Files
petrolyst-infra/stacks/fuel-monitoring/compose.yaml
T
Nasim SadatandClaude Opus 5.5 d3800ac9dd Petrolyst server infrastructure: Traefik, Trino and Superset
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>
2026-10-24 00:33:11 +02:00

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