DEV Community

Cover image for Hosting an Angular application in a Docker container on Amazon EC2 deployed by Amazon ECS

Hosting an Angular application in a Docker container on Amazon EC2 deployed by Amazon ECS

Introduction

In this article, a WEB application using the latest version of Angular in a built Docker image will be hosted on Amazon EC2 (Elastic Compute Cloud) and deployed by Amazon ECS (Elastic Container Service) using an Amazon ECR (Elastic Container Registry) containers repository.

Prerequisites

Before you start, you need to install and configure the tools below to create the Angular application, the Docker image and push the image to the repository on Amazon ECR.

  • git: Git is a distributed version control system and it will be used to sync the repository.
  • Node.js and npm: Node.js is a JavaScript code runtime software based on Google's V8 engine. npm is a package manager for Node.js (Node.js Package Manager). They will be used to build and run the Angular application and install the libraries.
  • Docker Engine: Docker Engine is a command line utility tool for Docker and it will be used to create and run containers.
  • IDE (e.g. Visual Studio Code or WebStorm): IDE (Integrated Development Environment) is a tool with a graphical interface to help in the development of applications and it will be used to develop the Angular application.
  • AWS CLI: AWS Command Line Interface is a command line utility tool for interacting with all Amazon Web Services services.

Getting started

Create the repository on Amazon ECR

Amazon ECR is a Docker containers registry service that enables you store and manage conteiner images.

1. Let's create and configure the account. Access the site https://aws.amazon.com/ecr/ and click on the button Get started with Amazon ECS.

Amazon ECR - Home page

2. Now we will click on the option Root user, fill in the field Root user email address and click on the button Next.

Amazon ECR - Sign in

Note:

3. Next, we will fill in the field Password and click on the button Sign in.

Amazon ECR - Root user sign in

4. Then, we will type ecr in the search field and click on the option Elastic Container Registry.

Amazon ECR - Elastic Container Registry service

5. After click on the option Elastic Container Registry, we will click on the button Get started.

Amazon ECR - Elastic Container Registry

6. Now we will click on the option Public, fill in the field Repository name and click on the button Create repository.

Amazon ECR - Create repository

7. Next, we will click on the created repository and click on the button View push commands.

Amazon ECR - Public repositories

8. Then, we will copy the commands because they will be used to push the Docker image of the Angular application and click on the button Close.

Amazon ECR - Push commands

9. Ready! The repository to store the Docker image of the Angular application was created.

Push the Docker image of the Angular application

1. Let's user the Angular application created in the post Creating and running an Angular application in a Docker container. We will clone the repository https://github.com/rodrigokamada/angular-docker.

git clone https://github.com/rodrigokamada/angular-docker angular-docker-amazon-ecs
Enter fullscreen mode Exit fullscreen mode

2. Now we will change the file Dockerfile with the content below.

FROM node:alpine AS app

WORKDIR /usr/src/app

COPY . /usr/src/app

RUN npm install

RUN npm run build



FROM nginx:alpine

COPY --from=app /usr/src/app/dist/angular-docker/browser /usr/share/nginx/html

RUN ls /usr/share/nginx/html

COPY ./nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80
Enter fullscreen mode Exit fullscreen mode

Notes:

  • The FROM node:alpine AS app setting defines the base Docker image of Node.js to build the Angular application.
  • The WORKDIR /usr/src/app setting defines the default application directory. The defined directory is created if it does not exist.
  • The COPY . /usr/src/app setting copies the local application files and directories to the defined directory.
  • The RUN npm install setting installs the Angular application dependencies.
  • The RUN npm run build setting compiles the Angular application.
  • The FROM nginx:alpine setting defines the base Docker image of NGINX to serve the Angular application files.
  • The COPY --from=app /usr/src/app/dist/angular-docker/browser /usr/share/nginx/html setting copies the compiled Angular application files to the NGINX directory.
  • The COPY ./nginx.conf /etc/nginx/conf.d/default.conf setting copies the NGINX configuration file to serve the Angular application.
  • The EXPOSE 80 setting defines the Docker port. NGINX uses the default port 80.

3. Next, we will create the file nginx.conf with the NGINX configuration in the root directory of the Angular application.

touch nginx.conf
Enter fullscreen mode Exit fullscreen mode

4. Then, we will configure the file nginx.conf with the content below.

server {
    listen 80;

    location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
        try_files $uri $uri/ /index.html =404;
    }
}
Enter fullscreen mode Exit fullscreen mode

5. After configure the file nginx.conf, we will authenticate the Docker client with the repository registry.

aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/d3o6w2v8

Login Succeeded
Enter fullscreen mode Exit fullscreen mode

6. Now we will create the Docker image.

docker build -t angular-docker-amazon-ecs .
[+] Building 45.5s (10/10) FINISHED                                                                                                         docker:default
 => [internal] load build definition from Dockerfile                                                                                                  0.1s
 => => transferring dockerfile: 191B                                                                                                                  0.0s
 => [internal] load metadata for docker.io/library/node:alpine                                                                                        2.4s
 => [internal] load .dockerignore                                                                                                                     0.1s
 => => transferring context: 2B                                                                                                                       0.0s
 => [1/5] FROM docker.io/library/node:alpine@sha256:d3271e4bd89eec4d97087060fd4db0c238d9d22fcfad090a73fa9b5128699888                                  4.5s
 => => resolve docker.io/library/node:alpine@sha256:d3271e4bd89eec4d97087060fd4db0c238d9d22fcfad090a73fa9b5128699888                                  0.0s
 => => sha256:6af33fd59f0638fb0acc2992b2b54c7baf68fe593083f0f52815cf29d1288803 7.13kB / 7.13kB                                                        0.0s
 => => sha256:4abcf20661432fb2d719aaf90656f55c287f8ca915dc1c92ec14ff61e67fbaf8 3.41MB / 3.41MB                                                        1.0s
 => => sha256:2997c41553473c7c926a796f330b4a7b03e9d2a7a9ee059a66bf68e02040bf40 43.53MB / 43.53MB                                                      2.0s
 => => sha256:803074618b54a85228c5e10d79b5320e5eba82a2f89abddf233e852420430ba2 2.37MB / 2.37MB                                                        1.0s
 => => sha256:d3271e4bd89eec4d97087060fd4db0c238d9d22fcfad090a73fa9b5128699888 1.43kB / 1.43kB                                                        0.0s
 => => sha256:f5d3a6aea1b1d35066e6c034f5c264cd5b051fc7c7cb0160bb88899e7b1f0c83 1.16kB / 1.16kB                                                        0.0s
 => => extracting sha256:4abcf20661432fb2d719aaf90656f55c287f8ca915dc1c92ec14ff61e67fbaf8                                                             0.1s
 => => sha256:249f9271d1d17cdc2d12d106e2dcfafdc306da21f65123a06aa2290baa5c4fac 451B / 451B                                                            1.4s
 => => extracting sha256:2997c41553473c7c926a796f330b4a7b03e9d2a7a9ee059a66bf68e02040bf40                                                             1.7s
 => => extracting sha256:803074618b54a85228c5e10d79b5320e5eba82a2f89abddf233e852420430ba2                                                             0.3s
 => => extracting sha256:249f9271d1d17cdc2d12d106e2dcfafdc306da21f65123a06aa2290baa5c4fac                                                             0.0s
 => [internal] load build context                                                                                                                     0.1s
 => => transferring context: 683.88kB                                                                                                                 0.0s
 => [2/5] WORKDIR /usr/src/app                                                                                                                        0.3s
 => [3/5] COPY . /usr/src/app                                                                                                                         0.1s
 => [4/5] RUN npm install -g @angular/cli                                                                                                            20.1s
 => [5/5] RUN npm install                                                                                                                            13.8s
 => exporting to image                                                                                                                                4.0s
 => => exporting layers                                                                                                                               4.0s
 => => writing image sha256:e6b87cf9530701fe49f487780093e6bd0e87c2052147750debf8fdf3e6544851                                                          0.0s
 => => naming to docker.io/library/angular-docker-amazon-ecs
Enter fullscreen mode Exit fullscreen mode

7. Next, we will create the image tag.

docker tag angular-docker-amazon-ecs:latest public.ecr.aws/d3o6w2v8/angular-docker-amazon-ecs:latest
Enter fullscreen mode Exit fullscreen mode

8. Then, we will push the Docker image to the repository.

docker push public.ecr.aws/d3o6w2v8/angular-docker-amazon-ecs:latest
The push refers to repository [public.ecr.aws/d3o6w2v8/angular-docker-amazon-ecs]
0d182ddaeba2: Pushed 
692f273c8005: Pushed 
f19fda91d840: Pushed 
118d5d6c8a47: Pushed 
6ac923e38b05: Pushed 
18ffdcddf862: Pushed 
aab2cca0cf91: Pushed 
d4fc045c9e3a: Pushed 
latest: digest: sha256:2f09379b02c2669c915fc63116536d1bb5040c3d608a68b8f3306f10af4d125d size: 2000
Enter fullscreen mode Exit fullscreen mode

Note:

  • The AWS CLI user must have the permission AmazonElasticContainerRegistryPublicFullAccess.

9. After push the Docker image to the repository, we will check if the Docker image was pushed to the repository. We will go back to the site and click on the repository name.

Amazon ECR - Public repositories

10. Now we will see the Docker image pushed.

Amazon ECR - Images

11. Ready! The Docker image of the Angular application was pushed to the repository on Amazon ECR.

Create the conteiner on Amazon ECS

Amazon ECS is a Docker containers orchestration service that enables you deploy, manage and scale containerized applications.

1. Let's type ecs in the search field and click on the option Elastic Container Service.

Amazon ECS - Access Elastic Container Service

2. Now we will click on the button Create cluster.

Amazon ECS - Elastic Container Service

3. Next, we will fill in the field Cluster name, click on the option Amazon EC2 instances, select the option Amazon Linux 2 in the field Operating system/Architecture, select the option c1.medium in the field EC2 instance type, fill in the field Maximum, select the option Turn on in the field Auto-assign public IP and click on the button Create.

Amazon ECS - Create cluster

4. Then, we will click on the menu Task definitions.

Amazon ECS - Clusters

5. After click on the menu Task definitions, we will click on the button Create new task definition.

Amazon ECS - Tasks definitions

6. Now we will fill in the field Task definition family, click on the option Amazon EC2 instances, select the option default in the field Network mode, fill in the field CPU, fill in the field Memory, fill in the field Name with the tag name, fill in the field Image URI with the Docker image name, fill in the field Host port with the external port, fill in the field Container port with the NGINX port and click on the button Create.

Amazon ECS - Create new task definition

7. Next, we will click on the button Deploy and click on the option Run task.

Amazon ECS - Overview

8. Then, we will click on the button Create because the fields Existing cluster, Family and Revision was filled in.

Amazon ECS - Create run task

9. After click on the button Create, we will wait for the EC2 instance to be created in the session Tasks.

Amazon ECS - Tasks launched

10. Now we will type ec2 in the search field and click on the option EC2.

Amazon ECS - Search EC2

11. Next, we will click on the menu Instances.

Amazon ECS - EC2 Dashboard

12. Then, we will click on the created instance.

Amazon ECS - Instances

13. After click on the created instance, we will click on the icon to copy the domain in Public IPv4 DNS.

Amazon ECS - Copy domain

14. Now we will access the URL http://ec2-54-146-190-174.compute-1.amazonaws.com in a browser.

Amazon ECS - Angular application

15. Ready! The Docker image of the Angular application was deployed and the application is working.

Conclusion

Summarizing what was covered in this article:

  • We created a public repository on Amazon ECR.
  • We changed the Docker configuration of the Angular application.
  • We created the NGINX configuration file in the Angular application.
  • We created a Docker image.
  • We pushed the Docker image to the repository.
  • We created a container on Amazon ECS for the deployment.
  • We tested the Angular application inside the Docker container served on EC2 instance.

You can use this article to create a Docker container with an Angular application image, push the image to a repository on Amazon ECR and deploy the container using Amazon ECS to an EC2 instance where the Angular application will be served.

Thank you for reading and I hope you enjoyed the article!

This tutorial was posted on my blog in portuguese.

To stay updated whenever I post new articles, follow me on Twitter and LinkedIn.

Top comments (1)

Collapse
 
jangelodev profile image
João Angelo

Hi Rodrigo Kamada,
Your tips are very useful
Thanks for sharing