Deploy your Angular app with Docker and Nginx


For our deployments we use Kubernetes or OpenShift. Everything has to be in a container and be part of a develop / build / deploy pipeline.

Your final directory structure should be something similar:

[ANGULAR-PROJECT-ROOT]/ 
|-- dist/ 
|    |-- [PROJECT-NAME]/  
|            |-- index.html 
|            |-- ... 
| 
|-- ... 
|-- Dockerfile 
|-- nginx.conf 

You have to create a Dockerfile and a nginx.conf file in the project directory of your Angular application.

The docker container

Dockerfile

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 nginx Docker image
COPY nginx.conf /etc/nginx/nginx.conf we copy our own nginx configuration.
COPY ./dist/[PROJECT_NAME] /usr/share/nginx/html we copy the prod build of our Angular app.

ng build generates the prod files in the directory ./dist/[PROJECT_NAME] you have to copy the path to this directory using the name of your project.

Nginx configuration

We have a custom configuration for nginx nginx.conf:

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

To build the Dockerfile you can use a command like:

docker build -t my-super-project-name .

when Docker complete the build of the container you can start it with:

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.

Limit the access to external ressources

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

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

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.

location / { 
    allow 192.168.1.0/24; 
    deny  all; 

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

location / { 
    auth_basic           "no access"; 
    auth_basic_user_file conf/htpasswd; 

Note that if you are using groups of addresses you have to use the CIDR format.



WebApp built by Marco using SpringBoot, Java 17, Mustache, Markdown and in Azure