Spinning up Docker Infrastructure for Apache-Php-MySql

Spinning up docker infrastructure for apache-php-mysql can have its own queer requirements. In this blog we will see, how we can get going and setting it up.

Installation

Let's download and install the CE-edition of docker and docker-compose from the official docker website.

What we Got!!!

After fresh installation, we have

$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest fce289e99eb9 15 months ago 1.84kB
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
efc1e1ca6409 bridge bridge local
34f81bd2e623 host host local
94d2f826785d none null local

Dockerfile for php-apache

Let us create a Dockerfile for installation of php-apache. This Dockerfile will cater for pdo_mysql extensions.

FROM php:7.4-apache
RUN apt update && apt-get upgrade -y
RUN docker-php-ext-install pdo_mysql
EXPOSE 80

Compose docker-compose.yml

Now lets, create docker-compose.yml file. Create three folders in the directory containing docker-compose.yml file.

  • php
  • vol-db
  • vol-php

Copy the Dockerfile we created previously into the php folder. vol-db and vpl-php will be used to map the database and php volumes. We will also create a database and user for MySql, database myapp_db; username devuser; and password devpass.

So, our docker-compose.yml looks like:

version: '3'
services:
db:
image: mysql:latest
container_name: app-db-mysql
environment:
MYSQL_ROOT_PASSWORD: tiger
MYSQL_DATABASE: myapp_db
MYSQL_USER: devuser
MYSQL_PASSWORD: devpass
volumes:
- ./vol-db:/var/lib/mysql/
networks:
- app-network
web:
build:
context: ./php
dockerfile: Dockerfile
container_name: app-web-php74
depends_on:
- db
volumes:
- ./vol-www:/var/www/html/
ports:
- 5000:80
networks:
- app-network
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: app-phpmyadmin
depends_on:
- db
links:
- db:db
environment:
MYSQL_ROOT_PASSWORD: tiger
ports:
- 5001:80
networks:
- app-network
networks:
app-network:

docker-compose up

cd into the directory containing docker-compose.yml file and the run sudo docker-compose up command.

Now, lets check the sate of our docker containers and networks

$ docker container ls --format "{{.ID}}: {{.Names}}: {{.Ports}}"
1f3cb046fe8c: app-web-php74: 0.0.0.0:5000->80/tcp
c715238c051c: app-phpmyadmin: 0.0.0.0:5001->80/tcp
b66a4f79e291: app-db-mysql: 3306/tcp, 33060/tcp
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
5e9b89160c36 app-machine_app-network bridge local
efc1e1ca6409 bridge bridge local
a2e9779a2337 docker-files_server-network bridge local
34f81bd2e623 host host local
94d2f826785d none null local
$ docker network inspect app-machine_app-network
...
"Containers": {
"1f3cb046fe8cd8a1c6581d8c582d1acc6854b6af5badf17f6ed395a4f4acd934": {
"Name": "app-web-php74",
"EndpointID": "4807260f315b9b97cec457e73c5eec78ad70170d0e7b4e34fd30c57448b96e8f",
"MacAddress": "02:42:ac:19:00:04",
"IPv4Address": "172.25.0.4/16",
"IPv6Address": ""
},
"b66a4f79e2911a56671a2c35543ac2d9bb2a4ef8826f2f426ba6a555ace46ff6": {
"Name": "app-db-mysql",
"EndpointID": "eff9246fa1ffd075ca5b7a66f2ab5a01177b7607a50b545a9814eda76b1e22e6",
"MacAddress": "02:42:ac:19:00:02",
"IPv4Address": "172.25.0.2/16",
"IPv6Address": ""
},
"c715238c051c85f3516d55e70079b3fe85bad7a43c6bc9cc64601b81f9650f62": {
"Name": "app-phpmyadmin",
"EndpointID": "3626814d31c4909c05a41f73bb7afb06fded070d217c9ece38cf297e31626850",
"MacAddress": "02:42:ac:19:00:03",
"IPv4Address": "172.25.0.3/16",
"IPv6Address": ""
}
},
...

Testing our Docker Infrastructure

Test apache-php

Let's create index.php file and place it in vol-www folder

<?php
// Show all information, defaults to INFO_ALL
phpinfo();
?>

In the browser, write localhost:5000 and we should get phpinfo page. Similarly, we can check phpmyadmin page by checking url localhost:5001.

The phpinfo page will show the location of the php configuration file php.ini in the Loaded Configuration File section. This path can then be mapped to the local vol in order to preserve any changes in the php.ini file. This can be done by inserting following line in the docker-compose.yml file under web/volume section.

- ./vol-php:/usr/local/etc/php/

Test connection with database

create a file conn.php in vol-www folder

<?php
$servername = "app-db-mysql";
$username = "devuser";
$password = "devpass";
try {
$conn = new PDO("mysql:host=$servername;dbname=myapp_db", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully";
}
catch(PDOException $e)
{
echo "Connection failed: " . $e->getMessage();
}
?>

Now, lets check the connection with database by running localhost:5000\conn.php

Peep inside my running php-apache instance

Let's see whats happening inside my running docker instance

$ docker exec -it app-web-php74 bash