# How to Deploy your Node.js Application?

# Introduction

So far we have created a NodeJs REST API that scrapes and return pinned repos from the user's GitHub Profile. We also added some new features like scraping social preview of each pinned repo, filtering only pinned repos' Github API data and giving users a very basic UI to get started with.

Now, it works fine on our local system but we need to deploy and host it on a server to consume it. So, today we will learn 3 ways to deploy our NodeJs app.

1. Deploying to Heroku
    
2. Deploying to Heroku using GitHub Actions
    
3. Deploying to AWS
    

# Pushing our code to GitHub

Before we start deploying to these hosting platforms, we need to push our code to GitHub. Follow these steps:

## Creating a New Repository

1. Open https://github.com and log in to your account.
    
2. Click on **New Repository**
    
3. Now in the form fill **Repository name** and select either **Public** or **Private**. Skip **Description** and **Initialize this repository with** section and click **Create Repository**.
    

## Creating .gitignore file

1. Coming back to our terminal, make sure you are at the root folder of your project.
    
2. Now, create a **.gitignore** file by running
    

```bash
echo "" >.gitignore # in Windows
```

OR

```bash
touch .gitignore # in Linux or Mac
```

and populate it with [this code](https://github.com/github/gitignore/blob/main/Node.gitignore).

## Pushing our code to GitHub

1. Download **git** from https://git-scm.com/ if you haven't.
    
2. Now, run `git init` to initialise git in your directory.
    
3. Then, run `git add .` to add all the files to the staging area except the ones mentioned in the **.gitignore** file.
    
4. Now, we will make our first commit using: `git commit -m "<Your Commit Message>"`.
    

> 💡 Commit Messages should always be descriptive like: **\[INITIAL\] complete local version**. Check the last section for more.

1. And finally, push our commit(s) to our remote repository in GitHub by running: `git push -u origin main`.
    

Voila!! Your code is now available on GitHub. 🎉

# Deploying to Heroku

Heroku is a Platform as a Service (PaaS) that is hosted on AWS. It takes care of all the Infrastructure configurations like launching new servers during high traffic, etc. letting you focus on your app rather than worrying about scalabily and other related issues.

Now, we will deploy our app to Heroku.

## Create Heroku app

1. Click **New** &gt; **Create new app**.
    
2. Enter your **App name** and click **Create app**.
    

## What is CI/CD?

In Software Development we try to automate manual tasks as much as possible. There are many platforms like Jenkins, CircleCI, GitHub Actions, etc. that are generally used for automating workflows. CI/CD is the process of automating the steps from testing the pushed code to deploying the final build of the application.

* **Continuous Integration (CI)** involves building and testing the code merged in the main branch against predefined tests.
    
* **Continuous Delivery (CD)** involves deploying the code to a testing server that is supposed to be a replica of the production server. After code at this stage is approved manually then only it is deployed to the production server.
    
* **Continuous Development (CD)** involves deploying the code directly to the production server once it passes all the tests.
    

> You can learn more about CI/CD [here](https://resources.github.com/ci-cd).

## Heroku's in-built CI/CD

1. In your Heroku app open the **Deploy** tab and select **GitHub** as your **Deployment method**.
    
2. Now, **Connect to GitHub** and then, search and select your GitHub Repo.
    

![Select GitHub repo in Heroku for deployment](https://cdn.hashnode.com/res/hashnode/image/upload/v1646140426088/NC0i6jDpN.png align="left")

1. After connecting your repo select **Enable Automatic Deploys** under **Automatic deploys** section and select **Deploy Branch** under **Manual deploy** section (make sure that **master** or **main** branch is selected from the dropdown menu).
    

![Deploy your app with CI/CD](https://cdn.hashnode.com/res/hashnode/image/upload/v1646140595681/ySj2BRoVm.png align="left")

You have deployed your app once manually and from now on, whenever you push a new change into your **master** or **main** branch, Heroku will deploy it automatically.

Under the **Activity** tab, once Heroku creates the **build** successfully and deploys it, you can use **Open app** to check out your live app.

## Use GitHub Actions to deploy the app to Heroku

GitHub Actions is a platform that allows you to integrate CI/CD into your project.

Create `main.yml`

```plaintext
mkdir .github
mkdir .github/workflows
touch .github/workflows/main.yml
```

## Create a YAML file

Now, populate your main.yml file with the following code:

```yaml
name: Main
on:
  push:
    branches: [main]
  workflow_dispatch:
jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - name: Use Node.js
        uses: actions/setup-node@v2
        with:
          node-version: "14.x"
      - name: Install dependencies
        run: npm install

  deploy:
    runs-on: ubuntu-latest
    needs: [build]
    steps:
      - uses: actions/checkout@v2
      - uses: akhileshns/heroku-deploy@v3.12.12
        with:
          heroku_api_key: ${{secrets.HEROKU_API_KEY}}
          heroku_app_name: ${{secrets.HEROKU_APP_NAME}}
          heroku_email: ${{secrets.HEROKU_EMAIL}}
```

### What is going on here?

1. `name:` is an optional keyword if used at the beginning then, make its value the name of the workflow otherwise the value represents the name of the next steps. It will look like this on GitHub Actions' dashboard:
    
2. `on:` specifies on **which event** should GitHub trigger the workflow.
    
3. `push:` specifies on event **push**, GitHub should trigger the workflow.
    
4. `branches: [main]` means on **push to the main branch**.
    
5. `workflow_dispatch:` gives you the ability to **manually run the workflow** from the GitHub Actions dashboard.
    
6. `jobs:` everything inside this is a **job** that will be executed. A job can be executed sequentially or parallelly (by default).
    
7. `build:` is a **job** that will be executed on its virtual machine runner.
    
8. `runs-on:` specifies which virtual machine runner to be used to run (or execute) the **job**. You can get more details and a list of virtual machine runners [here](https://github.com/actions/virtual-environments).
    
9. All jobs are made up of `steps:` that are to be executed.
    
10. Rather than reinventing the wheel we should be focusing on our GitHub Action's main logic so, GitHub Actions provides us with a keyword `uses:` to use already defined GitHub Actions like `checkout` in our case.
    
    Now, the `checkout` Action itself **checks out** in our repository so, that GitHub can run the rest of our GA logic seamlessly. You can read in detail [here](https://github.com/actions/checkout).
    
11. `setup-node` as the name suggests, helps GitHub in setting up a node environment for our app. `with: node-version:` is also a part of this Action that specifies the version of NodeJs GitHub has to install.
    
12. `run:` specifies the command that GitHub has to execute.
    
13. Similarly, in `deploy` we specify **ubuntu** as our virtual machine runner.
    
14. Then, we use `needs: [build]` to wait for the job `build` to be successfully completed first and then only move on to the next steps.
    
15. Here also, we use `actions/checkout` and then we use another action `heroku-deploy` created by **akhileshns**.
    
16. This Action requires three values: **heroku\_api\_key**, **heroku\_app\_name** and **heroku\_email**. We are passing the values from our repo's secrets (like we do with environment variables in our local repo).
    

![Add new repo secret](https://cdn.hashnode.com/res/hashnode/image/upload/v1646421868817/qH92RXbIZ.png align="left")

![Add new repo secret](https://cdn.hashnode.com/res/hashnode/image/upload/v1646422058461/ENIY38uFV.png align="left")

Now, push your code to GitHub and after you see the **yaml** file on your GitHub repo, either push some changes again or you can run the workflow manually.

![GitHub Actions completed successfully](https://cdn.hashnode.com/res/hashnode/image/upload/v1646502200842/64ylCLIBp.png align="left")

Congratulations, you can now check your live app hosted on Heroku.

# Deploying to AWS

We will be using 2 services from AWS:

1. **Elastic Beanstalk:** To run our app
    
2. **CodePipeline:** For CI/CD
    

## Elastic Beanstalk

1. Open Elastic Beanstalk service from navbar and click **Create a new application**.
    
2. Enter your **Application name** and click **Create**.
    
3. Click **Create a new environment** and select **Web server environment**.
    
4. In the Platform section, choose Node.js as the **Platform** (leave everything else as it is) and hit **Create Environment**.
    

![AWS Elastic Beanstalk empty application environment dashboard](https://cdn.hashnode.com/res/hashnode/image/upload/v1646508516340/U1hwKNFud.png align="left")

1. Wait for a few minutes until it is successfully created.
    

![AWS Elastic Beanstalk application environment created successfully](https://cdn.hashnode.com/res/hashnode/image/upload/v1646508989111/_bEhcOVXT.png align="left")

## Codepipeline

Now, we will connect our GitHub repo to our Elastic Beanstalk using the AWS Codepipeline service. It is similar to Heroku's in-built CI/CD.

1. Open Codepipeline and click **Create pipeline**.
    

![AWS Codepipeline empty dashboard](https://cdn.hashnode.com/res/hashnode/image/upload/v1646509324771/9HV0TKGDr.png align="left")

1. Enter the name of your pipeline and hit **Next**.
    

![AWS Codepipeline create new pipeline](https://cdn.hashnode.com/res/hashnode/image/upload/v1646509523769/YzILNmpwm.png align="left")

1. Select **GitHub (Version 1)** as the **Source provider** and hit **Connect to GitHub**.
    
2. After you have connected to GitHub, select your Repository and **master** (or **main**) branch under **Branch**. Click **Next**.
    
3. Click **Skip build stage**.
    
4. In **Add deploy stage**, select **AWS Elastic Beanstalk** as your **Deploy provider**. Choose your recently created Elastic Beanstalk application and the environment under **Application name** and **Environment name** and click **Next**.
    
5. After reviewing click **Create pipeline** and wait for a few minutes until **Deployment** is successful.
    

![AWS Codepipeline created new pipeline successfully](https://cdn.hashnode.com/res/hashnode/image/upload/v1646510532836/-mzgVe8mQ.png align="left")

1. You can now open your app using the link provided in your Elastic Beanstalk application environment.
    

![AWS Elastic Beanstalk application url](https://cdn.hashnode.com/res/hashnode/image/upload/v1646510703278/C78qxZkbk.png align="left")

# Concluding

Congratulations on coming so far...🎉

That's all I had for this series. Stay tuned for upcoming articles.

If you have any doubts or issues, feel free to use the comment section and I will try my best to help you out.

Thank you for reading!!

# Resources for better commits

You don't have to use all of them strictly, just try them out and see what feels more organised and clean. The whole point of writing a commit message is to briefly describe the changes to the reader in a meaningful manner.

* [Mindfully Commit with a Descriptive Message](https://theodorusclarence.com/blog/mindful-commit-message)
    
* [Write Categorized Git Commit Messages](https://medium.com/@rcwestlake/write-categorized-git-commit-messages-c9f953ea6040)
    
* [Semantic Commit Messages with Emojis](https://medium.com/walmartglobaltech/semantic-commit-messages-with-emojis-dba2541cea9a)
    

Not about commits but still insightful:

* [What are some examples of commonly used practices for naming git branches](https://stackoverflow.com/questions/273695/what-are-some-examples-of-commonly-used-practices-for-naming-git-branches)
