diff --git a/Dockerfile b/Dockerfile index 4c7c788..01afbff 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Set default values for build arguments -ARG DEFRA_VERSION=3.0.4 +ARG DEFRA_VERSION=3.0.5 ARG BASE_VERSION=24.14.0-alpine3.23 FROM node:$BASE_VERSION AS production diff --git a/JOB.env b/JOB.env index f297853..6d8db91 100644 --- a/JOB.env +++ b/JOB.env @@ -1,2 +1,2 @@ -DEFRA_VERSION=3.0.4 +DEFRA_VERSION=3.0.5 IMAGE_NAME=node diff --git a/examples/Dockerfile.service b/examples/Dockerfile.service index 13a5265..bc03631 100644 --- a/examples/Dockerfile.service +++ b/examples/Dockerfile.service @@ -1,14 +1,9 @@ # This assumes that the parent image has been built locally using production and development build configuration as defra-node # and defra-node-development tagged with a version. -ARG BASE_VERSION=2.7.0-node22.14.0 +ARG BASE_VERSION=3.0.4-node24.14.0 FROM defra-node:$BASE_VERSION AS base -# Copy our package files so that our package install will do a clean install. This installs the exact versions of the packages -# listed in package-lock.json, and does not update either the package-lock.json or the package.json file. -# Our production dependencies are now installed. -COPY --chown=node:node package*.json ./ -RUN npm ci --ignore-scripts # Development stage installs devDependencies, builds app from source and declares a file watcher as the default command. # We name this stage so we can refer to it in later stages @@ -39,7 +34,14 @@ CMD [ "npm", "run", "test" ] # Production stage exposes service port, copies in built app code and declares the Node app as the default command FROM base AS production +# Copy application artifacts and assign root ownership to prevent modification by other users. +COPY --from=development --chown=root:root /home/node/package*.json ./ +COPY --from=development --chown=root:root /home/node/app/ ./app/ + +# Install node modules and remove write permissions. +RUN npm ci --ignore-scripts --omit=dev && chmod -R a-w /home/node + # This is the command that is run for the production service. The parent image has an ENTRYPOINT that uses a lightweight -# init program "tini" that handles signals. As long as we don't override the ENTRYPOINT the "tini" routine will handle signals and -# orphaned processes +# init program "tini" that handles signals. As long as we don't override the ENTRYPOINT the "tini" routine will handle signals and +# orphaned processes CMD [ "node", "app/index" ] diff --git a/examples/Dockerfile.web b/examples/Dockerfile.web index 8664309..b7cd987 100644 --- a/examples/Dockerfile.web +++ b/examples/Dockerfile.web @@ -1,19 +1,13 @@ # This assumes that the parent image has been built locally using production and development build configuration as defra-node # and defra-node-development tagged with a version. -ARG BASE_VERSION=2.5.2-node22.14.0 +ARG BASE_VERSION=3.0.4-node24.14.0 FROM defra-node:$BASE_VERSION AS base # Set the port that is going to be exposed later on in the Dockerfile as well. ARG PORT=3000 ENV PORT=${PORT} -# Copy our package files so that our package install will do a clean install. This installs the exact versions of the packages -# listed in package-lock.json, and does not update either the package-lock.json or the package.json file. -# Our production dependencies are now installed. -COPY --chown=node:node package*.json ./ -RUN npm ci --ignore-scripts - # Development stage installs devDependencies, builds app from source and declares a file watcher as the default command. # We name this stage so we can refer to it in later stages FROM defra-node-development:$BASE_VERSION AS development @@ -53,10 +47,14 @@ WORKDIR /home/node EXPOSE ${PORT} # Copy in the files that we built using the tools in the development stage. The final production stage will have the built files, -# but none of the tools required to build those files. This reduces the attack surface, and also the size of the final production image -COPY --from=development /home/node/app/ ./app/ +# but none of the tools required to build those files. This reduces the attack surface, and also the size of the final production image +COPY --from=development --chown=root:root /home/node/package*.json ./ +COPY --from=development --chown=root:root /home/node/app/ ./app/ + +# Install node modules and remove write permissions. +RUN npm ci --ignore-scripts --omit=dev && chmod -R a-w /home/node # This is the command that is run for the production service. The parent image has an ENTRYPOINT that uses a lightweight -# init program "tini" that handles signals. As long as we don't override the ENTRYPOINT the "tini" routine will handle signals and -# orphaned processes +# init program "tini" that handles signals. As long as we don't override the ENTRYPOINT the "tini" routine will handle signals and +# orphaned processes CMD [ "node", "app/index" ]