Add Docker infrastructure for dev and prod environments

- Separate PHP Dockerfiles (dev/prod) with extensions and prod opcache/php.ini optimization
- docker-compose-dev: PHP, PostgreSQL, Redis, Messenger, Mailpit, RedisInsight
- docker-compose-prod: 2x PHP replicas, PgSQL master/slave with PgBouncer, 2x Messenger, Redis
- Makefile with build/start/stop/purge commands
- AGENT.md to restrict AI access to the repository

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Serreau Jovann
2026-03-18 20:12:09 +01:00
parent 9341647acf
commit 653d7b4729
14 changed files with 378 additions and 0 deletions

31
AGENT.md Normal file
View File

@@ -0,0 +1,31 @@
# AGENT.md
## Interdiction generale
**Aucun agent IA, assistant de code, ou outil automatise n'est autorise a modifier, committer, pousser, supprimer ou alterer de quelque maniere que ce soit les fichiers de ce depot.**
Cela inclut, sans s'y limiter :
- La modification de fichiers existants
- La creation de nouveaux fichiers
- La suppression de fichiers
- Les commits et pushs Git
- L'ouverture de pull requests ou d'issues
- La modification de la configuration du projet
- L'execution de commandes destructrices
## Portee
Cette interdiction s'applique a tous les agents IA et outils automatises, y compris mais sans s'y limiter :
- Claude Code / Claude
- GitHub Copilot
- Cursor
- Windsurf
- Devin
- OpenAI Codex
- Tout autre assistant IA ou bot
## Exceptions
Aucune exception. Toute intervention IA sur ce depot est strictement interdite sauf autorisation explicite et ecrite du proprietaire du projet.

27
Makefile Normal file
View File

@@ -0,0 +1,27 @@
.DEFAULT_GOAL := help
## —— Help ————————————————————————————————————————
help: ## Affiche la liste des commandes disponibles
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
## —— Docker ——————————————————————————————————————
build_dev: ## Build les images Docker pour le dev
docker compose -f docker-compose-dev.yml build
build_prod: ## Build les images Docker pour la prod
docker compose -f docker-compose-prod.yml build
start_dev: ## Lance les containers dev
docker compose -f docker-compose-dev.yml up
start_prod: ## Lance les containers prod en background
docker compose -f docker-compose-prod.yml up -d
stop_dev: ## Arrete les containers dev
docker compose -f docker-compose-dev.yml down
purge_dev: ## Arrete et purge les containers dev (volumes inclus)
docker compose -f docker-compose-dev.yml down -v --rmi all --remove-orphans
stop_prod: ## Arrete les containers prod
docker compose -f docker-compose-prod.yml down

0
assets/app.scss Normal file
View File

82
docker-compose-dev.yml Normal file
View File

@@ -0,0 +1,82 @@
services:
php:
build:
context: ./docker/php/dev
dockerfile: Dockerfile
container_name: e-ticket_php
restart: unless-stopped
volumes:
- .:/app
ports:
- "9000:9000"
depends_on:
database:
condition: service_healthy
redis:
condition: service_healthy
database:
image: postgres:16-alpine
container_name: e-ticket_database
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
POSTGRES_DB: e-ticket
ports:
- "5432:5432"
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d e-ticket"]
interval: 5s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
container_name: e-ticket_redis
command: redis-server --requirepass e-ticket
ports:
- "6379:6379"
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "-a", "e-ticket", "ping"]
interval: 5s
timeout: 5s
retries: 5
messenger:
build:
context: ./docker/php/dev
dockerfile: Dockerfile
container_name: e-ticket_messenger
command: php bin/console messenger:consume async -vv
restart: unless-stopped
volumes:
- .:/app
depends_on:
database:
condition: service_healthy
redis:
condition: service_healthy
mailpit:
image: axllent/mailpit
container_name: e-ticket_mailpit
ports:
- "1025:1025"
- "8025:8025"
redisinsight:
image: redis/redisinsight:latest
container_name: e-ticket_redisinsight
ports:
- "5540:5540"
depends_on:
redis:
condition: service_healthy
volumes:
db-data:
redis-data:

114
docker-compose-prod.yml Normal file
View File

