From 1dde5dc308e6ab4c7ca79442411df81d65073993 Mon Sep 17 00:00:00 2001 From: tdurieux Date: Tue, 5 May 2026 00:52:55 +0300 Subject: [PATCH] docker: multi-stage build with alpine runtime Split into builder (node:21-slim, full deps + tsc/gulp) and runtime (node:21-alpine, production deps only). Drops ~hundreds of MB from the published image and removes dev tooling from the runtime layer. --- Dockerfile | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/Dockerfile b/Dockerfile index 386e2ba..dac7176 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,20 +1,28 @@ -FROM node:21-slim - -ENV PORT 5000 -EXPOSE $PORT +# syntax=docker/dockerfile:1 +FROM node:21-slim AS builder WORKDIR /app -COPY package.json . -COPY package-lock.json . - -COPY gulpfile.js . -COPY tsconfig.json . -COPY healthcheck.js . +COPY package.json package-lock.json ./ +RUN npm ci +COPY tsconfig.json gulpfile.js ./ COPY public ./public COPY src ./src +RUN npm run build && npm prune --omit=dev && npm cache clean --force -RUN npm install && npm run build && npm cache clean --force +FROM node:21-alpine AS runtime -CMD [ "node", "./build/server/index.js"] \ No newline at end of file +ENV NODE_ENV=production +ENV PORT=5000 +EXPOSE 5000 + +WORKDIR /app + +COPY --from=builder /app/node_modules ./node_modules +COPY --from=builder /app/build ./build +COPY --from=builder /app/public ./public +COPY --from=builder /app/package.json ./package.json +COPY healthcheck.js ./healthcheck.js + +CMD ["node", "./build/server/index.js"]