Skip to content

Commit 671b9ac

Browse files
committed
revert(webapp): drop cross-build asset carry-forward from Docker images
Mixing assets from two builds in one image adds too much debugging complexity. Stale clients during a deploy window are covered by the client-side recovery reload; a longer-term fix (serving /build from object storage with retention) can be designed separately.
1 parent 48ceec7 commit 671b9ac

3 files changed

Lines changed: 1 addition & 44 deletions

File tree

.github/workflows/publish-webapp.yml

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -113,27 +113,6 @@ jobs:
113113
username: ${{ github.repository_owner }}
114114
password: ${{ secrets.GITHUB_TOKEN }}
115115

116-
- name: 🔎 Resolve previous image for asset carry-forward
117-
id: prev_image
118-
# Previous image whose /build assets the Dockerfile carries forward.
119-
# Prefer the tag being published (mutable tags still point at the
120-
# previous build here); for fresh immutable/semver tags fall back to
121-
# `latest` (the previous release — its users hold the stale HTML),
122-
# then `main`. If nothing exists the Dockerfile default makes the
123-
# carry-forward a no-op.
124-
run: |
125-
for candidate in "${IMAGE_REPO}:${TAG}" "${IMAGE_REPO}:latest" "${IMAGE_REPO}:main"; do
126-
if docker manifest inspect "$candidate" >/dev/null 2>&1; then
127-
echo "prev_image=${candidate}" >> "$GITHUB_OUTPUT"
128-
echo "Using previous image: ${candidate}"
129-
exit 0
130-
fi
131-
done
132-
echo "No previous image found; asset carry-forward will be a no-op"
133-
env:
134-
IMAGE_REPO: ${{ steps.set_tags.outputs.image_repo }}
135-
TAG: ${{ steps.get_tag.outputs.tag }}
136-
137116
- name: 🐳 Build image and push to GitHub Container Registry
138117
id: build_push
139118
uses: depot/build-push-action@98e78adca7817480b8185f474a400b451d74e287 # v1.18.0
@@ -151,7 +130,6 @@ jobs:
151130
SENTRY_RELEASE=${{ steps.set_build_info.outputs.BUILD_GIT_SHA }}
152131
SENTRY_ORG=triggerdev
153132
SENTRY_PROJECT=trigger-cloud
154-
PREV_IMAGE=${{ steps.prev_image.outputs.prev_image || 'builder' }}
155133
secrets: |
156134
sentry_auth_token=${{ secrets.SENTRY_AUTH_TOKEN }}
157135

.server-changes/stale-deploy-asset-recovery.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ area: webapp
33
type: fix
44
---
55

6-
Fix intermittent unstyled/broken pages during rolling deploys, caused by stale HTML requesting `/build` asset hashes that 404 on the new image. Docker images now carry forward the previous image's `/build` assets (`PREV_IMAGE` build arg, no-op for forks/self-hosted, 14-day retention), documents default to `Cache-Control: no-cache`, and an inline script reloads the page (max twice) when a `/build` asset fails to load.
6+
Fix intermittent unstyled/broken pages during rolling deploys, caused by stale HTML requesting `/build` asset hashes that 404 on the new image. Documents now default to `Cache-Control: no-cache` so browsers always revalidate HTML, and an inline script reloads the page (max twice) when a `/build` asset fails to load.

docker/Dockerfile

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
ARG NODE_IMAGE=node:22.23.1-bookworm-slim@sha256:813a7480f28fdadac1f7f5c824bcdad435b5bc1322a5968bbbdef8d058f9dff4
2-
# Previously published image whose /build assets are carried forward so
3-
# stale clients survive a rolling deploy. Default (builder) is a no-op.
4-
ARG PREV_IMAGE=builder
52

63
FROM golang:1.26-alpine AS goose_builder
74
RUN go install github.com/pressly/goose/v3/cmd/goose@v3.27.1
@@ -77,9 +74,6 @@ RUN --mount=type=secret,id=sentry_auth_token \
7774
SENTRY_AUTH_TOKEN=$(cat /run/secrets/sentry_auth_token) \
7875
pnpm run build --filter=webapp...
7976

80-
# Previous release's hashed browser assets (see PREV_IMAGE above).
81-
FROM ${PREV_IMAGE} AS prev-assets
82-
8377
# Runner
8478
FROM ${NODE_IMAGE} AS runner
8579
RUN apt-get update && apt-get upgrade -y && apt-get install -y --no-install-recommends openssl netcat-openbsd ca-certificates && rm -rf /var/lib/apt/lists/*
@@ -93,22 +87,7 @@ COPY --from=production-deps --chown=node:node /triggerdotdev .
9387
COPY --from=dev-deps --chown=node:node /triggerdotdev/internal-packages/database/generated ./internal-packages/database/generated
9488
COPY --from=builder --chown=node:node /triggerdotdev/apps/webapp/build/server.js ./apps/webapp/build/server.js
9589
COPY --from=builder --chown=node:node /triggerdotdev/apps/webapp/build ./apps/webapp/build
96-
# Previous assets, pruned to a 14-day window (COPY keeps mtimes), then the
97-
# current build on top. Pruning BEFORE the overlay means the current build's
98-
# assets can never be deleted, whatever mtimes the builder produces — a
99-
# broken prune can only mean slow image growth, never a broken image.
100-
COPY --from=prev-assets --chown=node:node /triggerdotdev/apps/webapp/public/build ./apps/webapp/public/build
101-
RUN find ./apps/webapp/public/build -type f -mtime +14 -delete \
102-
&& find ./apps/webapp/public/build -type d -empty -delete
10390
COPY --from=builder --chown=node:node /triggerdotdev/apps/webapp/public ./apps/webapp/public
104-
# Guard against silent retention failure (e.g. a builder that stops
105-
# preserving mtimes, making the prune a no-op): fail the build loudly if the
106-
# carried-forward window grows past a size no healthy 14-day window can reach.
107-
RUN size_mb=$(du -sm ./apps/webapp/public/build | cut -f1) \
108-
&& if [ "$size_mb" -gt 1024 ]; then \
109-
echo "public/build is ${size_mb}MB (>1024MB): asset carry-forward is not being pruned" >&2; \
110-
exit 1; \
111-
fi
11291
COPY --from=builder --chown=node:node /triggerdotdev/scripts ./scripts
11392

11493
# Goose and schemas

0 commit comments

Comments
 (0)