FROM node:20-alpine WORKDIR /app # Copy package files first for better layer caching COPY --chown=node:node package*.json ./ RUN npm ci --only=production && npm cache clean --force # Copy the rest of the application code COPY --chown=node:node . . # Production environment ENV NODE_ENV=production # Run as non-root user (node user is provided by the base image, uid 1000) USER node EXPOSE 3000 # Pure Node.js healthcheck - does not depend on wget, curl, or other binaries # that may not be present in minimal Alpine images. Respects PORT env var. HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \ CMD node -e 'const h=require("http");const p=process.env.PORT||3000;const r=h.get("http://localhost:"+p+"/health",res=>process.exit(res.statusCode==200?0:1));r.on("error",()=>process.exit(1));r.setTimeout(2000,()=>{r.destroy();process.exit(1)})' || exit 1 CMD ["npm", "start"]