DEV Community

Arpan Kc
Arpan Kc

Posted on • Updated on

Deploying Node.js App to Heroku using Github Actions

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
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
  1. Get Heroku API key using the Heroku command line tool. Running the following command:
heroku authorizations:create
Enter fullscreen mode Exit fullscreen mode
  1. Add the following Github secrets in your github repo:

    • HEROKU_API_KEY
    • HEROKU_APP_NAME
  2. 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
  1. 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:
module.exports = {
    apps : [{
      name: "matched-betting-tracker",
      script: "./index.js",
      instances: "max",
      env: {
        NODE_ENV: "development",
      },
      env_production: {
        NODE_ENV: "production",
      }
    }]
  }
Enter fullscreen mode Exit fullscreen mode
  1. Define the start script inside the package.json of our server Node.js application.
"scripts":{
   // Other scripts
   "heroku-prebuild": "npm install pm2 -g",
   "start": "pm2-runtime start ecosystem.config.js --env production"
   }
Enter fullscreen mode Exit fullscreen mode

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:

Here's a link to an article where I write about implementing OAuth2.0 on my app.

P.S. Please follow me on twitter, I'd really appreciate it. @Nipeshkc

Discussion (0)