1- # Use Node.js as the base image
2- FROM node:18 -alpine AS build
1+ # Use Node.js 20 LTS for Angular 20 compatibility
2+ FROM node:20 -alpine AS build
33
44# Set working directory
55WORKDIR /app
66
7- # Copy package.json and package-lock.json
7+ # Copy package.json and package-lock.json for better Docker layer caching
88COPY package.json package-lock.json* ./
99
10- # Install dependencies
10+ # Install dependencies with exact versions for reproducibility
1111RUN npm ci
1212
1313# Copy the rest of the application code
@@ -16,13 +16,36 @@ COPY . .
1616# Build the Angular app for production
1717RUN npm run build:ci
1818
19+ # Production stage
20+ FROM node:20-alpine AS production
1921
20- FROM node:18-alpine
22+ # Create app directory
23+ WORKDIR /app
24+
25+ # Create non-root user for security
26+ RUN addgroup -g 1001 -S nodejs && \
27+ adduser -S nextjs -u 1001
28+
29+ # Copy the built application and dependencies
30+ COPY --from=build --chown=nextjs:nodejs /app/dist/utilplex ./dist/utilplex
31+ COPY --from=build --chown=nextjs:nodejs /app/package.json ./
32+ COPY --from=build --chown=nextjs:nodejs /app/package-lock.json* ./
2133
22- # Copy the build output to replace the default nginx contents
23- COPY --from=build /app/dist/utilplex ./
34+ # Install only production dependencies
35+ RUN npm ci --only=production && npm cache clean --force
2436
25- CMD node server/server.mjs
37+ # Switch to non-root user
38+ USER nextjs
39+
40+ # Set NODE_ENV to production
41+ ENV NODE_ENV=production
2642
2743# Expose port 4000
2844EXPOSE 4000
45+
46+ # Add health check
47+ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
48+ CMD node --version || exit 1
49+
50+ # Start the application
51+ CMD ["node" , "dist/utilplex/server/server.mjs" ]
0 commit comments