Multi-stage Docker Builds for Angular with Nginx
This guide demonstrates how a multi-stage Dockerfile can compile an Angular application and then package it inside an Nginx container.
The Dockerfile shown above is composed of two distinct phases:
- Phase 1: Installing NPM dependencies and compiling the Angular project
- Phase 2: Constructing the Docker image using the
distfolder generated in the preceding phase
Phase 1: Dependency Installation and Angular Compilation
- The project is built with the Node 16 alpine image, which also accepts a
CONFIGURATIONbuild argument. At build time, this value can be changed according to your target environment.
docker build --build-arg CONFIGURATION=dev .
Additionally, you have the flexibility to define any number of other arguments as needed.
- Set
/appas the working directory. All source code and project files will be transferred into the/appfolder within the Node container.
WORKDIR /app
- Copy the package.json file into the /app directory. This step allows Docker to preserve and reuse the
node_modulescache. Subsequent builds will rely on this cached layer as long aspackage.jsonremains unchanged, avoiding a full dependency reinstall.
COPY package.json .
- Run the
npm installcommand to fetch dependencies, passing the—-legacy-peer-depsflag to avoid compilation failures on NPM versions 7 and above.
RUN npm install --legacy-peer-deps
- Afterwards, transfer the application source code and execute
npm run buildto generate the production build.
COPY . .
RUN npm run build -- --output-path=dist --configuration=$CONFIGURATION --output-hashing=all
- The compiled application files will reside in the
/app/distdirectory inside the Node container.
Phase 2: Constructing the Docker Image
- The Nginx alpine stable image serves as the runtime environment for the Angular application in production.
- Clear the pre-existing HTML files with the following command:
RUN rm -rf /usr/share/nginx/html/*
- Transfer the Nginx configuration file from the source tree to the
/etc/nginx/nginx.conflocation. If you lack a custom configuration, the sample provided below can be used.
- Next, copy the
distfolder from the build stage into the Nginx web root directory.
COPY — from=builder /app/dist /usr/share/nginx/html
- Finally, specify the Nginx start command in the Dockerfile. That completes the setup.
It's also possible to break Phase 1 into two independent stages: one dedicated solely to installing dependencies, and another focused on compiling the Angular application :)
