From Code to the Cloud: A Step-by-Step Guide to Deploying Your Node.js App on AWS EC2
Tags: aws, node, beginners, programming
Published: 2023-10-16 06:04:50


##### Introduction
In this article, we will deploy a nodejs express app to ec2. We will also add SSL and Nginx in the next article.

**Let's dive in** ![imh](https://media.giphy.com/media/aF3sxYuPo3gNeksFyz/giphy.gif)

&nbsp;

##### Prerequisites
🎯 AWS account
🎯 Github account
🎯 Nodejs installed on your local machine
🎯 Git installed on your local machine
🎯 Basic knowledge of nodejs and express
🎯 Basic knowledge of git
🎯 Basic knowledge of ssh
🎯 Basic knowledge of linux commands

&nbsp;

##### ⏭️ Create a Nodejs express app
Run the following commands in your terminal

```bash
mkdir ec2
cd ec2
npm init -y
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6nxm5xrchgxeud5ulnjj.png)

The `-y` flag is to skip the questions and use the default values


##### ⏭️ Install the following packages
```bash
npm install express dotenv
```
✅ Express is a web framework for nodejs
✅ Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env. 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ejhen2o0in4n0ataxtr.png)



##### ⏭️ Confirm the installed packages in the package.json file
✅ `package.json` is the heart💖 of npm. It holds metadata relevant to the project and it is used to give information to npm that allows it to identify the project as well as handle the project's dependencies.
```json
{
  "name": "ec2",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "dotenv": "^16.3.1",
    "express": "^4.18.2"
  }
}
```

##### ⏭️ Write your start script
In essence, you can run `npm start` to start your server.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oa399mkuy7wq9drkn1ap.png)



##### ⏭️ Create a .env file
This is where we will store our environment variables. The environment variables are accessible through `process.env` object. We will use the `dotenv` package to load the environment variables from the `.env` file into `process.env` object.
```bash
touch .env
```

##### ⏭️ Add the following to the .env file
```bash
PORT=2323
```

##### ⏭️ Create a .gitignore file
This is where we will add the files we don't want to push to github. Preventing the `.env` file from being pushed to github is very important because it contains sensitive information like your database credentials, api keys, etc.
```bash
touch .gitignore
```

##### ⏭️ Add the following to the .gitignore file
```bash
node_modules
.env
```

##### ⏭️ Create app.js

```javascript
require('dotenv').config(); // load environment variables from .env file
const express = require('express');
const app = express();
const port = process.env.PORT || 3000; // default port is 3000

app.get('/', (req, res) => {
    return res.status(200).json({
        message: 'Hello World'
    });
});

app.listen(port, () => {
    console.log(`Server running on port ${port}`);
});
```

##### ⏭️ Start the server
Open your terminal and run the following command
```bash
npm start
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8tqgkcpebjdu8ga0zjlg.png)



##### ⏭️ Curl the server
Open another terminal and run the following command
```bash
curl localhost:2323
```

You should see the following
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qd2snrfxsl1vzmq722yx.png)

&nbsp;

##### ⏭️ Create a git repository
Now that we have our app running, let's create a git repository and push our code to github. Run the following commands in your terminal
```bash
git init
git add .
git commit -m "Initial commit"

```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1m4yi18ixq7k6s9ypuhz.png)



##### ⏭️ Create a new repository on github

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2yq1t6jh7wf3br4d7mg1.png)



##### ⏭️ I choose private because I don't want this code to be public

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kihwnznylh7id5q60izk.png)



##### ⏭️ Copy the code in the highlighted area and add to your terminal

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xl2n4icxotp0layw6r43.png)



##### ⏭️ You should see the following

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8dk3qsok2k0w65z4d9fg.png)



---

##### ⏭️ Now lets setup our ec2 instance
Login to your aws account and go to ec2

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c9hpcn6ryvvqmdoeffdb.png)



##### ⏭️ Choose EC2 from the list of services 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3s13fqtnlj0pw7i3p7zn.png)




##### ⏭️ Choose Launch Instance

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wcvbdft9pusrj4gdzlhs.png)



##### ⏭️ Choose Ubuntu Server 20.04 LTS (HVM), SSD Volume Type
Name your instance and click next

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nfgf0q4tzmav28xxsw9u.png)



