chore: remplace le Makefile par un service compose wakdo-migrate (migrate + seed idempotents) #40
10 changed files with 236 additions and 276 deletions
|
|
@ -157,9 +157,8 @@ TRAEFIK_DOMAIN_ADMIN=admin.example.com
|
|||
# traefik - setups simples
|
||||
# proxy - autre convention frequente
|
||||
#
|
||||
# Le reseau doit exister AVANT 'make init' (cree par votre stack de
|
||||
# reverse proxy, ou manuellement : docker network create <nom>).
|
||||
# La cible 'make init' echoue proprement avec un message d'aide si le
|
||||
# reseau est introuvable.
|
||||
# Le reseau doit exister AVANT 'docker compose up' (cree par votre stack de
|
||||
# reverse proxy, ou manuellement : docker network create <nom>). Sinon
|
||||
# 'docker compose up' echoue avec une erreur sur le reseau externe introuvable.
|
||||
|
||||
REVERSE_PROXY_NETWORK=traefik_proxy
|
||||
|
|
|
|||
233
Makefile
233
Makefile
|
|
@ -1,233 +0,0 @@
|
|||
#
|
||||
# Wakdo - Makefile d'orchestration locale
|
||||
#
|
||||
# Conventions :
|
||||
# - Une cible = une action unitaire. Les cibles composites sont commentees.
|
||||
# - Chaque cible est documentee par un `## description` pour auto-help.
|
||||
# - Echec sur erreur (set -e implicite via bash recipes + pipefail).
|
||||
#
|
||||
# Documentation :
|
||||
# make help
|
||||
#
|
||||
|
||||
SHELL := /usr/bin/env bash
|
||||
.SHELLFLAGS := -eu -o pipefail -c
|
||||
|
||||
# === Configuration ===
|
||||
|
||||
# Chargement du .env s'il existe (variables Make + export pour docker compose)
|
||||
ifneq (,$(wildcard .env))
|
||||
include .env
|
||||
export
|
||||
endif
|
||||
|
||||
# Prefixe du projet compose (utilise pour nommer les containers)
|
||||
PROJECT := wakdo
|
||||
|
||||
# Nom du fichier compose (override possible : make up COMPOSE_FILE=docker-compose.prod.yml)
|
||||
COMPOSE_FILE := docker-compose.yml
|
||||
COMPOSE := docker compose -f $(COMPOSE_FILE) -p $(PROJECT)
|
||||
|
||||
# Services docker-compose
|
||||
SERVICE_WEB := wakdo-web
|
||||
SERVICE_APP := wakdo-app
|
||||
SERVICE_DB := wakdo-db
|
||||
SERVICE_CRON := wakdo-cron
|
||||
|
||||
# === Meta ===
|
||||
|
||||
.DEFAULT_GOAL := help
|
||||
.PHONY: help
|
||||
help: ## Liste toutes les cibles disponibles avec leur description
|
||||
@echo "Wakdo - cibles Make disponibles :"
|
||||
@echo ""
|
||||
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " \033[1m%-22s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) | sort
|
||||
@echo ""
|
||||
|
||||
# === Orchestration principale ===
|
||||
|
||||
.PHONY: init
|
||||
init: ## Build et demarre toute la stack en une commande (Cr RNCP 7.c.4)
|
||||
@test -f .env || { echo "ERREUR: .env manquant. Executer : cp .env.example .env"; exit 1; }
|
||||
@$(MAKE) --no-print-directory check-env
|
||||
@echo "[init] Verification du reseau docker '$(REVERSE_PROXY_NETWORK)'..."
|
||||
@docker network inspect $(REVERSE_PROXY_NETWORK) >/dev/null 2>&1 || { \
|
||||
echo "ERREUR: reseau docker '$(REVERSE_PROXY_NETWORK)' introuvable."; \
|
||||
echo " - Si un Traefik est installe sur l'hote, verifier le nom de son reseau ;"; \
|
||||
echo " - Adapter REVERSE_PROXY_NETWORK dans .env en consequence ;"; \
|
||||
echo " - Sinon creer le reseau manuellement :"; \
|
||||
echo " docker network create $(REVERSE_PROXY_NETWORK)"; \
|
||||
exit 1; }
|
||||
@echo "[init] Build des images..."
|
||||
@$(COMPOSE) build
|
||||
@echo "[init] Demarrage des services..."
|
||||
@$(COMPOSE) up -d
|
||||
@echo "[init] Attente de la base de donnees..."
|
||||
@$(MAKE) --no-print-directory wait-db
|
||||
@echo "[init] Execution des migrations..."
|
||||
@$(MAKE) --no-print-directory migrate
|
||||
@echo "[init] Stack operationnelle."
|
||||
@$(COMPOSE) ps
|
||||
|
||||
.PHONY: up
|
||||
up: ## Demarre les services sans rebuild
|
||||
@$(COMPOSE) up -d
|
||||
|
||||
.PHONY: down
|
||||
down: ## Arrete et supprime les containers (volumes preserves)
|
||||
@$(COMPOSE) down
|
||||
|
||||
.PHONY: stop
|
||||
stop: ## Arrete les services sans les supprimer
|
||||
@$(COMPOSE) stop
|
||||
|
||||
.PHONY: restart
|
||||
restart: ## Redemarre tous les services
|
||||
@$(COMPOSE) restart
|
||||
|
||||
.PHONY: build
|
||||
build: ## Build les images (utilise le cache)
|
||||
@$(COMPOSE) build
|
||||
|
||||
.PHONY: rebuild
|
||||
rebuild: ## Rebuild complet sans cache puis restart
|
||||
@$(COMPOSE) build --no-cache
|
||||
@$(COMPOSE) up -d
|
||||
|
||||
# === Observabilite ===
|
||||
|
||||
.PHONY: ps
|
||||
ps: ## Affiche le statut des services
|
||||
@$(COMPOSE) ps
|
||||
|
||||
.PHONY: logs
|
||||
logs: ## Suit les logs de tous les services (Ctrl+C pour sortir)
|
||||
@$(COMPOSE) logs -f --tail=100
|
||||
|
||||
.PHONY: logs-app
|
||||
logs-app: ## Suit les logs du service applicatif PHP-FPM
|
||||
@$(COMPOSE) logs -f --tail=100 $(SERVICE_APP)
|
||||
|
||||
.PHONY: logs-web
|
||||
logs-web: ## Suit les logs du service web Apache
|
||||
@$(COMPOSE) logs -f --tail=100 $(SERVICE_WEB)
|
||||
|
||||
.PHONY: logs-db
|
||||
logs-db: ## Suit les logs de la base de donnees
|
||||
@$(COMPOSE) logs -f --tail=100 $(SERVICE_DB)
|
||||
|
||||
# === Acces shell ===
|
||||
|
||||
.PHONY: shell-app
|
||||
shell-app: ## Ouvre un shell dans le container applicatif
|
||||
@$(COMPOSE) exec $(SERVICE_APP) sh
|
||||
|
||||
.PHONY: shell-db
|
||||
shell-db: ## Ouvre le client mariadb dans le container de base de donnees
|
||||
@$(COMPOSE) exec $(SERVICE_DB) mariadb -u root -p"$${DB_ROOT_PASSWORD}"
|
||||
|
||||
.PHONY: shell-cron
|
||||
shell-cron: ## Ouvre un shell dans le container cron
|
||||
@$(COMPOSE) exec $(SERVICE_CRON) sh
|
||||
|
||||
# === Verification env ===
|
||||
|
||||
.PHONY: check-env
|
||||
check-env: ## Verifie que les variables critiques Wakdo sont definies dans .env
|
||||
@missing=""; \
|
||||
for var in DB_PASSWORD DB_ROOT_PASSWORD REVERSE_PROXY_NETWORK TRAEFIK_DOMAIN_KIOSK TRAEFIK_DOMAIN_ADMIN APP_URL_KIOSK APP_URL_ADMIN CORS_ALLOWED_ORIGIN; do \
|
||||
if [ -z "$${!var:-}" ]; then missing="$$missing $$var"; fi; \
|
||||
done; \
|
||||
if [ -n "$$missing" ]; then \
|
||||
echo "ERREUR: variables manquantes dans .env :$$missing"; \
|
||||
echo "Conseil : si vous aviez un .env pre-existant (tooling externe),"; \
|
||||
echo " merger les variables manquantes depuis .env.example au lieu"; \
|
||||
echo " d'ecraser le fichier."; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
# === Base de donnees ===
|
||||
|
||||
.PHONY: wait-db
|
||||
wait-db: ## Attend que la base de donnees accepte les connexions (timeout 60s)
|
||||
@echo "[wait-db] En attente de MariaDB..."
|
||||
@timeout 60 bash -c 'until $(COMPOSE) exec -T $(SERVICE_DB) healthcheck.sh --connect --innodb_initialized >/dev/null 2>&1; do sleep 2; done' \
|
||||
|| { echo "ERREUR: MariaDB ne repond pas apres 60s"; $(COMPOSE) logs --tail=50 $(SERVICE_DB); exit 1; }
|
||||
@echo "[wait-db] OK"
|
||||
|
||||
.PHONY: migrate
|
||||
migrate: ## Applique les migrations SQL en attente (db/migrations/)
|
||||
@bash db/migrate.sh
|
||||
|
||||
.PHONY: seed
|
||||
seed: ## Charge les donnees de demo (db/seeds/)
|
||||
@bash db/seed.sh
|
||||
|
||||
.PHONY: backup
|
||||
backup: ## Declenche un dump SQL horodate immediat (via le container cron)
|
||||
@mkdir -p ./var/backups
|
||||
@echo "[backup] Execution manuelle de /scripts/backup-db.sh dans wakdo-cron..."
|
||||
@$(COMPOSE) exec -T $(SERVICE_CRON) /scripts/backup-db.sh
|
||||
@echo "[backup] Dernier dump :"
|
||||
@ls -lh ./var/backups/ | tail -n 1
|
||||
|
||||
.PHONY: backup-ls
|
||||
backup-ls: ## Liste les dumps SQL presents dans ./var/backups/
|
||||
@ls -lh ./var/backups/ 2>/dev/null || echo "[backup-ls] Pas de backups (./var/backups/ vide ou inexistant)."
|
||||
|
||||
# === Tests ===
|
||||
|
||||
.PHONY: test
|
||||
test: ## Lance la suite complete de tests PHPUnit [a venir]
|
||||
@echo "[test] Pas encore implemente. PHPUnit via .phar sera configure en P2."
|
||||
|
||||
.PHONY: test-unit
|
||||
test-unit: ## Lance uniquement les tests unitaires [a venir]
|
||||
@echo "[test-unit] Pas encore implemente."
|
||||
|
||||
.PHONY: test-integration
|
||||
test-integration: ## Lance uniquement les tests d'integration [a venir]
|
||||
@echo "[test-integration] Pas encore implemente."
|
||||
|
||||
# === Qualite code ===
|
||||
|
||||
.PHONY: lint
|
||||
lint: ## Lance php -l sur tous les fichiers src/ [a venir]
|
||||
@echo "[lint] Pas encore implemente. PHP syntax check via php -l + outil de style en P2."
|
||||
|
||||
# === Nettoyage ===
|
||||
|
||||
.PHONY: clean
|
||||
clean: ## Stop + suppression containers + volumes (DESTRUCTIF, demande confirmation)
|
||||
@read -p "Supprimer containers ET volumes (les donnees seront perdues) ? [y/N] " ans; \
|
||||
if [ "$$ans" = "y" ] || [ "$$ans" = "Y" ]; then \
|
||||
$(COMPOSE) down -v; \
|
||||
echo "[clean] Stack et volumes supprimes."; \
|
||||
else \
|
||||
echo "[clean] Annule."; \
|
||||
fi
|
||||
|
||||
.PHONY: clean-force
|
||||
clean-force: ## Version non interactive de clean (pour CI uniquement)
|
||||
@$(COMPOSE) down -v
|
||||
|
||||
# === Documentation ===
|
||||
|
||||
.PHONY: docs-render
|
||||
docs-render: ## Regenere les diagrammes Mermaid (docs/**/_diagrams/*.mmd -> *.svg)
|
||||
@echo "[docs-render] Recherche des sources Mermaid sous docs/..."
|
||||
@count=0; \
|
||||
for src in $$(find docs -name '*.mmd' -path '*/_diagrams/*'); do \
|
||||
out="$${src%.mmd}.svg"; \
|
||||
echo " $$src -> $$out"; \
|
||||
npx -y -p @mermaid-js/mermaid-cli mmdc -i "$$src" -o "$$out" >/dev/null 2>&1 \
|
||||
|| { echo "[docs-render] ECHEC sur $$src"; exit 1; }; \
|
||||
count=$$((count + 1)); \
|
||||
done; \
|
||||
echo "[docs-render] $$count diagramme(s) genere(s)."
|
||||
|
||||
# === Hooks Git ===
|
||||
|
||||
.PHONY: install-hooks
|
||||
install-hooks: ## Installe les hooks git depuis .githooks/ [a venir]
|
||||
@echo "[install-hooks] Pas encore implemente. Voir scripts/install-hooks.sh a venir."
|
||||
32
README.md
32
README.md
|
|
@ -55,9 +55,9 @@ Realisation avec l'assistance d'outils d'IA generative (Claude Code, BYAN), conf
|
|||
| Tests | PHPUnit | 11.x (`.phar` autonome, sans Composer) |
|
||||
| Front | HTML5 + CSS3 + JS ES6+ vanilla | — |
|
||||
| Conteneurisation | Docker + docker compose v2 | — |
|
||||
| Orchestration locale | Makefile | — |
|
||||
| CI/CD | GitHub Actions | — |
|
||||
| Versioning | Git + GitHub | Conventional Commits |
|
||||
| Orchestration locale | docker compose v2 (service one-shot `wakdo-migrate`) | — |
|
||||
| CI/CD | Forgejo Actions | — |
|
||||
| Versioning | Git + Forgejo (`git.acadenice.com`, miroir GitHub) | Conventional Commits |
|
||||
|
||||
Detail et justifications : `docs/PROJECT_CONTEXT.md` section 6.
|
||||
|
||||
|
|
@ -106,19 +106,22 @@ git clone git@github.com:AcadeNice/wakdo_corentin.git
|
|||
cd wakdo_corentin
|
||||
cp .env.example .env
|
||||
# Editer .env : DB_PASSWORD, DB_ROOT_PASSWORD, APP_URL_*, TRAEFIK_DOMAIN_*
|
||||
make init
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
> **Attention au `.env` pre-existant.** Si un fichier `.env` existe deja a la racine (tooling externe, autre plateforme installee dans le meme repertoire), **ne pas faire** `cp .env.example .env` — cela ecraserait les variables existantes. Faire un **merge manuel** a la place : ajouter les variables manquantes du template dans le `.env` actuel. Les prefixes de variables de ce projet (`APP_`, `DB_`, `SESSION_`, `CORS_`, `UPLOAD_`, `CRON_`, `TRAEFIK_`, `REVERSE_PROXY_`) sont disjoints de ceux utilises par des outils tiers courants, donc la cohabitation est safe.
|
||||
|
||||
Critere RNCP Cr 7.c.4 couvert : une seule commande (`make init`) orchestre build, demarrage, attente BDD, migrations et seed.
|
||||
Critere RNCP Cr 7.c.4 couvert : une seule commande (`docker compose up -d`) lance la
|
||||
stack complete. Le service one-shot `wakdo-migrate` applique le schema (migrations)
|
||||
puis les donnees de reference (seed) avant que l'app ne serve ; `wakdo-app`/`wakdo-web`
|
||||
attendent sa completion (`depends_on: service_completed_successfully`). Migrations et
|
||||
seed sont idempotents (tables de suivi `schema_migrations` / `seeds_applied`).
|
||||
Detail : `docs/journal/2026-06-17--makefile-to-compose-migrate.md`.
|
||||
|
||||
Services accessibles apres `make init` :
|
||||
Services accessibles apres `docker compose up -d` :
|
||||
- Borne : la valeur de `TRAEFIK_DOMAIN_KIOSK` dans `.env`
|
||||
- Admin + API : la valeur de `TRAEFIK_DOMAIN_ADMIN` dans `.env`
|
||||
|
||||
Liste complete des cibles : `make help`.
|
||||
|
||||
### Installation Docker sur un hote neuf (Debian / Ubuntu)
|
||||
|
||||
Procedure officielle detaillee : `https://docs.docker.com/engine/install/` (selectionner la distribution). Resume pour Debian stable :
|
||||
|
|
@ -153,13 +156,13 @@ docker network create mon_reseau_proxy
|
|||
# REVERSE_PROXY_NETWORK=mon_reseau_proxy
|
||||
```
|
||||
|
||||
Avant le premier `make init`, s'assurer que le reseau existe. Verification rapide :
|
||||
Avant le premier `docker compose up`, s'assurer que le reseau existe. Verification rapide :
|
||||
|
||||
```bash
|
||||
docker network inspect "$(grep ^REVERSE_PROXY_NETWORK .env | cut -d= -f2)"
|
||||
```
|
||||
|
||||
Si la commande retourne une erreur, soit adapter `REVERSE_PROXY_NETWORK` au nom du reseau utilise par votre proxy, soit creer le reseau manuellement. La cible `make init` echoue proprement avec un message d'aide si le reseau est introuvable.
|
||||
Si la commande retourne une erreur, soit adapter `REVERSE_PROXY_NETWORK` au nom du reseau utilise par votre proxy, soit creer le reseau manuellement (le reseau externe doit exister avant `docker compose up`).
|
||||
|
||||
*Section mise a jour au fil de l'implementation (migrations reelles, seed, CI/CD deploiement).*
|
||||
|
||||
|
|
@ -170,8 +173,8 @@ Si la commande retourne une erreur, soit adapter `REVERSE_PROXY_NETWORK` au nom
|
|||
```
|
||||
.
|
||||
|-- .claude/ # Methodologie BYAN (visible jury : CLAUDE.md + rules/)
|
||||
|-- .github/
|
||||
| `-- workflows/ # CI/CD GitHub Actions [a venir]
|
||||
|-- .forgejo/
|
||||
| `-- workflows/ # CI Forgejo Actions (ci.yml : secret-scan, php-lint, static-tests, js-tests, auto-merge)
|
||||
|-- .githooks/ # pre-commit + commit-msg [a venir]
|
||||
|-- docker/ # Dockerfiles customs par service
|
||||
| |-- apache/
|
||||
|
|
@ -199,7 +202,6 @@ Si la commande retourne une erreur, soit adapter `REVERSE_PROXY_NETWORK` au nom
|
|||
|-- .env.example
|
||||
|-- .dockerignore
|
||||
|-- .gitignore
|
||||
|-- Makefile
|
||||
|-- docker-compose.yml
|
||||
`-- README.md
|
||||
```
|
||||
|
|
@ -212,7 +214,7 @@ Si la commande retourne une erreur, soit adapter `REVERSE_PROXY_NETWORK` au nom
|
|||
|
||||
- **Commits** : Conventional Commits en anglais (`feat`, `fix`, `docs`, `refactor`, `test`, `chore`, `ci`, `db`, `perf`, `style`). Format : `type(scope): description`. Voir `docs/PROJECT_CONTEXT.md` section 9.
|
||||
- **Branches** : `feat/*`, `fix/*`, `refactor/*`, `docs/*`, `ci/*`, `db/*`, `chore/*`, `test/*` depuis `dev`. Merge vers `dev` par PR squashee. Periodiquement `dev` -> `main` par PR avec tag semver.
|
||||
- `main` et `dev` sont proteges cote GitHub (PR requise, force push bloque, resolution des conversations requise).
|
||||
- `main` et `dev` sont proteges cote Forgejo (PR requise, force push bloque, checks requis : secret-scan / php-lint / static-tests).
|
||||
- Pas d'emoji dans le code, les commits ou les specs techniques (Mantra IA-23).
|
||||
|
||||
*Sections detaillees (setup env de dev, lint, tests) : a completer au fil de l'implementation.*
|
||||
|
|
@ -227,7 +229,7 @@ Si la commande retourne une erreur, soit adapter `REVERSE_PROXY_NETWORK` au nom
|
|||
|
||||
## Deploiement
|
||||
|
||||
*Section a completer. Strategie cible : CI GitHub Actions sur PR vers `dev` (lint + PHPUnit), CD automatique sur merge vers `main` via SSH + `make rebuild`, voir `docs/PROJECT_CONTEXT.md` section 7 Bloc 5.*
|
||||
*Strategie : CI Forgejo Actions sur PR vers `dev`/`main` (secret-scan gitleaks, php-lint, static-tests PHPStan+PHPUnit, js-tests) avec auto-merge sur label + CI verte. CD : declenchement humain, redeploiement par `docker compose pull && docker compose up -d`. Voir `docs/PROJECT_CONTEXT.md` section 7 Bloc 5.*
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ bash db/migrate.sh --status # liste l'etat sans rien appliquer
|
|||
Le runner cible le conteneur `wakdo-db` et lit les identifiants dans `.env`
|
||||
(`DB_NAME`, `DB_ROOT_PASSWORD`). Il maintient une table `schema_migrations`
|
||||
(une ligne par fichier applique) : relancer ne rejoue que les nouvelles
|
||||
migrations. La cible `make migrate` est destinee a appeler ce script.
|
||||
migrations. La cible `bash db/migrate.sh` est destinee a appeler ce script.
|
||||
|
||||
## Conventions
|
||||
|
||||
|
|
|
|||
66
db/migrate-container.sh
Normal file
66
db/migrate-container.sh
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Wakdo - runner migrations + seed IN-CONTAINER (service compose one-shot wakdo-migrate).
|
||||
#
|
||||
# Applique, dans l'ordre lexicographique et de maniere IDEMPOTENTE :
|
||||
# 1. db/migrations/*.sql (suivi : table schema_migrations)
|
||||
# 2. db/seeds/*.sql (suivi : table seeds_applied)
|
||||
# Relancer ne rejoue que les fichiers en attente (tracking par nom de fichier).
|
||||
#
|
||||
# Contrairement a db/migrate.sh (hote, via `docker exec`), ce runner tourne DANS
|
||||
# un conteneur et se connecte a la base PAR LE RESEAU compose (DB_HOST). Il est
|
||||
# lance par le service `wakdo-migrate` apres que `wakdo-db` soit healthy ; les
|
||||
# services applicatifs (app/web) attendent sa COMPLETION (service_completed_successfully).
|
||||
#
|
||||
# But : `docker compose up` amene une stack COMPLETE et utilisable (schema + donnees
|
||||
# de reference, dont l'admin bootstrap) en une seule commande, sans dependance a
|
||||
# l'hote (Cr 7.c.4) -> remplace `make init`.
|
||||
#
|
||||
# Variables injectees par docker-compose : DB_HOST, DB_PORT, DB_NAME, DB_ROOT_PASSWORD.
|
||||
# Root requis : migrations = DDL, seeds = INSERT de reference.
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
: "${DB_HOST:?DB_HOST manquant}"
|
||||
: "${DB_NAME:?DB_NAME manquant}"
|
||||
: "${DB_ROOT_PASSWORD:?DB_ROOT_PASSWORD manquant}"
|
||||
PORT="${DB_PORT:-3306}"
|
||||
|
||||
db() { mariadb -h "$DB_HOST" -P "$PORT" -uroot -p"$DB_ROOT_PASSWORD" "$@"; }
|
||||
|
||||
# Applique les *.sql d'un dossier non encore enregistres dans sa table de suivi.
|
||||
apply_tracked() {
|
||||
local dir="$1" table="$2"
|
||||
local f base n applied=0
|
||||
|
||||
db "$DB_NAME" -e "CREATE TABLE IF NOT EXISTS ${table} (
|
||||
filename VARCHAR(255) NOT NULL PRIMARY KEY,
|
||||
applied_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;"
|
||||
|
||||
shopt -s nullglob
|
||||
local files=("$dir"/*.sql)
|
||||
if [ ${#files[@]} -eq 0 ]; then
|
||||
echo "[${table}] aucun fichier dans ${dir}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
for f in "${files[@]}"; do
|
||||
base="$(basename "$f")"
|
||||
n="$(db "$DB_NAME" -N -s -e "SELECT COUNT(*) FROM ${table} WHERE filename='${base}';")"
|
||||
if [ "$n" = "0" ]; then
|
||||
echo "[${table}] application de ${base} ..."
|
||||
db "$DB_NAME" < "$f"
|
||||
db "$DB_NAME" -e "INSERT INTO ${table} (filename) VALUES ('${base}');"
|
||||
applied=$((applied + 1))
|
||||
else
|
||||
echo "[${table}] ${base} deja applique, ignore"
|
||||
fi
|
||||
done
|
||||
echo "[${table}] termine (${applied} nouveau(x))."
|
||||
}
|
||||
|
||||
echo "[migrate] cible ${DB_HOST}:${PORT}/${DB_NAME}"
|
||||
apply_tracked /db/migrations schema_migrations
|
||||
apply_tracked /db/seeds seeds_applied
|
||||
echo "[migrate] stack a jour (schema + donnees de reference)."
|
||||
|
|
@ -7,7 +7,9 @@
|
|||
# deja appliques, donc relancer ne rejoue que les nouvelles migrations.
|
||||
#
|
||||
# Cible : le service docker-compose `wakdo-db` (MariaDB). Lance depuis l'hote
|
||||
# (c'est ce que `make migrate` appellera). Identifiants lus dans .env.
|
||||
# (usage manuel / `--status`, identifiants lus dans .env). Au boot de la stack,
|
||||
# c'est le service `wakdo-migrate` (db/migrate-container.sh, via le reseau) qui
|
||||
# applique migrations + seed automatiquement.
|
||||
#
|
||||
# Usage :
|
||||
# bash db/migrate.sh # applique les migrations en attente
|
||||
|
|
@ -30,7 +32,7 @@ DB_ROOT_PASSWORD="$(grep -E '^DB_ROOT_PASSWORD=' "$ENV_FILE" | cut -d= -f2-)"
|
|||
db() { docker exec -i "$CONTAINER" mariadb -uroot -p"$DB_ROOT_PASSWORD" "$@"; }
|
||||
|
||||
# Le conteneur doit etre en marche.
|
||||
docker exec "$CONTAINER" true 2>/dev/null || { echo "ERREUR : conteneur $CONTAINER non demarre (make up)" >&2; exit 1; }
|
||||
docker exec "$CONTAINER" true 2>/dev/null || { echo "ERREUR : conteneur $CONTAINER non demarre (docker compose up -d)" >&2; exit 1; }
|
||||
|
||||
# Journal des migrations appliquees.
|
||||
db "$DB_NAME" -e "CREATE TABLE IF NOT EXISTS schema_migrations (
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ DB_ROOT_PASSWORD="$(grep -E '^DB_ROOT_PASSWORD=' "$ENV_FILE" | cut -d= -f2-)"
|
|||
|
||||
db() { docker exec -i "$CONTAINER" mariadb -uroot -p"$DB_ROOT_PASSWORD" "$@"; }
|
||||
|
||||
docker exec "$CONTAINER" true 2>/dev/null || { echo "ERREUR : conteneur $CONTAINER non demarre (make up)" >&2; exit 1; }
|
||||
docker exec "$CONTAINER" true 2>/dev/null || { echo "ERREUR : conteneur $CONTAINER non demarre (docker compose up -d)" >&2; exit 1; }
|
||||
|
||||
if [ ! -d "$SEEDS_DIR" ]; then
|
||||
echo "[seed] aucun repertoire db/seeds/ - rien a charger"
|
||||
|
|
|
|||
|
|
@ -18,11 +18,11 @@
|
|||
# wakdo_uploads : named volume pour les uploads produits back-office
|
||||
# ./var/backups : bind-mount lecture-ecriture pour les dumps SQL
|
||||
#
|
||||
# Variables d'env consommees depuis .env (chargees par make via `include .env`
|
||||
# et transmises ici par docker compose qui fait l'expansion automatique).
|
||||
# Variables d'env consommees depuis .env : docker compose lit automatiquement le
|
||||
# fichier .env a la racine et fait l'expansion des ${...} ci-dessous.
|
||||
#
|
||||
# Persistance : un `make down` preserve les named volumes. Seul `make clean`
|
||||
# (interactif) ou `docker compose down -v` supprime les donnees.
|
||||
# Persistance : `docker compose down` preserve les named volumes ; seul
|
||||
# `docker compose down -v` supprime les donnees.
|
||||
#
|
||||
|
||||
name: wakdo
|
||||
|
|
@ -62,8 +62,7 @@ volumes:
|
|||
wakdo_db_data:
|
||||
# Named volume MariaDB. Permissions gerees par Docker (UID mysql=999
|
||||
# dans le conteneur), zero souci cote hote. Survit a `docker compose down`.
|
||||
# Pour remise a zero : `make clean` (interactif, confirme) ou
|
||||
# `docker compose down -v` (destructif direct).
|
||||
# Pour remise a zero : `docker compose down -v` (destructif : supprime les volumes).
|
||||
|
||||
wakdo_uploads:
|
||||
# Images produits uploadees par les equipiers depuis le back-office.
|
||||
|
|
@ -113,6 +112,38 @@ services:
|
|||
retries: 6
|
||||
start_period: 30s
|
||||
|
||||
# =======================================================================
|
||||
# wakdo-migrate : service ONE-SHOT (migrations + seed idempotents)
|
||||
# =======================================================================
|
||||
# Tourne une fois apres que wakdo-db soit healthy, applique le schema puis les
|
||||
# donnees de reference (idempotent via schema_migrations / seeds_applied), et
|
||||
# sort. app/web attendent sa COMPLETION : `docker compose up` rend ainsi la stack
|
||||
# complete + utilisable en UNE commande, sans dependance a l'hote (Cr 7.c.4).
|
||||
wakdo-migrate:
|
||||
image: mariadb:11.4
|
||||
container_name: wakdo-migrate
|
||||
restart: "no"
|
||||
|
||||
environment:
|
||||
DB_HOST: ${DB_HOST}
|
||||
DB_PORT: ${DB_PORT}
|
||||
DB_NAME: ${DB_NAME}
|
||||
# Root : migrations = DDL, seeds = INSERT de reference.
|
||||
DB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
|
||||
|
||||
volumes:
|
||||
# migrations + seeds + le runner, en lecture seule.
|
||||
- ./db:/db:ro
|
||||
|
||||
networks:
|
||||
- wakdo_internal
|
||||
|
||||
depends_on:
|
||||
wakdo-db:
|
||||
condition: service_healthy
|
||||
|
||||
entrypoint: ["bash", "/db/migrate-container.sh"]
|
||||
|
||||
# =======================================================================
|
||||
# wakdo-app : PHP-FPM 8.3 (execute le code back-office + API)
|
||||
# =======================================================================
|
||||
|
|
@ -171,13 +202,16 @@ services:
|
|||
|
||||
# Named volume pour les uploads, plus specifique que le bind-mount
|
||||
# parent : les uploads ne vont pas dans ./src, ils restent dans le
|
||||
# volume Docker et survivent aux `make down`.
|
||||
# volume Docker et survivent aux `docker compose down`.
|
||||
- wakdo_uploads:/var/www/html/public/uploads
|
||||
|
||||
networks:
|
||||
- wakdo_internal
|
||||
|
||||
depends_on:
|
||||
# Le schema + les donnees de reference sont en place AVANT que l'app serve.
|
||||
wakdo-migrate:
|
||||
condition: service_completed_successfully
|
||||
wakdo-db:
|
||||
condition: service_healthy
|
||||
|
||||
|
|
@ -210,6 +244,8 @@ services:
|
|||
- reverse_proxy
|
||||
|
||||
depends_on:
|
||||
wakdo-migrate:
|
||||
condition: service_completed_successfully
|
||||
wakdo-app:
|
||||
condition: service_started
|
||||
wakdo-db:
|
||||
|
|
|
|||
|
|
@ -113,13 +113,13 @@ Client Borne (Bloc 1) API (Bloc 2) BDD
|
|||
|
||||
**Un seul codebase, deux FQDN d'exposition publique.** Le front Bloc 1 et le back Bloc 2 coexistent dans la meme arborescence. Une bascule mode JSON-seuls (Bloc 1 isole) vs mode API-connecte doit rester possible via configuration.
|
||||
|
||||
**Pourquoi pas strategie A (deux rendus isoles)** : le Bloc 5 DevOps impose une conteneurisation **unique** qui lance la stack complete avec `make init` en une commande (Cr 7.c.4). Deux codebases isolees seraient incoherentes avec cette exigence.
|
||||
**Pourquoi pas strategie A (deux rendus isoles)** : le Bloc 5 DevOps impose une conteneurisation **unique** qui lance la stack complete avec `docker compose up` en une commande (Cr 7.c.4). Deux codebases isolees seraient incoherentes avec cette exigence.
|
||||
|
||||
### Compatibilite evaluation par bloc
|
||||
|
||||
- **Jury Bloc 1** : voit le front seul ; le front peut tomber en fallback sur JSON statiques fournis (`src/public/borne/data/*.json`) si l'API est indisponible.
|
||||
- **Jury Bloc 2** : voit le back-office + teste l'API via curl/Postman de maniere autonome, sans dependre du front.
|
||||
- **Jury Bloc 5** : lance `make init` ou `docker compose up`, verifie la CI/CD, les crons, l'archi, les scripts.
|
||||
- **Jury Bloc 5** : lance `docker compose up` ou `docker compose up`, verifie la CI/CD, les crons, l'archi, les scripts.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -193,7 +193,7 @@ Reseaux :
|
|||
| Reverse proxy | Traefik (deja en place) | existant | `admin_proxy` network |
|
||||
| TLS | Let's Encrypt via Traefik | auto | `acme.json` existant |
|
||||
| Conteneurisation | Docker + docker compose | v2 | Cr 7.c |
|
||||
| Orchestration locale | Makefile | — | Cr 7.b (script) + Cr 7.c.4 (une commande) |
|
||||
| Orchestration locale | docker compose (service wakdo-migrate) | — | Cr 7.b (script) + Cr 7.c.4 (une commande) |
|
||||
| CI/CD | Forgejo Actions (act_runner auto-heberge) | — | Cr 7.d |
|
||||
| Versioning | Git + Forgejo auto-heberge (push-mirror GitHub) | — | Cr 4.f (collaboration) |
|
||||
| Hooks Git | pre-commit + commit-msg | versionnes dans `.githooks/` | Conventional Commits |
|
||||
|
|
@ -263,14 +263,14 @@ Reseaux :
|
|||
**IN scope :**
|
||||
- Dockerfile custom PHP-FPM avec extensions
|
||||
- `docker-compose.yml` orchestrant les 4 services (web, app, db, cron)
|
||||
- `Makefile` avec cible `make init` qui lance tout en une commande (Cr 7.c.4)
|
||||
- `docker compose up` lance toute la stack (service one-shot `wakdo-migrate` : migrations + seed idempotents) en une commande (Cr 7.c.4)
|
||||
- Scripts Bash d'automatisation (backup, deploy, migrate)
|
||||
- **Cron tab** avec au moins 3 jobs planifies dans la fenetre de maintenance (01h30-09h30) :
|
||||
- `0 3 * * *` — backup BDD quotidien a 03h00 (entre fin service 01h et ouverture 10h)
|
||||
- `*/15 * * * *` — purge sessions expirees toutes les 15 min (leger, peut tourner en service)
|
||||
- `30 4 * * *` — agregation stats commandes a 04h30 sur le **jour de service** ecoule (10h J-1 → 01h J)
|
||||
- **CI Forgejo Actions** (act_runner auto-heberge) : lint PHP + PHPStan + PHPUnit + secret-scan (gitleaks) sur PR -> dev
|
||||
- **CD Forgejo Actions** : deploy auto sur merge main (SSH + pull + `make rebuild`)
|
||||
- **CD Forgejo Actions** : deploy auto sur merge main (SSH + `docker compose pull && docker compose up -d`)
|
||||
- `.env.example` documente (parametres securite : argon2id, lockout, seuils throttle, retention RGPD), secrets hors du repo
|
||||
- `php.ini` durci (expose_php off, session cookies httponly/secure/samesite, upload limite)
|
||||
- Healthcheck Traefik + readiness probes
|
||||
|
|
@ -328,13 +328,13 @@ Reseaux :
|
|||
| Critere | Libelle court | Feature Wakdo couvrant |
|
||||
|---|---|---|
|
||||
| Cr 7.a.1-3 | Analyse infra + securite | Audit code + proposition automatisation documentee |
|
||||
| Cr 7.b.1 | Langage de script | Bash (deploy, backup) + Makefile |
|
||||
| Cr 7.b.2 | Automatisation fiabilisee | Makefile avec exit codes, retries, logs |
|
||||
| Cr 7.b.1 | Langage de script | Bash (db/*.sh migrate/seed, scripts/forgejo-*.sh, entrypoints, backup) |
|
||||
| Cr 7.b.2 | Automatisation fiabilisee | Scripts Bash (set -euo pipefail, exit codes, logs) + service compose wakdo-migrate idempotent |
|
||||
| Cr 7.b.3 | **Cron tab** | `wakdo-cron` service avec crontab : backup BDD, purge sessions, stats |
|
||||
| Cr 7.c.1 | VM operationnelle | Serveur existant Acadenice |
|
||||
| Cr 7.c.2 | OS conteneur installe | Docker Engine |
|
||||
| Cr 7.c.3 | App conteneurisee complete | 4 services (web, app, db, cron) |
|
||||
| Cr 7.c.4 | **Une ligne de commande** | `make init` lance toute la stack + migrate + seed |
|
||||
| Cr 7.c.4 | **Une ligne de commande** | `docker compose up` lance toute la stack + migrate + seed |
|
||||
| Cr 7.d.1 | Architecture serveur | Traefik reverse + reseaux segmentes documentes |
|
||||
| Cr 7.d.2 | Tests avant deploy | CI PHPUnit + PHPStan + secret-scan sur PR (Forgejo Actions) |
|
||||
| Cr 7.d.3 | Integration/deploiement continus | Forgejo Actions deploy automatique sur merge main |
|
||||
|
|
@ -439,7 +439,7 @@ Les branches `main` et `dev` sont **protegees** cote Forgejo (push direct interd
|
|||
| 8 | 2 FQDN | Separation claire borne publique / admin+API interne, defensible jury |
|
||||
| 9 | API sous `/api` sur le FQDN admin | Simplicite d'exploitation, CORS explicite gere |
|
||||
| 10 | Service cron dedie | Cr 7.b.3 explicite + realiste prod |
|
||||
| 11 | Makefile avec `make init` | Cr 7.c.4 + demonstration DevOps |
|
||||
| 11 | Orchestration `docker compose up` (service wakdo-migrate) | Cr 7.c.4 + demonstration DevOps |
|
||||
| 12 | Conventional Commits + hooks | Cr 4.f.x + discipline de versioning |
|
||||
| 13 | Branches feat/* -> dev -> main | Pipeline propre pour jury, PR tracee (Forgejo, mirror GitHub) |
|
||||
| 14 | CI/CD Forgejo Actions (act_runner auto-heberge) | Cr 7.d explicite ; forge + CI maitrisees de bout en bout (argument Bloc 5) |
|
||||
|
|
@ -490,7 +490,7 @@ Buffer : ~8 h pour imprevus. Cible effective : ~264 h sur 20 semaines = **~13 h/
|
|||
**Bloc 5 :**
|
||||
- `docker-compose.yml` commente
|
||||
- Dockerfiles customs commentes
|
||||
- `Makefile` avec `make help`
|
||||
- Orchestration via `docker compose` (service one-shot `wakdo-migrate` : migrate + seed)
|
||||
- `.forgejo/workflows/` avec CI (PHPUnit + PHPStan + secret-scan) + CD
|
||||
- Crontab documente
|
||||
- Script de backup/restore teste
|
||||
|
|
@ -500,7 +500,7 @@ Buffer : ~8 h pour imprevus. Cible effective : ~264 h sur 20 semaines = **~13 h/
|
|||
|
||||
- **README.md** synthetique (quick start + liens docs)
|
||||
- **Presentation** (slides ou live) argumentant les choix
|
||||
- **Demo** live : borne + back-office + API (Postman/curl) + `make init`
|
||||
- **Demo** live : borne + back-office + API (Postman/curl) + `docker compose up`
|
||||
- **Capacite modification en direct** (Cr 4.a.1) : code structure pour permettre modifs sans casser
|
||||
|
||||
---
|
||||
|
|
@ -511,7 +511,7 @@ Buffer : ~8 h pour imprevus. Cible effective : ~264 h sur 20 semaines = **~13 h/
|
|||
|---|---|---|---|
|
||||
| Sous-estimation temps front (accessibilite RGAA stricte) | Haute | Moyen | 60 h budgetees + tests W3C/axe-core pendant le dev, pas a la fin |
|
||||
| Complexite MCT (statuts commande) mal modelisee | Moyenne | Fort | Valider MCT avec un pair ou prof avant d'implementer Bloc 2 |
|
||||
| Dockerfile PHP extensions manquantes decouvert tard | Moyenne | Faible | Tester `make up` + un vrai appel BDD des P0 |
|
||||
| Dockerfile PHP extensions manquantes decouvert tard | Moyenne | Faible | Tester `docker compose up -d` + un vrai appel BDD des P0 |
|
||||
| Conflit reseau Docker `wakdo_internal` existant | Faible | Faible | Verifie au setup, fallback nom `wakdo_backend` |
|
||||
| CORS mal configure bloque la borne | Moyenne | Moyen | Test immediat apres setup 2 FQDN |
|
||||
| Performance borne sur ecran tactile reel | Faible | Fort | Optimiser images + lazy loading + tests sur device tactile si possible |
|
||||
|
|
@ -614,7 +614,7 @@ L'auteur peut recourir ponctuellement a d'autres outils IA (completion IDE, assi
|
|||
- **Choix du scope fonctionnel** : defini par l'auteur a partir du brief RNCP. L'IA n'ajoute ni ne retire de fonctionnalite sans instruction explicite.
|
||||
- **Modelisation Merise** (MCD, MCT, MLD) : formalisation produite par l'IA a partir du dictionnaire de donnees et des user stories ; arbitrage, validation et corrections par l'auteur. Chaque cardinalite, chaque relation et chaque transition de statut est validee par l'auteur avant integration. Le livrable final reflete ses decisions.
|
||||
- **Validation des livrables** : reservee au jury. L'IA n'emet pas de jugement final sur la conformite RNCP.
|
||||
- **Deploiements** : declenchement humain uniquement, y compris sur `make init` local. Aucune action sur environnement serveur sans instruction explicite.
|
||||
- **Deploiements** : declenchement humain uniquement, y compris sur `docker compose up` local. Aucune action sur environnement serveur sans instruction explicite.
|
||||
- **Commit en son nom** : aucun trailer `Co-Authored-By: Claude...` n'est appose sur les commits. Voir section 17.7.
|
||||
- **Decisions de securite critiques** : tous les choix de type hash mdp, CORS, RBAC, politique sessions sont valides par l'auteur meme si l'IA en propose la mise en oeuvre.
|
||||
|
||||
|
|
|
|||
88
docs/journal/2026-06-17--makefile-to-compose-migrate.md
Normal file
88
docs/journal/2026-06-17--makefile-to-compose-migrate.md
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
# 2026-06-17 — Du Makefile a `docker compose up` (service wakdo-migrate)
|
||||
|
||||
**Auteur : BYAN.** Remplacement de l'orchestration locale par Makefile par un service
|
||||
compose one-shot. Objectif : que `docker compose up` amene a lui seul une stack
|
||||
complete et utilisable, et retirer un Makefile devenu en partie trompeur.
|
||||
|
||||
## Pourquoi ce changement
|
||||
|
||||
### Le declencheur : le Makefile mentait en partie
|
||||
Un audit du Makefile (24 cibles) a montre trois categories :
|
||||
- **Cibles mortes / trompeuses** : `test`, `test-unit`, `test-integration`, `lint`
|
||||
affichaient *« Pas encore implemente … en P2 »* alors que les tests EXISTENT et
|
||||
tournent (PHPUnit via `.phar`, 263 tests unit + 301/916 en integration ; PHPStan
|
||||
L6 ; tests JS node:test+jsdom). `install-hooks` referencait un `.githooks/` et un
|
||||
`scripts/install-hooks.sh` absents. Une cible qui annonce un faux est pire qu'une
|
||||
cible absente.
|
||||
- **Wrappers fins** : `up/down/logs/shell/...` = une ligne au-dessus de
|
||||
`docker compose`, valeur surtout de decouvrabilite (`make help`).
|
||||
- **Une seule cible reellement porteuse** : `init` (build -> up -> wait-db ->
|
||||
migrate), citee comme la preuve du critere RNCP **Cr 7.c.4** (*« lancer la stack
|
||||
complete avec une seule ligne de commande »*).
|
||||
|
||||
### Le point cle : Cr 7.c.4 parle d'un RESULTAT, pas de `make`
|
||||
Le critere exige *une commande -> stack complete*. Il ne mentionne pas `make` ;
|
||||
`make init` n'etait qu'un choix d'implementation. Or `docker compose up` seul ne
|
||||
suffisait pas : il demarre les conteneurs mais **n'applique pas les migrations**
|
||||
(base vide -> stack non « complete »). C'etait l'unique raison d'etre de `make init`.
|
||||
|
||||
En deplacant migration + seed DANS la stack (un service one-shot qui tourne au
|
||||
boot), c'est `docker compose up` LUI-MEME qui amene la stack complete. Avantages :
|
||||
- **Commande universelle** : `docker compose up`, sans dependance a l'outil `make`
|
||||
sur l'hote (un correcteur n'a pas a installer/connaitre `make`).
|
||||
- **Comportement = documentation** : l'ancien `make init` ne faisait meme PAS le
|
||||
seed (il s'arretait a `migrate`), alors que le README annoncait « migrate + seed ».
|
||||
Le nouveau chemin seed pour de vrai, donc la stack est *loginnable* (admin present)
|
||||
en une commande.
|
||||
- **Plus idiomatique** : faire porter l'init par la couche d'orchestration (compose)
|
||||
plutot que par un outil hote externe.
|
||||
|
||||
## Ce qui a ete fait
|
||||
|
||||
- **`db/migrate-container.sh`** : runner in-container. Applique `db/migrations/*.sql`
|
||||
(suivi `schema_migrations`) PUIS `db/seeds/*.sql` (suivi `seeds_applied`), de
|
||||
maniere idempotente, en se connectant a la base par le reseau compose (DB_HOST).
|
||||
Distinct de `db/migrate.sh` (hote, via `docker exec`), conserve pour l'usage manuel
|
||||
(`--status`) et la CI.
|
||||
- **Service `wakdo-migrate`** (image mariadb, `restart: "no"`) : `depends_on`
|
||||
`wakdo-db: service_healthy`, lance le runner puis sort. `wakdo-app` et `wakdo-web`
|
||||
gagnent `depends_on wakdo-migrate: service_completed_successfully` -> ils ne servent
|
||||
qu'une fois le schema + le seed en place.
|
||||
- **Makefile supprime.** Les commandes equivalentes en clair :
|
||||
`docker compose up -d` (= ex-`make init`/`up`), `docker compose down` (`make down`),
|
||||
`docker compose down -v` (`make clean`), `docker compose build --no-cache && up -d`
|
||||
(`make rebuild`), `docker compose logs -f` (`make logs`),
|
||||
`docker compose exec wakdo-db mariadb -uroot -p"$DB_ROOT_PASSWORD"` (`make shell-db`).
|
||||
Tests : `docker run --rm -v "$PWD":/app -w /app wakdo-wakdo-app php phpunit.phar -c phpunit.xml`
|
||||
(cf. README / SESSION_RESUME).
|
||||
|
||||
## Verification
|
||||
|
||||
Base MariaDB ephemere et vierge (pour ne pas toucher la dev) :
|
||||
- Run #1 : 2 migrations + 2 seeds appliques.
|
||||
- Run #2 : 0 nouveau (idempotent, tout ignore).
|
||||
- Donnees : 5 roles, 23 permissions, admin `admin@wakdo.local` present ;
|
||||
`schema_migrations`=2, `seeds_applied`=2.
|
||||
|
||||
`docker compose -p wakdo config` valide. La CI n'utilise pas `make` (0 appel) :
|
||||
elle garde sa propre boucle migrate -> non impactee.
|
||||
|
||||
## Mapping Cr 7.c.4 (apres ce changement)
|
||||
*« Le fichier de configuration permet de lancer la stack applicative complete avec
|
||||
une seule ligne de commande »* -> **`docker compose up`** : `docker-compose.yml`
|
||||
decrit la stack, le service `wakdo-migrate` applique schema + donnees, app/web
|
||||
attendent sa completion. Une commande, aucune dependance hote.
|
||||
|
||||
## Note de deploiement (environnements deja seedes)
|
||||
Sur une base existante deja migree ET seedee AVANT l'introduction du suivi
|
||||
(`seeds_applied` absente), le premier `docker compose up` avec le nouveau service
|
||||
tenterait de rejouer les seeds (INSERT non idempotents) -> conflits d'unicite. Pour
|
||||
ces environnements : back-fill une fois la table de suivi
|
||||
(`CREATE TABLE seeds_applied(...)` + INSERT des noms de fichiers seed deja appliques,
|
||||
idem `schema_migrations` si besoin) AVANT le premier up. Les deploiements sur volume
|
||||
VIERGE ne sont pas concernes (le service applique tout proprement, comme verifie).
|
||||
|
||||
## Compromis assumes
|
||||
- migrations + seeds evalues a CHAQUE `up` : cout negligeable (le suivi rend les
|
||||
re-runs sans effet).
|
||||
- `wakdo-migrate` se connecte en root (DDL + INSERT de reference), comme `migrate.sh`.
|
||||
Loading…
Add table
Reference in a new issue