Deploying Your Angular App with Docker and Nginx: A Step-by-Step Tutorial

How to dockerize angular

Deploying Your Angular App with Docker and Nginx: A Step-by-Step Tutorial

Example of dockerization of an Angular application.

In this first example the goal is to deploy an Angular application using a production web server (nginx).

There are other use cases, like build and deploy an Angular application in docker that is often presented on the web.

I personally prefer to separate the building process from the deployment. In our example we build the Angular application on our machine and we deploy the artifact in the docker image.

This solution can be adapted to a CI/CD pipeline.

Basic Angular application

We use a standard Angular project directory. It should be similar to this one (e.g. after ng new [PROJECT-NAME]):

[ANGULAR-PROJECT-ROOT]/
|-- dist/
|    |-- [PROJECT-NAME]/ 
|            |-- index.html
|            |-- ...
|
|-- angular.json
|-- node_modules
|    |-- ...
|-- package.json
|-- src
|    |-- ...
|-- ...

The dist folder is created after we build our application with ng build.

We have to deploy the content of this directory in our docker container.

[ANGULAR-PROJECT-ROOT]/
...
|-- Dockerfile
|-- nginx.conf

In the ROOT folder of the Angular application we need to create a Dockerfile and a nginx.conf file.

Preparing the Docker image

Here the content of our Dockerfile:

``` docker FROM nginx COPY nginx.conf /etc/nginx/nginx.conf COPY ./dist/[PROJECT_NAME] /usr/share/nginx/html


We use Nginx as web server for the deployment. In theory an Angular app is a simple Javascript application and it doesn't need a web server. An online file storage offered by a cloud provider could be enough.

Some advantages of a web server:
* own rules and filters
* compression
* resolution of the html urls (404 error after refresh)

Our docker consists in only 3 lines.

`FROM nginx` we use the official _nginx_ Docker image.

`COPY nginx.conf /etc/nginx/nginx.conf`, we have a custom _nginx_ configuration.

`COPY ./dist/[PROJECT_NAME] /usr/share/nginx/html` we copy the prod build of our Angular app.

## Nginx configuration

We have a custom configuration for nginx `nginx.conf`, this is an example with some optimizations.

The content of the angular application is stored in `/usr/share/nginx/html` and we tell Docker that this is the _root_ of our website.

``` bash
events {
  worker_connections  1024;  ## Default: 1024
}

http {

    ## use mime types
    include /etc/nginx/mime.types;

     server {
       
        listen 80;

        location / {
            root /usr/share/nginx/html;
            index  index.html;
            ## without this our .css are not loaded
            try_files $uri $uri/ /index.html?$query_string;
        }
    }

    ## enable gzip compression
    gzip on;
    gzip_vary on;
    gzip_min_length 256;
    gzip_proxied any;

    gzip_types
      ## text/html is always compressed : https://nginx.org/en/docs/http/ngx_http_gzip_module.html
      text/plain
      text/css
      text/javascript
      application/javascript
      application/x-javascript
      application/xml
      application/json
      application/ld+json;
}

Solving the 404 error when the page is refreshed

Using nginx the problem of the 404 page not found error is automatically solved.

Usually we have this issue when we try to (re)load a page in our Angular application (e.g. [ROOT]/page2) but the server doesn't know it because the routing is handled by Angular.

NGINX does the same as our Java solution in the backend, you can find a tutorial here: https://marmo.dev/how-to-solve-the-redirection-404-error-in-angular-using-java

Build and deploy the application

To build the Docker image you need the following steps:

  • Build the Angular application using ng build, this generates the prod files in the directory ./dist/[PROJECT_NAME].
  • Build the Docker image: e.g. docker build -t my-super-project-name .
  • Run the Docker container: e.g. docker run -p 80:80 my-super-project-name

Remember to specify the port or Nginx will show his default page: Welcome to nginx! If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

This error could appear in case of error during the copy of your configuration file too.

With this solution you are running a web server that listen port 80, makes a compressions of the response and redirect to the main page if a URL is not found.

Extra: Limit the access to external resources

If you want the limit the access to your website (e.g. your site is under attack) you can use the ngxhttpaccessmodule.

The following instruction will block the access to the user with the IP address 192.168.1.1

``` javascript location / { # http, server, location, limit_except deny  192.168.1.1;


To allow the access only to some addresses you can specify the allowed addresses and `deny all;`, the rules are evaluated in sequence.

``` javascript
location / {
    allow 192.168.1.0/24;
    deny  all;

As alternative, you can limit the access using the combination 'username/password' with

``` javascript location / { authbasic           "no access"; authbasicuserfile conf/htpasswd;