Niccolo Lampa
The Data Life

The Data Life

Deploying Angular App with Docker and Nginx

Deploying Angular App with Docker and Nginx

Niccolo Lampa's photo
Niccolo Lampa

Published on Apr 15, 2021

3 min read

There are various ways to deploy our Angular application.

One way is to deploy an Angular app via Docker and Nginx.

To do this just implement the following steps:

1. Create docker folder

To keep things organized we create a docker folder at project root.

test-app/docker/

2. Create nginx.conf file

The nginx.conf will contain the configuration for our Nginx server.

Place the configuration file inside

test-app/docker/nginx/

Let's assume the app's API server is running at port 3000. Any request having a path of /api/v1/ will be redirected to our API server running at localhost:3000. Since our docker container is running inside its own docker network we will use the IP 172.17.0.1 to access our host machine's port 3000.

For other details see comments in the nginx.conf file.

events { }

http {

    server {
        listen 80;

        # location order matters. Here api path comes first before others. 

        location /api/v1/ {
           rewrite ^/api/v1(.*) $1 break;
           # use this ip to access ports outside the nginx's docker network
           # assuming your api is running on another docker network 
             proxy_pass http://172.17.0.1:3000;
             proxy_http_version 1.1;
             proxy_set_header Upgrade $http_upgrade;
             proxy_set_header Connection 'upgrade';
             proxy_set_header Host $host;
             proxy_cache_bypass $http_upgrade;
             client_max_body_size 200M;
        }

        # for any other paths beside API Nginx will try to serve Angular assets. 
        location / {
            default_type  application/octet-stream;
            include /etc/nginx/mime.types;
            root /usr/share/nginx/html;

            try_files $uri $uri/ /test-app/index.html;

        # these are needed to prevent Mime Type Errors in Angular 
            location ~ \.css {
                add_header  Content-Type    text/css;
            }

            location ~ \.js {
                add_header  Content-Type    application/x-javascript;
            }
        }
    }
}

3. Creating Dockerfile

Now let's create the Dockerfile which will provide the instructions in creating our test-app-nginx container.

Save Dockerfile inside the test-app/docker/nginx/ folder.

To have a working server our Nginx container should be able to serve our app's Angular assets (dist files). The Dockerfile therefore needs to implement a multi-stage build where the 1st stage will build our dist files.

The 2nd stage will then build our Nginx container and copy the Angular assets from the previous stage into it.

# implement a multi-stage build
# 1ST STAGE: Node image for building Angular assets (dist files)

# name the node image "builder"
FROM node:10 AS builder

# set working directory
WORKDIR /app

# copy all files from current dir to working dir in image
COPY . .

# install node modules and build assets 
RUN npm i && npm run build

# 2ND STAGE: Nginx to serve Angular assets built from previous stage

# nginx state for serving content
FROM nginx:alpine

# Set working directory to nginx asset directory
WORKDIR /usr/share/nginx/html

# Remove default nginx static assets
RUN rm -rf ./*

# copy Angular static assets (dist files) from builder image
COPY --from=builder /app/dist .

# Container run nginx 
# -g  global directives
# daemon off
ENTRYPOINT ["nginx", "-g", "daemon off;"]

4. Create a docker-compose-file

Place the docker-compose file inside test-app/docker folder.

Make sure that the build context is set properly. In the file we set the context to ../ (relative to location of docker-compose file) which refers to the project root.

It is important to set the context as we will experience errors when the Dockerfile is executed. For example, it may not find the files/folders it needs for the multi-stage build (e.g. package.json).

Another important thing to highlight is that we are mounting the nginx.conf file we created earlier to the Nginx Docker container. This makes it easy for changes in the nginx.conf file to be reflected in our Nginx container.

Last, we expose port 80 (http) and 443(https).

version: "3.5"
services:
  test-project-nginx:
    image: nginx
    build:
      context: ../
      dockerfile: ./docker/nginx/Dockerfile
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    ports:
      - "80:80"
      - "443:443"

5. Run the Docker Nginx Server

$ cd test-app/docker/

$ docker-compose up

After Docker finishes building, your Nginx server will be running.

Go to your domain and enjoy the sight of your website being served by Nginx.

Stay stoked and code. :)

 
Share this