Automate Your Node.js & React App Deployments

You know how it is with side projects. You're developing locally and everything is peachy, but at some point you upload your creation to a server to show the world. Over time, it gets harder and harder to manage as tracking the files you've uploaded to 'hotfix' the site mount up.

Or maybe that's just me.

An Easier Way

Thankfully, there's a better alternative to manual file copies: using a Build Server (usually as part of a Continuous Integration/Continuous Delivery pipeline).

Better still, the folks at Gitlab provide this service for free!

Prerequisites

This article assumes you have the following set up:

  • Web Server: Somewhere to host your site, for example an Ubuntu server running Nginx or Apache on Digital Ocean.
  • Site Setup: I'll assume you've set up Apache or Nginx to serve out your website, and if you're using Node you're using a service like PM2 to manage the node process.

Using Pipelines

Gitlab has the concept of 'pipelines'. Pipelines are processes that can be configured to compile and deploy your app when they are triggered (usually via a code push).

ci_1

In a nutshell, Gitlab projects spin up publicly available Docker images to build and deploy your project. If you're using a common build stack like Node.js, Python or even Dotnet Core then chances are there's a docker image that'll work for your project straight out of the box.

Configuring your Build

Gitlab uses a file called .gitlab-ci.yml checked into the root of your repository as the basis for the build configuraton.

There are loads of options, but here's a sample configuration file that covers the build of a standard Node & React app:

image: node

cache:
  paths:
    - node_modules/

before_script:
 - apt-get update -qq && apt-get install -y -qq sshpass

deploy_production:
  stage: deploy
  environment: Production
  only:
    - master
  script:
    - rm ./package-lock.json
    - npm install
    - npm run webpack
    - rm -rf ./assets
    - rm -rf ./node_modules
    - rm -rf ./.git
    - ls
    - sshpass -V
    - export SSHPASS=$USER_PASS 
    - sshpass -e scp -o stricthostkeychecking=no -r . user@site.com:/var/www/project/
    - sshpass -e ssh user@site.com "cd /var/www/project && npm install"

There are a few things going on here:

  • image: The name of the Docker image downloaded and used for the build
  • before_script: Steps to carry out on the docker instance before running the build. In this case we're installing sshpass - more on that below.
  • deploy_production: The set of steps for production builds (you can have several of these groups).
    • only: The branch to be built.
    • script: The commands to be run on the command line. Note I'm deleting the node_modules and .git folders before running the SCP command as we don't need to spend time copying those up to production (writing a script to copy the files you need into a dist folder during the build might be better here!).

Note we're using $USER_PASS in the script above to store the SSH password to the server, this utilises Gitlab's 'variable' settings, which means you can keep sensitive stuff like passwords out of your scripts (availale in Settings > CI/CD):

ci_2

You might also want to add a final command in at the end to instruct whatever process you're using to manage Node on the server to restart the app once the deployment is finished.

Once the build has gone green, you can sit back and enjoy your updated website - and all you had to do was push your code to Gitlab.

ci_3

Wrapping Up

I've shown a quick way to automate deployments of your projects using Gitlab's CI/CD pipeline. Once you've mastered the basics, adding in extra steps specific to your workflow should be pretty simple.

As always, feel free to reach out to me @paulaik with comments, suggestions or questions!

Show Comments