Run the ERA5 lake service in every environment (#20)
All checks were successful
secrets-guard / encrypted (push) Successful in 6s
All checks were successful
secrets-guard / encrypted (push) Successful in 6s
This commit is contained in:
parent
21eea3a4c2
commit
8e09155aaf
6 changed files with 61 additions and 6 deletions
|
|
@ -70,4 +70,10 @@ jobs:
|
|||
# thermograph-lan is host-native (the runner job runs directly on the
|
||||
# LAN box, not over SSH like beta/prod), so plain env vars on the
|
||||
# command reach deploy-dev.sh directly -- no ssh-action needed here.
|
||||
# The lake creds ride the Actions S3 secrets: dev renders no vault
|
||||
# (deploy-dev.sh's no-op secrets path), and compose interpolates
|
||||
# ${THERMOGRAPH_LAKE_S3_*} straight from the deploy environment.
|
||||
env:
|
||||
THERMOGRAPH_LAKE_S3_ACCESS_KEY: ${{ secrets.S3_ACCESS_KEY }}
|
||||
THERMOGRAPH_LAKE_S3_SECRET_KEY: ${{ secrets.S3_SECRET_KEY }}
|
||||
run: SERVICE=backend BACKEND_IMAGE_TAG=${{ steps.tag.outputs.tag }} bash "$HOME/thermograph-dev/infra/deploy/deploy-dev.sh"
|
||||
|
|
|
|||
|
|
@ -177,11 +177,12 @@ esac
|
|||
export BACKEND_IMAGE_TAG="${BACKEND_IMAGE_TAG:-local}"
|
||||
export FRONTEND_IMAGE_TAG="${FRONTEND_IMAGE_TAG:-local}"
|
||||
|
||||
# Which compose services this run pulls/rolls.
|
||||
# Which compose services this run pulls/rolls. lake runs the backend image
|
||||
# with a different role, so it rolls with every backend deploy.
|
||||
case "$SERVICE" in
|
||||
backend) TARGETS=(backend) ;;
|
||||
backend) TARGETS=(backend lake) ;;
|
||||
frontend) TARGETS=(frontend) ;;
|
||||
all) TARGETS=(backend frontend) ;;
|
||||
all) TARGETS=(backend lake frontend) ;;
|
||||
esac
|
||||
|
||||
# Login only when a token is supplied. The SSH/CI deploy paths (deploy.yml,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ THERMOGRAPH_VAPID_PRIVATE_KEY: ENC[AES256_GCM,data:sTtkAbMVUtwvRssCZJa2PWUjlfnYS
|
|||
THERMOGRAPH_VAPID_PUBLIC_KEY: ENC[AES256_GCM,data:SnFw+pwNgZlxMEhMUH/1daMZlRB2QFNJHtL+4C3S1eFcJJdT2uNGkY7Ym9FPfx1V7cwt/3urHg1oVgdDzYaIal2wye4l5HhKBP5PjtQkDW+Pck24kxul,iv:Ku4MhsrAfyA2Y3CqhGIsYKrjhKQ4cqAYjCqjFeEvBWE=,tag:hw42iS+79D7gNf+BPTYM0g==,type:str]
|
||||
THERMOGRAPH_VAPID_CONTACT: ENC[AES256_GCM,data:ox+hHiFMTPZqYwICDSwPwcT13ZDSKiGcAVHfVVMNYQ==,iv:DssV/olPXERpdmXNMmzjVYvhn/0zmuSp2XlTs42pIi0=,tag:4YHXI1BFbGZ6JsdXqJuf3w==,type:str]
|
||||
REGISTRY_TOKEN: ENC[AES256_GCM,data:pC1Zzs56la8qjzWcbkuKyeVHwS5WfIe+mrLm5Sdi/LKYziAvRU5cOA==,iv:57PlJEBdgwNJsfFdNOGqAnKk8l6zpmMSWYFEKS6pn+4=,tag:pPftNHUVU6+CY2nWMaXO6w==,type:str]
|
||||
THERMOGRAPH_LAKE_S3_ACCESS_KEY: ENC[AES256_GCM,data:ZEQ278P7azMKlYMjUraP6hIqnjymqL90zEbvTNC9iXU=,iv:5nXXZwx7RfqwCMqx5LWtxQy2nQcq+6Yr79ulBi6BOnE=,tag:jXcCCCcz4NsDoIZwa/ji4A==,type:str]
|
||||
THERMOGRAPH_LAKE_S3_SECRET_KEY: ENC[AES256_GCM,data:p5qCrHWoH1i3smDZZBIO8zMSWWxDARYsTY12AA0E8ao=,iv:PVOEQ0kBFeYaE/FT2UswtSTY7S84U/YOPSbcsXR51f4=,tag:JFwaOwAYInPs199li66U/g==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- enc: |
|
||||
|
|
@ -27,7 +29,7 @@ sops:
|
|||
0+PQdtDxom72BqrAoj5lhepxW8YWPqQIRXsVS/XYQEQfPJuuuiRMKw==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
recipient: age1xx4dzs0dxlwvkv9sjuqzsphl7lfrxannkfken374yu2qvvcte9sqzktqt2
|
||||
lastmodified: "2026-07-22T03:17:28Z"
|
||||
mac: ENC[AES256_GCM,data:npF+ngF4Khj3NJ2PNFcQjQYIrZVpdPM0drk43pAI6HfFaynX8JOqRFZRsH0sCfMoPkXB/ffCJxla1Tt3Mu3zgKTNSWcn+mjzl+dYvlruY1VylHLS+GnTO9zKeQcwbrYzTfZNWzQhm6/mw8KCL3791U/xNHwJc6g5VxRUWl6TBdo=,iv:JLzY8rm33NLG8CqyAlU6vBhlODUiRipKu9daoRvgyzg=,tag:yIsxVZAnw8FD7Bt/x55wMQ==,type:str]
|
||||
lastmodified: "2026-07-23T22:30:10Z"
|
||||
mac: ENC[AES256_GCM,data:JWfkQk4Z1ohPha9LID/hvZOycmDy0sUyjiqDdCidfCQEsPx+OwhPatcM31x1ZKFgh3TyYTxrauoSTlIeuwfy7+R9jATDdBBZe9zMqgs6Szu9WUdFiaZzIFpG7SEVw+8IqIyAuqZVSW3k5yHmchcmkNyDekV+1RIF8wxUrOeSCVQ=,iv:6PXUiCnYBiFyNPnCRAs6f7a+RuvWI4jSIMXwuMn7WjA=,tag:y+Ix2m65hQRkSt8FylfKSg==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.13.2
|
||||
|
|
|
|||
|
|
@ -157,9 +157,16 @@ if [ "$SERVICE" = "all" ] || ! docker service inspect "${STACK_NAME}_web" >/dev/
|
|||
else
|
||||
case "$SERVICE" in
|
||||
backend)
|
||||
echo "==> Rolling web + worker to $BACKEND_IMAGE"
|
||||
echo "==> Rolling web + worker + lake to $BACKEND_IMAGE"
|
||||
docker service update --with-registry-auth --detach=false --image "$BACKEND_IMAGE" "${STACK_NAME}_web"
|
||||
docker service update --with-registry-auth --detach=false --image "$BACKEND_IMAGE" "${STACK_NAME}_worker"
|
||||
# lake ships in the same image; a stack file predating it has no service
|
||||
# yet — the next SERVICE=all stack deploy creates it, so don't fail here.
|
||||
if docker service inspect "${STACK_NAME}_lake" >/dev/null 2>&1; then
|
||||
docker service update --with-registry-auth --detach=false --image "$BACKEND_IMAGE" "${STACK_NAME}_lake"
|
||||
else
|
||||
echo " (no ${STACK_NAME}_lake service yet; created on the next full stack deploy)"
|
||||
fi
|
||||
;;
|
||||
frontend)
|
||||
echo "==> Rolling frontend to $FRONTEND_IMAGE"
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ services:
|
|||
db:
|
||||
cpus: !reset null
|
||||
deploy: !reset null
|
||||
lake:
|
||||
cpus: !reset null
|
||||
deploy: !reset null
|
||||
# Uncapped memory on dev too (prod ceilings it at 8g). The Postgres/DuckDB
|
||||
# memory *budget* is still the ~8 GB derived by deploy/db/init/20-tuning.sh from
|
||||
# the default DB_MEMORY (raise DB_MEMORY to give dev more); shm_size stays (it's
|
||||
|
|
|
|||
|
|
@ -124,6 +124,11 @@ services:
|
|||
# (NOT /app/data) so it never shadows the Python `data/` package -- see the
|
||||
# volumes: note below and thermograph-backend paths.py.
|
||||
THERMOGRAPH_SINGLETON_LOCK: /state/notifier.lock
|
||||
# History reads ask the lake service before any third-party source; if
|
||||
# the lake has no bucket creds (LAN without them exported) it answers
|
||||
# 503 and climate.py falls straight through to NASA — an accelerator,
|
||||
# never a dependency.
|
||||
THERMOGRAPH_LAKE_URL: http://lake:8141
|
||||
# Prod secrets live in /etc/thermograph.env: POSTGRES_PASSWORD,
|
||||
# THERMOGRAPH_AUTH_SECRET, THERMOGRAPH_VAPID_PRIVATE_KEY/_PUBLIC_KEY,
|
||||
# THERMOGRAPH_COOKIE_SECURE=1, mail/Discord keys, ... (see
|
||||
|
|
@ -157,6 +162,36 @@ services:
|
|||
- "127.0.0.1:8137:8137"
|
||||
restart: unless-stopped
|
||||
|
||||
# The ERA5 lake service: partition-pruned reads over the era5-thermograph
|
||||
# bucket with a local parquet cache, same backend image with
|
||||
# THERMOGRAPH_ROLE=lake (the entrypoint starts lake_app — no database, no
|
||||
# migrations, so no depends_on: db). Bucket creds come from
|
||||
# /etc/thermograph.env where the vault renders them (beta/prod) or from the
|
||||
# deploy environment (LAN — deploy-dev.yml injects the Actions S3 secrets);
|
||||
# without them the service stays healthy and every read falls through to
|
||||
# NASA. Never published on a host port: only the backend talks to it.
|
||||
lake:
|
||||
image: ${REGISTRY_HOST:-git.thermograph.org}/${BACKEND_IMAGE_PATH:-emi/thermograph/backend}:${BACKEND_IMAGE_TAG:-local}
|
||||
environment:
|
||||
THERMOGRAPH_ROLE: lake
|
||||
PORT: 8141
|
||||
THERMOGRAPH_SERVICE_ROLE: backend
|
||||
WORKERS: "1"
|
||||
THERMOGRAPH_LAKE_CACHE: /state/lake-cache
|
||||
THERMOGRAPH_LAKE_S3_ACCESS_KEY: ${THERMOGRAPH_LAKE_S3_ACCESS_KEY:-}
|
||||
THERMOGRAPH_LAKE_S3_SECRET_KEY: ${THERMOGRAPH_LAKE_S3_SECRET_KEY:-}
|
||||
env_file:
|
||||
- path: /etc/thermograph.env
|
||||
required: false
|
||||
volumes:
|
||||
- lakecache:/state
|
||||
cpus: ${LAKE_CPUS:-2}
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: "${LAKE_CPUS:-2}"
|
||||
restart: unless-stopped
|
||||
|
||||
frontend:
|
||||
# Frontend's OWN image, published by thermograph-frontend's build-push.yml
|
||||
# from its own Dockerfile (which starts `uvicorn app:app` directly -- no
|
||||
|
|
@ -187,6 +222,7 @@ volumes:
|
|||
pgdata: {}
|
||||
appdata: {}
|
||||
applogs: {}
|
||||
lakecache: {}
|
||||
|
||||
networks:
|
||||
# Pin the default network's subnet + gateway so the host Postfix can rely on a
|
||||
|
|
|
|||
Loading…
Reference in a new issue