DEV Community

Cover image for Dockerize php application
Ayman Elmalah
Ayman Elmalah

Posted on

Dockerize php application

In this article you will learn how to dockerize php application or any php framework like laravel, symfony and others
The first question is : What is docker ?
Docker is a set of platform as service (PaaS) products that uses OS level virtualization to deliver software in packages called containers. Containers are isolated from one another and bundle their own software, libraries and configuration files; they can communicate with each other through well-defined channels. All containers are run by a single operating system kernel and therefore use fewer resources than virtual machines

you can learn more about docker from https://www.docker.com/

Prerequests

Docker installed
Knowledge about docker
Knowledge about php
What services we will use in this article ?

php
mysql
nginx
phpmyadmin
composer
artisan
npm
We need to build directory structure for the application first

|-- phpdock
|   |-- nginx
|   |   |-- default.conf
|   |-- php
|   |   |-- Dockerfile
|   |-- .env
|   |-- .env.example
|   |-- .gitignore
|   |-- docker-compose.yml
|
|-- src
    |-- public
        |-- index.php
Enter fullscreen mode Exit fullscreen mode

First thing we will open our phpdock/docker-compose.yml then start structuring our file

version: '3'

networks:
backend:

services:
php:

mysql:

nginx:

phpmyadmin:

composer:

artisan:

npm:

This will be the file structure for docker-compose.yml file, we will use version 3 of docker compose, the network to communicate between services will be backend, you can name it the name you want

and we will list the services as showed in code

HINT : we will use .env to save environment data and call it in docker

As known .env can contain key=value and in docker we can call value by the given key as this way ${KEY}

Now we can start building the first service in our app, it's PHP

we still openeing docker-compose.yml so web can update php service

php:
build:
context: ./php
dockerfile: Dockerfile
container_name: php
volumes:
- ../src:/var/www/html
ports:
- "${PHP_PORT}:${PHP_HOST_PORT}"
networks:
- backend

We can now explain this part

In this part we will use Dockerfile to pull php from docker, the docker file will be placed in phpdock/php/Dockerfile so the service will use context ./php as it's the path of Dockerfile, then the docker file name is Dockerfile, we can now name the pulled container php or the name you want, we will use the volumes to share user data to the container directory so developer will work on src/ and we can access this path using ../src and it will share this data to var/www/html as working directory, now we need to use a port for php, we will write it in .env and use it in this file as a variable like ${KEY}, networks that will be used in php is backend

Now we can update phpdock/php/Dockerfile

FROM php:7.4-fpm-alpine

WORKDIR /var/www/html

RUN docker-php-ext-install pdo pdo_mysql

in dockerfile we can pull php version from official php, and we can make workdir /var/www/html , we need other extenstions to be installed in our app, you can add the extensions you want, it's a simple example 

Now we can update phpdock/.env

################## PHP

PHP_PORT=8081
PHP_HOST_PORT=80

The other service that we need to update is MYSQL, we will open docker-compose.yml and update mysql service

mysql:
image: mysql:${MYSQL_VERSION}
container_name: mysql
restart: always
tty: true
ports:
- "${MYSQL_PORT}:${MYSQL_HOST_PORT}"
environment:
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
SERVICE_TAGS: dev
SERVICE_NAME: mysql
networks:
- backend

The same code as php but now we can pull mysql from docker-compose.yml, the new thing you need to know that in mysql we need to create database with user and password after installation, so we wrote environment variables

Now we can update phpdock/.env

################## MYSQL

MYSQL_VERSION=5.7.29
MYSQL_DATABASE=default
MYSQL_USER=default
MYSQL_PASSWORD=secret
MYSQL_ROOT_PASSWORD=secret
MYSQL_PORT=3306
MYSQL_HOST_PORT=3306

The other service that we need to update is NGINX, we will open docker-compose.yml and update nginx service

