The other day, I wrote an article I made an API that returns the predicted value of the machine learning model with Docker, but I can get the predicted value with the API. Now that I want to make a prediction from the Web page, I built it with Docker. The image to be built this time is as shown in the figure below.
I would like to set up three containers on Docker, access WordPress from a local browser, and check the prediction result with WordPress.
The environment to use is as follows.
$sw_vers
ProductName: Mac OS X
ProductVersion: 10.13.6
BuildVersion: 17G9016
$docker version
Client: Docker Engine - Community
Version: 19.03.4
API version: 1.40
(abridgement)
Server: Docker Engine - Community
Engine:
Version: 19.03.4
API version: 1.40 (minimum version 1.12)
(abridgement)
I think there are various steps, but this time after building WordPress, we will build a container for prediction. After confirming those connections, we will build a WordPress article and check the operation.
Get the container image used to predict WordPress and machine learning models. Refer to this [^ 1] article and execute the following three commands to get the image.
$ docker pull mysql:5.7.25
$ docker pull wordpress:4.9.1
Check the images obtained with the docker images
command.
$docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7.25 98455b9624a9 7 months ago 372MB
wordpress 4.9.1 28084cde273b 22 months ago 408MB
Start the WordPress and MySQL container.
Refer to here [^ 2] and build a network with the docker network
command before starting.
$docker network create test-network
Confirm that the network has been created with the following command.
$docker network ls
NETWORK ID NAME DRIVER SCOPE
edbb6037a089 bridge bridge local
5f7c06763a14 host host local
1b7e419414a4 none null local
687f0232408b test-network bridge local
Start the container on the created network.
$docker run --name mysql --network test-network -e MYSQL_ROOT_PASSWORD=test-pw -d mysql:5.7.25
$docker run --name wordpress --network test-network -e WORDPRESS_DB_PASSWORD=test-pw -v $(pwd)/vol:/mnt -p 8080:80 -d wordpress:4.9.1
For WordPress, the -v
option mounts a local directory named vol in / mnt inside the container. This is because the php script to be used later for POST communication to the prediction API is created locally and stored in the container.
I also set port forwarding with the -p
option to forward the local port 8080 to port 80 in the container.
When you access http: // localhost: 8080
with your local browser, the WordPress setting screen will appear, so set your preferred language.
Set the administrator user name and password. You will also need to enter your email address, but it's okay if you enter it appropriately.
Click the "Install WordPress" button and a screen for the administrator will appear.
At this point, if you access http: // localhost: 8080 /
again with your browser, a stylish page will appear.
This is the end of WordPress construction. The part that hits the prediction API will be set later.
The construction is as described in I made an API that returns the predicted value of the machine learning model with Docker, so I will omit it, but when starting the container Make sure to specify the created network.
$docker run -it --name test-api --network test-network --rm -p 5000:5000 -v $(pwd)/vol:/home myflask/mlapi:1.0 /bin/bash
root@b9e8ac7cdb71:/# cd home/
root@b9e8ac7cdb71:/home# python3 api.py
Server is running ...
* Serving Flask app "api" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
You have now set up a predictive API server.
Make sure that three docker containers are running so far.
$docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b9e8ac7cdb71 myflask/mlapi:1.0 "/bin/bash" 8 seconds ago Up 6 seconds 0.0.0.0:5000->5000/tcp test-api
c6b2f713a6a5 wordpress:4.9.1 "docker-entrypoint.s…" 17 minutes ago Up 17 minutes 0.0.0.0:8080->80/tcp wordpress
290950f0f643 mysql:5.7.25 "docker-entrypoint.s…" 18 minutes ago Up 18 minutes 3306/tcp, 33060/tcp mysql
Check the connection with the prediction API server with the curl command from the WordPress container once.
Enter the WordPress container with the docker exec
command and send the prediction data with the curl command.
$docker exec -i -t c6b2f713a6a5 /bin/bash
root@c6b2f713a6a5:/var/www/html# curl http://test-api:5000/predict -X POST -H 'Content-Type:application/json' -d '{"feature":{"season":[1], "year":[0], "month":[1], "hour":[0], "holiday":[0], "weekday":[6], "workingday":[0], "weather":[1], "temp":[0.24], "feelslike":[0.3], "humidity":[0.8], "windspeed":[0.0]}}'
{"Content-Type":"application/json","prediction":[34.67747315059312],"success":true}
The predicted value is 34.67 ..., so the connection seems to be okay.
Now let's move on to WordPress settings. Create a new fixed page and fill in the following contents. In addition, the numerical choices for each item are set to Texto.
<form action="/ml-submit.php" method="post">
season: <select name="season">
<option value=0>0</option>
<option value=1>1</option>
<option value=2>2</option>
</select>
year: <select name="year">
<option value=0>0</option>
<option value=1>1</option>
<option value=2>2</option>
</select>
month: <select name="month">
<option value=0>0</option>
<option value=1>1</option>
<option value=2>2</option>
</select>
hour: <select name="hour">
<option value=0>0</option>
<option value=1>1</option>
<option value=2>2</option>
</select>
holiday: <select name="holiday">
<option value=0>0</option>
<option value=1>1</option>
<option value=2>2</option>
</select>
weekday: <select name="weekday">
<option value=0>0</option>
<option value=1>1</option>
</select>
workingday: <select name="workingday">
<option value=0>0</option>
<option value=1>1</option>
</select>
weather: <select name="weather">
<option value=0>0</option>
<option value=1>1</option>
<option value=2>2</option>
</select>
temp(0-1): <input type="text" name="temp">
feelslike(0-1): <input type="text" name="feelslike">
humidity(0-1): <input type="text" name="humidity">
windspeed(0-1): <input type="text" name="windspeed">
<input class="submit" type="submit" value="Run php" /></form>
Now when you click Publish, you will be able to see the page you created.
When you click the "Forecast" button on the created page, the data will be sent to the forecast API and the forecast result will be returned and displayed on the page. Create a php file locally.
ml-submit.php
<?php
$data = array(
'feature'=> array(
'season'=> array((int)$_POST['season']),
'year' => array((int)$_POST['year']),
'month' => array((int)$_POST['month']),
'hour' => array((int)$_POST['hour']),
'holiday' => array((int)$_POST['holiday']),
'weekday' => array((int)$_POST['weekday']),
'workingday' => array((int)$_POST['workingday']),
'weather' => array((int)$_POST['weather']),
'temp' => array((float)$_POST['temp']),
'feelslike' => array((float)$_POST['feelslike']),
'humidity' => array((float)$_POST['humidity']),
'windspeed' => array((float)$_POST['windspeed'])
)
);
$data_json = json_encode($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, 'http://test-api:5000/predict');
curl_setopt($ch, CURLOPT_PORT, 5000);
$result=curl_exec($ch);
$res_json = json_decode($result , true );
echo 'PREDICTION:'.$res_json['prediction'][0];
curl_close($ch);
echo "<br>update:".date("Y/m/d H:i:s");
?>
The data entered on the web page is stored in array format, converted to json format, and then sent to the prediction API server. I am trying to display the predicted value of the return value. In addition, about the creation of php, here [^ 3] is referred to. Store the locally created file in a WordPress container. Store php in the vol directory.
$ls vol/ml-submit.php
vol/ml-submit.php
Since the vol directory is mounted on / mnt on the container, copy the file to the directory where php is stored.
root@c6b2f713a6a5:/var/www/html# cp /mnt/ml-submit.php .
root@c6b2f713a6a5:/var/www/html# ls
index.php readme.html wp-blog-header.php wp-config.php wp-includes wp-login.php wp-signup.php
license.txt wp-activate.php wp-comments-post.php wp-content wp-links-opml.php wp-mail.php wp-trackback.php
ml-submit.php wp-admin wp-config-sample.php wp-cron.php wp-load.php wp-settings.php xmlrpc.php
Construction is complete up to this point.
Now, let's enter the appropriate value on the page created by WordPress and press the "Predict" button.
When you press the "Predict" button, the predicted value is displayed. Yay.
Predicted values etc. are displayed on a white page and it looks bad, but I was able to display it by hitting the prediction API on the web page.
I was able to predict the machine learning model on a web page created using WordPress on Docker. There are still some areas where I haven't studied enough, and it looks bad, but this is a topic for the future. In the future, I would like to run it on the cloud such as AWS.
Recommended Posts