The recent curtailing of the popular BitBucket repository service* made me re-think my method of code deployment. Instead of using GitHub Actions or other proprietary service as my sole method of pushing code to my own server, I am cutting GitHub out of the loop and going direct.
*Bitbucket used to have no storage limit – now it’s 1GB for the free version. I had 14GB already on there!! GitHub will do this too at some point, no doubt..
SSH to the rescue
It turns out that pushing directly to your own VPS via ssh is not only supported by git, it is easy, fast and effective. I made my server re-load the web based code automatically (for me Flask) whenever I push. Here are the commands.
1. Set up bare git repository on VPS
mkdir -p /srv/git/myproject.git
cd /srv/git/myproject.git
git init --bare
2. Set up automatic update
create hooks/post-receive:
#!/bin/bash
GIT_WORK_TREE=/var/www/myproject git checkout -f main
make hooks/post-receive executable:
chmod +x /srv/git/myproject.git/hooks/post-receive
3. Add server as a remote
on your local machine:
git remote add server username@your-server-ip:/srv/git/myproject.git
(origin is still set to github, for backup)
4. Push code
git push server main
That’s it! Simple
Now I push main to the server and it deploys. There is much more to look at – the hooks are pretty powerful, you can do a bunch of stuff like update database, re-start web service and more whenever post is received.
Note: Permissions
/srv/git I gave user ownership of:
sudo chown -R username:username /srv/git
Bonus: restarting services with sudo
Allow your command to run as root in the /etc/sudoers file:
visudo
# add a line to the file
username ALL=(ALL) NOPASSWD: /usr/sbin/service myproject restart
Add restart command to hooks/post-receive file:
#!/bin/bash
GIT_WORK_TREE=/var/www/myproject git checkout -f main
echo "Restarting myproject service"
/usr/bin/sudo /usr/sbin/service myproject restart
Now when you push to server the service will automatically restart (and you get a message in the terminal).