Member preview

“turned on gray laptop computer” by Luca Bravo on Unsplash

Use Docker Compose to local develop with PHP

Requirements:

Installing PHP on your local machine is not necessary, however it can be required by some IDE to run code linter or code debug.

Why develop with Docker

With Docker you can keep your host machine clear, you don’t need to install anything beside Docker itself.

In this specific case you can run your PHP development environment with a simple command docker-compose up -d , and start coding.

File structure

You can find the source code here on GitHub. This is what your project must be like:

-nginx
web.dockerfile
vhost.conf
-php
app.dockerfile
-src
public
index.php
composer.json
-docker-compose.yaml

All PHP source files of our application will be inside our src directory.

App Docker File

The application’s DockerFile is the largest file in this environment, here we setup all the specification to install and run PHP and all his extension.

You can easily switch the PHP version by changing the base image version, in this example we are using PHP 7.2-fpm .

This DockerFile include some of the most basic package that can be used during a typical development, it also include the composer installation and run. In the file is also present a file permission setup. Those options aren’t required, but they can be really useful.

#php/app.dockerfile
FROM php:7.2-fpm
RUN buildDeps=" \
" \
runtimeDeps=" \
curl \
libxslt-dev \
mysql-client \
libfreetype6-dev \
libjpeg-dev \
unzip \
" \
&& apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y $buildDeps $runtimeDeps\
&& docker-php-ext-install pdo_mysql xsl mbstring zip opcache pcntl\
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install gd \
&& apt-get purge -y --auto-remove $buildDeps \
&& rm -r /var/lib/apt/lists/*

WORKDIR /var/www
COPY ./src /var/www
#Composer install and run
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN composer install --no-dev \
&& rm -rf /usr/local/bin/composer*
#File Permission Setup
RUN chown -R www-data:www-data /var/www/ \
&& find /var/www -type f -exec chmod 644 {} \; \
&& find /var/www -type d -exec chmod 775 {} \;

Nginx Web Server Docker File

Nginx Dockerfile is really simple, we don’t need to specify anything beside the image, all other settings will be made in docker-compose file.

#nginx/web.dockerfile
FROM nginx:stable

Nginx requires a configuration file, in the repository you will find it inside the nginx directory. Configuration file allows you to define all the server/reverse proxy configuration.

Nginx Web Server Configuration File

#nginx/nginx.conf
server {
listen 80;
index index.php index.html;
root /var/www/public;

location / {
try_files $uri /index.php?$args;
}
  location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}

In the location ~ \.php$ we setup a reverse proxy for all files with a php extension, you can check on Nginx official documentation more information about reverse proxy.

Docker Compose File

This docker compose simple describe the two necessary container needed to run a PHP development environment:

The Web Server

This container will listen on our HTTP or HTTPS ports and will serve all our static contents. It will also reverse proxy all the request made to a PHP files to our application container.

Application

This container has PHP and his extension installed, it will run our PHP files when the Web Server ask for them.

#docker-compose.yml
version: '3'
services:
####################################################################
# The Web Server
####################################################################
web:
build:
context: ./
dockerfile: ./nginx/web.dockerfile
working_dir: /var/www
volumes:
- ./src/:/var/www/
- ./nginx/vhost.conf:/etc/nginx/conf.d/default.conf
ports:
- "80:80"
- "443:443"
depends_on:
- app
####################################################################
# App
####################################################################
app:
build:
context: ./
dockerfile: ./php/app.dockerfile
working_dir: /var/www
volumes:
- ./src/:/var/www

Why we need Volumes?

In local development volumes are really important, with a volume we can update our code without rebuilding the whole image.

Volumes will be created when we run the container. If we need our files during docker build time we have to use Copy or Add in our DockerFile.

An example can be the composer.json file that is required by composer during the build process.

Why we need volumes on both Web Server and Application

To run PHP code we need to copy our php files inside the application container. The Nginx container doesn’t need our php files to reverse proxy all the requests.

In some cases we can need to serve static assets like css,html or js files, in this specific case we want to create a volume to copy those files in our web server. This volume allows Nginx to serve those static assets and allows us to change and modify those in real time.

Start Docker Compose

To run this commands you must be in the repository’s root.

  1. docker-compose build
  2. docker-compose up -d

Now you are ready to use your development environment.

The Web Server will listen on port 80 or 443, inside the repository you will find the file /src/public/index.php to test if the environment is working.

<?php
echo "Hello, this is a simple php script.";
?>

With this script we can be sure that PHP is working, you can simple navigate with a browser to localhost and get the response.

Useful Links