loading...
Cover image for Create efficient Angular Docker images with Multi Stage Builds

Create efficient Angular Docker images with Multi Stage Builds

avatsaev profile image Aslan Vatsaev ・2 min read

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;
  }

}

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;"]

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

Posted on by:

avatsaev profile

Aslan Vatsaev

@avatsaev

I do web engineering with Angular, Node, Rails, Docker... Currently R&D engineer at IRCAD/IHU France

Discussion

markdown guide
 

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.

 

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

 

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

 

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.

 

Thank you! Great for getting started

 

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

 
 

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