Apply migrate service pattern to docker-compose.prebuilt.yml

Brings docker-compose.prebuilt.yml in line with the migrate service
refactor from wilm (commit 58a3670529). Migrations, plugin bootstrap,
and seeds now run in a dedicated service with restart: "no" so failures
block deployment instead of crash-looping.

Changes:
- Add dedicated migrate service (runs db upgrade, bootstrap, seeds)
- API now depends on migrate: service_completed_successfully
- Database bound to 127.0.0.1:3306 (not 0.0.0.0) for security
- UTF-8 charset enforced server-wide
- Healthcheck uses TCP not socket (prevents false-healthy during init)

Testing:
- Verified migrations are idempotent (safe to re-run)
- Verified failed migration blocks API startup (fail-closed)
- Verified startup sequence: db -> migrate -> api (44s)
- Database at schema version 7d51_endpoint_logcollections (head)

Aligns dev environment with pull/airgap deployment pattern.
This commit is contained in:
Proudlock
2026-09-11 12:43:02 -04:00
parent c750b2ddc6
commit 0b252db7d2

View File

@@ -5,6 +5,9 @@
services:
db:
image: mysql:8.4
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
ports:
- "127.0.0.1:3306:3306"
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: shopdb_flask
@@ -13,12 +16,43 @@ services:
volumes:
- db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
# Schema, plugin bootstrap and seed data - runs once before API starts
migrate:
build:
context: .
dockerfile: Dockerfile.prebuilt
restart: "no"
depends_on:
db:
condition: service_healthy
environment:
- FLASK_ENV=${FLASK_ENV:-production}
- DATABASE_URL=mysql+pymysql://shopdb:${MYSQL_PASSWORD}@db:3306/shopdb_flask?charset=utf8mb4
- SECRET_KEY=${SECRET_KEY}
- JWT_SECRET_KEY=${JWT_SECRET_KEY}
- CORS_ORIGINS=${CORS_ORIGINS}
- LOG_LEVEL=${LOG_LEVEL:-INFO}
command:
- sh
- -c
- >
flask db upgrade &&
/app/scripts/bootstrap-plugins.sh &&
flask plugin upgrade-all &&
flask seed permissions &&
flask seed settings &&
flask seed reference-data
volumes:
- ./plugins:/app/plugins:ro
- ./scripts:/app/scripts:ro
- instance_data:/app/instance
api:
build:
context: .
@@ -46,6 +80,8 @@ services:
depends_on:
db:
condition: service_healthy
migrate:
condition: service_completed_successfully
restart: unless-stopped
command:
- gunicorn