diff --git a/AGENT.md b/AGENT.md new file mode 100644 index 0000000..08c7dbb --- /dev/null +++ b/AGENT.md @@ -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. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7addc73 --- /dev/null +++ b/Makefile @@ -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 diff --git a/assets/app.scss b/assets/app.scss new file mode 100644 index 0000000..e69de29 diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml new file mode 100644 index 0000000..810d9dd --- /dev/null +++ b/docker-compose-dev.yml @@ -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: diff --git a/docker-compose-prod.yml b/docker-compose-prod.yml new file mode 100644 index 0000000..c9894f3 --- /dev/null +++ b/docker-compose-prod.yml @@ -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: diff --git a/docker/pgsql/init-master.sql b/docker/pgsql/init-master.sql new file mode 100644 index 0000000..9649421 --- /dev/null +++ b/docker/pgsql/init-master.sql @@ -0,0 +1,2 @@ +CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'e-ticket'; +SELECT pg_create_physical_replication_slot('slave_slot'); diff --git a/docker/pgsql/init-slave.sh b/docker/pgsql/init-slave.sh new file mode 100755 index 0000000..bc258e4 --- /dev/null +++ b/docker/pgsql/init-slave.sh @@ -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 diff --git a/docker/pgsql/pgbouncer.ini b/docker/pgsql/pgbouncer.ini new file mode 100644 index 0000000..3eeb851 --- /dev/null +++ b/docker/pgsql/pgbouncer.ini @@ -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 diff --git a/docker/pgsql/userlist.txt b/docker/pgsql/userlist.txt new file mode 100644 index 0000000..bb3436a --- /dev/null +++ b/docker/pgsql/userlist.txt @@ -0,0 +1 @@ +"e-ticket" "md5f79275ff8ae69fcb9e6218d88e699961" diff --git a/docker/php/dev/Dockerfile b/docker/php/dev/Dockerfile new file mode 100644 index 0000000..0139a1c --- /dev/null +++ b/docker/php/dev/Dockerfile @@ -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 diff --git a/docker/php/prod/Dockerfile b/docker/php/prod/Dockerfile new file mode 100644 index 0000000..cf1044b --- /dev/null +++ b/docker/php/prod/Dockerfile @@ -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 diff --git a/docker/php/prod/opcache.ini b/docker/php/prod/opcache.ini new file mode 100644 index 0000000..0f7044e --- /dev/null +++ b/docker/php/prod/opcache.ini @@ -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 diff --git a/docker/php/prod/php.ini b/docker/php/prod/php.ini new file mode 100644 index 0000000..6f3d3a7 --- /dev/null +++ b/docker/php/prod/php.ini @@ -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 diff --git a/public/logo.png b/public/logo.png new file mode 100644 index 0000000..27bff6e Binary files /dev/null and b/public/logo.png differ