# Local qualification recipe only; no manifest/catalog activation or publication. # Input must be the exact tree verified by prepare-source.sh, never a checkout. FROM docker.io/library/node@sha256:db9a3a15e8e8e2adbaf1e1c3d93dfb04c2e294bdd027490addb2391b8e61cc6a AS frontend WORKDIR /build/frontend COPY frontend/package*.json ./ RUN npm ci --no-audit --no-fund COPY frontend/ ./ RUN npm run build FROM docker.io/library/node@sha256:db9a3a15e8e8e2adbaf1e1c3d93dfb04c2e294bdd027490addb2391b8e61cc6a AS server WORKDIR /build/server COPY server/package*.json ./ RUN npm ci --no-audit --no-fund COPY server/ ./ RUN npm run build && npm prune --omit=dev --no-audit --no-fund FROM docker.io/library/node@sha256:db9a3a15e8e8e2adbaf1e1c3d93dfb04c2e294bdd027490addb2391b8e61cc6a # OS package versions are recorded in the candidate; reproducible repository # snapshot/provenance is still a release gate, not implied by the base pin. RUN apt-get update && apt-get install -y --no-install-recommends ffmpeg \ && dpkg-query -W > /usr/local/share/podsteadr-package-versions.txt \ && rm -rf /var/lib/apt/lists/* WORKDIR /app COPY --from=server /build/server/node_modules ./node_modules COPY --from=server /build/server/package.json ./package.json COPY --from=server /build/server/dist ./dist COPY --from=frontend /build/frontend/dist ./public COPY .archipelago-nostr-provider.js ./public/nostr-provider.js COPY .archipelago-source-commit .archipelago-source-tree .archipelago-patched-tree .archipelago-provider-sha256 ./ RUN mkdir -p /data && chown 1000:1000 /data USER 1000:1000 ENV NODE_ENV=production PORT=8095 DATA_DIR=/data STATIC_DIR=/app/public EXPOSE 8095 HEALTHCHECK --interval=30s --timeout=5s --retries=3 CMD node -e 'fetch("http://127.0.0.1:8095/api/health").then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))' CMD ["node", "dist/index.js"]