196 lines
5.3 KiB
Markdown
196 lines
5.3 KiB
Markdown
# 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 :
|
|
|
|
```dotenv
|
|
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 :
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
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` :
|
|
|
|
```bash
|
|
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 :
|
|
|
|
```bash
|
|
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.
|
|
|
|
```dotenv
|
|
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
|
|
|
|
```json
|
|
{
|
|
"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
|
|
|
|
```bash
|
|
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 :
|
|
|
|
```bash
|
|
./docker/database-backup/restore-production latest-s3
|
|
```
|
|
|
|
Autres sources acceptées :
|
|
|
|
```bash
|
|
# 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 :
|
|
|
|
```bash
|
|
COMPOSE_FILE=docker-compose.prod.yml \
|
|
./docker/database-backup/restore-production latest-s3
|
|
```
|