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:
@@ -5,6 +5,9 @@
|
|||||||
services:
|
services:
|
||||||
db:
|
db:
|
||||||
image: mysql:8.4
|
image: mysql:8.4
|
||||||
|
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:3306:3306"
|
||||||
environment:
|
environment:
|
||||||
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
|
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
|
||||||
MYSQL_DATABASE: shopdb_flask
|
MYSQL_DATABASE: shopdb_flask
|
||||||
@@ -13,12 +16,43 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- db_data:/var/lib/mysql
|
- db_data:/var/lib/mysql
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
|
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"]
|
||||||
interval: 10s
|
interval: 10s
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 5
|
retries: 5
|
||||||
restart: unless-stopped
|
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:
|
api:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
@@ -46,6 +80,8 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
db:
|
db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
migrate:
|
||||||
|
condition: service_completed_successfully
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command:
|
command:
|
||||||
- gunicorn
|
- gunicorn
|
||||||
|
|||||||
Reference in New Issue
Block a user