Traefik as the server-wide edge (TLS via Let's Encrypt, dashboard on traefik.petrolyst.com behind oauth2-proxy and Keycloak). The fuel-monitoring stack: Superset on atoma.petrolyst.com with Keycloak login and Petrolyst branding, Trino reading the TimescaleDB fuel-db as catalog "fuel". Customization lives in petrolyst-insights/, deployment in the other folders. Deploys run server-side (deploy/deploy.sh) from a Gitea workflow or manually; releases are immutable, Superset metadata is backed up before migrations, and deploy/rollback.sh restores it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
175 lines
5.4 KiB
YAML
175 lines
5.4 KiB
YAML
# Fuel-monitoring analytics: Superset on atoma.petrolyst.com, reading the
|
|
# operational store (fuel-db) through Trino. Run only through deploy/deploy.sh
|
|
# or deploy/rollback.sh: they export SUPERSET_IMAGE_TAG and TRINO_CONFIG_HASH
|
|
# from the release's ARTIFACTS file, and the :? guards below stop Compose from
|
|
# running with either unset.
|
|
name: fuel-monitoring
|
|
|
|
x-superset-env: &superset-env
|
|
KEYCLOAK_REALM_URL: ${KEYCLOAK_REALM_URL:-https://iam.thedigitalbridge.io/realms/thedigitalbridge}
|
|
|
|
x-superset: &superset
|
|
image: fuel-superset:${SUPERSET_IMAGE_TAG:?SUPERSET_IMAGE_TAG unset - run through deploy/deploy.sh}
|
|
pull_policy: never
|
|
secrets:
|
|
- superset_secret_key
|
|
- superset_db_password
|
|
- keycloak_petrolyst_client_secret
|
|
|
|
services:
|
|
superset:
|
|
<<: *superset
|
|
build:
|
|
context: ./superset
|
|
additional_contexts:
|
|
insights: ../../petrolyst-insights
|
|
environment:
|
|
<<: *superset-env
|
|
SERVER_WORKER_AMOUNT: "2"
|
|
restart: unless-stopped
|
|
depends_on:
|
|
superset-db:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
networks:
|
|
- backend
|
|
- proxy
|
|
mem_limit: 1536m
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8088/health"]
|
|
interval: 15s
|
|
timeout: 5s
|
|
retries: 10
|
|
start_period: 60s
|
|
labels:
|
|
traefik.enable: "true"
|
|
traefik.docker.network: proxy
|
|
traefik.http.routers.fm-superset.rule: Host(`${ATOMA_HOST:-atoma.petrolyst.com}`)
|
|
traefik.http.routers.fm-superset.entrypoints: websecure
|
|
traefik.http.routers.fm-superset.tls.certresolver: le
|
|
traefik.http.routers.fm-superset.middlewares: secure-headers@file
|
|
traefik.http.services.fm-superset.loadbalancer.server.port: "8088"
|
|
|
|
# One-shot: never started by `up`; deploy.sh runs it with `compose run --rm`.
|
|
superset-init:
|
|
<<: *superset
|
|
profiles: ["init"]
|
|
environment: *superset-env
|
|
command: ["/bin/bash", "/app/petrolyst-init.sh"]
|
|
depends_on:
|
|
superset-db:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
networks:
|
|
- backend
|
|
restart: "no"
|
|
|
|
superset-db:
|
|
image: postgres:17.11-alpine
|
|
environment:
|
|
POSTGRES_USER: superset
|
|
POSTGRES_DB: superset
|
|
POSTGRES_PASSWORD_FILE: /run/secrets/superset_db_password
|
|
secrets:
|
|
- superset_db_password
|
|
volumes:
|
|
- superset_db_data:/var/lib/postgresql/data
|
|
networks:
|
|
- backend
|
|
restart: unless-stopped
|
|
mem_limit: 512m
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U superset -d superset"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 10
|
|
|
|
# Cache and rate-limit store only; nothing to persist.
|
|
redis:
|
|
image: redis:7.4.11-alpine
|
|
command: ["redis-server", "--maxmemory", "128mb", "--maxmemory-policy", "allkeys-lru", "--save", "", "--appendonly", "no"]
|
|
networks:
|
|
- backend
|
|
restart: unless-stopped
|
|
mem_limit: 256m
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 10
|
|
|
|
trino:
|
|
image: trinodb/trino:484
|
|
env_file:
|
|
- ${PETROLYST_ROOT:-/opt/petrolyst}/env/fuel-monitoring.env
|
|
volumes:
|
|
- ./trino/etc:/etc/trino:ro
|
|
labels:
|
|
# Compose cannot see content changes in a bind mount; this label changes
|
|
# with trino/etc, so exactly a config change recreates the container.
|
|
petrolyst.config-hash: ${TRINO_CONFIG_HASH:?TRINO_CONFIG_HASH unset - run through deploy/deploy.sh}
|
|
depends_on:
|
|
fuel-db:
|
|
condition: service_healthy
|
|
networks:
|
|
- backend
|
|
restart: unless-stopped
|
|
mem_limit: 3g
|
|
# The image's own healthcheck (/usr/lib/trino/bin/health-check) applies.
|
|
|
|
fuel-db:
|
|
image: timescale/timescaledb:2.31.0-pg17
|
|
environment:
|
|
POSTGRES_USER: postgres
|
|
POSTGRES_DB: fuel
|
|
POSTGRES_PASSWORD_FILE: /run/secrets/fuel_db_password
|
|
TS_TUNE_NUM_CPUS: "2"
|
|
secrets:
|
|
- fuel_db_password
|
|
- fuel_db_trino_password
|
|
volumes:
|
|
- fuel_db_data:/var/lib/postgresql/data
|
|
# A single file, not the folder: the image's own TimescaleDB init scripts
|
|
# live in the same directory and must stay visible.
|
|
- ./fuel-db/init/01-roles.sh:/docker-entrypoint-initdb.d/010_petrolyst_roles.sh:ro
|
|
networks:
|
|
- backend
|
|
- fuel-db-tunnel
|
|
# Loopback only, for `ssh -L 5433:127.0.0.1:5433 petrolyst`.
|
|
ports:
|
|
- "127.0.0.1:5433:5432"
|
|
restart: unless-stopped
|
|
mem_limit: 1536m
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U postgres -d fuel"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 10
|
|
|
|
networks:
|
|
backend:
|
|
internal: true
|
|
proxy:
|
|
external: true
|
|
# A port cannot be published from an internal network; this one exists only
|
|
# so fuel-db's loopback port works.
|
|
fuel-db-tunnel: {}
|
|
|
|
volumes:
|
|
superset_db_data:
|
|
fuel_db_data:
|
|
|
|
secrets:
|
|
superset_secret_key:
|
|
file: ${PETROLYST_ROOT:-/opt/petrolyst}/secrets/fuel-monitoring/superset_secret_key
|
|
superset_db_password:
|
|
file: ${PETROLYST_ROOT:-/opt/petrolyst}/secrets/fuel-monitoring/superset_db_password
|
|
fuel_db_password:
|
|
file: ${PETROLYST_ROOT:-/opt/petrolyst}/secrets/fuel-monitoring/fuel_db_password
|
|
fuel_db_trino_password:
|
|
file: ${PETROLYST_ROOT:-/opt/petrolyst}/secrets/fuel-monitoring/fuel_db_trino_password
|
|
keycloak_petrolyst_client_secret:
|
|
file: ${PETROLYST_ROOT:-/opt/petrolyst}/secrets/shared/keycloak_petrolyst_client_secret
|