The image build ran the tests without serve.ts present, so the server the tests spawn never started and the hook stalled until it timed out. The runtime stage would have failed on the same missing file immediately after. The test now bails the moment the process exits and reports its stderr, so this shows up as "serve.ts exited with 1 before listening" in 53ms rather than an unexplained hook timeout after five seconds. serve.ts is also in tsconfig's include now — it was outside it, so a type error in the file that serves the app would only have surfaced at runtime. Adding it immediately caught one in the test. Verified by replaying the build stage against exactly the copied file set. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
43 lines
1.3 KiB
Docker
43 lines
1.3 KiB
Docker
# Build the static site, then serve it from a distroless-ish runtime.
|
|
#
|
|
# Two stages so the image ships the built assets and nothing else: no source,
|
|
# no fixtures, no toolchain. The build is fully offline — it parses checked-in
|
|
# fixtures rather than fetching anything — so the image is reproducible and
|
|
# needs no network at build time.
|
|
|
|
FROM oven/bun:1.3-alpine AS build
|
|
WORKDIR /app
|
|
|
|
# Dependencies first, so a source-only change reuses this layer.
|
|
COPY package.json bun.lock ./
|
|
RUN bun install --frozen-lockfile
|
|
|
|
COPY tsconfig.json index.html serve.ts ./
|
|
COPY src ./src
|
|
COPY scripts ./scripts
|
|
COPY fixtures ./fixtures
|
|
COPY test ./test
|
|
|
|
# Fail the image on a type error or a failing test rather than shipping it.
|
|
RUN bun run typecheck && bun test
|
|
RUN bun run build
|
|
|
|
|
|
FROM oven/bun:1.3-alpine AS runtime
|
|
WORKDIR /app
|
|
|
|
ENV NODE_ENV=production
|
|
ENV PORT=3000
|
|
|
|
# Run unprivileged. The bun image ships a `bun` user; use it rather than root.
|
|
COPY --from=build --chown=bun:bun /app/public ./public
|
|
COPY --from=build --chown=bun:bun /app/serve.ts ./serve.ts
|
|
USER bun
|
|
|
|
EXPOSE 3000
|
|
|
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
|
CMD bun -e "await fetch('http://127.0.0.1:'+(process.env.PORT??3000)+'/api/health').then(r=>{if(!r.ok)process.exit(1)})"
|
|
|
|
CMD ["bun", "run", "serve.ts"]
|