Daily Meal API
API Laravel de Daily Meal.
Docker en production
Le fichier source du dépôt est docker-compose.prod.yml. Sur le serveur, il est
déployé sous le nom docker-compose.yml. Les commandes de ce guide sont donc
exécutées depuis le dossier de l'application sans option -f.
Configuration
Le Compose charge la configuration applicative depuis le .env de production.
Les variables Laravel ne sont pas répétées dans le fichier Compose afin de
conserver une seule source de vérité.
Exemple des variables propres à l'infrastructure :
IMAGE_TAG=2026-08-13.1
APP_ENV=production
APP_DEBUG=false
LOG_CHANNEL=stderr
LOG_LEVEL=warning
DB_CONNECTION=pgsql
DB_HOST=postgres
DB_PORT=5432
DB_DATABASE=bowli
DB_USERNAME=bowli
DB_PASSWORD=change-me
REDIS_HOST=redis
QUEUE_CONNECTION=redis
SCOUT_DRIVER=meilisearch
MEILISEARCH_HOST=http://meilisearch:7700
MEILISEARCH_KEY=change-me
FILESYSTEM_DISK=s3
AWS_ACCESS_KEY_ID=change-me
AWS_SECRET_ACCESS_KEY=change-me
AWS_DEFAULT_REGION=eu-west-3
IMAGE_TAG est obligatoire. Utiliser un tag de release immuable permet de savoir
exactement quelle version est déployée et évite l'utilisation accidentelle de
latest.
Volumes et réseau externes
PostgreSQL, Redis, Meilisearch et les sauvegardes locales utilisent des volumes externes. Ils restent présents quand le projet Compose est recréé.
À effectuer une seule fois sur un nouveau serveur :
docker volume create bemeal_pgsql_data
docker volume create bemeal_redis_data
docker volume create bemeal_meilisearch_data
docker volume create bemeal_database_backups
docker network create proxy
Ces commandes sont idempotentes. Le réseau proxy peut déjà avoir été créé par
le reverse proxy. Ne jamais supprimer bemeal_pgsql_data sans avoir validé une
sauvegarde.
Premier démarrage
docker compose config -q
docker compose pull app db-backup postgres redis meilisearch
docker compose up -d
docker compose ps
L'image db-backup contient pg_dump, pg_restore, AWS CLI, le cron et les
scripts de docker/database-backup. Elle est construite et publiée dans le
registre par la CI. Le serveur la télécharge avec docker compose pull et n'a
donc pas besoin de posséder le code source ni de construire une image localement.
Mettre à jour l'application
Après avoir changé IMAGE_TAG dans .env :
docker compose config -q
docker compose pull app db-backup
docker compose up -d --remove-orphans
docker compose ps
Si les migrations ne sont pas déjà gérées par le pipeline ou l'image :
docker compose exec app php artisan migrate --force
Sauvegardes PostgreSQL vers S3
Le service db-backup lance une sauvegarde au démarrage, puis chaque jour à
03:00. Chaque archive est compressée, contrôlée avec pg_restore, accompagnée
d'un checksum SHA-256 puis envoyée vers S3 avec le chiffrement AES-256. Les
copies locales sont conservées 7 jours par défaut.
BACKUP_CRON="0 3 * * *"
BACKUP_RUN_ON_START=true
BACKUP_LOCAL_RETENTION_DAYS=7
BACKUP_S3_BUCKET=bowli-backup
BACKUP_S3_PREFIX=database-backups/postgres
BACKUP_S3_ENDPOINT=
TZ=Europe/Paris
Ces valeurs sont les valeurs par défaut et peuvent être omises du .env. Le
bucket bowli-backup doit rester entièrement privé. BACKUP_S3_ENDPOINT reste
vide avec AWS S3.
Autorisations IAM minimales
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListDatabaseBackups",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::bowli-backup",
"Condition": {
"StringLike": {
"s3:prefix": [
"database-backups/postgres",
"database-backups/postgres/*"
]
}
}
},
{
"Sid": "ManageDatabaseBackupObjects",
"Effect": "Allow",
"Action": ["s3:PutObject", "s3:GetObject"],
"Resource": "arn:aws:s3:::bowli-backup/database-backups/postgres/*"
}
]
}
Le conteneur ne supprime pas les sauvegardes distantes. Configurer une règle de cycle de vie S3 sur ce préfixe, par exemple après 30 ou 90 jours.
Sauvegarde manuelle et contrôle
docker compose exec db-backup /usr/local/bin/backup-database manual
docker compose ps db-backup
docker compose logs --tail=100 db-backup
Restaurer une sauvegarde
Pour restaurer la sauvegarde S3 la plus récente :
./docker/database-backup/restore-production latest-s3
Autres sources acceptées :
# Dernière sauvegarde du volume local
./docker/database-backup/restore-production latest-local
# Sauvegarde S3 précise
./docker/database-backup/restore-production \
s3://bowli-backup/database-backups/postgres/20260813T030000Z-bowli-scheduled.dump
La restauration demande une confirmation explicite. Elle arrête l'application et les workers, crée une sauvegarde de sécurité, vérifie l'archive, restaure dans une base temporaire puis échange les bases. L'ancienne base est conservée sous un nom daté pour permettre un rollback.
Les services redémarrent uniquement si toute l'opération réussit. En cas d'échec, ils restent arrêtés afin d'éviter d'écrire dans une base potentiellement incomplète.
Pour utiliser exceptionnellement un autre nom de fichier Compose :
COMPOSE_FILE=docker-compose.prod.yml \
./docker/database-backup/restore-production latest-s3