FROM node:20-alpine AS base WORKDIR /app # ── 1. Install main project deps ───────────────────────────────────────────── FROM base AS deps COPY package.json package-lock.json ./ RUN npm install --legacy-peer-deps # ── 2. Install studio deps ──────────────────────────────────────────────────── FROM base AS studio-deps COPY studio/package.json studio/package-lock.json* ./ RUN npm install --legacy-peer-deps # ── 3. Build Sanity Studio ──────────────────────────────────────────────────── FROM base AS studio-build COPY --from=studio-deps /app/node_modules ./node_modules COPY studio/ ./ ARG SANITY_STUDIO_PROJECT_ID ARG SANITY_STUDIO_DATASET=production ENV SANITY_STUDIO_PROJECT_ID=$SANITY_STUDIO_PROJECT_ID ENV SANITY_STUDIO_DATASET=$SANITY_STUDIO_DATASET RUN npm run build # ── 4. Build Astro site (with studio output as static files) ────────────────── FROM base AS build COPY --from=deps /app/node_modules ./node_modules COPY . . COPY --from=studio-build /app/dist ./public/studio # Remove index.html so /studio requests fall through to the SSR route, # which rewrites /static/ asset paths to /studio/static/ before serving. RUN rm -f ./public/studio/index.html ARG SANITY_PROJECT_ID ARG SANITY_DATASET=production ARG SANITY_API_TOKEN ENV SANITY_PROJECT_ID=$SANITY_PROJECT_ID ENV SANITY_DATASET=$SANITY_DATASET ENV SANITY_API_TOKEN=$SANITY_API_TOKEN RUN npm run build # ── 5. Runtime ──────────────────────────────────────────────────────────────── FROM node:20-alpine AS runtime WORKDIR /app COPY --from=build /app/dist ./dist COPY --from=build /app/node_modules ./node_modules ENV HOST=0.0.0.0 ENV PORT=4321 EXPOSE 4321 CMD ["node", "./dist/server/entry.mjs"]