Automatic deployment to VPS with git
For new projects, I set up automatic deployment to an Ubuntu VPS via git. I use DigitalOcean for hosting and they have a tutorial for this. However, it is 8 years old and the commands provided now give me errors.
To make this process faster for new projects in the future, I am writing a shortened and modified version of the tutorial here. It will work with any VPS hosting provider:
1. Initialize a bare repository
Connect to the VPS via SSH (I have a shell alias for this command):
ssh [username]@[VPS IP address]
Then initialize a bare git repository:
cd /var
cd repo
mkdir [project-name].git
cd [project-name].git
git init --bare
Aside: This assumes you store repositories in /var/repo. In hindsight, I wish I had stored them in ~/repo, as they are specific to me as a user, but it would be too much work to change this for every project.
2. Set up a post-receive hook
Assuming you are still in /var/repo/[project-name].git on the VPS:
cd hooks
nano post-receive
Paste in the following and save:
#!/bin/sh
git --work-tree=/home/[username]/docs/[project-name] --git-dir=/var/repo/[project-name].git checkout -f
Finally, add execution permission to the file:
chmod +x post-receive
This will update your project files on the server, assuming you store them in ~/docs.
You now have two options to restart your app automatically:
- Use a process manager to restart the app automatically when file changes in the project directory are detected
- Add a command at the bottom of the post-receive file to restart the app
[Optional] More automation:
I also add these lines to the post-receive file for some projects:
cd /home/[username]/docs/[project-name]/server
npm install --silent
npm run build
pm2 reload [project-name]
This is NodeJS and PM2 specific. It does the following:
- Installs packages that I added on my development machine, as I skip them in
.gitignore
. - Runs a build process. For my latest project, it generates an optimized CSS file using the TailwindCSS CLI tool
- Restarts the app. Here, I use PM2 in cluster mode to run two instances of the app. The reload command restarts them in succession, ensuring zero downtime on deployment.
This is just what I could think of for my first project after I realized this was possible. Git hooks are powerful!
3. Configure a local repository
Leave the VPS
exit
Initialize a repository on your local machine:
cd [root of your project]
git init
Add a remote path (the name live
can be anything):
git remote add live ssh://[username]@[VPS IP address]/var/repo/[project-name].git
4. Push and deploy
git add .
git commit -m "Initial commit"
git push live master
That's it - your project is deployed. Now you can push your changes from the local machine, and they will automatically be deployed on the server.