PHP FPM container for Symfony 4 application with Docker Compose

How to run PHP FPM container with Docker Compose?

docker-compose.yml

Example container configuration:

services:
    php:
        build: .docker/php-fpm
        container_name: php
        working_dir: /application
        volumes:
            - .:/application
            - /application/node_modules
            - ./.docker/php-fpm/custom.ini:/etc/php/7.2/fpm/conf.d/custom.ini
            - ./.docker/php-fpm/xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
            - ~/.ssh/:/root/.ssh/
        env_file:
            - .env

What does it all mean?

        build: .docker/php-fpm

Configuration options that are applied at build time. In this case it is a string containing a path to the build context, which might be either a path to a directory containing a Dockerfile (as in this case), or a url to a git repository.

        container_name: php

Specifies a custom container name, rather than a generated default name.

        working_dir: /application

Sets the working directory of the container that is created. It is the same as the WORKDIR command in Dockerfile, and as the --workdir flag to docker run.

        volumes:

Mounts host paths or named volumes, specified as sub-options to a service.

In case of the above configuration:

            - .:/application

will mount current local directory (where docker-compose.yml is located) as /application in the container.

            - /application/node_modules

will exclude node_modules directory from the above mount.

            - ./.docker/php-fpm/custom.ini:/etc/php/7.2/fpm/conf.d/custom.ini

will mount local .docker/php-fpm/custom.ini file as /etc/php/7.2/fpm/conf.d/custom.ini in the container, allowing easy modifications to PHP configuration.

            - ./.docker/php-fpm/xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini

will mount local .docker/php-fpm/xdebug.ini file as /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini in the container, allowing easy modifications to XDebug configuration.

            - ~/.ssh/:/root/.ssh/

will mount local ~/.ssh/ directory as /root/.ssh/ in the container, allowing it to use all your local SSH keys.

        env_file:
            - .env

Add environment variables from a file. Can be a single value or a list.

.docker/php-fpm/Dockerfile

FROM php:7.2.7-fpm-alpine
# Not using eu.gcr.io/hubside-infra-prod/team-infra/docker-images/php-fpm:7.2-stretch
# as it presumes Symfony is already installed, and fails to start if it's not.

WORKDIR /application

# Install PHP modules
RUN apk add --no-cache --virtual \
        .phpize-deps $PHPIZE_DEPS \
        autoconf \
        pkgconf \
        libssl1.0 \
        openssl-dev \
        freetype-dev \
        libpng-dev \
        libjpeg-turbo-dev \
        libmcrypt-dev \
        git \
        openssh-client \
        curl \
        wget \
        libtool \
        zlib-dev \
        icu-dev \
        g++ \
        linux-headers > /dev/null \
    && pecl bundle -d /usr/src/php/ext redis \
    && docker-php-ext-install -j2 redis \
    && docker-php-ext-configure intl \
    && docker-php-ext-install -j2 intl \
    && pecl bundle -d /usr/src/php/ext mcrypt \
    && docker-php-ext-configure mcrypt \
    && pecl bundle -d /usr/src/php/ext apcu \
    && docker-php-ext-install -j2 apcu \
    && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install -j2 bcmath gd iconv mbstring mcrypt zip \
    && docker-php-ext-enable opcache \
    && rm /usr/src/php/ext/*.tgz \
    && pecl install xdebug \
    && docker-php-ext-enable xdebug \
    && echo "error_reporting = E_ALL" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
    && echo "display_startup_errors = On" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
    && echo "display_errors = On" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
    && echo "xdebug.profiler_enable = 0" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
    && echo "xdebug.remote_connect_back=off" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
    && echo "xdebug.remote_host=host.docker.internal" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
    && echo "xdebug.remote_port=10000" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
    && echo "xdebug.remote_autostart=0" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
    && echo "xdebug.idekey=PHPSTORM" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
    && echo "xdebug.max_nesting_level=256" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
    && echo "xdebug.remote_enable=1" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
    && php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
    && php composer-setup.php --filename=composer --install-dir=/usr/bin \
    && chmod +x /usr/bin/composer \
    && php -r "unlink('composer-setup.php');" \
    && composer --version \
    && pecl channel-update pecl.php.net \
    && pecl install mongodb \
    && docker-php-ext-enable mongodb \
    && composer global require "phpunit/phpunit" \
    && export PATH=$PATH:/root/.composer/vendor/bin \
    && ln -s /root/.composer/vendor/bin/phpunit /usr/bin/phpunit

.docker/php-fpm/custom.ini

memory_limit = 512M
upload_max_filesize = 100M
post_max_size = 100M

.docker/php-fpm/xdebug.ini

error_reporting = E_ALL
display_startup_errors = On
display_errors = On
xdebug.profiler_enable = 0
xdebug.remote_connect_back = off
xdebug.remote_host = host.docker.internal
xdebug.remote_port = 10000
xdebug.remote_autostart = 0
xdebug.idekey = PHPSTORM
xdebug.max_nesting_level = 256
xdebug.remote_enable = 1

.env.dist

COMPOSE_PROJECT_NAME=symfony

# PHP-FPM
PHP_IDE_CONFIG=serverName=docker_symfony

.dockerignore

node_modules
npm-debug.log