# Multi-stage build for the cuckoo-escapement docs site. # # Stages: # - base : Node, pnpm/npm tooling, deps installed # - dev : runs `astro dev` with HMR for local development # - builder : produces the static `dist/` # - prod : caddy:alpine that serves `dist/` (no Node at runtime) # # `docker compose --profile dev up` → dev target # `docker compose up` (no profile) → prod target # Pinned through the mirror.gcr.io pass-through to dodge intermittent # Docker Hub TLS hiccups during builds. Same content, more reliable # fetch path. The `docker pull` resolves identically against either. FROM mirror.gcr.io/library/node:22-alpine AS base WORKDIR /app COPY package.json ./ RUN --mount=type=cache,target=/root/.npm \ npm install --no-audit --no-fund # ----- dev: astro dev server with HMR ----- FROM base AS dev # Astro's binary is in node_modules/.bin — package.json's `dev` script # already binds to 0.0.0.0 for HMR-behind-Caddy. COPY . . ENV ASTRO_TELEMETRY_DISABLED=1 EXPOSE 4321 CMD ["npm", "run", "dev"] # ----- builder: produce dist/ ----- FROM base AS builder COPY . . ENV ASTRO_TELEMETRY_DISABLED=1 RUN npm run build # ----- prod: caddy serves the static build ----- FROM mirror.gcr.io/library/caddy:2-alpine AS prod # Caddyfile is intentionally minimal — caddy-docker-proxy on the host # handles TLS, routing, and the public-facing reverse proxy. This # container just serves files locally; the proxy points at it. RUN mkdir -p /srv/docs COPY --from=builder /app/dist /srv/docs RUN printf ':80 {\n\troot * /srv/docs\n\tfile_server\n\ttry_files {path} {path}/ /404.html\n\tencode zstd gzip\n}\n' > /etc/caddy/Caddyfile EXPOSE 80