nginx:
image: nginx:${NGINX_VERSION}
container_name: nginx
ports:
- "${NGINX_PORT}:${NGINX_HOST_PORT}"
volumes:
- ../src:/var/www/html
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
- mysql
networks:
- backend

 we will pull nginx and we can add a new volume to make developer write app configuration as the way app need, the nginx depends on php and mysql services

Now we can update phpdock/nginx/default.conf

server {
listen 80;
index index.php index.html;
server_name localhost;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/html/public;

location / {
    try_files $uri $uri/ /index.php?$query_string;
}

location ~ \.php$ {
    try_files $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass php:9000;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
}
Enter fullscreen mode Exit fullscreen mode

}

and we can also update phpdock/.env

################## NGINX

NGINX_VERSION=stable-alpine
NGINX_PORT=8080
NGINX_HOST_PORT=80

The other service that we need to update is PHPMYADMIN, we will open docker-compose.yml and update phpmyadmin service

phpmyadmin:
image: phpmyadmin/phpmyadmin:${PHPMYADMIN_VERSION}
container_name: phpmyadmin
restart: always
ports:
- "${PHPMYADMIN_PORT}:${PHPMYADMIN_HOST_PORT}"
depends_on:
- php
- mysql
environment:
PMA_HOST: ${PMA_HOST}
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
networks:
- backend

phpmyadmin is very easy to understand how to build, it's the same as other services and no thing is complicated, 

and we can also update phpdock/.env

################## PHPMYADMIN

PHPMYADMIN_VERSION=4.7
PHPMYADMIN_PORT=8082
PHPMYADMIN_HOST_PORT=80
PMA_HOST=mysql

Now the application is ready for running but other frameworks like laravel will need some features to work well like composer, artisan, and npm so we will add it to our app and of you dont need it you can skip this step

Now we can add features we will need, so we will update now composer service at docker-compose.yml

composer:
image: composer:${COMPOSER_VERSION}
container_name: composer
volumes:
- ../src:/var/www/html
working_dir: /var/www/html
depends_on:
- php
networks:
- backend

it's very easy to understand this code, so we can now update phpdock/.env

################## COMPOSER

COMPOSER_VERSION=latest

Now we can add artisan service, we can update docker-compose.yml

artisan:
build:
context: ./php
dockerfile: Dockerfile
container_name: artisan
volumes:
- ../src:/var/www/html
depends_on:
- mysql
working_dir: /var/www/html
entrypoint: ['php', '/var/www/html/artisan']
networks:
- backend

The new thing you want to know is entrypoint, we do it to make developer write the command artisan and it will point to php /var/www/html/artisan, it's the php path

The last section we will do is npm service, we can update docker-compose.yml

npm:
image: node:${NODE_VERSION}
container_name: npm
volumes:
- ../src:/var/www/html
working_dir: /var/www/html
entrypoint: ['npm']

And we need now update phpdock/.env

################## NODE

NODE_VERSION=13.7

Now we can copy .env file content to .env.example content, and in .gitignore we can make .env ignored so we can push it to any git repository without push .env to save our data

Now the services is ready for installed

you can now open your terminal and go to phpdock directory then run this command

docker-compose build && docker-compose up -d

Then open src/public/index.php

<?php

echo "Hello world";

Open your browser and visit http://127.0.0.1:8080/ for your php code, http://127.0.0.1:8082/ for phpmyadmin access

All thing is good until now

If you want to install laravel as example, you can clone it into src app then access this link in brwoser you will show laravel app http://127.0.0.1:8080/

To run composer command like composer dump autoload => go to terminal in phpdock and run this command
docker-compose run composer dump-autoload

To run artisan command like php artisan migrate => go to terminal in phpdock and run this command
docker-compose run artisan migrate

To run npm command like npm install => go to terminal in phpdock and run this command
docker-compose run npm install

If you are using laravel, these lines will be database environments variables in .env, or the variables you wrote in .env for docker

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=default
DB_USERNAME=default
DB_PASSWORD=secret

You will find source code https://github.com/ayman-elmalah/phpdock

Top comments (1)

Collapse
 
thalleslopes profile image
thalles-lopes

Format your code.