Build Docker Container for PHP 7 and MySQL Based Application

Blog primary image

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

PHP application running as docker container

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.

PHP MySQL connectivity from docker container

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.

PHPMyAdmin access to the docker application

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