Logo de Béjean Développement

Déployer Apache et PHP-FPM dans des conteneurs séparés

Objectif

Déployer Apache 2.4 (httpd) et PHP-FPM 8.1 sous Alpine 3.17 dans 2 conteneurs séparés.

Les fichiers sources sont disponibles sur le dépôt Froggit : Apache PHP-FPM.

Tutoriel

Arborescence

Commençons par créer un dossier dans lequel nous allons travailler :

mkdir apache-phpfpm

Dans ce dossier, nous allons créer un dossier pour stocker nos fichiers Dockerfile ainsi qu'un fichier de configuration pour Apache :

mkdir -p .docker/conf

Fichier index.php

A la racine de notre projet, nous allons créer le fichier index.php qui contiendra simplement :

<?php phpinfo();

Fichier : httpd.Dockerfile

Pour déployer Apache, on utilisera l'image httpd:2.4.57-alpine3.17, hormis la configuration du vhost, toute la configuration d'Apache se fera dans ce fichier que nous allons créer dans le dossier .docker :

# -*- coding: utf-8 -*-

FROM httpd:2.4.57-alpine3.17

LABEL authors="Nicolas Béjean <[email protected]>"
LABEL company="Béjean Développement"
LABEL website="www.bejean.eu"
LABEL version="1.0"

# Change port and update server name
RUN sed -i \
    -e 's/Listen 80/Listen 8000/' \
    -e 's/^#ServerName.*/ServerName localhost:8000/' \
    /usr/local/apache2/conf/httpd.conf

# Enable proxy and fcgi modules
RUN sed -i \
    -e 's/^#\(LoadModule proxy_module modules\/mod_proxy.so\)/\1/' \
    -e 's/^#\(LoadModule proxy_fcgi_module modules\/mod_proxy_fcgi.so\)/\1/' \
    /usr/local/apache2/conf/httpd.conf

# Add vhost configuration and copy vhost file
COPY conf/httpd-vhosts.conf /usr/local/apache2/conf/extra/httpd-vhosts.conf
RUN sed -i \
    -e 's/#Include\ conf\/extra\/httpd-vhosts.conf/Include\ conf\/extra\/httpd-vhosts.conf/' \
    /usr/local/apache2/conf/httpd.conf

# Create users, directories and update permissions
RUN addgroup -g 1000 app \
    && adduser -D -H -h /var/www/html -s /sbin/nologin -G app -u 1000 app \
    && mkdir -p /var/www/html /usr/local/apache2/logs \
    && chown -R app:app /var/www/html /usr/local/apache2/logs

# Change owner and group
USER app:app

# Change workdir
WORKDIR /var/www/html

# Expose port 8000
EXPOSE 8000

# Start apache
CMD ["httpd-foreground"]

J'ai pris soin de commenter chaque ligne du fichier afin de faciliter la lecture. Dans un premier temps, on modifie les paramètres du fichier de configuration d'Apache, puis on copie le fichier de configuration du virtualhost, que nous allons créer plus tard. On n'oublie pas de décommenter, à l'aide de la commande sed la directive permettant d'indiquer à Apache que le fichier de configuration httpd-vhosts.conf doit être chargée au lancement.

Fichier : phpfpm.Dockerfile

Pour déployer PHP-FPM, on utilisera l'image php:8.1.18-fpm-alpine3.17, la configuration de PHP-FPM est légèrement modifiée afin de lui indiquer le fuseau horaire ainsi que l'utilisateur qui sera utilisé par Apache pour exécuter les scripts PHP :

# -*- coding: utf-8 -*-

FROM php:8.1.18-fpm-alpine3.17

LABEL authors="Nicolas Béjean <[email protected]>"
LABEL company="Béjean Développement"
LABEL website="www.bejean.eu"
LABEL version="1.0"

# Set timezone
ENV TZ=Europe/Paris
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# Change port and update user, owner and group
RUN sed -i \
    -e 's/^user = www-data*/user = app/' \
    -e 's/^group = www-data*/group = app/' \
    -e 's/^;listen.owner = www-data*/listen.owner = app/' \
    -e 's/^;listen.group = www-data*/listen.group = app/' \
    /usr/local/etc/php-fpm.d/www.conf

# Create users, directories and update permissions
RUN addgroup -g 1000 app \
    && adduser -D -H -h /var/www/html -s /sbin/nologin -G app -u 1000 app \
    && mkdir -p /var/www/html /sock /var/log/php \
    && chown -R app:app /var/www/html /usr/local/etc /sock /var/log/php

# Change owner and group
USER app:app

# Change workdir
WORKDIR /var/www/html

# Expose port 9000
EXPOSE 9000

Le fichier est également commenté afin de faciliter la lecture.

Fichier de configuration du Virtualhost

Dans le dossier conf, nous allons créer le fichier httpd-vhosts.conf qui contiendra la configuration de notre virtualhost par défaut :

# -*- coding: utf-8 -*-

<VirtualHost *:8000>
    ServerName localhost:8000
    ServerAdmin webmaster@localhost

    DocumentRoot "/var/www/html"

    <Directory "/var/www/html">
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted

        DirectoryIndex index.php

        <FilesMatch \.php$>
            SetHandler "proxy:fcgi://phpfpm:9000"
        </FilesMatch>
    </Directory>

    ErrorLog /proc/self/fd/2
</VirtualHost>

Pour les besoins de l'article, j'ai choisi de déployer Apache sur le port 8000 de mon poste en local. Il est tout à fait possible d'utiliser un autre port.

Avant d'enregistrer et de fermer le fichier, n'oubliez pas de modifier les 2 valeurs des directives ServerName et ServerAdmin par vos propres valeurs.

La directive DirectoryIndex index.php permet de définir la liste de fichiers par défaut lorsqu'un utilisateur accède à un répertoire du virtualhost. En résumé, les adresses terminant par / afficheront le contenu des fichiers index.php. Il est possible d'ajouter autant de fichier que l'on souhaite, par exemple : DirectoryIndex index.php index.html. L'ordre est important, le premier fichier sera prioritaire par rapport aux autres.

Le bloc de directive ci-dessous va permettre à Apache de communiquer avec le conteneur PHP-FPM en passant par le module FastCGI.

<FilesMatch \.php$>
    SetHandler "proxy:fcgi://phpfpm:9000"
</FilesMatch>

La directive ErrorLog /proc/self/fd/2 permet de rediriger les erreurs vers la sortie standard du conteneur.

Fichier : docker-compose.yml

Terminons avec la création, à la racine du projet, du fichier docker-compose.yml. Ce dernier va nous permettre de construire et de lancer les conteneurs :

# -*- coding: utf-8 -*-

version: "3.9"

services:
    httpd:
        build:
            context: .docker
            dockerfile: httpd.Dockerfile
        ports:
            - 8000:8000
        depends_on:
            - phpfpm
        volumes:
            - .:/var/www/html

    phpfpm:
        build:
            context: .docker
            dockerfile: phpfpm.Dockerfile
        expose:
            - 9000
        volumes:
            - .:/var/www/html

Build et lancement

Pour terminer cette partie, lancer la commande ci-dessous pour construire et lancer les conteneurs :

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

Résultat

Vous pouvez visualiser votre page en ouvrant votre navigateur à l'adresse : http://localhost:8000