Last active
November 29, 2023 11:41
-
-
Save matzar/181f39b917bbc8e7a7a60556c3a987b0 to your computer and use it in GitHub Desktop.
Multi-stage build Dockerfile for a Node.js application that uses the NX workspace and Nginx as a web server for the runtime environment.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Use a specific version of the official Node.js image based on the slim variant | |
FROM node:18.16.0-bullseye-slim AS build | |
# Set the working directory | |
WORKDIR /usr/src/app | |
# Copy required files for installing dependencies | |
COPY package.json package-lock.json nx.json tsconfig.base.json decorate-angular-cli.js ./ | |
COPY apps/<app-name>/ ./apps/<app-name>/ | |
COPY apps/<app-name>-e2e/ ./apps/<app-name>-e2e/ | |
# Install npm dependencies using a secret .npmrc file | |
RUN --mount=type=secret,id=secret_npmrc,target=/root/.npmrc npm ci | |
# Set NX_DAEMON environment variable to false to prevent nx from running in daemon mode | |
ENV NX_DAEMON=false | |
# Build the application using the locally installed Nx | |
RUN npx nx run <app-name>:build | |
# Create a new stage for the runtime image | |
FROM nginx:1.25.3-alpine AS runtime | |
# Set the working directory | |
WORKDIR /usr/share/nginx/html | |
# USER root: Copy build artifacts from the build stage | |
COPY --from=build /usr/src/app/dist/apps/<app-name> . | |
# USER root: Copy the nginx configuration file | |
COPY apps/<app-name>/nginx.conf /etc/nginx/conf.d/default.conf | |
# Expose ports | |
EXPOSE 8100 8090 8080 | |
# Start the application using Nginx | |
CMD ["nginx", "-g", "daemon off;"] |
Thanks a lot for this @ikosta . Very valuable feedback indeed! Especially about putting your not-so-frequently-used dependencies into their own image. I've heard some people doing it and it's definitely something that could speed up the process significantly.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@matzar this looks like the config for an Angular (web) application and not a Node.js (server) application.
For an Angular apps this looks pretty fine but you may want to change the order of the Docker commands to get the most out of the Docker cache.
What changes often should be to the bottom of every stage and what changes less to the top.
ENV
in example would never change so put it to the top. Also thenginx.conf
will not be changed more than the/usr/src/app/dist/apps/<app-name>
. So copying/usr/src/app/dist/apps/<app-name>
after thenginx.conf
would use the cache more often.You can also use
npx nx run <app-name>:build
so you don't have to install nx. We actually have a build image with more dependencies installed that is used as builder. These dependencies are not changed very often and this build image is build beforehand.We build this image when Node.js is updated or we update npm or nx.
Pinning nx version is pretty necessary since you need to run migrations when updating.
As you will continue with more dependencies you will need also more native ones and you don't need to update several Dockerfile`s this way. Especially when working with Nx.dev.