Deploying Node.js App to Heroku using Github Actions
Tags: node, heroku, devops, github
Published: 2020-04-06 00:04:10

---
title: Deploying Node.js App to Heroku using Github Actions
published: true
description: Setting up a pipeline to deploy a Node.js application on Heroku using Github actions.
tags: Nodejs, Heroku, devops, github
---

Recently I started a project which was basically a Bet-tracking application with Node.js backend and Vue.js Frontend and Sqlite as the database. Initially I had planned on finishing the core functionality early and iterating often. So to do that, I decided to setup a CI/CD pipeline so that I could automate the testing and deployment. In this article I will talk about how I managed to setup a pipeline to automatically test and deploy my Node.js backend to Heroku using Github actions.

### Initial Folder structure

So this is how my folder structure looks like (Hid other files for simplicity):

```
- Client    //Vue App
- Server    //NodeJs App
```

The Server consists of a Node.js server and Client consists of a VueJs app that sends API requests to the Server for CRUD functionality.

So in development environment this is how I would run my server:
```
cd server;
node index.js;
```

### Setting Up Deployment pipeline

1. Creating a new deploy.yml file inside .github/workflows inside the root folder so the folder structure now looks like this:
```
- .github/workflows/deploy.yml
- Client    //Vue App
- Server    //NodeJs App
```

2. Get Heroku API key using the Heroku command line tool. Running the following command: 
```
heroku authorizations:create
```

3. Add the following Github secrets in your github repo:
       * HEROKU_API_KEY
       * HEROKU_APP_NAME

4. Inside the deploy.yml I add the following:

```
name: Deploy

on:
  push:
    branches: [master]
  pull_request:
    branches: [master]

jobs:
    
  deploy:
      name: Deploy
      runs-on: ubuntu-latest

      steps: 
        - name: Checkout
          uses: actions/checkout@v1

        - name: Add remote origin
          run: git remote add heroku https://heroku:${{ secrets.HEROKU_API_KEY }}@git.heroku.com/${{ secrets.HEROKU_APP_NAME }}.git

        - name: Deploy backend to heroku
          run: git push --force heroku `git subtree split --prefix server HEAD`:master
```

To break everything down, here is how this yml file works: 
* Runs every pull request OR push to the repo.
* Uses a pre-existing action called 'checkout' 
* Runs a job we named 'deploy' which adds a new remote heroku git repository 
* This command pushes the 'server' folder to heroku which contains our Node.js application: 
```
git push --force heroku `git subtree split --prefix server HEAD`:master
```

5. The pipeline is setup, so basically now we have pushed the repo's server folder into heroku, Now we have to instruct heroku on how to handle the application. Before that add a ecosystem.config.js file inside the server folder which contains the following: 
```javascript
module.exports = {
    apps : [{
      name: "matched-betting-tracker",
      script: "./index.js",
      instances: "max",
      env: {
        NODE_ENV: "development",
      },
      env_production: {
        NODE_ENV: "production",
      }
    }]
  }
```

6. Define the start script inside the package.json of our server Node.js application.

```javascript
"scripts":{
   // Other scripts
   "heroku-prebuild": "npm install pm2 -g",
   "start": "pm2-runtime start ecosystem.config.js --env production"
   }
```

This tells Heroku to install pm2 (which runs our nodejs app in production) before building the app and uses the 'start' script to run the application.

So next time you push to  your repo, it should be automatically deployed to Heroku.

Feedbacks appreciated !

If you are interested in my current project, here's a link to my repo:
* [Matched-betting-tracker](https://www.github.com/nipeshkc7/matched-betting-tracker)

Here's a link to an article where I write about implementing OAuth2.0 on my app.
* [OAuth 2.0 with Google API in Node.js](https://dev.to/nipeshkc7/oauth-2-0-with-google-api-in-node-js-48m1)

*P.S. Please follow me on twitter, I'd really appreciate it. [@Nipeshkc](https://twitter.com/NipeshKc7)*