Docker – Créer une stack LAMP

Le but

Le but est d’obtenir l’environnement de développement suivant :

  • Ubuntu 22.04 LTS
  • PHP 8.1
  • MySQL 8.0

Le fichier Dockerfile

FROM ubuntu:22.04

#
# Pour faire un build de l'image, se mettre dans le répertoire de ce fichier et exécuter la commande :
# docker build -t dev-php8.1 .
#

# Contact de la personne qui maintient ce fichier
LABEL maintainer="fabien MAILLE <fabien.maille.8@gmail.com>"

# Locale à utiliser
ENV LANG C.UTF-8

# Timezone à appliquer à la machine Ubuntu
ENV TZ Europe/Paris

# Permet qu'aucune question / boîte de dialogue ne soit posée pendant les installations via apt-get
ENV DEBIAN_FRONTEND noninteractive

# Installation de "apt-transport-https" avant les autres installations pour éviter des erreurs de packet/repository non trouvés
RUN apt-get update -y
RUN apt install -y curl wget gnupg2 ca-certificates lsb-release apt-transport-https

# Mise à jour de l'image Ubuntu
RUN apt-get -y update && apt-get upgrade -y

# Installations
RUN apt-get install -y \
	cron \
    curl \
    inetutils-ping \
    nano \
    openssh-client \
    sudo \
    vim

# Installation Apache & PHP
RUN apt-get install -y \
    apache2 \
    php8.1 \
    libapache2-mod-php8.1 \
    php8.1-bcmath \
    php8.1-curl \
    php8.1-gd \
    php8.1-imap \
    php8.1-mysql \
    php8.1-mbstring \
    php8.1-soap \
    php8.1-xml \
    php8.1-zip \
    php-xdebug

# Installation de locales
RUN apt-get install locales
RUN locale-gen fr_FR.UTF-8
RUN locale-gen en_US.UTF-8
#ENV LANG fr_FR.UTF-8
#ENV LANGUAGE fr_FR:fr
#ENV LC_ALL fr_FR.UTF-8 

#
# Configuration PHP
#

# On considère qu'on est sur un envrionnement de développement qui doit afficher les erreurs PHP
RUN sed -i -e 's/^error_reporting\s*=.*/error_reporting = E_ALL/' /etc/php/8.1/apache2/php.ini
RUN sed -i -e 's/^display_errors\s*=.*/display_errors = On/' /etc/php/8.1/apache2/php.ini

RUN sed -i -e 's/^zlib.output_compression\s*=.*/zlib.output_compression = Off/' /etc/php/8.1/apache2/php.ini

RUN sed -ri 's~^;(date.timezone =)$~\1 Europe/Paris~g' /etc/php/8.1/apache2/php.ini

# Configuration de xdebug
RUN echo "zend_extension=xdebug.so" > /etc/php/8.1/mods-available/xdebug.ini \
    && echo "xdebug.remote_enable=on" >> /etc/php/8.1/mods-available/xdebug.ini \
    && echo "xdebug.remote_autostart=1" >> /etc/php/8.1/mods-available/xdebug.ini \
    && echo "xdebug.idekey=PHPSTORM" >> /etc/php/8.1/mods-available/xdebug.ini \
    && echo "xdebug.remote_port=9000" >> /etc/php/8.1/mods-available/xdebug.ini \
    && echo "xdebug.remote_connect_back=0" >> /etc/php/8.1/mods-available/xdebug.ini    

# On veut pouvoir utiliser "nano" en ligne de commande via "docker exec -it [CONTAINER ID] bash"
ENV TERM xterm

#
# Configuration Apache
#

# Autoriser la réécriture d'URL dans les fichiers .htaccess
RUN a2enmod rewrite

# Pour consulter les logs en live : docker logs -f [CONTAINER ID]
# Sans la ligne suivante on obtiendrait : "AH00558: apache2: Could not reliably determine the server's fully qualified domain name"
RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf
# Autoriser les fichiers .htaccess
RUN sed -i '/<Directory \/var\/www\/>/,/<\/Directory>/ s/AllowOverride None/AllowOverride All/' /etc/apache2/apache2.conf

# Attribution des droits à l'utilisateur www-data sur le répertoire www
RUN chown -R www-data:www-data /var/www
RUN chmod 755 -R /var/www

EXPOSE 80

# Démarrer Apache2 au démarrage de l'image
CMD ["/usr/sbin/apache2ctl", "-DFOREGROUND"]

Le fichier docker-compose.yml

version: "3"

volumes:
  db-data:

services:
  app:
    image: dev-php8.1
    build:
      context: .
      dockerfile: ./docker/app/Dockerfile
    environment:
      XDEBUG_IDEKEY: PHPSTORM
      XDEBUG_REMOTE_HOST: host.docker.internal
    ports:
      - 8080:80
    links:
      - database:db
    volumes:
      - ./src:/var/www/html/

  database:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root-pass
      MYSQL_USER: fabien
      MYSQL_PASSWORD: fabien-pass
    command:
      - mysqld
      - --default-authentication-plugin=mysql_native_password
      - --default_storage_engine=InnoDB
      - --character-set-server=utf8
      - --collation-server=utf8_general_ci
      - --init-connect=SET NAMES utf8
    ports:
      - 3306:3306
    volumes:
      - db-data:/var/lib/mysql

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    links:
      - database:db
    ports:
      - 8181:80

Script PHP de connexion à la BDD

const DB_HOST = 'database'; // Nom du service dans le fichier docker-compose.yml
const DB_USER = 'root';
const DB_PASSWORD = 'root-pass';
const DB_DATABASE = 'test';

$link = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD);

if (!$link) {
    echo "Erreur : Impossible de se connecter à MySQL." . PHP_EOL;
    echo "Errno de débogage : " . mysqli_connect_errno() . PHP_EOL;
    echo "Erreur de débogage : " . mysqli_connect_error() . PHP_EOL;
    exit;
}

echo "Connexion établie à MySQL sur la base de donnée " . DB_DATABASE . PHP_EOL;

mysqli_close($link);

Les différentes URL d’accès