# ---- Builder Stage ---- # Use official Node.js 20 (Alpine) FROM node:20-alpine AS builder # Install init system RUN apk add --no-cache dumb-init # App dir WORKDIR /app # Copy package files COPY package*.json ./ # Install production deps RUN npm ci --only=production && npm cache clean --force # ---- Final Stage ---- FROM node:20-alpine LABEL maintainer="your-email@example.com" LABEL org.opencontainers.image.source="https://github.com/yourname/uta-gtfs-mysql" # Install dumb-init + MySQL client (optional but common) RUN apk add --no-cache dumb-init mysql-client # Create non-root user RUN addgroup -g 1001 -S nodejs \ && adduser -S utauser -u 1001 WORKDIR /app # Copy node_modules from builder COPY --from=builder /app/node_modules ./node_modules # Copy app source COPY . . RUN chown -R utauser:nodejs /app USER utauser # Healthcheck – you may want to change port if needed HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \ CMD wget -qO- http://localhost:3000/ || exit 1 EXPOSE 3000 ENTRYPOINT ["dumb-init", "--"] CMD ["node", "server.js"]