##### ⏭️ Create a new key pair
A key pair consists of a public key that AWS stores and a private key file that you store. Together, they allow you to connect to your instance securely. 
⚠️ Ensure you note the location of the key pair

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p95weoxtmptoos4rfadi.png)



##### ⏭️ Network setting 
Tick the the three boxes and click next
- Allow ssh traffic: This allows you to connect to the instance using ssh
- Allow http traffic from internet: This allows you to access the instance from the browser over http (unsecure)
- Allow https traffic from internet: This allows you to access the instance from the browser over https (secure)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/31yq59eid6kfesq5nkom.png)



##### ⏭️ Review and launch

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mqdaqsefev0bhrrtdjaf.png)



##### ⏭️ Success
We have successfully created our ec2 instance. Click on the instance highlighted in green to view the details
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/42pmkzn44u5u5fvn0mqv.png)




##### ⏭️  Click on the instance Id to view the details

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/12q3wytgrfn8axudigwz.png)




##### ⏭️ Connecting to the ec2 instance using ssh
There are two ways to connect to the ec2 instance using ssh. You can either use the **browser** or use the **terminal**. 

_Method 1:_ Using the browser
Click on connect and follow the instructions

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tn40gf790c8sh5b24zbm.png)



##### ⏭️ Click the connect button

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/820ycmqhyi7mnar7ytms.png)



##### ⏭️ Change to root user
- Sudo: Super User Do; allows a user with proper permissions to execute a command as another user, such as the superuser.
- su: Switch User; allows you to switch to another user account without logging out of your current terminal session.

- the `-` flag is used to preserve the environment variables
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t4s6c24k8yl20z1rlyyx.png)



##### ⏭️ Install nvm
nvm is a version manager for nodejs. It allows you to install multiple versions of nodejs and switch between them easily.
```
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
```

##### ⏭️  Activate nvm
We need to activate nvm so that we can use it in the current terminal session
```
. ~/.nvm/nvm.sh
```

##### Install node
Install the latest version of node using nvm
```
nvm install node
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tsmi41ry92d4h97z6907.png)



##### ⏭️  Install git 
Git is need to clone the repo we created earlier
```
sudo apt-get update -y
sudo apt-get install git -y
```

⚠️ You can omit the sudo since you are already root. So just run
```
apt-get update -y
apt-get install git -y
```

##### ⏭️ Check if node is installed
We have the latest version of node installed
```
node -v
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rlkj68i2mdjro5yyqlda.png)



##### ⏭️ Check if git is installed
```
git --version
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ntb4red2juvxcnowdb5a.png)




##### ⏭️ Clone the repo we created earlier using ssh
```
git clone git@github.com:drsimplegraffiti/ec2-deploy.git
```

You  should get this error because you have not added your ssh key to github


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vy3ig8zkx6kt1zrbza63.png)



##### ⏭️ Connect github ssh key to ec2 instance
Generate a fingerprint for the ssh key
```bash
ssh-keygen -t ed25519 -C "your email"
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/84779yxkklq3r16ukrx8.png)




Click enter thrice and leave the passphrase empty as default. You can add a passphrase if you want to add an extra layer of security.

##### ⏭️ eval the ssh-agent
eval is used to evaluate the ssh-agent in the current terminal session. The ssh-agent is a program that runs in the background and stores your ssh keys. The ssh-agent is used to authenticate you to the remote server without having to type your password every time.
```bash
eval "$(ssh-agent -s)"
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/98nik6zht0mlb69vaj0e.png)



##### ⏭️ Add the ssh key to the ssh-agent

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2gwrbgmp67nq6xjhvnja.png)




#####  ⏭️ Copy the ssh key to the clipboard
```bash
cat ~/.ssh/id_ed25519.pub
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u4j34t4e1zeveb3idaj9.png)



#####  ⏭️  Paste the ssh key to github
Go to github settings -> SSH and GPG keys -> New SSH key
Paste the key and save. Auhenticate with your github password or Github mobile app

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0paf1uwm1ytc207h4cys.png)



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3bn7qwuzmnuw5iaxjpsg.png)



#####  ⏭️  Test the connection
Scan the ssh
```bash
ssh-keyscan github.com >> ~/.ssh/known_hosts
```

