# ============================================================================= # wxcc-monitor - Multi-stage Dockerfile (Node 20 Alpine) # Production-oriented, minimal attack surface, non-root execution. # ============================================================================= # ---- Stage 1: Dependencies (production only) ---- FROM node:20-alpine AS deps WORKDIR /app # Copy only package files for better layer caching COPY package*.json ./ # Install production dependencies only (no dev deps, no optional) RUN npm ci --omit=dev --no-audit --no-fund # ---- Stage 2: Dev dependencies (includes nodemon for docker-compose.dev.yml) ---- FROM node:20-alpine AS dev-deps WORKDIR /app COPY package*.json ./ RUN npm ci --no-audit --no-fund # ---- Stage 3: Final production image ---- FROM node:20-alpine AS final WORKDIR /app RUN chown node:node /app USER node # Set production environment ENV NODE_ENV=production # Copy production node_modules from deps stage COPY --from=deps --chown=node:node /app/node_modules ./node_modules # Copy application source COPY --chown=node:node package*.json ./ COPY --chown=node:node src ./src COPY --chown=node:node scripts/healthcheck.js ./scripts/healthcheck.js # Runtime directories (overridden by bind mounts in compose, but ensures local runs work) RUN mkdir -p data logs # Expose the application port (internal) EXPOSE 3000 # Healthcheck using the existing /health endpoint (node:20-alpine has no wget) HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \ CMD ["node", "scripts/healthcheck.js"] # Default command - production CMD ["npm", "start"] # ---- Stage 4: Development image (used by docker-compose.dev.yml) ---- FROM node:20-alpine AS dev WORKDIR /app RUN chown node:node /app USER node ENV NODE_ENV=development COPY --from=dev-deps --chown=node:node /app/node_modules ./node_modules COPY --chown=node:node package*.json ./ COPY --chown=node:node nodemon.json ./ COPY --chown=node:node src ./src RUN mkdir -p data logs EXPOSE 3000 CMD ["npm", "run", "dev"] # ============================================================================= # Notes for docker-compose usage: # - In docker-compose.dev.yml we override the command to "npm run dev" # and add source code bind mounts for live reload. # - Always mount host ./data and ./logs when running in production. # - The container serves the app at root (/). Any /test prefix is handled # by an external reverse proxy (see server.js comments). # =============================================================================