Angular – How to Dockerize an Angular application

By | 02/06/2020

In this post, we will see how to Dockerize an Angular application and how to deploy it in Docker Hub.

ANGULAR PROJECT:
We start creating a new Angular project called “AngularDockerUI” with three components:
ng new AngularDockerUI
ng g c share/menu
ng g c share/homepage
ng g c pages/pagelist

Finally, we install Bootstrap using the command npm install bootstrap and then, we add bootstrap.min.css into the file src/styles.cs:
@import ‘~bootstrap/dist/css/bootstrap.min.css’

Now, we open src/app/app-routing.module.ts and we modify the app-routing:

[APP-ROUTING.MODULE.TS]

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { PagelistComponent } from './pages/pagelist/pagelist.component';
import { HomepageComponent } from './share/homepage/homepage.component';

const routes: Routes = [
  { path: '', pathMatch: 'full', redirectTo: 'homepage'},
  { path: 'homepage', component: HomepageComponent },
  { path: 'list', component: PagelistComponent },
  { path: '**', pathMatch: 'full', redirectTo: 'homepage' }  
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }



Then, we open src/app/share/menu/menu.component.html and we add a menu:

[MENU.COMPONENT.HTML]

<nav class="navbar navbar-dark bg-dark mb-5">
  <a class="navbar-brand" routerLink="homepage">HOMEPAGE</a>
  <div class="navbar-expand mr-auto">
    <ul class="nav navbar-nav" routerLinkActive="active">
        <li class="nav-item"><a class="nav-link" routerLink="/list">Page List</a></li>
    </ul>
  </div>
</nav>



Finally, we open src/app/app.component.html and we add here the component menu:

[APP.COMPONENT.HTML]

<app-menu></app-menu>
<router-outlet></router-outlet>



If we run the application, this will be the result:

Now, we add a class called user:

[USER.TS]

export class User {
    id: number;
    userName: string;
    typeUser: string;
    creationDate: string;

    constructor(inputId: number, inputUserName: string, inputTypeUser: string, inputCreationDate: string) 
    {
        this.id = inputId;
        this.userName = inputUserName;
        this.typeUser = inputTypeUser;
        this.creationDate = inputCreationDate;
    }
}



Then, we add a service called core, using the command ng g service services/core, where we will add a function to give the list of Users:

import { Injectable } from '@angular/core';
import { User } from '../entities/user';

@Injectable({
  providedIn: 'root'
})
export class CoreService {

  constructor() { }

  GetAllUsers(): Array<User>{
    
    let lstUsers: Array<User> = [];
    
    for(var counter:number = 1; counter<3; counter++)
    {
      var objUser = new User(counter, "UserAdmin"+counter, "Admin", "06/06/2019");
      lstUsers.push(objUser);
    } 

    for(var counter:number = 4; counter<7; counter++)
    {
      var objUser = new User(counter, "UserReader"+counter, "Reader", "12/02/2019");
      lstUsers.push(objUser);
    } 

    for(var counter:number = 10; counter<14; counter++)
    {
      var objUser = new User(counter, "UserTest"+counter, "Test", "21/04/2019");
      lstUsers.push(objUser);
    } 
    
    return lstUsers
  };
}



Finally, we modify the file pagelist.component, in order to display the list of Users:

[PAGELIST.COMPONENT.TS]

import { Component, OnInit } from '@angular/core';
import { CoreService } from '../../services/core.service';
import { User } from '../../entities/user';

@Component({
  selector: 'app-pagelist',
  templateUrl: './pagelist.component.html',
  styleUrls: ['./pagelist.component.css']
})
export class PagelistComponent implements OnInit {

  lstUsers: User[];

  constructor(private coreservice: CoreService) { }

  ngOnInit(): void {
    this.lstUsers = this.coreservice.GetAllUsers();
  }
}



[PAGELIST.COMPONENT.HTML]

<p>List of Users</p>
<table class="table">
    <thead>
      <tr>
        <th scope="col">#</th>
        <th scope="col">Id</th>
        <th scope="col">Username</th>
        <th scope="col">TypeUser</th>
        <th scope="col">Creation Date</th>
      </tr>
    </thead>
    <tbody *ngFor="let item of lstUsers; index as i"> 
      <tr>
        <td>{{i+1}}</td>
        <td>{{item.id}}</td>
        <td>{{item.userName}}</td>
        <td>{{item.typeUser}}</td>
        <td>{{item.creationDate}}</td>
      </tr>
    </tbody>
  </table>



Now, if we run the application, this will be the result:

Everything works fine and now, we will Dockerize this application.

DOCKERIZE THE ANGULAR PROJECT:
First of all, I advice to install a useful plug-in for Visual Studio Code, called Docker, that it will help us to create and manage containerized applications:

After the installation, we start creating a Dockerfile into the Angular project:

[DOCKERFILE]

# We use a node.js container to build our application
# We call this contanier 'node'
FROM node:latest as node
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build --prod

# We move our builded application into a nginx container
FROM nginx:alpine
# we can take the value of our "outputPath" into angular.json file
COPY --from=node /app/dist/AngularDockerUI /usr/share/nginx/html



Now, we click the right mouse button and we select the option “Command Palette” and then, we run the Docker command Images build:

We insert the name and the tag of our image:

and finally, we press Enter in order to create our Docker image:

Then, in order to verify everything worked fine, we will run our Docker image:

Now, if we open e browser and we go to http://localhost, this will be the result:

UPLOAD DOCKER IMAGE ON DOCKER HUB:
First of all, we run the Docker command Images Tag:

It is important to add our Docker Hub UserId into the Tag image:


Now, we push the image into Docker Hub, using the Docker command Images Push:


When the process is over, we will see the new image into our Docker Hub:

RUN THE ANGULAR DOCKER IMAGE IN ANOTHER COMPUTER:
In order to verify everything works fine, we will run our new Docker image in another computer, using the command
docker run -p 80:80 commander2020/testdockerui:v1

Now, if we open a browser and we go to http://localhost/homepage, this will be the result:



Leave a Reply

Your email address will not be published. Required fields are marked *