📁 Structure des fichiers

~/Works/docker-web/
├── docker-compose.yml
├── .env
├── .gitignore
├── www/                 
├── php/
│   ├── Dockerfile
│   └── php.ini
├── nginx/
│   └── default.conf
└── mariadb/
    ├── init/
    │   └── 01-init.sql
    └── data/

Le répertoire ~/Works/docker-web/www restera sur ta machine hôte et sera monté dans les conteneurs

créations du projet , les répertoires sur la machine hote:

mkdir -p ~/Works/docker-web/php
mkdir -p ~/Works/docker-web/nginx
mkdir -p ~/Works/docker-web/mariadb/init
mkdir -p ~/Works/docker-web/mariadb/data
mkdir -p ~/Works/docker-web/www

# Vérification
find ~/Works/docker-web -type d | sort

fichier .env

COMPOSE_PROJECT_NAME=webstack

HTTP_PORT=8080
MARIADB_PORT=3306

MYSQL_ROOT_PASSWORD=change-me-root
MYSQL_DATABASE=mydb
MYSQL_USER=dev
MYSQL_PASSWORD=change-me-user

TZ=Europe/Paris
UID=1000
GID=1000

docker-compose.yml

services:
  mariadb:
    image: mariadb:11.4
    container_name: ${COMPOSE_PROJECT_NAME}-mariadb
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      TZ: ${TZ}
    volumes:
      - ./mariadb/data:/var/lib/mysql
      - ./mariadb/init:/docker-entrypoint-initdb.d:ro
    ports:
      - "${MARIADB_PORT}:3306"
    networks:
      - backend
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 5

  php:
    build:
      context: ./php
      args:
        UID: ${UID}
        GID: ${GID}
    container_name: ${COMPOSE_PROJECT_NAME}-php
    restart: unless-stopped
    volumes:
      - ./www:/var/www/html
      - ./php/php.ini:/usr/local/etc/php/conf.d/custom.ini:ro
    environment:
      TZ: ${TZ}
    networks:
      - backend
    depends_on:
      mariadb:
        condition: service_healthy

  nginx:
    image: nginx:1.27-alpine
    container_name: ${COMPOSE_PROJECT_NAME}-nginx
    restart: unless-stopped
    ports:
      - "${HTTP_PORT}:80"
    volumes:
      - ./www:/var/www/html:ro
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
    environment:
      TZ: ${TZ}
    networks:
      - backend
    depends_on:
      - php

networks:
  backend:
    driver: bridge

Le fichier /php/Dockerfile

FROM php:8.3-fpm-alpine

ARG UID=1000
ARG GID=1000

RUN apk add --no-cache \
        bash git curl unzip \
        icu-dev libzip-dev libpng-dev libjpeg-turbo-dev freetype-dev oniguruma-dev \
        mariadb-client $PHPIZE_DEPS \
    && docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install -j$(nproc) \
        pdo pdo_mysql mysqli gd zip intl mbstring opcache \
    && apk del $PHPIZE_DEPS \
    && rm -rf /var/cache/apk/*

COPY --from=composer:2 /usr/bin/composer /usr/bin/composer

RUN addgroup -g ${GID} dev \
    && adduser -u ${UID} -G dev -s /bin/bash -D dev

WORKDIR /var/www/html
USER dev

EXPOSE 9000
CMD ["php-fpm"]

le fichier /php/php.ini

display_errors = On
error_reporting = E_ALL
log_errors = On

upload_max_filesize = 100M
post_max_size = 100M
max_execution_time = 300
memory_limit = 512M

opcache.enable = 0
opcache.validate_timestamps = 1

date.timezone = Europe/Paris

le fichier nginx/default.conf

server {
    listen 80;
    server_name localhost;
    root /var/www/html;
    index index.php index.html;

    client_max_body_size 100M;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_read_timeout 300;
    }

    location ~ /\.ht {
        deny all;
    }
}

le fichier mariadb/init/01-init.sql

SET NAMES utf8mb4;

CREATE DATABASE IF NOT EXISTS `mydb`
    CHARACTER SET utf8mb4
    COLLATE utf8mb4_unicode_ci;

GRANT ALL PRIVILEGES ON `mydb`.* TO 'dev'@'%';
FLUSH PRIVILEGES;

le fichier .gitignore

.env
mariadb/data/
*.log