Hello Everyone!
Deploying a web application is a challenging task (at least for me), especially when it comes to keeping it updated. It can take up a lot of time and energy if it has to be deployed manually every time a change is made. But I recently discovered a way to automate the deployment process for the Next.js app using AWS CodeDeploy and CodePipeline. It made my life so much easier, and I’m excited to share it with you.
In this blog, I’ll guide you through the process of setting up auto-deployment for your Next.js app using AWS services such as CodePipeline and CodeDeploy. By the end of it, you’ll be able to save a lot of time by deploying your app automatically every time you push the code.
Let’s get started!
Table of Contents
Prerequisites
- EC2 Machine running Ubuntu
- Very basic knowledge of EC2 and IAM AWS Services
How to deploy the Next.js app to AWS EC2
To start simple, let’s manually deploy the sample Next.js boilerplate app “hello-world” to EC2. The steps are almost the same for all Next.js applications.
Login to EC2
Login to the EC2 machine which you’ve created using the below command
ssh -i /path/key-pair-name.pem instance-user-name@instance-IP-address
When you try to log in to EC2, this is the common error that most people will encounter (including me).
This error describes that the .pem
should be read-protected. Only the root user should be able to read it. So, you have to set the file permission to 400
. Run the following command to achieve that.
chmod 400 key-pair-name.pem
EC2 by default come with no software installed. Once you logged into EC2, install NodeJS. There’s an excellent article published by Digital Ocean and I use it every time I have to install NodeJS on the server.
I have uploaded the boilerplate repo to Github. You can clone the repo by running the following command.
git clone https://github.com/5minslearn/deploy_nextjs_app.git
Navigate to the project repo and install the project dependencies by running the below commands.
A Quick note here. I’m a big fan of yarn for its lightning-fast dependency management. But I see most people use npm
to manage their dependencies. If you like to use npm
, you can replace yarn install
with npm install
in the below commands.
If you like to go with yarn
, install yarn by following this tutorial first.
cd deploy_nextjs_app
yarn install
Let’s run the Application.
yarn dev
Hit “http://ec2-public-ip-address:3000/” on your browser and you should be able to see the following page.
There’s another common issue that most people face here.
How to fix timeout error (EC2)
“Oh, My God!!! My site is loading for a long time and finally, it’s throwing a timeout error. What could be the issue? Where did I made mistake?”
If this happens to you, then you can follow the below steps to fix that.
This issue basically occurs if your server does not expose port 3000. Remember people, by default NextJS app, will be running on port 3000. But, you have to allow port 3000 from the Security Group of your EC2 console to access from your browser.
Login to your AWS console, select your EC2 instance and then select the Security group option. Click on the “Edit inbound rules” button. Add port 3000 to the list as shown in the below screenshot. Then hit the “Save rules” button.
Visit the link “http://ec2-public-ip-address:3000/”, and you’ll be amazed to see your page loaded like magic.
So far, we just ran our app in development mode and verified that it’s working.
Run Next.js App in Production Mode
To deploy the app in Production Mode, you have to build your app first. Run yarn build
to build the app and yarn start
to start the app in production mode.
yarn build
yarn start
Hit “http://ec2-public-ip-address:3000/” again and this time you’ll note that your app loads faster than earlier.
Because the apps running in Production mode will always be faster when compared to the ones running in Development mode. And the reason for it is, the Production apps will be optimized for performance.
How to run Next.js app forever when console is closed?
So, you have your app running now. You could notice that it’s blocking you from closing your terminal and exiting from server connection. If you do so, your site will be down. That’s where PM2 comes to play. Basically, PM2 is a process manager that helps to keep NodeJS applications alive all the time. It runs in the background managing NodeJS applications for you.
Install PM2 using the following command
sudo yarn global add pm2
After PM2 installation, run the below command to run and manage your app in the background.
pm2 start yarn --name [name-of-your-app] -- start -p [port-number]
Replace [name-of-your-app]
with your app name and [port-number]
with 3000. Here’s an example command,
pm2 start yarn --name next_hello_world_app -- start -p 3000
Hit “http://ec2-public-ip-address:3000/” and you’ll again be amazed to see your app is up and running.
It’s always a best practice to save the PM2 process. When you reboot your instance, your PM2 instances will be lost. In order to restore it to its old state, you have to save the PM2 process. Here’s the command for that.
pm2 save
Here’s the command to restore your PM2 instances.
pm2 resurrect
We have successfully deployed the Next.js app manually. But remember, every time you make a code change and want to see them on your site, you have to login into EC2, pull the latest changes, build the app, and restart the app. This will consume plenty of time and I’m super lazy to do this. Let’s automate this in the next step!
Before setting up automatic deployment you have to have a knowledge of CodeDeploy.
CodeDeploy
CodeDeploy is used to deploy our application automatically to any number of EC2 instances. We need to get ready with two items before beginning this.
- CodeDeploy Agent must be installed in EC2 instance – It is used to continuously poll CodeDeploy and deploy if anything is available
- A file called
appspec.yml
must be present in the root folder – This file describes the steps to be followed for the deployment
There is awesome documentation by AWS to install CodeDeploy Agent. Please follow each and every step in the documentation to install CodeDeploy Agent on your EC2 machine.
To verify CodeDeploy agent is installed run the below command. If you see active (running) Kudos to you! CodeDeploy was installed successfully!
sudo service codedeploy-agent status
Now let’s create the appspec.yml
file. I’ve written the deployment instructions in deploy.sh
file. It’s enough to run the file in appspec.yml
file. If you want to learn more about appspec.yml
check out AWS official documentation
Create a file called appspec.yml
and add the following contents
version: 0.0
os: linux
hooks:
ApplicationStart:
- location: deploy.sh
timeout: 300
runas: ubuntu
I hope you understand the instruction in the above file. If not, here’s a super simple explanation. I’m advising the CodeDeploy Agent that I’m running a Linux OS in my instance and instructing it to run the deploy.sh
file as ubuntu
user with the timeout being 300 seconds.
Here’s my deploy.sh
file.
#!/bin/bash
cd /path/to/project/on/EC2
git pull origin master
yarn install &&
yarn build &&
pm2 restart [name]
This file contains instructions to navigate to the project folder on EC2, pull the latest code from source control, install dependencies, build the project, and restart the project instance.
Commit these files and push them to Git. Now it’s time to set up automatic deployment.
How to setup auto deployment using CodePipeline and CodeDeploy
Two IAM roles have to be created to set up auto-deployment. Some complications will begin from here. To make things simple, I’ve attached screenshots with the appropriate items highlighted with red boxes.
Create IAM Role for CodeDeploy
Navigate to IAM in AWS Console by searching on the search bar at the top. Click Roles on the left pane and Click Create role button at the top right.
Choose AWS service in Trusted entity types and choose CodeDeploy in Use cases and proceed to the next step.
Now, you can see AWSCodeDeployRole policy is the only policy available, and it’ll be chosen by default in this (Permissions) step. Let’s proceed to the next section.
Enter a name for your IAM role. It’s advised to choose a meaningful name to identify this in the future. I’m calling it service-role-for-code-deploy. Review the permission in the JSON and Click Create role button at the bottom.
Create IAM role for EC2
Let’s create the next role. This role is for EC2. Choose AWS service in the Trusted entity type, EC2 in the Common use cases section and choose CodeDeploy in Use cases for other AWS services. Click Next to proceed to the next section.
There are lot of policies available for EC2 and CodeDeploy. In the Add permissions section, search for codedeploy (No space between code and deploy) and select “AmazonEC2RoleForCodeDeploy” and proceed to the next step.
No change in this step. Review and give a meaningful name for your role and click Create role button.
How to Attach the IAM role to EC2
Once the IAM role for EC2 is created, we have to attach it to the EC2 instance.
To attach the IAM role to the EC2 instance, open your EC2 instance, click on the “Actions” button on the top right and select “Security” in the drop-down, then select “Modify IAM role”.
Select the IAM role which you created last and click the “Update IAM role” button. Reboot the EC2 for the changes to take effect.
After rebooting the EC2, login to EC2 with SSH and run pm2 resurrect
command to restore the pm2 processes. Missing to do this may land you at “PM2 Process or Namespace not found error”.
How to create CodeDeploy Application
In the AWS Console, search “CodeDeploy” in the search bar at the top. Select “Applications” in the left pane. Click on the “Create application” button on the top right.
Enter the Application name, choose the “EC2/On-premises” compute platform, and click the “Create application” button.
Once it’s done, you’ll automatically be redirected to the Deployment groups section. We have to create a deployment group. Click on the “Create deployment group” button.
Enter the deployment group name, select the service role (1st created role) you created, and select the deployment type as In-place
In the Environment configuration section, select “Amazon EC2 instances” and select the key as Name, enter your EC2 instance name in the value.
In the Agent configuration section, select Never, as we installed CodeDeployAgent already. Select “CodeDeployDefault.AllAtOnce” in the Deployment settings section. Leave the “Enable load balancing” checkbox unchecked. Finally, click Create a deployment group button.
CodePipeline
AWS CodePipeline helps you to automate your release pipelines for fast and reliable application and infrastructure updates. Now it’s time to create CodePipeline. In the AWS Console, search for “CodePipeline” in the search bar.
Select “Pipelines” in the left pane and click on “Create pipeline” button.
Enter the Pipeline name, and enter the Role name. Remember, we created a Role for EC2 and CodeDeploy and not for CodePipeline. AWS by default creates it from here and we have to enter the Role name.
Add Source Stage
We have to connect our repo with CodePipeline to deploy the changes immediately after the code is pushed.
We’ll be using GitHub as our source. The next step is to add a GitHub repo to CodePipeline. Choose GitHub(version 2) in the source provider, and click on the “Connect to GitHub” button, which will open up a new pop-up window, click the “Connect to GitHub” button.
This will take you to the GitHub authorization page where you have to sign into your GitHub account, and click the “Install a new app” button.
Choose “Only select repositories” and choose your repository below that.
Once installed it will prompt you for the password. Click the “Connect” button once you’re done with your authentication.
After connecting to GitHub, select the Repository name and branch name. To start the CodePipline on code change, it’s important to select the check box “Start the pipeline on source code change” otherwise auto deployment will not happen. For “Output and artifact format”, select “CodePipeline default” and click the “Next” button.
The next step is to add the build stage, since we’re deploying a simple app we don’t need a build stage. If you want me to write about CodeBuild let me know. I will cover it in my upcoming blogs, but for now, let’s keep things simple and simply skip the build stage.
Add deploy Stage
In the deployment stage, choose “AWS CodeDeploy” for the “Deploy provider” and select the region where you created the above CodeDeploy application. Then select the “Application name” and “Deployment group” that we created in the previous steps and click the “Next” button.
The last step is “Review”. Review everything carefully and click on the “Create pipeline” button. Once the pipeline is created it will start the deployment process. If you followed all the above steps the pipeline should be “Succeeded” on your very first build.
Verifying Auto Deployment
Now let’s verify if the Auto-deployment works properly. This is the Home page of our project.
Let’s change the text from “Hello World” to “Welcome to 5minslearn” and push the code to GitHub.
Here we go!!! The CodePipeline has triggered automatically and the changes are successfully deployed.
Now head to “http://ec2-public-ip-address:3000/”, you will see the below page.
Congrats! 🎉 We successfully completed setting up the auto-deployment for Next.js app.
Conclusion
In this article, we learned how to deploy Next.js manually on EC2 and set up auto-deployment using AWS services such as CodeDeploy and CodePipeline.
Hope you enjoyed reading this article! If you are stuck at any point feel free to drop your queries to me at my email. I’ll be happy to help you!
If you wish to learn more about AWS, subscribe to my newsletter by entering your email address in the below box.
Have a look at my site which has a consolidated list of all my blogs.