Project Report: Containerization of a javascript application, pushing it in private ECR and deploying it in development server
1. Introduction
This project aims to containerize a Node.js application, its associated MongoDB database, and deploy them using Docker. The application will be deployed on a development server, and the Docker images will be stored in a private Amazon Elastic Container Registry (ECR). The report will provide a step-by-step guide from the initial setup to containerization and deployment.
2. Project Setup
Set up an AWS EC2 instance or any development server where you will deploy the application.
Install Docker on the EC2 instance following the appropriate instructions for your operating system.
Clone the Node.js application repository from the GitHub repository to your EC2 instance:
git clone https://github.com/your-github-username/your-nodejs-app.git
Replace "your-github-username" and "your-nodejs-app" with the actual GitHub repository URL of your Node.js application.
3. Pulling MongoDB and mongo-express Images:
- Pull the MongoDB and mongo-express images from Docker Hub using the following commands:
docker pull mongo
docker pull mongo-express
4.Creating a Docker network:
Create a docker network naming "mongo-network" to allow communication between the MongoDB and mongo-express containers
docker network create mongo-network
5. MongoDB and mongo-expressContainerization
docker run -d --name mongodb -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=adminpassword --network docker-network -p 27017:27017 mongo:latest
Explanation:
The
-e
flag is used to set environmental variables. Here, we set the root username to "admin" and the root password to "adminpassword" for MongoDB initialization.The
-p
flag maps port 27017 from the container to port 27017 on the host machine, allowing access to the MongoDB service.
MongoDB Express (mongo-express) Containerization: Run a MongoDB Express container connected to the "docker-network" using the following command:
docker run -d --name mongo-express -e ME_CONFIG_MONGODB_SERVER=mongodb -e ME_CONFIG_MONGODB_ADMINUSERNAME=admin -e ME_CONFIG_MONGODB_ADMINPASSWORD=adminpassword --network docker-network -p 8081:8081 mongo-express:latest
Explanation:
The
-e
flag sets environmental variables for the MongoDB Express container. We specify the MongoDB server ("mongodb"), along with the root username and password for authentication.The
-p
flag maps port 8081 from the container to port 8081 on the host machine, enabling access to the MongoDB Express web interface.
6. Docker Compose for Multi-Container Deployment:
Now that we have individual Docker run commands for each container, we can simplify the management of these containers using Docker Compose. Docker Compose allows us to define and run multi-container applications with a single YAML file.
Step 6.1: Create docker-compose.yaml
In the project's root directory, create a file named docker-compose.yaml
with the following content:
version: '3'
services:
mongodb:
image: mongo:latest
container_name: mongodb
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: adminpassword
ports:
- "27017:27017"
networks:
- docker-network
mongo-express:
image: mongo-express:latest
container_name: mongo-express
environment:
ME_CONFIG_MONGODB_SERVER: mongodb
ME_CONFIG_MONGODB_ADMINUSERNAME: admin
ME_CONFIG_MONGODB_ADMINPASSWORD: adminpassword
ports:
- "8081:8081"
networks:
- docker-network
networks:
docker-network:
driver: bridge
Step 6.2: Running with Docker Compose
With the docker-compose.yaml
file in place, you can now start all the containers with a single command:
docker-compose -f docker-compose.yaml up -d
Explanation:
The
docker-compose -f docker-compose.yaml up
command reads thedocker-compose.yaml
file and starts all defined services.The
-d
flag runs the containers in detached mode, allowing them to run in the background.
Step 6.3: Stopping Containers
To stop and remove the containers created by Docker Compose, use the following command:
docker-compose -f docker-compose.yaml down
This will gracefully stop and remove all the containers defined in the docker-compose.yaml
file.
7. Creating a Dockerfile:
A Dockerfile serves as a blueprint for building Docker images. We created a Dockerfile for the Node.js application that specifies the base Node.js image, sets environment variables for MongoDB credentials, and copies the application code into the container. Additionally, the Dockerfile installs application dependencies and starts the application using the server.js file.
FROM node:13-alpine
ENV MONGO_DB_USERNAME=admin \
MONGO_DB_PWD=password
RUN mkdir -p /home/app
COPY ./app /home/app
WORKDIR /home/app
RUN npm install
CMD ["node", "server.js"]
8. Node.js Application Containerization and Connection to MongoDB:
Provided Dockerfile
for the Node.js application, we will proceed with the containerization and connection to the MongoDB database.
Step 8.1: Dockerfile for Node.js Application:
Here's the Dockerfile
:
# Use the official Node.js base image
FROM node:13-alpine
# Set environmental variables for MongoDB credentials
ENV MONGO_DB_USERNAME=admin \
MONGO_DB_PWD=password
# Create a directory for the Node.js application inside the container
RUN mkdir -p /home/app
# Copy the contents of the local "app" directory into the container's app directory
COPY ./app /home/app
# Set the working directory to /home/app so that subsequent commands execute in this directory
WORKDIR /home/app
# Install Node.js dependencies using npm
RUN npm install
# Start the Node.js application using the "server.js" file in the /home/app directory
CMD ["node", "server.js"]
Step 8.2: Building and Running the Node.js Application Container:
Assuming you have your Node.js application files and the Dockerfile
in the same directory, we will build the Docker image and run the Node.js application container connected to the MongoDB container through the docker-network
.
Open a terminal, navigate to the directory containing the
Dockerfile
and Node.js application code.Build the Docker image for your Node.js application using the following command:
docker build -t nodejs-app -f Dockerfile .
- After successfully building the image, you can run the Node.js application container and connect it to the MongoDB container through the
docker-network
:
docker run -d --name nodejs-container -e MONGO_URL=mongodb://mongodb:27017/your-database-name --network docker-network -p 3000:3000 nodejs-app
Explanation:
The
-e
flag sets theMONGO_URL
environment variable inside the Node.js application container to specify the connection URL for MongoDB. Replaceyour-database-name
with the name of your MongoDB database.The
-p
flag maps port 3000 from the container to port 3000 on the host machine, allowing access to the Node.js application.
Step 8.3: Verify the Connection:
To verify that the Node.js application is successfully connected to the MongoDB database, access your Node.js application in a web browser or use tools like curl
or Postman to interact with the application's API endpoints.
Example API Endpoint in server.js
:
const express = require('express');
const app = express();
const mongoose = require('mongoose');
const mongoUrl = process.env.MONGO_URL || 'mongodb://localhost:27017/mydb';
mongoose.connect(mongoUrl, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => {
console.log('Connected to MongoDB successfully!');
})
.catch((error) => {
console.error('Error connecting to MongoDB:', error);
});
// Define your API routes and other application logic here
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
8. Building Docker Image for the Node.js Application:
With the Dockerfile ready, you can proceed to build the Docker image for your Node.js application. The image will be named "my-app" with the tag "1.0".
Step 8.1: Build Docker Image
Open a terminal or command prompt.
Navigate to the directory containing your Node.js application files and the
Dockerfile
.Use the following command to build the Docker image:
docker build -t my-app:1.0 -f Dockerfile .
Explanation:
docker build
: This command is used to build a Docker image from a specified Dockerfile.-t my-app:1.0
: The-t
flag tags the built image with the name "my-app" and the version "1.0".-f Dockerfile
: The-f
flag specifies the path to the Dockerfile. In this case, it's in the current directory (denoted by the dot.
).
Step 8.2: Verify the Built Image
After the build process completes, you can verify that the image "my-app" with the tag "1.0" is present in your Docker environment by running:
docker images
You should see the newly built image listed among your Docker images.
9. Running the "my-app:1.0" Container and Verifying Application Environment:
Now that you have built the Docker image for your Node.js application, it's time to run the container and verify that the application starts successfully and the environment is configured properly.
Step 9.1: Run the Container
Use the following command to run the "my-app:1.0" container:
docker run -d --name my-app-container -e MONGO_URL=mongodb://mongodb:27017/your-database-name --network docker-network -p 3000:3000 my-app:1.0
Explanation:
The
-d
flag runs the container in detached mode, allowing it to run in the background.The
--name my-app-container
option specifies the name of the container as "my-app-container".The
-e
flag sets theMONGO_URL
environment variable inside the container to specify the connection URL for MongoDB. Replaceyour-database-name
with the name of your MongoDB database.The
-p
flag maps port 3000 from the container to port 3000 on the host machine, allowing access to the Node.js application.Step 9.2: Verify Application and Environment
- Check if the "my-app-container" is running using the following command:
docker ps
Access your Node.js application in a web browser using
localhost:3000
or use tools likecurl
or Postman to interact with the application's API endpoints.Ensure that the application behaves as expected and shows signs of successful initialization, such as logging indicating a successful MongoDB connection.
Verify that the environment variables, including
MONGO_DB_USERNAME
,MONGO_DB_PWD
, andMONGO_URL
, are correctly applied within the container. For example, you can log these variables in your Node.js application to verify their values:
console.log("MONGO_DB_USERNAME:", process.env.MONGO_DB_USERNAME);
console.log("MONGO_DB_PWD:", process.env.MONGO_DB_PWD);
console.log("MONGO_URL:", process.env.MONGO_URL);
10. Pushing Docker Image to AWS ECR:
With the Node.js application containerized and successfully running, we will proceed to push the Docker image to the private Amazon Elastic Container Registry (ECR) for secure storage.
Step 10.1: Authenticate Docker with AWS ECR
Before pushing the Docker image, you need to authenticate Docker with your AWS ECR registry. Follow these steps:
Open a terminal or command prompt on your local machine.
Run the following command to authenticate Docker with your AWS ECR registry:
aws ecr get-login-password --region your-aws-region | docker login --username AWS --password-stdin your-aws-account-id.dkr.ecr.your-aws-region.amazonaws.com
Replace:
your-aws-region
with the AWS region where your ECR repository is located (e.g.,us-east-1
).your-aws-account-id
with your AWS account ID.
This command retrieves the login credentials for your ECR registry and uses them to authenticate Docker.
Step 10.2: Tag the Docker Image
Next, you need to tag your Docker image with the ECR repository URI. Use the following command:
docker tag my-app:1.0 your-aws-account-id.dkr.ecr.your-aws-region.amazonaws.com/my-app-repo:1.0
Replace:
your-aws-region
with the AWS region where your ECR repository is located.your-aws-account-id
with your AWS account ID.my-app-repo
with the name of your ECR repository.
This command tags the "my-app:1.0" Docker image with the ECR repository URI.
Step 10.3: Push the Docker Image
Now, you can push the Docker image to your AWS ECR repository:
docker push your-aws-account-id.dkr.ecr.your-aws-region.amazonaws.com/my-app-repo:1.0
Replace:
your-aws-region
with the AWS region where your ECR repository is located.your-aws-account-id
with your AWS account ID.my-app-repo
with the name of your ECR repository.
This command pushes the "my-app:1.0" Docker image to your private AWS ECR repository.
Step 10.4: Verify Image in ECR
You can verify that the Docker image has been successfully pushed to your ECR repository by checking the AWS Management Console for ECR. Alternatively, you can use the AWS CLI:
aws ecr describe-images --repository-name my-app-repo --region your-aws-region
Replace:
your-aws-region
with the AWS region where your ECR repository is located.my-app-repo
with the name of your ECR repository.
This command will display information about the images in your ECR repository, including the "my-app:1.0" image.
11. Deploying Docker Compose with Private Image from AWS ECR:
With the Docker image successfully pushed to your private AWS ECR repository, we can now deploy the application using the Docker Compose file, which references the private image.
Step 11.1: Configure Docker Compose File
In your existing Docker Compose file, uncomment and modify the "my-app" service to use the private image from AWS ECR. Update the service configuration as follows:
version: '3'
services:
my-app:
image: your-aws-account-id.dkr.ecr.your-aws-region.amazonaws.com/my-app-repo:1.0
ports:
- 3000:3000
environment:
- MONGO_URL=mongodb://mongodb:27017/your-database-name
depends_on:
- mongodb
- mongo-express
mongodb:
image: mongo
ports:
- 27017:27017
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=password
volumes:
- mongo-data:/data/db
mongo-express:
image: mongo-express
restart: always
ports:
- 8080:8081
environment:
- ME_CONFIG_MONGODB_ADMINUSERNAME=admin
- ME_CONFIG
Replace:
your-aws-region
with the AWS region where your ECR repository is located.your-aws-account-id
with your AWS account ID.my-app-repo
with the name of your ECR repository.your-database-name
with the name of your MongoDB database.
Step 11.2: Deploy Docker Compose
Copy the updated Docker Compose file to your development server.
Open a terminal on the development server and navigate to the directory containing the Docker Compose file.
Run the following command to deploy your application:
docker-compose up -d
The -d
flag runs the containers in detached mode, allowing them to run in the background.
Step 11.3: Verify Deployment
Once the Docker Compose deployment is complete, you can verify that your application is running on the development server.
- Check the status of the containers to ensure they are running:
docker-compose ps
- Access your Node.js application in a web browser using
http://your-server-ip:3000
. Ensure that the application behaves as expected and interacts with MongoDB correctly.
Conclusion:
By deploying your Docker Compose file with the private image from AWS ECR, you have successfully deployed your application on the development server. The Docker Compose file orchestrates the containers and allows them to communicate with each other using the specified configurations.
This step completes the deployment process, and your application should now be accessible and running on the development server.
LINKS:
Github Repo: https://github.com/itspsycho07/my-app-demo
Private ECR:
It is seen that the image is been successfully pushed in my private ECR and is displayed with its tag.