# ── stage: tester ──────────────────────────────────────────────────────────── FROM node:24-alpine AS tester WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . # Run only server-side unit tests; browser (Playwright) tests require a full # Chromium environment that is not available in the Alpine build stage. RUN npm run test:unit -- --run --project=server # ── stage: builder ─────────────────────────────────────────────────────────── FROM node:24-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # ── stage: runner ──────────────────────────────────────────────────────────── FROM node:24-alpine AS runner WORKDIR /app # Install yt-dlp (primary Instagram extractor) and Playwright system dependencies (fallback) RUN apk add --no-cache \ python3 \ py3-pip \ chromium \ font-liberation \ font-noto \ font-noto-cjk && \ pip3 install --break-system-packages yt-dlp COPY package*.json ./ RUN npm ci --omit=dev COPY --from=builder /app/build ./build EXPOSE 3000 ENV NODE_ENV=production ENV CHROMIUM_EXECUTABLE_PATH=/usr/bin/chromium-browser # Declare volume for Instagram authentication persistence VOLUME ["/app/secrets"] CMD ["node", "-e", "import('./build/index.js')"]