From a598d1b4987d9283c7d807c59d464f3b4f2602d6 Mon Sep 17 00:00:00 2001 From: Spirit-act <16631523+Spirit-act@users.noreply.github.com> Date: Tue, 22 Apr 2025 11:07:22 +0200 Subject: [PATCH 1/3] run container as unprivileged user - change export path of files to tmp folder - restructure Dockerfile - build with non root user (as far as possible) - use multistage build for smaller images - exclude dev dependencies from prod build - set default env variables Signed-off-by: Spirit-act <16631523+Spirit-act@users.noreply.github.com> --- Dockerfile | 38 +++++++++++-------- .../excelGenerator/excelGeneratorRouter.ts | 2 +- .../powerpointGeneratorRouter.ts | 2 +- .../wordGenerator/wordGeneratorRouter.ts | 2 +- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/Dockerfile b/Dockerfile index 3a1efbb..6161525 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,30 @@ -FROM node:current-slim +FROM node:current-slim AS builder -# Create app directory -WORKDIR /usr/src/app +ARG UID=3000 +ARG GID=3000 -# Copy package.json and package-lock.json -COPY package*.json ./ +WORKDIR /app -# Install app dependencies -RUN npm ci +COPY --chown=$UID:$GID . . -# Bundle app source -COPY . . +RUN npm ci && npm run build && chown -R $UID:$GID /app -# Build the TypeScript files -RUN npm run build +FROM node:current-slim AS prod -# Expose port 8080 -EXPOSE 8080 +ARG UID=3000 +ARG GID=3000 -# Start the app -CMD npm run start +ENV NODE_ENV="production" +ENV PORT="8080" +ENV HOST="0.0.0.0" + +WORKDIR /app + +COPY --from=builder --chown=$UID:$GID /app/dist /app/dist +COPY --from=builder /app/package*.json /app/ + +RUN npm ci --omit=dev --ignore-scripts && chown -R $UID:$GID /app + +USER $UID:$GID + +CMD ["dist/index.js"] diff --git a/src/routes/excelGenerator/excelGeneratorRouter.ts b/src/routes/excelGenerator/excelGeneratorRouter.ts index cc7570c..f9d0322 100644 --- a/src/routes/excelGenerator/excelGeneratorRouter.ts +++ b/src/routes/excelGenerator/excelGeneratorRouter.ts @@ -26,7 +26,7 @@ excelGeneratorRegistry.registerPath({ }); // Create folder to contains generated files -const exportsDir = path.join(__dirname, '../../..', 'excel-exports'); +const exportsDir = '/tmp/excel-exports'; // Ensure the exports directory exists if (!fs.existsSync(exportsDir)) { diff --git a/src/routes/powerpointGenerator/powerpointGeneratorRouter.ts b/src/routes/powerpointGenerator/powerpointGeneratorRouter.ts index 8d0f543..9a2150c 100644 --- a/src/routes/powerpointGenerator/powerpointGeneratorRouter.ts +++ b/src/routes/powerpointGenerator/powerpointGeneratorRouter.ts @@ -28,7 +28,7 @@ powerpointGeneratorRegistry.registerPath({ }); // Create folder to contains generated files -const exportsDir = path.join(__dirname, '../../..', 'powerpoint-exports'); +const exportsDir = '/tmp/powerpoint-exports'; // Ensure the exports directory exists if (!fs.existsSync(exportsDir)) { fs.mkdirSync(exportsDir, { recursive: true }); diff --git a/src/routes/wordGenerator/wordGeneratorRouter.ts b/src/routes/wordGenerator/wordGeneratorRouter.ts index 8823b0a..9f1b79f 100644 --- a/src/routes/wordGenerator/wordGeneratorRouter.ts +++ b/src/routes/wordGenerator/wordGeneratorRouter.ts @@ -45,7 +45,7 @@ wordGeneratorRegistry.registerPath({ }); // Create folder to contains generated files -const exportsDir = path.join(__dirname, '../../..', 'word-exports'); +const exportsDir = '/tmp/word-exports'; // Ensure the exports directory exists if (!fs.existsSync(exportsDir)) { fs.mkdirSync(exportsDir, { recursive: true }); From 0109bd1c7890e33fb1998f65a58e551ce5b60376 Mon Sep 17 00:00:00 2001 From: Spirit-act <16631523+Spirit-act@users.noreply.github.com> Date: Tue, 22 Apr 2025 11:21:02 +0200 Subject: [PATCH 2/3] improve Dockerfile comments Signed-off-by: Spirit-act <16631523+Spirit-act@users.noreply.github.com> --- Dockerfile | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6161525..7f7a302 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,30 +1,48 @@ FROM node:current-slim AS builder +# Define User ID and Group ID which the Server should run under +# Should be specified on buld, therfor buildargs ARG UID=3000 ARG GID=3000 +# Set the WORKDIR +# also make it simple so it can not be confused with system files WORKDIR /app +# copy the whole repo into the container because all +# required files are stored on the project root COPY --chown=$UID:$GID . . -RUN npm ci && npm run build && chown -R $UID:$GID /app +# run npm install and build as root +# because npm and node store some files und /root for some reason +RUN npm ci && npm run build \ + && chown -R $UID:$GID /app # change permission to the specified UID and GID after finish FROM node:current-slim AS prod ARG UID=3000 ARG GID=3000 +# set default env variable for prod ENV NODE_ENV="production" ENV PORT="8080" ENV HOST="0.0.0.0" WORKDIR /app +# copy the dist folder from the previous stage COPY --from=builder --chown=$UID:$GID /app/dist /app/dist +# we also need the package.json and package-lock.json for the deps COPY --from=builder /app/package*.json /app/ -RUN npm ci --omit=dev --ignore-scripts && chown -R $UID:$GID /app +# reinstall all prod dependencies (this also needs to run as root) +# skip scripts (prepare script) because it uses a dev dependency +RUN npm ci --omit=dev --ignore-scripts \ + && chown -R $UID:$GID /app # correct permissions +# Drop user to the defined uid and gid USER $UID:$GID +# run server via direct call +# becuase npm run start requires a dev dependency CMD ["dist/index.js"] From e8c06ba7c3e58a5181836bd8fa3df7e4905dac01 Mon Sep 17 00:00:00 2001 From: Spirit-act <16631523+Spirit-act@users.noreply.github.com> Date: Tue, 22 Apr 2025 11:23:21 +0200 Subject: [PATCH 3/3] add expose Signed-off-by: Spirit-act <16631523+Spirit-act@users.noreply.github.com> --- Dockerfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Dockerfile b/Dockerfile index 7f7a302..a3d2e2b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -43,6 +43,10 @@ RUN npm ci --omit=dev --ignore-scripts \ # Drop user to the defined uid and gid USER $UID:$GID +# define which port will be exposed +# this can be build with a build argument +EXPOSE 8080 + # run server via direct call # becuase npm run start requires a dev dependency CMD ["dist/index.js"]