Welcome Devs to the world of DevOps and Cloud computing. Today, we are diving into an exciting Next.js project—we’ll be deploying a Book reader app using a Docker container. This setup will be hosted on AWS, the most popular cloud provider. We’ll create an EC2 instance as our host machine, build a Docker image of the app, and run it in a container. This beginner-friendly guide will help you understand Docker’s utility. So, without further ado, let’s get started!

Prerequisites

Before we start building and deploying the project, we need to ensure we have the following requirements met:

After ensuring the above requirements are met, we can start with the project.

Step 1: Setting Up the EC2 Instance

We will start the project by creating the Ec2 instance from the Ec2 dashboard. This will act as our host machine for the project.

1. Launching the EC2 Instance:

2. Connecting to the EC2 Instance:

ssh -i <your-key.pem> ubuntu@<public-ip-address-of-instance>


Important: If you created a new key pair, set the correct permissions:

chmod 400 <your-key.pem>

Step 2: Installing Docker, Node.js, and NPM

To install the required tools like Docker, node js and NPm, use the following commands:

sudo apt update -y

sudo apt install -y docker.io

sudo systemctl enable --now docker

sudo usermod -aG docker $USER && newgrp docker

sudo apt install -y node npm

Verify the installations:

docker --version

node -v

npm -v

If you see the version numbers, you’re all set!

Step 3: Cloning the repo and running the Project

After setting up the host machine, we will clone the code from the github repo. I have hosted the code on application on Github repo to save some time.

  1. Clone the GitHub Repository:

    First, clone the Book Reader App repository using Git:

    https://github.com/rajudandigam/book-website-nextjs-app.git

  2. Navigate to the Project Directory:

cd book-website-nextjs-app

  1. Install the Required Packages:

npm install

  1. Start the Application in Development Mode:

npm run dev

Step 4: Open Port 3000 in the Security Group

Since Next.js application runs on port 3000, we need to allow port 3000 in the inbound rules of our security group that is attached to the instance, For that follow the steps below:

Now, you should be able to access the app using:

http://<public-ip-address>:3000

Step 5: Understanding the Dockerfile

The application code contains the Dockerfile for the project, it is a multi-stage docker file that is efficient in size and performance, a brief explanation of the dockerfile is provided below:

# Stage 1: Build Stage
FROM node:20-alpine AS builder

WORKDIR /app

# Install dependencies separately for caching
COPY package*.json ./
RUN npm install

# Copy the rest of the app
COPY . .

# Build the Next.js app
RUN npm run build

# Install only production dependencies
RUN npm ci --only=production

🧱 Build Stage:

# Stage 2: Production Stage
FROM node:20-alpine AS runner

WORKDIR /app

# Copy the built app from the build stage
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/public ./public
COPY --from=builder /app/next.config.js ./next.config.js

ENV NODE_ENV=production

EXPOSE 3000

CMD ["npm", "run", "start"]

🚀 Production Stage:

Step 6: Building and Running the Docker Container

  1. Build the Docker Image:

    We will build the docker image using the following command:

    docker build -t book-read-app:v1

This will create a Docker image named book-read-app with the v1 tag.

2. Run the Docker Container:

To run a container of the application, use the following command

docker run -d -p 3000:3000 book-read-app:v1

The -d flag runs the container in detached mode, and the -p flag maps port 3000 of the container to port 3000 of the EC2 instance.

Step 7: Accessing the Application

http://<public-ip-address>:3000

💡 Conclusion

And there you have it, folks! We've successfully deployed our Book Reader App on an AWS EC2 instance, containerized it using Docker, and followed best practices with a multi-stage Dockerfile. By going through this project, we’ve not only sharpened our skills with Next.js and Docker but also got hands-on experience with cloud computing using AWS.

This journey demonstrates how powerful containerization can be in making our applications more portable, scalable, and easy to manage. Plus, running the app inside a Docker container ensures a consistent environment, whether on a local machine or in the cloud.

We hope this tutorial helped you gain confidence in building and deploying applications on the cloud. If you encounter any challenges or if you have more ideas to make this project even cooler, don’t hesitate to drop your thoughts in the comments!