Let's test the connection to github in the ec2 instance terminal
```bash
ssh -T git@github.com
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ns3e4buno2lkus7pxbt2.png)



#####  ⏭️  Clone the repo again
This time, we should be able to clone the repo without any error
```bash
git clone git@github.com:drsimplegraffiti/ec2-deploy.git
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/asfkevv2yd4lv7bb49s5.png)



#####  ⏭️  List the files in the directory
```bash
ls -la
```
You should see the ec2-deploy folder

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m8v3h6tlm3aive39on9x.png)



cd into the ec2-deploy
- cd - change directory

##### ⏭️ See the files in the ec2-deploy folder
```bash
ls -la
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6emqd97df721val68xyg.png)



##### ⏭️ Install dependencies
```bash
cd ec2-deploy
npm install
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wvvq5ag9uufjy7int0bc.png)



##### ⏭️ Start the server
```bash
npm start
```
We got port 3000 because we ignored the .env file in the .gitignore file

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/83l6b2pphovwih5pbv0h.png)



💡 You can also use pm2 to start the server if you want to keep the server running even after you close the terminal
Install pm2 globally
```bash
npm install pm2 -g
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/okmo6v3qpvnow1gf6n48.png)



##### ⏭️ Start the server with pm2
```bash
pm2 start app.js
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gkhydasai4hyei15pa6z.png)



##### ⏭️ Pick the ip address of the ec2 instance and curl it


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5isg3oprlfaugk60h9k5.png)



YAAY! We have our server running on ec2 mapped to this ip address 🎉🎉🎉. However it is not secure because it is running on http. We will add SSL and Nginx in the next article.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rcw3iqeypkgwqqyvb701.png)



##### ⏭️  Method 2: Connecting to the ec2 instance using ssh from your local machine

Click connect from your instance -> connect -> ssh client -> copy the ssh command

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pcyb8tqcz8ttd5vdbpva.png)



##### ⏭️ Open your terminal and cd into the directory where you saved the key pair
```bash
cd Downloads
```

##### Run the ssh command
```bash
ssh -i "devtokey.pem" ubuntu@ec2-35-175-174-169.compute-1.amazonaws.com
```

##### ⏭️ You will get this warning
This warning is related to permissions. We need to change the permissions of the key pair. We will do that in the next step

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oy36058esd2xrj2xkjif.png)



##### ⏭️ Chmod the key pair
Chmod is a command in Linux and other Unix-like operating systems that allows to change the permissions (or access mode) of a file or directory.
```bash
chmod 400 devtokey.pem
```
⚙️ 400 - read only by owner
⚙️ 600 - read and write by owner

##### ⏭️ Run the ssh command again
```bash
ssh -i "devtokey.pem" ubuntu@ec2-35-175-174-169.compute-1.amazonaws.com
```

##### ⏭️ You should see the following

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mqau87jdyw27mhxur13p.png)



##### ⏭️ Start the server
```bash
cd ec2-deploy
pm2 start app.js
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qygc9a98nx8hfdb3m1wy.png)



You should get script already running because we already started the server on the ec2 instance earlier in the browser. Stop the ec2 on the browser by running
```bash
pm2 stop app.js
```

or 

```bash
pm2 stop 0 # 0 is the id of the script referencing app.js
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/crc2yu5b78kd8eowdqmr.png)



##### ⏭️ Start the server again
```bash
pm2 start app.js
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2vq3x44cn608p233n9hs.png)




##### ⏭️  Check the ec2 ip by running
```bash
curl ifconfig.me
```
##### ⏭️ Pick the ip address of the ec2 instance and curl it

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jouaacbubwobsrq84m5i.png)



##### ⏭️ Open another terminal and curl the ip address
```bash
curl 35.175.174.169
```
🎉🎉🎉 We have connected to our ec2 instance using ssh from our local machine. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6duoa1p58ot4okfdayka.png)

&nbsp;

##### Conclusion

We have successfully deployed our nodejs express app to ec2. We will add SSL and Nginx in the next article. Thanks for reading. Please leave a comment if you have any questions or suggestions.
![lol](https://media.giphy.com/media/mVJ5xyiYkC3Vm/giphy.gif)