1
- # Use an official Node runtime as a parent image
2
- # Choose a version compatible with your application (e.g., LTS version like 18 or 20)
3
- FROM node:18-alpine
1
+ # ---- Builder Stage ----
2
+ FROM node:18-alpine AS builder
4
3
5
- # Set the working directory in the container
6
4
WORKDIR /usr/src/app
7
5
8
- # Copy package.json and package-lock.json for root dependencies
6
+ # Install necessary build tools (if any, e.g., python, make for some native deps)
7
+ # RUN apk add --no-cache ...
8
+
9
+ # Copy only necessary package files first
9
10
COPY package*.json ./
10
11
11
- # Install root dependencies
12
- RUN npm install
12
+ # Install ALL dependencies (including dev needed for build)
13
+ # Using npm ci for faster, more reliable builds in CI/CD
14
+ RUN npm ci
13
15
14
- # Copy server package.json and package-lock.json
15
- COPY server/package*.json ./server/
16
+ # Copy the rest of the application code
17
+ # Important: Copy . before running build commands
18
+ COPY . .
16
19
17
- # Install server dependencies
18
- RUN cd server && npm install
20
+ # Build the production CSS
21
+ RUN npm run build:css
19
22
20
- # Copy the rest of the application code
21
- # Copy server code first
22
- COPY server/ ./server/
23
- # Copy public directory into src/public to match server path expectations
24
- COPY src/public/ ./src/public/
23
+ # Prune devDependencies after build
24
+ RUN npm prune --production
25
+
26
+ # ---- Runner Stage ----
27
+ FROM node:18-alpine
28
+
29
+ WORKDIR /usr/src/app
25
30
26
- # Application listens on port 7655 by default (as per .env.example)
31
+ # Create a non-root user and group
32
+ RUN addgroup -S appgroup && adduser -S appuser -G appgroup
33
+
34
+ # Copy necessary files from builder stage
35
+ # Copy node_modules first (can be large)
36
+ COPY --from=builder /usr/src/app/node_modules ./node_modules
37
+ # Copy built assets
38
+ COPY --from=builder /usr/src/app/src/public ./src/public
39
+ # Copy server code
40
+ COPY --from=builder /usr/src/app/server ./server
41
+ # Copy root package.json needed for npm start and potentially other metadata
42
+ COPY --from=builder /usr/src/app/package.json ./
43
+ # Optionally copy other root files if needed by the application (e.g., .env.example, README)
44
+ # COPY --from=builder /usr/src/app/.env.example ./
45
+
46
+ # Ensure correct ownership of application files
47
+ # Use /usr/src/app to cover everything copied
48
+ RUN chown -R appuser:appgroup /usr/src/app
49
+
50
+ # Switch to non-root user
51
+ USER appuser
52
+
53
+ # Expose port
27
54
EXPOSE 7655
28
55
29
- # Define the command to run the app using the start script from root package.json
30
- # This script should handle changing into the server directory
56
+ # Run the application using the start script
31
57
CMD [ "npm" , "run" , "start" ]
0 commit comments