A Friendly Guide To Automate Deployment For Node.js Apps With Git Hooks
Note: This article is just a simpler version of this and this.
Note2: You may want to checkout prepare your droplet for running Node.js apps first.
Our Goal Here
- With git, the code on a droplet must be up-to-date with the code on our laptop.
- The app restarts automatically after each deploy.
The Mental Model of This
First, you will setup a git repo on a droplet that will reflect your code on your laptop. Imagine something like github repo, a place that you push code to. While the code on github is for sharing, the code on your droplet will actually be running.
Second, we can automatically run some scripts after a particular event occurs in a git repo. This is done via git hooks. As you might imagined, it would do something like npm install
and npm start.
After these setups, now every time you push your code there, git hooks will done the rest to get your app running.
Steps
- Introducing pm2
- Setting up bare repo on your droplet
- Adding remote repo on your working directory
1. What’s pm2?
pm2 is a command line to manage and run multiple processes. Normally you’re blocked after you run ‘npm start’. However, pm2 runs apps and leave them alone. It also restarts an app automatically if any app crashes. Plus, you get a beautiful panel to check all apps running with pm2.
To install this on your droplet:
$ npm install pm2 -g
And you can start an app with this command:
$ pm2 start npm --name ‘aunnnn-by-githook’ — start
2. Setting Up Automate Deployment in 3 Steps
Alright here’s the main part. Do these on your droplet.
- Initialize a git bare repository at
/opt
$ git init --bare /opt/my-first-app.git
What’s a bare repo? It’s a repo specifically for pushing your work to, e.g., not for developing on it directly. Perfect for live version.
2. Clone to a directory that will contain all your code
$ git clone /opt/my-first-app.git /opt/live/my-first-app
3. Add post-receive hook at /opt/my-first-app.git/hooks
The file contains commands that you want your droplet to run after the bare repo receives all the code.
You’ll see lots of hooks there, but no post-receive yet. You must create one yourself. E.g., nano post-receive
and add something like this:
#!/bin/bashecho ‘post-receive: Triggered.’cd /opt/live/my-first-appecho ‘post-receive: git check out…’git --git-dir=/opt/my-first-app.git --work-tree=/opt/live/my-first-app checkout master -fecho ‘post-receive: npm install…’npm install \&& echo ‘post-receive: building…’ \&& npm run build \&& echo ‘post-receive: → done.’ \&& (pm2 delete ‘my-first-app-by-githook’ || true) \&& pm2 start npm --name ‘my-first-app-by-githook’ -- start \&& echo ‘post-receive: app started successfully with pm2.
Just edit the above to suit your need. E.g., edit echo, skip npm build
Note 1: &&
is to execute commands synchronously.
Note 2: \
is to write && in multiple lines. It’s the same as one-liner: command1 && command2 && command3 && ...
4. Make post-receive executable
$ chmod ug+x ./post-receive
3. Add the remote repo on your laptop
Last step. Do these on your working directory on your laptop.
Now we have to add remote repository at your working directory, so that we can push our code to the bare repo we just set up.
- If you need to check existing remote repo first:
$ git remote -v
2. To add a new remote repo:
$ git remote add live ssh://root@123.123.123.123/opt/my-first-app.git
Suppose IP Address of your droplet is 123.123.123.123
Note: you can change live
to something else, e.g., prod
. It’s just a name of your remote.
If you have remote repo at github too, you’d see something like this:
Let’s try
OK. All are set. Now suppose you edit some code. Committed, and merged it to master.
To deploy these new commits, just type:
git push live master
PS: It feels sooooooooo good if it works.