Merge pull request 'Promote main to release: lake extension bake + daemon healthcheck fixes' (#32) from main into release
All checks were successful
secrets-guard / encrypted (push) Successful in 11s
shell-lint / shellcheck (push) Successful in 10s
Build + push backend image (Forgejo registry) / build-push (push) Successful in 50s
Deploy backend to prod VPS / deploy (push) Successful in 1m15s

This commit is contained in:
emi 2026-07-24 03:50:47 +00:00
commit 372813b67b
2 changed files with 11 additions and 3 deletions

View file

@ -33,9 +33,6 @@ RUN apt-get update \
# Install deps first so this layer caches across code-only changes. # Install deps first so this layer caches across code-only changes.
COPY requirements.txt /tmp/requirements.txt COPY requirements.txt /tmp/requirements.txt
RUN pip install --no-cache-dir -r /tmp/requirements.txt RUN pip install --no-cache-dir -r /tmp/requirements.txt
# Bake DuckDB's httpfs extension so the lake role's S3 reads need no runtime
# extension download (tasks may roll while egress is degraded).
RUN python -c "import duckdb; duckdb.connect().execute('INSTALL httpfs')"
# The daemon binary lands before the app tree: it changes far less often than # The daemon binary lands before the app tree: it changes far less often than
# the Python code, so this layer usually cache-hits and only the COPY below # the Python code, so this layer usually cache-hits and only the COPY below
@ -56,6 +53,10 @@ RUN useradd --system --create-home --uid 10001 thermograph \
&& chown -R thermograph:thermograph /app /state && chown -R thermograph:thermograph /app /state
USER thermograph USER thermograph
# Bake DuckDB's httpfs extension AS THE RUNTIME USER — extensions install to
# the invoking user's ~/.duckdb, and a root-time bake leaves uid 10001 unable
# to LOAD it (seen live: prod lake /query 500'd on exactly this).
RUN python -c "import duckdb; duckdb.connect().execute('INSTALL httpfs')"
WORKDIR /app WORKDIR /app
ENV PORT=8137 \ ENV PORT=8137 \

View file

@ -208,6 +208,13 @@ services:
# endpoints on a timer), so the daemon holds no state and logs to stdout. # endpoints on a timer), so the daemon holds no state and logs to stdout.
volumes: volumes:
- /etc/thermograph/stack.env:/host/thermograph.env:ro - /etc/thermograph/stack.env:/host/thermograph.env:ro
# The image HEALTHCHECK curls /healthz on ${PORT} — right for the app,
# meaningless for the daemon (it serves nothing). Without this override
# Swarm marks the task unhealthy and restarts it forever (seen live on the
# first prod stack deploy: gateway up, killed ~100s later, 0/1 loop). The
# compose file already disables it; the stack file must too.
healthcheck:
disable: true
networks: networks:
- internal - internal
deploy: deploy: