Skip to content

Commit 18fa564

Browse files
aws docker done
1 parent 0ebf5af commit 18fa564

File tree

4 files changed

+330
-2
lines changed

4 files changed

+330
-2
lines changed
565 KB
Loading
Lines changed: 322 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,322 @@
1+
---
2+
title: 'Deploy NodeJs API on AWS EC2 with docker'
3+
date: '2021-07-03'
4+
author: 'Wojciech Cendrzak'
5+
image: '/images/nodejs-ec2-docker.png'
6+
tags: 'devops, nodejs, aws, docker'
7+
isPublished: true
8+
includeReferences: deploy-nodejs-api-series-section
9+
---
10+
11+
In this, we'll cover how to **dockerized** NodeJs application. Finally, we will deploy it on AWS EC2.
12+
13+
{{deploy-nodejs-api-series-section}}
14+
15+
## What Docker is
16+
17+
**Docker** itself is a platform that allows us to manage **containerized** applications. It can run on Linux, Windows, and Mac.
18+
Linux and Windows support it **natively**.
19+
20+
On Mac, Docker is running through a **lightweight Linux Virtual Machine**. So it is a Docker on Linux under the hood.
21+
It also exposes Docker API to your Mac environment. Therefore we can use the Docker commands from the Mac terminal in the same way as on the native Linux.
22+
23+
In this tutorial, we will be using Mac. Make sure you have [**Docker Desktop**](https://www.docker.com/products/docker-desktop) installed.
24+
25+
You can check the installation by typing:
26+
27+
```bash
28+
$ sudo docker version
29+
```
30+
31+
The output should looks like this:
32+
33+
```bash
34+
Client:
35+
Cloud integration: 1.0.17
36+
Version: 20.10.7
37+
API version: 1.41
38+
Go version: go1.16.4
39+
Git commit: f0df350
40+
Built: Wed Jun 2 11:56:22 2021
41+
OS/Arch: darwin/amd64
42+
Context: desktop-linux
43+
Experimental: true
44+
45+
Server: Docker Engine - Community
46+
Engine:
47+
Version: 20.10.7
48+
API version: 1.41 (minimum version 1.12)
49+
Go version: go1.13.15
50+
Git commit: b0f5bc3
51+
Built: Wed Jun 2 11:54:58 2021
52+
OS/Arch: linux/amd64
53+
Experimental: false
54+
containerd:
55+
Version: 1.4.6
56+
GitCommit: d71fcd7d8303cbf684402823e425e9dd2e99285d
57+
runc:
58+
Version: 1.0.0-rc95
59+
GitCommit: b9ee9c6314599f1b4a7f497e1f1f856fe433d3b7
60+
docker-init:
61+
Version: 0.19.0
62+
GitCommit: de40ad0
63+
```
64+
65+
## What Container is
66+
67+
**Container** is a piece of software that runs in **isolation** from hosting OS and from other containers.
68+
69+
More precisely, it allows us to **package an application with its environment**, dependencies, and configuration.
70+
71+
Exp, it makes it easy to make development on the local machine. Then deploy it to the cloud without worries that some dependencies will be missing or has a version that our app is not supporting.
72+
73+
It allows us also to run multiple applications that use different versions of a specific library.
74+
E. g two different versions of the same database engine. It wouldn't be easy without containers. We can achieve that by running multiply Virtual Machines on the host OS. With Docker containers, this is far way easy.
75+
76+
## Isn't the Container a VM itself?
77+
78+
This metaphor is accurate from a usage perspective, but not technically.
79+
A container provides isolation just like a virtual machine but in a different way.
80+
81+
When running software on **virtual machine**, we need to install the guest OS on it. VM **shares hardware** from the host machine.
82+
83+
In opposition, the container shares not only hardware but **shares a host OS** too. It utilizes container concepts such as **cgroups** and **namespaces**. Those were implemented directly on the Linux kernel and then ported to Windows. So you don't need to install an additional OS.
84+
It gives an advantage over the virtual machine such as:
85+
86+
- it is very **lightweight**,
87+
- switching containers on/off is significant **faster**
88+
- **no additional license** needed for VM guest OS
89+
90+
Docker Container can be from an **Image**.
91+
92+
## What Image is
93+
94+
In simple words, we can say that Docker Image is a **blueprint** for a container. Or a class, for instance. Or container template for a container. We can create a Docker Image through Dockerfile.
95+
96+
## What Dockerfile is
97+
98+
A Dockerfile is a recipe from which we will build an Image.
99+
It is essentially a **text file** that contains the commands to build an image.
100+
Those commands are read-only layers, each of which represents a Dockerfile instruction.
101+
The layers are stacked, and each one is a delta of the changes from the previous layer.
102+
103+
## Complete flow
104+
105+
1. We will create a NodeJs app
106+
2. We will create a **Dockerfile**
107+
3. From a Dockerfile we will build an **Image**
108+
4. We will run an Image into a new **Container**
109+
110+
## 1. Create a NodeJs project
111+
112+
We can create any NodeJs app or clone this git repo:
113+
114+
```bash
115+
https://github.com/WojciechCendrzak/nestjs-api
116+
```
117+
118+
A complete solution is also available here:
119+
120+
```bash
121+
https://github.com/WojciechCendrzak/nestjs-api/tree/docker
122+
```
123+
124+
## 2. Create a Dockerfile
125+
126+
Create a Dockerfile in main folder:
127+
128+
```dockerfile
129+
# ./Dockerfile
130+
131+
FROM node:14
132+
133+
WORKDIR /usr/src/app
134+
135+
COPY package*.json ./
136+
137+
RUN npm install
138+
139+
COPY . .
140+
141+
EXPOSE 3000
142+
143+
CMD [ "npm", "run", "start" ]
144+
```
145+
146+
Let's take a look at the Dockerfile anatomy and break it down, line by line.
147+
You can check a full specification here [Dockerfile reference](https://docs.docker.com/engine/reference/builder/)
148+
149+
```dockerfile
150+
FROM node:14
151+
```
152+
153+
In the first line, we can define from which **parent Image** we want to start. It is also possible to create an image from scratch. In that case, we can completely omit **FROM**. But, in most cases, we will base a new Image on another existing one. It simplifies stuff a lot. In this case, we will use 'node:14'. This image comes with NodeJS version 14 LTS and npm installed. It will be taken from [Docker Hub](https://hub.docker.com/_/node) during the build process.
154+
155+
```dockerfile
156+
WORKDIR /usr/src/app
157+
```
158+
159+
Next, we set a working directory for any following Docker instructions. Later we will copy our NodeJs application there. It will be created on the container filesystem if not exists.
160+
161+
```dockerfile
162+
COPY package*.json ./
163+
164+
RUN npm install
165+
```
166+
167+
In the two following lines, we will install dependencies. First, we copy a package.json and package-lock.json (notice a wildcard \*). What interesting is we are not going to copy all project files. It is because we want to take benefit of **cached Docker layers**.
168+
169+
```dockerfile
170+
COPY . .
171+
```
172+
173+
After that, we want to copy our application source files to the container filesystem.
174+
The first param stands for source. In this case, a dot means a folder containing Dockerfile.
175+
The second is a destination inside the container filesystem. In this case, a dot means a WORKDIR that we set up before.
176+
177+
```dockerfile
178+
EXPOSE 3000
179+
```
180+
181+
Our NesjJs API is bind to port 3000. The EXPOSE instruction informs Docker that the container listens on that port at runtime.
182+
183+
```dockerfile
184+
CMD [ "npm", "run", "start" ]
185+
```
186+
187+
Finally, we will run API by triggering _npm run start_.
188+
The template for providing this instruction is like that:
189+
190+
```bash
191+
CMD ["executable","param1","param2"]
192+
```
193+
194+
## 3. Buil an Image
195+
196+
Before we build, let create '.dockerignore' file
197+
198+
```bash
199+
# .dockerignore
200+
201+
node_modules
202+
npm-debug.log
203+
```
204+
205+
It will prevent our local modules and debug logs from being copied onto our Docker image.
206+
207+
Let's navigate the directory with our Dockerfile and run the following command to build the Docker image.
208+
The **-t** flag lets us tag our image, so it's easier to find later.
209+
210+
```bash
211+
$ docker build . -t nestjs-api
212+
```
213+
214+
Now we can list our new image:
215+
216+
```bash
217+
$ docker images
218+
219+
REPOSITORY TAG IMAGE ID CREATED SIZE
220+
nestjs-api latest cb53842aa908 8 seconds ago 1.17GB
221+
```
222+
223+
## 4. Run the Container
224+
225+
```bash
226+
$ docker run -p 3000:3000 -d nestjs-api
227+
```
228+
229+
The **-p** flag redirects a public port to a private port inside a container.
230+
We can also pass **-d** flag, and it will run the container in detached mode.
231+
We can then close the console leaving the container running in the background.
232+
233+
## Check whether container is running
234+
235+
```bash
236+
$ curl -i localhost:3000
237+
238+
HTTP/1.1 200 OK
239+
X-Powered-By: Express
240+
Content-Type: text/html; charset=utf-8
241+
Content-Length: 12
242+
ETag: W/"c-Lve95gjOVATpfV8EL5X4nxwjKHE"
243+
Date: Fri, 02 Jul 2021 23:20:06 GMT
244+
Connection: keep-alive
245+
Keep-Alive: timeout=5
246+
247+
Hello World!
248+
```
249+
250+
## Other Docker commands
251+
252+
#### List containers
253+
254+
```bash
255+
$ docker ps
256+
257+
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
258+
542cd674ae6b nestjs-api "docker-entrypoint.s…" 4 minutes ago Up 4 minutes 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp suspicious_goldwasser
259+
```
260+
261+
#### Prints a logs
262+
263+
```bash
264+
$ docker logs <container id>
265+
```
266+
267+
#### Stop the container
268+
269+
```bash
270+
$ docker stop <container id>
271+
```
272+
273+
#### Go inside running container
274+
275+
```bash
276+
$ docker exec -it <container id> /bin/bash
277+
```
278+
279+
## Deploying on AWS EC2
280+
281+
Now we will see all the beauty of Docker:
282+
We can run our dockerized NestJs API on AWS EC2 in the same way as locally.
283+
284+
First login to AWS EC2.
285+
286+
If you haven't yet created any EC2 check [this](/post/deploy-nodejs-api-on-aws-ec2) article.
287+
288+
After connected via SSH, let install first a docker:
289+
290+
```bash
291+
$ sudo apt install docker.io
292+
```
293+
294+
Let's double-check installation:
295+
296+
```bash
297+
$ sudo docker version
298+
```
299+
300+
Clone NestJs API from git and change branch 'docker':
301+
302+
```bash
303+
$ git clone https://github.com/WojciechCendrzak/nestjs-api
304+
$ cd nestjs-api
305+
$ git branch -a
306+
$ git checkout remotes/origin/docker
307+
```
308+
309+
Build and run the container:
310+
311+
```bash
312+
$ sudo docker build . -t nestjs-api
313+
$ sudo docker run -p 3000:3000 -d nestjs-api
314+
```
315+
316+
Finally, we can check whether it's alive from a local machine:
317+
318+
```bash
319+
$ curl -i http://ec2-100-24-242-27.compute-1.amazonaws.com:3000
320+
```
321+
322+
Thanks for reading.

src/content/deploy-nodejs-api-to-aws-ec2.md renamed to src/content/deploy-nodejs-api-on-aws-ec2.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
---
2-
title: 'How to deploy NodeJs API to AWS EC2'
2+
title: 'Deploy NodeJs API on AWS EC2'
33
date: '2021-06-29'
44
author: 'Wojciech Cendrzak'
55
image: '/images/nodejs-ec2.png'
66
tags: 'devops, nodejs, aws'
77
isPublished: true
8+
includeReferences: deploy-nodejs-api-series-section
89
---
910

10-
In this article, we'll cover how to deploy a simply NodeJs API to AWS EC2. To ensure everything works fine, we will try to access it from the browser.
11+
In this article, we'll cover how to deploy a simply NodeJs API on AWS EC2. To ensure everything works fine, we will try to access it from the browser.
12+
{{deploy-nodejs-api-series-section}}
1113

1214
## NodeJS server
1315

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Note that this article is part of series about deploying application to the cloud:
2+
3+
- [Part 1 - Deploy NodeJs API on AWS EC2](/post/deploy-nodejs-api-on-aws-ec2)
4+
- [Part 2 - Deploy NodeJs API on AWS EC2 with docker](/post/deploy-nodejs-api-on-aws-ec2-with-docker)

0 commit comments

Comments
 (0)