Hello everyone, today we will create a simple NodeJS application, create a Docker image from it, store it under ECR and use that image to serve an application with Docker.
On my computer I created a simple Node Express application which sends basic json data as a response.
//index.js
const express = require("express");
const app = express();
const port = 3000;
app.get("/", (req, res) => {
res.json({"success": true, "data": "hello world"});
});
app.listen(port, () => {
console.log("Listening on port 3000");
});
Let’s create a Dockerfile and .dockerignore
# Dockerfile
FROM node:16
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./
RUN npm install
# If you are building your code for production
# RUN npm ci --only=production
# Bundle app source
COPY . .
EXPOSE 3000
CMD [ "node", "index.js" ]
# .dockerignore
node_modules
npm-debug.log
.dockerignore prevents your local modules and debug logs from being copied onto your Docker image.
Finally we will build the Docker image. Beware that in order to build the image you need your Docker instance up and running
docker build . -t node-docker-app
When the build is done you can check if the image is there by entering the docker images
command
REPOSITORY TAG IMAGE ID CREATED SIZE
node-docker-app latest f79101f16617 33 seconds ago 919MB
First we will test if the image is working just fine by typing
docker run -p 3000:3000 -d node-docker-app
This will start the app and you can confirm it by typing docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
44e119eaaa85 node-docker-app "docker-entrypoint.s…" 8 minutes ago Up 8 minutes 0.0.0.0:3000->3000/tcp, 8080/tcp ding_dong
Now when you visit localhost:3000
in the browser you will see the json response.
First you need to navigate to your AWS management console and create a repository on ECR
After creating your repository, you need to configure your aws credentials in order to push ECR. You can simply type aws configure
and follow the steps or you can edit the files :
~/.aws/credentials
on Linux, macOS, or UnixC:\Users\USERNAME\.aws\credentials
on Windows[default]aws_access_key_id = your_access_key_id
aws_secret_access_key = your_secret_access_key
After the configuration we need to retrieve a token and authenticate our Docker client by typing the following command aws ecr get-login-password --region eu-central-1 | docker login --username AWS --password-stdin <image_uri>
you can find your image URI just like in the image below.
After you see Login Succeeded
message you can tag your image with the command docker tag node-docker-app:latest <image_uri>:<tag>
. You can name the tag whatever you like but latest
is just fine.
Finally to push the image you can use docker push <image_uri>:<tag>
The push refers to repository [12345678.dkr.ecr.eu-central-1.amazonaws.com/node-docker-app]
1b619aaf1ebd: Pushed
e30ed1581a5e: Pushed
e74cb2ef12d0: Pushed
219742f14735: Pushed
630cfb4ef1b4: Pushed
baa7d1140933: Pushed
ac3ca0266e42: Pushed
ba72cf902ea2: Pushed
34d4a130d4f6: Pushed
9dfd4aa4568a: Pushed
afa8cfa38e8c: Pushed
7a023423c8b3: Pushed
f0a234338d2a: Pushed
latest: digest: sha256:f5d7ed23423424323495d29de2f1effab2cd12313123a91521825b1 size: 3050
First make sure that your server has Docker and aws-cli installed. If not you can navigate to https://docs.docker.com/engine/install/ and follow the instructions.
In order to pull the image we will use the command docker pull egistry/repository[:tag]
. You can easily copy the uri from the ECR management dashboard and append it to docker pull
After pulling the image verify it with the command docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
.../node-docker-app latest f7123129f33217 15 hours ago 919MB
Now run the image with the command
docker run -p 3000:3000 -d <image>
This will run the application in port 3000 and we can confirm it with running docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9eafd1227fe86 .../node-docker-app "docker-entrypoint.s…" 5 seconds ago Up 3 seconds 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp, 8080/tcp ping_pong
We need reverse proxy server configuration for hosting our application. I use nginx in this example.
# /etc/nginx/sites-available/domain.com
server {
listen 80;
listen [::]:80;
root /var/www/your_domain/html;
index index.html index.htm index.nginx-debian.html;
server_name domain.com www.domain.com;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Finally when you visit the url from the browser you will see the application running and returning our json.
Follow me on Instagram, Facebook or Twitter if you like to keep posted about tutorials, tips and experiences from my side.
You can support me from Patreon, Github Sponsors, Ko-fi or Buy me a coffee