Complete guide to deploying your Express.js App on Vercel using GitHub Actions

How to Deploy Express REST API on Vercel

Express.js is used with Node.js as a server framework for building Rest APIs. It can be nauseating at times looking for the right place to deploy your APIs for free, maybe for a side project or some other stuff, and it scales. Vercel takes care of that seamlessly. In this guide, we will also look at how you can use GitHub actions to deploy your REST API easily.

Setting up your Project

  1. Create and set up a new project.

    You can start by creating a new project from your terminal or command line. Navigate to the folder you would like to create your express app, and enter the following commands;

     mkdir express-vercel-app 
     cd express-vercel-app 
     npm init -y
    

    The command above will create a new project directory for your app, and a package.json file containing default configurations for running the app.

    Proceed with adding express.js and other packages your project would require. You can install express using npm install express

  2. Once you are done with setting up your app, you should have an src folder. Proceed to add a directory called /api and add a new file index.ts. If this is a new project, you can decide to use this as the entry point for your app, otherwise, if it is an existing project where you have your index.ts setup directly in your src folder, you can decide to configure your index.ts in the /api directory like this;

     // /api/index.ts
     import app from '../src/index'
    
     module.exports = app;
    

    Since the index.ts is already your entry point in your existing app, you can just add an export the app;

     //index.ts
     // Import necessary modules and packages
     import express from 'express';
     const app = express();
    
     app.get("/api/v1", (req, res) => {
       res.send("Express Rest Api");
     });
     app.listen(8080, () => console.log("Server ready on port 8080."));
     export default app;
    

    Perhaps you are working on a new project, you can decide to make your /api/index.ts your entry point for the app, and the configuration should look like this;

     // /api/index.ts
     // Import necessary modules and packages
     import express from 'express';
     const app = express();
    
     app.get("/api/v1", (req, res) => {
       res.send("Express Rest Api");
     });
     app.listen(8080, () => console.log("Server ready on port 8080."));
    
     module.exports = app;
    

Configuring Vercel for your project

The next step to achieving this is configuring Vercel in your application. For people who decide to link their Vercel account to GitHub, they may not necessarily need to do this. I mean, since you can just deploy directly from your Github by giving Vercel access to the repository.

  1. First, we start by creating a token on Vercel. Navigate to the tokens page on your Vercel dashboard settings;

    Fill the Token name and Scope fields respectively, and also choose an expiration date. Copy the toke, you created and proceed to the Actions page, under Secrets and Variables in your GitHub repository settings;

    Click on New repository secret and define the values for YOUR_SECRET_NAME and Secret value, in this case, Name will be VERCEL_TOKEN and paste the value you copied from the token you created as Secret.

    We proceed to getting our VERCEL_PROJECT_ID and VERCEL_ORG_ID. To get this, we can easily create it locally using the vercel cli. Login to your Vercel account from your express project directory using;

     cd express-vercel-app 
     vercel login or npx vercel login
    

    You will be prompted to login via your default login mode, select the option that fits your login method, you should get a response if logged in successfully. Next, we create our project using;

     vercel link
    

    You will be asked a few questions, provide the appropriate responses, and modify your settings as you want. Here is an example;

    Once this is complete, you should have a .vercel folder created in your root directory, where you can find your projectId and orgId in the project.json;

     {"projectId":"prj_*******","orgId":"********CWVBQt"}
    

    Back to the GitHub Actions, where you created VERCEL_TOKEN secrets, you will add two new secrets for VERCEL_PROJECT_ID and VERCEL_ORG_ID and paste the values from your projectId and orgId as the secrets.

    To round up this configuration, create a new file vercel.json in your root folder, and add the following content;

     { "version": 2, "rewrites": [{ "source": "/(.*)", "destination": "/api" }] }
    

    This is simply asking Vercel to route all requests to the /api folder we created earlier.

Create and Configure CI/CD pipelines

To configure our CI/CD pipelines, we will first create a folder .github and a sub folder workflows. We will be adding two pipelines, production.yaml and preview.yaml.

Your production.yaml file should look like this;

name: Vercel Production Deployment
env:
  VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
  VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
on:
  push:
    branches:
      - Master
jobs:
  Deploy-Production:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Install Vercel CLI
        run: npm install --global vercel@latest
      - name: Pull Vercel Environment Information
        run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
      - name: Build Project Artifacts
        run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
      - name: Deploy Project Artifacts to Vercel
        run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}

And preview.yaml

name: Vercel Preview Deployment
env:
  VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
  VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
on:
  push:
    branches-ignore:
      - Master
jobs:
  Deploy-Preview:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Install Vercel CLI
        run: npm install --global vercel@latest
      - name: Pull Vercel Environment Information
        run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
      - name: Build Project Artifacts
        run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
      - name: Deploy Project Artifacts to Vercel
        run: vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }}

The basic difference between preview and production pipelines is that, the preview pipeline deploys all other branches aside Master, and the production pipeline deploys the Master branch only.

Depending on which testing library you may be using, you can decide to add unit testing to either or both pipelines.

Once you are done with the configurations, you can proceed to push the code to your GitHub and monitor the GitHub actions. The deployment should be successful, if otherwise, try to crosscheck your code and debug accordingly.