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:
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Screenshot-2020-04-01-at-23.13.37-1024x269.png)
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Screenshot-2020-04-01-at-23.15.00-1024x229.png)
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:
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Screenshot-2020-04-02-at-00.09.30-1024x520.png)
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:
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Screenshot-2020-04-08-at-17.58.29-1024x301.png)
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:
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Screenshot-2020-04-08-at-18.31.11-1.png)
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Screenshot-2020-04-08-at-18.31.36-1024x233.png)
We insert the name and the tag of our image:
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Screenshot-2020-04-08-at-18.32.18-1024x144.png)
and finally, we press Enter in order to create our Docker image:
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Screenshot-2020-04-08-at-18.33.54-1024x158.png)
Then, in order to verify everything worked fine, we will run our Docker image:
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Screenshot-2020-04-08-at-20.40.40-1024x255.png)
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Screenshot-2020-04-08-at-20.40.52-1024x270.png)
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Screenshot-2020-04-08-at-20.40.59-1024x194.png)
Now, if we open e browser and we go to http://localhost, this will be the result:
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Screenshot-2020-04-08-at-20.43.13-1024x208.png)
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Screenshot-2020-04-08-at-20.43.20-1024x499.png)
UPLOAD DOCKER IMAGE ON DOCKER HUB:
First of all, we run the Docker command Images Tag:
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Screenshot-2020-04-08-at-20.53.08-1024x293.png)
It is important to add our Docker Hub UserId into the Tag image:
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Screenshot-2020-04-08-at-20.53.27-1024x170.png)
Now, we push the image into Docker Hub, using the Docker command Images Push:
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Screenshot-2020-04-08-at-20.53.42-1024x225.png)
When the process is over, we will see the new image into our Docker Hub:
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Screenshot-2020-04-08-at-21.04.03-1024x244.png)
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
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Screenshot-2020-04-08-at-21.13.18-1024x587.png)
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Screenshot-2020-04-08-at-21.14.27-1024x597.png)
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Screenshot-2020-04-08-at-21.15.01-1024x582.png)
Now, if we open a browser and we go to http://localhost/homepage, this will be the result:
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Screenshot-2020-04-08-at-21.15.19-1024x301.png)
![](https://www.zoneofdevelopment.com/wp-content/uploads/2020/04/Capture-1024x660.png)