Skip to content

Commit 4590bfd

Browse files
committed
refactor: enhance Dockerfile for improved build process and security practices
1 parent 945d52b commit 4590bfd

File tree

1 file changed

+74
-20
lines changed

1 file changed

+74
-20
lines changed

Docker/Dockerfile.api

Lines changed: 74 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,89 @@
1-
FROM node:22-slim
1+
# Use an ARG to allow for easy version upgrades
2+
ARG NODE_VERSION=22
23

3-
# 🛠 Install OpenSSL 1.1 (needed by Prisma) and other required packages
4-
RUN apt-get update && apt-get install -y \
5-
openssl \
6-
libssl-dev \
7-
libstdc++6 \
8-
zlib1g \
9-
bash \
10-
&& rm -rf /var/lib/apt/lists/*
4+
# =================================================================================================
5+
# 1. Builder Stage: Installs all dependencies, builds the source code, and prunes dev dependencies.
6+
# =================================================================================================
7+
FROM node:${NODE_VERSION}-slim AS builder
118

12-
RUN npm install -g pnpm@9.9.0
9+
# Set environment variables for pnpm
10+
ENV PNPM_HOME="/pnpm"
11+
ENV PATH="$PNPM_HOME:$PATH"
12+
# Use corepack to install pnpm, which is the recommended method since Node.js v16.13
13+
RUN corepack enable && corepack prepare pnpm@9.9.0 --activate
1314

1415
WORKDIR /usr/src/app
1516

16-
COPY ./packages ./packages
17-
COPY ./pnpm-lock.yaml ./pnpm-lock.yaml
18-
COPY ./pnpm-workspace.yaml ./pnpm-workspace.yaml
17+
# 🛠 Install OpenSSL and build tools needed for native modules (like Prisma)
18+
RUN apt-get update && apt-get install -y --no-install-recommends \
19+
openssl \
20+
libssl-dev \
21+
pkg-config \
22+
build-essential \
23+
python3 \
24+
&& rm -rf /var/lib/apt/lists/*
1925

20-
COPY ./package.json ./package.json
21-
COPY ./tsconfig.json ./tsconfig.json
22-
COPY ./turbo.json ./turbo.json
26+
# Copy only the files required to install dependencies.
27+
# This maximizes layer caching. The install step will only re-run if these files change.
28+
COPY pnpm-lock.yaml pnpm-workspace.yaml ./
29+
COPY package.json tsconfig.json turbo.json ./
30+
COPY packages/ packages/
31+
COPY apps/api/package.json apps/api/
2332

24-
COPY ./apps/api ./apps/api
33+
# Use `pnpm fetch` to download dependencies into a shared content-addressable store.
34+
# This creates a highly cacheable layer.
35+
RUN pnpm fetch
2536

26-
RUN pnpm install --frozen-lockfile
37+
# Copy the rest of the source code
38+
COPY . .
2739

28-
# Generate Prisma client
40+
# Install dependencies using the fetched packages (offline) and generate Prisma client
41+
RUN pnpm install --frozen-lockfile --offline
2942
RUN pnpm db:generate
3043

44+
# Build the specific 'api' application
3145
RUN pnpm build --filter=api
3246

47+
# Prune development dependencies to reduce the size of the node_modules folder
48+
RUN pnpm prune --prod
49+
50+
# =================================================================================================
51+
# 2. Production Stage: Creates the final, small, and secure image.
52+
# =================================================================================================
53+
FROM node:${NODE_VERSION}-slim AS production
54+
55+
# Set the environment to production
56+
ENV NODE_ENV=production
57+
58+
WORKDIR /usr/src/app
59+
60+
# Install only the runtime dependency for Prisma (OpenSSL)
61+
RUN apt-get update && apt-get install -y --no-install-recommends \
62+
openssl \
63+
&& rm -rf /var/lib/apt/lists/*
64+
65+
# Create a non-root user and group for security
66+
RUN addgroup --system --gid 1001 nodejs
67+
RUN adduser --system --uid 1001 nodejs
68+
69+
# Copy pruned dependencies, built code, and necessary package files from the builder stage
70+
# --chown sets the correct permissions for our non-root user
71+
COPY --from=builder --chown=nodejs:nodejs /usr/src/app/node_modules ./node_modules
72+
COPY --from=builder --chown=nodejs:nodejs /usr/src/app/pnpm-lock.yaml ./pnpm-lock.yaml
73+
COPY --from=builder --chown=nodejs:nodejs /usr/src/app/apps/api/dist ./apps/api/dist
74+
COPY --from=builder --chown=nodejs:nodejs /usr/src/app/apps/api/package.json ./apps/api/package.json
75+
# Prisma client also needs access to the schema file at runtime
76+
COPY --from=builder --chown=nodejs:nodejs /usr/src/app/apps/api/prisma ./apps/api/prisma
77+
78+
# Switch to the non-root user
79+
USER nodejs
80+
81+
# Change to the app-specific directory
3382
WORKDIR /usr/src/app/apps/api
3483

35-
CMD ["pnpm", "start"]
84+
# Expose the port your app runs on (replace 3000 if different)
85+
EXPOSE 3000
86+
87+
# Start the application directly with node, avoiding the need for pnpm in the final image.
88+
# Assumes your start script runs `node dist/main.js` or similar.
89+
CMD ["node", "dist/main.js"]

0 commit comments

Comments
 (0)