@@ -0,0 +1,114 @@
name: e-ticket
services:
php:
build:
context: ./docker/php/prod
dockerfile: Dockerfile
deploy:
replicas: 2
restart: unless-stopped
volumes:
- .:/app
ports:
- "9000-9001:9000"
depends_on:
pgbouncer:
condition: service_started
redis:
condition: service_healthy
db-master:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: e-ticket
POSTGRES_PASSWORD: e-ticket
POSTGRES_DB: e-ticket
command:
- postgres
- -c
- wal_level=replica
- -c
- max_wal_senders=3
- -c
- wal_keep_size=64MB
- -c
- hot_standby=on
volumes:
- db-master-data:/var/lib/postgresql/data
- ./docker/pgsql/init-master.sql:/docker-entrypoint-initdb.d/init-master.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U e-ticket -d e-ticket"]
interval: 5s
timeout: 5s
retries: 5
db-slave:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: e-ticket
POSTGRES_PASSWORD: e-ticket
POSTGRES_DB: e-ticket
PGDATA: /var/lib/postgresql/data
volumes:
- db-slave-data:/var/lib/postgresql/data
- ./docker/pgsql/init-slave.sh:/init-slave.sh
entrypoint: ["/bin/bash", "/init-slave.sh"]
command: ["postgres"]
depends_on:
db-master:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "pg_isready -U e-ticket -d e-ticket"]
interval: 5s
timeout: 5s
retries: 5
pgbouncer:
image: edoburu/pgbouncer
restart: unless-stopped
volumes:
- ./docker/pgsql/pgbouncer.ini:/etc/pgbouncer/pgbouncer.ini
- ./docker/pgsql/userlist.txt:/etc/pgbouncer/userlist.txt
ports:
- "6432:6432"
depends_on:
db-master:
condition: service_healthy
db-slave:
condition: service_healthy
messenger:
build:
context: ./docker/php/prod
dockerfile: Dockerfile
command: php bin/console messenger:consume async --time-limit=3600 --memory-limit=256M --limit=500 -vv
deploy:
replicas: 2
restart: unless-stopped
volumes:
- .:/app
depends_on:
pgbouncer:
condition: service_started
redis:
condition: service_healthy
redis:
image: redis:7-alpine
restart: unless-stopped
command: redis-server --requirepass e-ticket
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "-a", "e-ticket", "ping"]
interval: 5s
timeout: 5s
retries: 5
volumes:
db-master-data:
db-slave-data:
redis-data:

View File

@@ -0,0 +1,2 @@
CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'e-ticket';
SELECT pg_create_physical_replication_slot('slave_slot');

12
docker/pgsql/init-slave.sh Executable file
View File

@@ -0,0 +1,12 @@
#!/bin/bash
set -e
until pg_isready -h db-master -U e-ticket; do
echo "Waiting for master..."
sleep 2
done
rm -rf /var/lib/postgresql/data/*
pg_basebackup -h db-master -D /var/lib/postgresql/data -U replicator -Fp -Xs -P -R
echo "hot_standby = on" >> /var/lib/postgresql/data/postgresql.conf

View File

@@ -0,0 +1,19 @@
[databases]
e-ticket = host=db-master port=5432 dbname=e-ticket
e-ticket_readonly = host=db-slave port=5432 dbname=e-ticket
[pgbouncer]
listen_addr = 0.0.0.0
listen_port = 6432
auth_type = md5
auth_file = /etc/pgbouncer/userlist.txt
pool_mode = transaction
max_client_conn = 200
default_pool_size = 20
min_pool_size = 5
reserve_pool_size = 5
reserve_pool_timeout = 3
server_lifetime = 3600
server_idle_timeout = 600
log_connections = 0
log_disconnections = 0

View File

@@ -0,0 +1 @@
"e-ticket" "md5f79275ff8ae69fcb9e6218d88e699961"

28
docker/php/dev/Dockerfile Normal file
View File

@@ -0,0 +1,28 @@
FROM php:8.4-fpm
RUN apt-get update && apt-get install -y \
libpq-dev \
libsqlite3-dev \
libzip-dev \
libxml2-dev \
libicu-dev \
libpng-dev \
libjpeg-dev \
libfreetype6-dev \
libmagickwand-dev \
unzip \
&& rm -rf /var/lib/apt/lists/*
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install \
pdo_mysql \
pdo_pgsql \
pdo_sqlite \
zip \
xml \
intl \
mbstring \
gd
RUN pecl install redis imagick \
&& docker-php-ext-enable redis imagick

View File

@@ -0,0 +1,32 @@
FROM php:8.4-fpm
RUN apt-get update && apt-get install -y \
libpq-dev \
libsqlite3-dev \
libzip-dev \
libxml2-dev \
libicu-dev \
libpng-dev \
libjpeg-dev \
libfreetype6-dev \
libmagickwand-dev \
unzip \
&& rm -rf /var/lib/apt/lists/*
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install \
pdo_mysql \
pdo_pgsql \
pdo_sqlite \
zip \
xml \
intl \
mbstring \
gd \
opcache
RUN pecl install redis imagick \
&& docker-php-ext-enable redis imagick
COPY php.ini /usr/local/etc/php/conf.d/app.ini
COPY opcache.ini /usr/local/etc/php/conf.d/opcache.ini

View File

@@ -0,0 +1,9 @@
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0
opcache.save_comments=0
opcache.enable_cli=1
opcache.jit=tracing
opcache.jit_buffer_size=128M

21
docker/php/prod/php.ini Normal file
View File

@@ -0,0 +1,21 @@
date.timezone = Europe/Paris
memory_limit = 256M
upload_max_filesize = 100M
post_max_size = 150M
max_execution_time = 30
max_input_time = 30
expose_php = Off
display_errors = Off
display_startup_errors = Off
log_errors = On
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
realpath_cache_size = 4096K
realpath_cache_ttl = 600
session.cookie_secure = On
session.cookie_httponly = On
session.cookie_samesite = Lax
session.use_strict_mode = 1

BIN
public/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB