Import the wilm endpoint-monitor and channel-distribution work
Everything on origin/wilm that is not on the published main, applied as one
change because the published history has rewritten hashes: per-commit
cherry-pick conflicts against our main even though the squashed diff applies
clean.
Contents: endpoint monitor catalog + policy attachment + warn-only drift
reconciler, operator issue reports from the tray, agent launch-path allowlist,
and the GHCR channel-image distribution path for dev workstations.
NOT READY FOR main. Open items:
- 10 new routes are absent from docs/api-inventory.json, so
test_api_inventory_parity fails. That gate SKIPS on the published mirror
(the test ships, its data file is scrubbed), which is why wilm never saw it.
- dev-bootstrap.ps1 and Start-ShopDBDev.ps1 hardcode the ge-aero GitHub org.
- plugins/endpoints/plugin.py carries a whitespace-only re-indent.
Scope: product
This commit is contained in:
92
docker-compose.pull.yml
Normal file
92
docker-compose.pull.yml
Normal file
@@ -0,0 +1,92 @@
|
||||
# shopdb-flask PULL stack for dev workstations (stable / edge channels).
|
||||
#
|
||||
# WHY this exists: pilots behind an inspecting proxy cannot reliably BUILD the
|
||||
# image from source (npm's many small fetches get reset mid-install). Instead
|
||||
# CI (.github/workflows/publish-images.yml) builds the image on clean runners
|
||||
# and publishes it to GHCR; this file just PULLS and RUNS it. One resumable
|
||||
# image pull survives the proxy where hundreds of npm requests do not.
|
||||
#
|
||||
# Nothing is built here (no `build:`), mirroring docker-compose.airgap.yml:
|
||||
# - api/migrate use `image:` (pulled from GHCR), never `build: .`.
|
||||
# - NO ./plugins bind mount; the image carries every plugin baked in.
|
||||
# - a one-shot `migrate` runs db upgrade + plugin upgrade-all + seed before
|
||||
# api starts, so `up -d` alone brings up a working site.
|
||||
#
|
||||
# Driven by scripts/dev-bootstrap.ps1, which sets SHOPDB_IMAGE (the channel
|
||||
# image ref), SHOPDB_ENV_LABEL, API_PORT and MYSQL_PORT per channel and picks a
|
||||
# compose project name (-p shopdb-stable / -p shopdb-edge) so the two channels
|
||||
# run side by side without colliding.
|
||||
|
||||
x-app-env: &app-env
|
||||
FLASK_APP: wsgi.py
|
||||
FLASK_ENV: production
|
||||
DATABASE_URL: mysql+pymysql://shopdb:${MYSQL_PASSWORD}@db:3306/shopdb_flask?charset=utf8mb4
|
||||
SECRET_KEY: ${SECRET_KEY:?SECRET_KEY must be set}
|
||||
JWT_SECRET_KEY: ${JWT_SECRET_KEY:?JWT_SECRET_KEY must be set}
|
||||
CORS_ORIGINS: ${CORS_ORIGINS:?CORS_ORIGINS must be set}
|
||||
LOG_LEVEL: ${LOG_LEVEL:-INFO}
|
||||
# Empty on stable; 'DEV' on edge, which lights the sidebar badge.
|
||||
SHOPDB_ENV_LABEL: ${SHOPDB_ENV_LABEL:-}
|
||||
|
||||
services:
|
||||
db:
|
||||
image: mysql:8.4
|
||||
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:?MYSQL_ROOT_PASSWORD must be set}
|
||||
MYSQL_DATABASE: shopdb_flask
|
||||
MYSQL_USER: shopdb
|
||||
MYSQL_PASSWORD: ${MYSQL_PASSWORD:?MYSQL_PASSWORD must be set}
|
||||
volumes:
|
||||
- db_data:/var/lib/mysql
|
||||
ports:
|
||||
- "127.0.0.1:${MYSQL_PORT:-3306}:3306"
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
# One-shot schema + seed. Runs to completion and exits; api waits for it.
|
||||
# Every step is idempotent, so it is safe to run on every `up`.
|
||||
migrate:
|
||||
image: ${SHOPDB_IMAGE:?SHOPDB_IMAGE must be set to the channel image ref}
|
||||
pull_policy: always
|
||||
restart: "no"
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
<<: *app-env
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- >
|
||||
flask db upgrade &&
|
||||
flask plugin upgrade-all &&
|
||||
flask seed permissions &&
|
||||
flask seed settings &&
|
||||
flask seed reference-data
|
||||
volumes:
|
||||
- instance_data:/app/instance
|
||||
|
||||
api:
|
||||
image: ${SHOPDB_IMAGE:?SHOPDB_IMAGE must be set to the channel image ref}
|
||||
pull_policy: always
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
migrate:
|
||||
condition: service_completed_successfully
|
||||
environment:
|
||||
<<: *app-env
|
||||
ports:
|
||||
- "${API_PORT:-5001}:5001"
|
||||
volumes:
|
||||
- instance_data:/app/instance
|
||||
|
||||
volumes:
|
||||
db_data:
|
||||
instance_data:
|
||||
Reference in New Issue
Block a user