Creating a PHP project with Docker

Development environment for a PHP project is fairly small, and consists of only several key components: PHP binaries, a web server and dependency management tool. Those will ensure you can solve most of the problems on your way and produce a usable and configurable PHP application.

Docker containers, as a concept, are designed to be lightweight and exist for a limited amount of time, so the popular approach is to separate application components into containers. The easiest approach though is to combine everything in a single container and run continuously, because it mimics how you would do it on a live server.

Here is a gist which contains the setup –
It uses Ubuntu 18.04, PHP 7.2 and the latest available Apache server. You can adjust the versions according to your needs, but the basic approach stays.

Dockerfile for PHP project

First lines setup the base image for the container, which is Ubuntu. Also we’re disabling any interactions the OS might ask of us, for example locale setup details.

FROM ubuntu:18.04
ENV DEBIAN_FRONTEND=noninteractive

Then we’re installing the Linux packages we need for project development. Those would include:

  • PHP 7.2 binaries
  • PHP 7.2 extensions: curl, json, MySQL, Soap, Zip, Xml, etc
  • Apache web server
  • Apache PHP module, to run PHP scripts from a web server
  • MySQL client, in case you need to connect to a database via terminal
  • Zip / Unzip packages, for dependency manager (composer)
# install apache / php
RUN apt-get update && apt-get install -yq --no-install-recommends \
    apt-utils \
    curl \
    # Install git
    git \
    # Install apache
    apache2 \
    # Install php 7.2
    libapache2-mod-php7.2 \
    php7.2-cli \
    php7.2-json \
    php7.2-curl \
    php7.2-fpm \
    php7.2-gd \
    php7.2-ldap \
    php7.2-mbstring \
    php7.2-mysql \
    php7.2-soap \
    php7.2-sqlite3 \
    php7.2-xml \
    php7.2-zip \
    php7.2-intl \
    # Install tools
    openssl \
    ca-certificates \
    mysql-client \
    iputils-ping \
    locales \
    sqlite3 \
    ssh \
    sudo \
    gnupg \
    zip \
    unzip \
    && apt-get clean

Next we’re installing Composer dependency manager, which is a de-facto standart for PHP projects.

# Install composer
RUN curl -sS | php -- --install-dir=/usr/local/bin --filename=composer

Next we need to configure Linux locales, basically to avoid unnecessary confusion and notices for those. And of course enable Apache rewrite mod, in case you are keen on using .htaccess files.

# Set locales
RUN locale-gen en_US.UTF-8 en_GB.UTF-8 de_DE.UTF-8 es_ES.UTF-8 fr_FR.UTF-8 it_IT.UTF-8 km_KH sv_SE.UTF-8 fi_FI.UTF-8
RUN a2enmod rewrite expires

Last we define the working directory as /var/www/html, because that’s the default directory for apache. Then start the web server.

# install app
WORKDIR /var/www/html
# run
CMD apache2ctl -D FOREGROUND

The container will be alive until you kill the web-server process. You can develop your project while the server is running, and check your code right away without restarting the container. To achieve that, when launching the container, you need to mount your project directory to /var/www/html.

Starting the project

The commands in this example are from Windows 10 Power shell, but would actually work on Mac and Linux as well, given you installed the docker first.

Make the directory for your project and go to that directory.

mkdir tutorial-docker-project
cd tutorial-docker-project

Get the RAW version of the Dockerfile in the

wget -o Dockerfile

Build the container using the Dockerfile and call it apache2-php

docker build -t apache2-php .

Now we can actually start the container and mount our working directory. Also, bind http://localhost:8080 to the Apache server 80 port, so we could actually open our PHP scripts in browser.

docker run -d -p 8080:80 --name example-phplogger-project -v ${PWD}:/var/www/html apache2-php

Setting up the project

Now the container is running, we can connect into the instance and start coding things.

docker exec -it example-phplogger-project bash

First, lets initialize a dependency management system, because there’s objectively no PHP project without open source libraries in it. This will do absolutely nothing, except create a composer.json file, which will be the basis for our dependencies.

composer init --no-interaction

Now let us create index.php file with the following contents.

# index.php
echo 'Hello, world!';

Now if you open http://localhost:8080, you should see the Hello, world! message, which means everything works as expected and you can start the actual development.