Files
mesreleves-php/docker-compose.prod.yml
T
yann64 ba7fe10329 Versioning, déploiement et mise à jour automatique
Gestion des versions :
- Fichier VERSION (1.0.0) comme source de vérité
- config/update.php : URL Gitea, AUTO_UPDATE (false par défaut), rétention des sauvegardes

Artisan commands :
- app:check-update  : interroge l'API Gitea, cache Redis 1h, déclenche app:update si AUTO_UPDATE=true
- app:update        : télécharge l'archive, sauvegarde pg_dump, rsync, composer install, migrate, reload php-fpm
- app:rollback      : liste les sauvegardes et restaure via psql

UpdateService :
- Téléchargement via Http::sink() (streaming, pas de charge mémoire)
- Sauvegarde pg_dump dans storage/app/backups/ avant chaque mise à jour
- Rechargement php-fpm gracieux (kill -USR2 1) sans downtime
- Purge automatique des anciennes sauvegardes (configurable)

Docker (refactor pour volume-mount) :
- Dockerfile : runtime seulement (PHP + extensions + composer + rsync + pg_client)
  Le code n'est plus copié dans l'image → les mises à jour ne nécessitent pas de rebuild
- entrypoint.sh : composer install + key:generate + caches au démarrage du container
- docker-compose.prod.yml : montage du code comme volume (.:/var/www/html)

Scripts de déploiement :
- bin/build-release.sh : rsync + tar.gz + sha256, exclut vendor/node_modules/tests
- install.sh : guide d'installation Docker complète (première mise en service)

Interface admin :
- Bandeau "mise à jour disponible" dans le dashboard admin (version courante + cible)
- Badge version + icône "à jour" en pied de tableau de bord
- Commande à copier-coller pour appliquer depuis le container

Planification :
- routes/console.php : Schedule::command('app:check-update')->daily()
- .env.example : variables GITEA_*, AUTO_UPDATE, UPDATE_BACKUPS_TO_KEEP

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 17:38:39 +02:00

87 lines
2.1 KiB
YAML

# Déploiement production — stack complète (app + db + redis + nginx)
# Usage : docker compose -f docker-compose.prod.yml up -d
services:
app:
build:
context: .
dockerfile: docker/Dockerfile
container_name: mesreleves_app
restart: unless-stopped
environment:
APP_ENV: production
APP_KEY: ${APP_KEY}
DB_CONNECTION: pgsql
DB_HOST: db
DB_PORT: 5432
DB_DATABASE: ${DB_DATABASE:-mesreleves}
DB_USERNAME: ${DB_USERNAME:-mesreleves}
DB_PASSWORD: ${DB_PASSWORD}
CACHE_STORE: redis
SESSION_DRIVER: redis
QUEUE_CONNECTION: redis
REDIS_HOST: redis
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
volumes:
# Le code est monté depuis l'hôte : les mises à jour ne nécessitent pas de rebuild image
- .:/var/www/html
# Le storage est un volume nommé (uploads, logs, sessions — persisté indépendamment du code)
- app_storage:/var/www/html/storage
networks:
- internal
nginx:
image: nginx:alpine
container_name: mesreleves_nginx
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./docker/nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./public:/var/www/html/public:ro
- app_storage:/var/www/html/storage:ro
depends_on:
- app
networks:
- internal
db:
image: postgres:18-alpine
container_name: mesreleves_db
restart: unless-stopped
environment:
POSTGRES_DB: ${DB_DATABASE:-mesreleves}
POSTGRES_USER: ${DB_USERNAME:-mesreleves}
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- pgdata:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME:-mesreleves}"]
interval: 10s
timeout: 5s
retries: 5
networks:
- internal
redis:
image: redis:7-alpine
container_name: mesreleves_redis
restart: unless-stopped
volumes:
- redisdata:/data
networks:
- internal
volumes:
pgdata:
redisdata:
app_storage:
networks:
internal:
driver: bridge