add db-setup service: idempotent per-service Postgres user bootstrap
Runs on every 'docker compose up -d' before product services start.
Creates dd0c_{drift,alert,portal,cost,run} users with least-privilege
grants if they don't exist. Fixes auth failures on existing PG volumes
that predate the security hardening.
This commit is contained in:
@@ -53,6 +53,43 @@ services:
|
|||||||
- meili_data:/meili_data
|
- meili_data:/meili_data
|
||||||
|
|
||||||
|
|
||||||
|
# --- DB User Bootstrap (idempotent, runs every up) ---
|
||||||
|
db-setup:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
restart: "no"
|
||||||
|
depends_on:
|
||||||
|
postgres: { condition: service_healthy }
|
||||||
|
environment:
|
||||||
|
PGHOST: postgres
|
||||||
|
PGUSER: ${POSTGRES_USER:-dd0c}
|
||||||
|
PGPASSWORD: ${POSTGRES_PASSWORD:-dd0c-dev}
|
||||||
|
DB_DRIFT_PASSWORD: ${DB_DRIFT_PASSWORD:-dd0c-dev}
|
||||||
|
DB_ALERT_PASSWORD: ${DB_ALERT_PASSWORD:-dd0c-dev}
|
||||||
|
DB_PORTAL_PASSWORD: ${DB_PORTAL_PASSWORD:-dd0c-dev}
|
||||||
|
DB_COST_PASSWORD: ${DB_COST_PASSWORD:-dd0c-dev}
|
||||||
|
DB_RUN_PASSWORD: ${DB_RUN_PASSWORD:-dd0c-dev}
|
||||||
|
entrypoint: ["sh", "-c"]
|
||||||
|
command:
|
||||||
|
- |
|
||||||
|
set -e
|
||||||
|
create_user() {
|
||||||
|
local db=$$1 user=$$2 pass=$$3
|
||||||
|
psql -d postgres -c "DO \$$\$$ BEGIN CREATE USER $$user WITH PASSWORD '$$pass'; EXCEPTION WHEN duplicate_object THEN ALTER USER $$user WITH PASSWORD '$$pass'; END \$$\$$;"
|
||||||
|
psql -d "$$db" -c "GRANT CONNECT ON DATABASE $$db TO $$user;"
|
||||||
|
psql -d "$$db" -c "GRANT USAGE ON SCHEMA public TO $$user;"
|
||||||
|
psql -d "$$db" -c "GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO $$user;"
|
||||||
|
psql -d "$$db" -c "GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO $$user;"
|
||||||
|
psql -d "$$db" -c "ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO $$user;"
|
||||||
|
psql -d "$$db" -c "ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE, SELECT ON SEQUENCES TO $$user;"
|
||||||
|
echo "✓ $$user → $$db"
|
||||||
|
}
|
||||||
|
create_user dd0c_drift dd0c_drift "$$DB_DRIFT_PASSWORD"
|
||||||
|
create_user dd0c_alert dd0c_alert "$$DB_ALERT_PASSWORD"
|
||||||
|
create_user dd0c_portal dd0c_portal "$$DB_PORTAL_PASSWORD"
|
||||||
|
create_user dd0c_cost dd0c_cost "$$DB_COST_PASSWORD"
|
||||||
|
create_user dd0c_run dd0c_run "$$DB_RUN_PASSWORD"
|
||||||
|
echo "db-setup complete"
|
||||||
|
|
||||||
# --- dd0c Products ---
|
# --- dd0c Products ---
|
||||||
# P1: LLM Cost Router (Rust — API server)
|
# P1: LLM Cost Router (Rust — API server)
|
||||||
# NOTE: Rust services are behind the "rust" profile because they take 10+ min to compile.
|
# NOTE: Rust services are behind the "rust" profile because they take 10+ min to compile.
|
||||||
@@ -127,6 +164,7 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
postgres: { condition: service_healthy }
|
postgres: { condition: service_healthy }
|
||||||
redis: { condition: service_healthy }
|
redis: { condition: service_healthy }
|
||||||
|
db-setup: { condition: service_completed_successfully }
|
||||||
|
|
||||||
# P3: Alert Intelligence
|
# P3: Alert Intelligence
|
||||||
alert:
|
alert:
|
||||||
@@ -146,6 +184,7 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
postgres: { condition: service_healthy }
|
postgres: { condition: service_healthy }
|
||||||
redis: { condition: service_healthy }
|
redis: { condition: service_healthy }
|
||||||
|
db-setup: { condition: service_completed_successfully }
|
||||||
|
|
||||||
# P4: Lightweight IDP / Service Catalog
|
# P4: Lightweight IDP / Service Catalog
|
||||||
portal:
|
portal:
|
||||||
@@ -167,6 +206,7 @@ services:
|
|||||||
postgres: { condition: service_healthy }
|
postgres: { condition: service_healthy }
|
||||||
redis: { condition: service_healthy }
|
redis: { condition: service_healthy }
|
||||||
meilisearch: { condition: service_started }
|
meilisearch: { condition: service_started }
|
||||||
|
db-setup: { condition: service_completed_successfully }
|
||||||
|
|
||||||
# P5: AWS Cost Anomaly Detection
|
# P5: AWS Cost Anomaly Detection
|
||||||
cost:
|
cost:
|
||||||
@@ -187,6 +227,7 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
postgres: { condition: service_healthy }
|
postgres: { condition: service_healthy }
|
||||||
redis: { condition: service_healthy }
|
redis: { condition: service_healthy }
|
||||||
|
db-setup: { condition: service_completed_successfully }
|
||||||
|
|
||||||
# P6: Runbook Automation (SaaS)
|
# P6: Runbook Automation (SaaS)
|
||||||
run:
|
run:
|
||||||
@@ -206,6 +247,7 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
postgres: { condition: service_healthy }
|
postgres: { condition: service_healthy }
|
||||||
redis: { condition: service_healthy }
|
redis: { condition: service_healthy }
|
||||||
|
db-setup: { condition: service_completed_successfully }
|
||||||
|
|
||||||
# dd0c Console (React SPA)
|
# dd0c Console (React SPA)
|
||||||
console:
|
console:
|
||||||
|
|||||||
Reference in New Issue
Block a user