Docker + Angular + Nginx
Tags: angular, javascript, docker, nginx
Published: 2021-08-23 02:51:43

So recently, I have been digging into DevOps and Cloud Technologies and came across this service called Google Cloud Run which lets you host your application, but the only thing that bugged me was it required a docker image, and at this point, I had no idea what docker, containers, images or any of this words meant. 😕

So like any sane person with no social life on weekends 🤪 I started learning about Docker and at first, it did seem a little challenging but eventually, I think the process is quite easy and interesting.

So, if you have no idea about Docker and containers, I have put some links at the bottom which were super useful to me.

#####But here's a summary of Docker 🐳
Docker is a container runtime. That's it 🤯. It allows us to run containerized applications.
#####So what are containers? 📦
Containers are lightweight, portable and isolated processes running on your system using the same OS kernel and user space but each with its own set of specific dependencies that do not conflict with each other.
#####And Images? 🙄
A Docker image is a file used to execute code in a container. It contains application code, libraries, tools, dependencies and other files needed to run the application.

So without wasting any more time, let's get started with the main topic 

#Dockerizing an Angular application 

#####Now obviously there are certain things you need to have installed in your system
1. Docker ([Download link](https://www.docker.com/products/docker-desktop))
2. NodeJS ([Download link](https://nodejs.org/en/))
3. Angular CLI ([Download link](https://angular.io/guide/setup-local))
4. Visual studio code (Optional) ([Download link](https://code.visualstudio.com/)) 

###Step 1: Creating an Angular Application
This one is pretty basic, we aren't going to build anything fancy here, just the pre-built template will work for this tutorial.

To create your angular application, just open the terminal in the folder where you want to create your app, and write the following command.
``` terminal
ng new my-docker-angular-app
```
Now once this is done you should have an angular app generated, open it in VS code

###Step 2: Creating Dockerfile and .dockerignore
#####Dockerfile
In the main folder of your application, create a new file and name it "__Dockerfile__". In the file, write the following commands
<a name="exposePort"></a>
```Docker
### STAGE 1:BUILD ###
# Defining a node image to be used as giving it an alias of "build"
# Which version of Node image to use depends on project dependencies 
# This is needed to build and compile our code 
# while generating the docker image
FROM node:12.14-alpine AS build
# Create a Virtual directory inside the docker image
WORKDIR /dist/src/app
# Copy files to virtual directory
# COPY package.json package-lock.json ./
# Run command in Virtual directory
RUN npm cache clean --force
# Copy files from local machine to virtual directory in docker image
COPY . .
RUN npm install
RUN npm run build --prod


### STAGE 2:RUN ###
# Defining nginx image to be used
FROM nginx:latest AS ngi
# Copying compiled code and nginx config to different folder
# NOTE: This path may change according to your project's output folder 
COPY --from=build /dist/src/app/dist/my-docker-angular-app /usr/share/nginx/html
COPY /nginx.conf  /etc/nginx/conf.d/default.conf
# Exposing a port, here it means that inside the container 
# the app will be using Port 80 while running
EXPOSE 80
```
#####DockerIgnore
If you have worked with git and know .gitignore, .dockerignore does the same thing, it specifies the files that we want to ignore while creating our docker image
Normally it may contain node_modules, test files, etc...
To create dockerignore, just create a file and name "__.dockerignore__"
For our application, just write the following inside the file
```
.git
.editorconfig
/.vscode/*
/node_modules
/e2e
/docs
.gitignore
*.zip
```

###Step 3: Create nginx.conf
We'll be using Nginx to host the angular build inside the container. So for this, we need to create a configuration file for nginx.
Create a file inside main folder and name it "__nginx.conf__".

__NOTE__: We're telling nginx to listen to port 80 here as that is the port we had exposed in Dockerfile [(refer)](#exposePort). This needs to be same as what we defined in there
```Nginx
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   256;
  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;
  }
}
```
    
###Step 4: Creating a docker image
To create a docker image, open a terminal in your project folder and write the following command
```terminal 
docker build -t ng-docker-app:v1.0.0 -f ./Dockerfile .
```
-t: Tag (if not specified, docker will take "latest" by default)
-f: File (Write the path to your Dockerfile)

After this, we should have a docker image created in your system. To get the list of docker images in your system, write the following in the terminal 
```terminal 
docker image ls
```
     
###Step 5: Create a docker container
To create and host your docker container, write the following command 
```terminal
docker run -p 8000:80 -d ng-docker-app:v1.0.0
``` 
-p: Port
Here you'll need to define a port on which the container will be hosted and the port on which app is hosted inside the container
Syntex: &lt;host-port&gt;:&lt;docker-port&gt;
-d: Detach 
If this is not specified, the docker will keep the console running

__NOTE__: We had exposed port 80 in Dockerfile and assigned nginx to listen to port 80, so &lt;docker-port&gt; has to be the same here as well

To get the list of currently running containers in your system, you can get this by typing 
```terminal
docker container ls
```

###Finally
Voila!!🎉 If you have followed each step, you should have your docker container running on Port 8000 and your application running on [localhost:8000](http://localhost:8000) 😎

#Referances
[How to install docker on windows 10?](https://medium.com/@tushar0618/installing-docker-desktop-on-window-10-501e594fc5eb)
[How to install docker on Mac OS?](https://medium.com/crowdbotics/a-complete-one-by-one-guide-to-install-docker-on-your-mac-os-using-homebrew-e818eb4cfc3)
[How to install docker on Ubuntu](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-18-04)
[Freecodecamp - What is docker used for?](https://www.freecodecamp.org/news/what-is-docker-used-for-a-docker-container-tutorial-for-beginners/)
[Freecodecamp - Docker handbook](https://www.freecodecamp.org/news/the-docker-handbook/)
[IBM - What is docker?](https://www.ibm.com/in-en/cloud/learn/docker#toc-docker-too-_SKIsywS)