# --- Build stage: produce static dist/ --- # Debian (glibc), not alpine: Astro 7's Rust toolchain (rolldown/oxc) resolves # cleanly against the linux-x64-gnu lockfile entries. FROM node:22-slim AS build WORKDIR /app # Use npm install (not npm ci): Astro 7's wasm32 optional deps (@emnapi/*) # make npm ci's strict lock-sync check fail across npm/node versions. install # reconciles the lockfile and builds reliably. # git: the build fetches the app repositories whose docs/PRIVACY.md this site # renders (scripts/sync-external.mjs, run from `prebuild`). node:slim ships # without it; the script would fall back to fetching the raw files over HTTPS, # but a shallow clone is the intended path and keeps the failure modes obvious. RUN apt-get update \ && apt-get install -y --no-install-recommends git ca-certificates \ && rm -rf /var/lib/apt/lists/* COPY package.json package-lock.json* ./ RUN npm install --no-audit --no-fund COPY . . # PUBLIC_* env vars are inlined at build time. In Coolify, set them as # build-time variables so analytics is baked into the static output. RUN npm run build # --- Runtime stage: serve dist/ with Caddy --- FROM caddy:2-alpine AS runtime COPY Caddyfile /etc/caddy/Caddyfile COPY --from=build /app/dist /srv EXPOSE 80