DEV Community

Cover image for Create efficient Angular Docker images with Multi Stage Builds
Aslan Vatsaev
Aslan Vatsaev

Posted on

Create efficient Angular Docker images with Multi Stage Builds

In this write up we’ll see how to dockerize an Angular app in an efficient manner with Docker’s Multi-Stage Builds.

At the time of writing this post, I'm using Angular v7

Prerequisites

  • NodeJS +8
  • Angular CLI (npm i -g @angular/cli@latest)
  • Docker +17.05
  • Basic understanding of Docker and Angular CLI commands

The plan

To dockerize a basic Angular app built with Angular CLI, we need to do the following:

  • npm install the dependencies (dev dependencies included)
  • ng build with --prod flag
  • move the artifacts from dist folder to a publicly accessible folder (via an an nginx server)
  • Setup an nginx config file, and spin up the http server

Ultimate Courses

We’ll do this in 2 stages:

  • Build stage: will depend on a Node alpine Docker image
  • Setup stage: will depend on NGINX alpine Docker image and use the artifacts from the build stage, and the nginx config from our project.

Initialize an empty Angular project

$ ng new myapp

Add a default nginx config

At the root of your Angular project, create nginx folder and create a file named default.conf with the following contents (./nginx/default.conf):

server {

  listen 80;

  sendfile on;

  default_type application/octet-stream;


  gzip on;
  gzip_http_version 1.1;
  gzip_disable      "MSIE [1-6]\.";
  gzip_min_length   1100;
  gzip_vary         on;
  gzip_proxied      expired no-cache no-store private auth;
  gzip_types        text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
  gzip_comp_level   9;


  root /usr/share/nginx/html;


  location / {
    try_files $uri $uri/ /index.html =404;
  }

}
Enter fullscreen mode Exit fullscreen mode

Create the Docker file


### STAGE 1: Build ###

# We label our stage as ‘builder’
FROM node:10-alpine as builder

COPY package.json package-lock.json ./

## Storing node modules on a separate layer will prevent unnecessary npm installs at each build

RUN npm ci && mkdir /ng-app && mv ./node_modules ./ng-app

WORKDIR /ng-app

COPY . .

## Build the angular app in production mode and store the artifacts in dist folder

RUN npm run ng build -- --prod --output-path=dist


### STAGE 2: Setup ###

FROM nginx:1.14.1-alpine

## Copy our default nginx config
COPY nginx/default.conf /etc/nginx/conf.d/

## Remove default nginx website
RUN rm -rf /usr/share/nginx/html/*

## From ‘builder’ stage copy over the artifacts in dist folder to default nginx public folder
COPY --from=builder /ng-app/dist /usr/share/nginx/html

CMD ["nginx", "-g", "daemon off;"]

Enter fullscreen mode Exit fullscreen mode

Build the image

$ docker build -t myapp .

Run the container

$ docker run -p 8080:80 myapp

And done, your dockerized app will be accessible at http://localhost:8080

And the size of the image is only ~15.8MB, which will be even less once pushed to a Docker repository.

You can see a full example in this GitHub repository: https://github.com/avatsaev/angular-contacts-app-example

Top comments (8)

Collapse
 
bbj1980 profile image
bbj1980

What changes need to make to access HTTPS request from nginx? While trying to access HTTPS I am getting CORS error. I think we have to configure HTTPS on nginx. Can you please help for same.

Collapse
 
writemevenkat profile image
Venkat Muthu

Great post Aslan. I'm new to Angular and was able to get this up and running in 10 mins.

Collapse
 
ruvan83 profile image
ruvan83 • Edited

Thanks for the tutorial, how do I use this docker image to run my application in AWS code build/code pipeline?

Collapse
 
inoubli profile image
aymen inoubli

Hi Aslan, thank you for sharing, it's working for me, I jut want to know the way to Dockerize my Angular App to let it rebuild automatically after every change when I'm in dev mode.

Collapse
 
mfik profile image
mfik

Thank you! Great for getting started

Collapse
 
claudiocampisi profile image
claudiocampisi

Thanks for the article. How can i build an angular docker image in order to promote it in different environments? I don't want to build an image for each environment

Collapse
 
beaussart profile image
Nicolas Beaussart

I wrote a post about a way to do that dev.to/beaussart/runtime-config-wi... :)

Collapse
 
vajohn profile image
Lajabu John

Hi, this was simple enough to follow even with IVY. Yet having a hard time doing it for universal angular app.