Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/images-carry-current-security-updates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"hephaestus": patch
---

Hephaestus container images now install the operating-system security updates published since their
base image was built, instead of shipping whatever the base image happened to contain. The web
application image carries no known high or critical operating-system vulnerabilities as of this
release. No action is needed to upgrade.
6 changes: 6 additions & 0 deletions .github/workflows/ci-docker-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ jobs:
docker-file: "./docker/agents/pi/Dockerfile"
docker-context: "./docker/agents"
registry: "ghcr.io"
# Cache-busts the OS-package upgrade layer; this build imports the `cache-main` registry cache.
build-args: |
SOURCE_COMMIT=${{ github.sha }}
single-arch: ${{ github.event_name == 'pull_request' || github.event_name == 'merge_group' }}
labels: |
org.opencontainers.image.title=Hephaestus Agent - Pi
Expand All @@ -137,6 +140,9 @@ jobs:
docker-file: "./docker/postgres/Dockerfile"
docker-context: "./docker/postgres"
registry: "ghcr.io"
# Cache-busts the OS-package upgrade layer; this build imports the `cache-main` registry cache.
build-args: |
SOURCE_COMMIT=${{ github.sha }}
single-arch: ${{ github.event_name == 'pull_request' || github.event_name == 'merge_group' }}
labels: |
org.opencontainers.image.title=Hephaestus Postgres
Expand Down
13 changes: 12 additions & 1 deletion docker/agents/pi/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,18 @@
ARG NODE_VERSION=24.19.0
FROM node:${NODE_VERSION}-slim@sha256:a9f5f7c91a432850b2a8a7797adf5eadb6c733ceed61167806cee7ea7fbc29df

RUN apt-get update -qq && apt-get install -y --no-install-recommends git findutils tree jq ca-certificates grep && \
# The base digest is pinned, so Debian security updates published after the upstream image was
# built can reach it only here; Renovate bumps the digest only when upstream republishes one.
#
# SOURCE_COMMIT is what makes that upgrade actually run. The builder imports the `cache-main`
# registry cache and nothing else in this layer changes between builds, so without a per-build
# input BuildKit would replay a weeks-old package set and the upgrade would silently stop
# happening — the exact failure this layer exists to prevent. webapp/Dockerfile gets the same
# argument, one instruction ahead of its own upgrade.
ARG SOURCE_COMMIT
RUN echo "source commit: ${SOURCE_COMMIT:-<unset — local build>}" && \
apt-get update -qq && apt-get upgrade -y -qq && \
apt-get install -y --no-install-recommends git findutils tree jq ca-certificates grep && \
rm -rf /var/lib/apt/lists/*

RUN groupmod --new-name agent node && \
Expand Down
9 changes: 9 additions & 0 deletions docker/postgres/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,16 @@ FROM postgres:${PG_MAJOR}-bookworm
ARG PG_MAJOR=18
# Pinned for reproducibility (PGDG bookworm pool). Bump deliberately.
ARG PARTMAN_VERSION=5.5.0-1.pgdg12+1
# The tag floats, so docker-library rebuilds already carry most OS updates here; the upgrade closes
# the window between a Debian security publication and the next upstream rebuild. Same posture as
# webapp/Dockerfile and docker/agents/pi/Dockerfile so no image is the one that blocks a release.
#
# SOURCE_COMMIT is what makes that upgrade actually run: the builder imports the `cache-main`
# registry cache, and a layer with no per-build input would replay a stale package set instead.
ARG SOURCE_COMMIT
RUN set -eux; \
echo "source commit: ${SOURCE_COMMIT:-<unset — local build>}"; \
apt-get update; \
apt-get upgrade -y; \
apt-get install -y --no-install-recommends "postgresql-${PG_MAJOR}-partman=${PARTMAN_VERSION}"; \
rm -rf /var/lib/apt/lists/*
7 changes: 6 additions & 1 deletion webapp/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ FROM nginx:stable-alpine@sha256:97d490c12ba55b4946b01546d1c3ed324e8d41ab1c9fcb2a
ARG COOLIFY_BRANCH
ARG SOURCE_COMMIT
ENV BUILD_GIT_BRANCH=$COOLIFY_BRANCH BUILD_GIT_COMMIT=$SOURCE_COMMIT
RUN apk add --no-cache bash sed grep curl
# The base digest is pinned, so Alpine security updates published after the upstream image was
# built can reach it only here — `nginx:stable-alpine` keeps resolving to the same digest, so
# Renovate has nothing to bump. `apk add` is already unversioned against the live index, so this
# costs no reproducibility. nginx itself comes from a one-shot `apk add -X <nginx.org repo>` that
# the upstream image never persists to /etc/apk/repositories, so this upgrades OS packages only.
RUN apk upgrade --no-cache && apk add --no-cache bash sed grep curl
COPY --from=build /repo/webapp/dist /usr/share/nginx/html
COPY webapp/docker/entrypoint.sh /entrypoint.sh
COPY webapp/docker/nginx.conf /etc/nginx/conf.d/default.conf
Expand Down
Loading