Build Docker Container for PHP 7 and MySQL Based Application
Docker has given a different perception to application development and their run time environment. Containerization of application is very much essential now a days. Think about you have two different application in production server at same time and those applications are developed in PHP 7.2 and PHP 5.6 respectively. Now you can imagine how much trouble it could be to manage two different PHP version.
If you were using Docker, you could simply spin up another container, set the PHP version to 5.6 and put it right next to your other container that has PHP version 7.2 on it, running on the same server with no problems whatsoever. That flexibility, portability and the option to more efficiently use your server resources are what make Docker so compelling to use.
The below YouTube Video will tell you how to install Docker. Here we are using Ubuntu as OS but if you are an Windows user, you can create a virtual machine using Virtual Box and Install Ubuntu as Virtual OS. This approach is better as your primary or host OS is untouched from any activity required for your learning purpose. You may watch this YouTube video on How to Install Ubuntu as virtual machine (VM).
Once you have installed and familiar with docker commands, let's begin with our application development in PHP and MySQL and PHPMyAdmin to access the database with proper GUI.
You may watch the YouTube video on building Docker container for PHP7 + MySQL application.
In this demo application we will also need docker-compose
for the complete application. Check is docker compose is installed already by docker-compose -v
command in Linux terminal. In case you need to install it, you may run the command apt install docker-compose
to install from apt
package manager.
PHP Application:
Create a folder (something like $HOME/Documents/docker-example/moe-php-mysql-demo
) and start writing your PHP code.
www/index.php
<?php
echo "This is a PHP-MySQL demo application - Created by MyOnlineEdu.com.";
echo "<br>";
echo "Thanks for watching...";
This is a simple PHP page to render few textual information with with echo
. Now let us create one more page with name www/php-info.php
<?php
echo 'PHP-MySQL demo application for docker by MyOnlineEdu.com';
phpinfo();
?>
In the above code we will display the phpinfo()
function to display all details of the PHP installed.
Create Docker Image and Run the Image as Container:
Now we have developed the PHP application, it is time to create an Docker image and execute the image as docker container.So far we have not used MySQL and it will be discussed later with docker-compose
. Now we have to create a Docker file (the file name is Dockerfile without any extension) with the below content:
FROM php:7.2-apache
RUN apt-get update && apt-get install -y
RUN docker-php-ext-install mysqli pdo_mysql
RUN mkdir /app \
&& mkdir /app/moe-php-mysql-demo \
&& mkdir /app/moe-php-mysql-demo/www
COPY www/ /app/moe-php-mysql-demo/www/
RUN cp -r /app/moe-php-mysql-demo/www/* /var/www/html/.
Now build the image with docker command:
$sudo docker build . -t amakundu/moe-php-mysql-demo:1.0.0
Replace the amakundu
with your own docker repository name with any name you want.
Run the Command to see docker images:
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
amakundu/moe-php-mysql-demo 1.0.0 45bb32043b10 2 days ago 411MB
php 7.2-apache 3492f624190e 3 days ago 378MB
Now you see that your docker image amakundu/moe-php-mysql-demo
is created and available. Now you have to run the image to execute and start the PHP application.
To execute use the below command:
$ sudo docker run -d -it -p 30001:80 --name "moe-php-mysql-app" \
-v "$(pwd)"/www:/var/www/html \
amakundu/moe-php-mysql-demo:1.0.0
This will run the application image as container which you can see the run time with below command:
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0a5673538ae3 amakundu/moe-php-mysql-demo:1.0.0 "docker-php-entrypoi…" 7 seconds ago Up 7 seconds 0.0.0.0:30001->80/tcp moe-php-mysql-app
The -p 30001:80
is telling that to publish the port 80 to host's 30001 port. Now you can access your application to http://localhost:30001
in any web browser.
Also the -v "$(pwd)"/www:/var/www/html
option is telling to bind a volume to the container's /var/www/html
directory to "$(pwd)"/www
. This will help the development as every time you do a code change it will be reflected ASAP to the container application.
Docker Compose for PHP, MySQL and PHPMyAdmin:
Now it is time to deploy the all three that is the PHP application, MySQL database and PHPMyAdmin as docker container and connect the MySQL database from PHP application. For this we will use docker-compose. You need to write a docker-compose.yml
file whose content will as below:
version: "3.2"
services:
php:
build:
context: .
image: amakundu/moe-php-mysql-demo:1.0.0
networks:
- frontend
- backend
environment:
- MYSQL_HOST=moe-mysql-app
- MYSQL_USER=moeuser
- MYSQL_PASSWORD=moepass
- MYSQL_DB=moe_db
volumes:
- ./www/:/var/www/html/
ports:
- "30001:80"
container_name: moe-php-app
mysql:
image: mysql:5.7
networks:
- backend
environment:
- MYSQL_ROOT_PASSWORD=rootpassword
- MYSQL_USER=moeuser
- MYSQL_PASSWORD=moepass
- MYSQL_DATABASE=moe_db
container_name: moe-mysql-app
phpmyadmin:
image: phpmyadmin/phpmyadmin:4.7
depends_on:
- mysql
networks:
- backend
ports:
- "30002:80"
environment:
- PMA_HOST=moe-mysql-app
- PMA_PORT= 3306
volumes:
- /sessions
container_name: moe-phpmyadmin-app
networks:
frontend:
backend:
Run the command for the docker compose:
$ sudo docker-compose up --build
Now check the application is available at http://localhost:30001
Write a PHP page www/mysql-connect.php
as below:
<h3>Hello Learner! Welcome to MyOnlineEdu.com Tutorial</h3>
<h4>Attempting MySQL connection from php...</h4>
<?php
if(!empty($_ENV['MYSQL_HOST']))
$host = $_ENV['MYSQL_HOST'];
else
$host = 'moe-mysql-app';
if(!empty($_ENV['MYSQL_USER']))
$user = $_ENV['MYSQL_USER'];
else
$user = 'moeuser';
if(!empty($_ENV['MYSQL_PASSWORD']))
$pass = $_ENV['MYSQL_PASSWORD'];
else
$pass = 'moepass';
if(!empty($_ENV['MYSQL_DB']))
$db_name = $_ENV['MYSQL_DB'];
else
$db_name = 'moe_db';
echo "Connecting to Database: $host $user $pass $db_name";
echo "<br><br>";
$conn = new mysqli($host, $user, $pass, $db_name);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
echo "Connected to MySQL successfully!";
echo "<br><br>";
$res = $conn->query("Select ITEM_NAME, ITEM_DESC, ITEM_ONHAND from MOE_ITEM_T");
for ($row_no = 0; $row_no < $res->num_rows; $row_no++) {
$res->data_seek($row_no);
$row = $res->fetch_assoc();
echo " Item Name = " . $row['ITEM_NAME'] . " Item Description = " . $row['ITEM_DESC'] . " Item Onhand = " . $row['ITEM_ONHAND'];
echo "<br>";
}
$res->close();
$conn->close();
?>
Access this page by http://localhost:30001/mysql-connect.php and you will see the below output in your browser.
Now you might be wondering how the data are coming from MySQL database? Well, as we also have PHPMyAdmin container, we can connect to the MySQL database from browser with the port given in the docker-compose.yml
file as 30002
.
After that you can create the tables as per the below database script:
-- phpMyAdmin SQL Dump
-- version 4.7.9
-- https://www.phpmyadmin.net/
--
-- Generation Time: Dec 04, 2018 at 11:50 AM
-- Server version: 5.7.24
-- PHP Version: 7.2.2
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `moe_db`
--
-- --------------------------------------------------------
--
-- Table structure for table `MOE_ITEM_T`
--
CREATE TABLE `MOE_ITEM_T` (
`ITEM_NAME` varchar(50) NOT NULL,
`ITEM_DESC` varchar(100) NOT NULL,
`ITEM_ONHAND` int(5) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Dumping data for table `MOE_ITEM_T`
--
INSERT INTO `MOE_ITEM_T` (`ITEM_NAME`, `ITEM_DESC`, `ITEM_ONHAND`) VALUES
('TEST-ITEM-1', 'TEST-ITEM-DESC-1', 10),
('TEST-ITEM-2', 'TEST-ITEM-DESC-2', 20);
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
Now you are all set to run the complete application as PHP-MySql combination. Here the PHP application is containerized and also the MySQL is containerized. They are running as two different container and talking to each other. Similarly the PHPMyAdmin is another container and talking to the MySQL container.
You can find the code from GitHub here.
Comments