Hey there! π In the spirit of modern dev practices, I am writing this blog to highlight a life saver for me. When I started out as a backend developer, I used Heroku (and still use it occasionally) which has this amazing way of automatically building and deploying your apps whenever you push to the connected git repositories. I was forced to learn how to do it myself when my work started driving me to use bare-bone machines on AWS or Digital Ocean and I would always have to SSH into the server just to manually pull from my git repo and build it on my server before deploying. Coming from a lazy perspective, this was crazy work that I wasn't ready to do each time I make a change to the app and the spirit of automation started ringing in my ears.
The words that came into my head were "GIT SERVER"! I googled to see if it was a thing and luckily it was. I finally figured out how GitHub was able to do it. So I embarked on my own journey to make my own git server.
The next few paragraphs detail how I conquered that beast;
Well you do need git installed for starters so go do that first. This article assumes you have SSH set up on your ubuntu server.
Step 1
The first thing we need to do is create a git bare repository on our server.
# incase you already have a codebase
git clone --bare remote_repo_url.git server_repo.git
# but if you wanna start from scratch you could just use init
mkdir server_repo.git && cd server_repo.git
git init --bare
A bare git repository isn't like a regular repository. It stores our git objects but not the actual source code. It's typically the .git
folder in a regular repository. After that we need to create a directory on the server to store the actual source code:
mkdir server_source
Step 2
Now, from a machine that has SSH Access to your ubuntu server you'll add your bare repository as a git remote:
git remote add production <username>@<machine>:server_repo.git
# You can now push to this remote
git push production master
# Or pull from it
git pull production master
basically server_repo.git
has to be the location of your bare repo on the ubuntu server while username
and machine
are your login details just like when logging in with SSH.
Step 3
Next is the feature that makes all this possible. GIT HOOKS! I have written about them in the past here:
How to run tests automatically on each push to the repository | by Benjamin Chibuzor-Orie | FAUN | Medium
Benjamin Chibuzor-Orie γ» γ» 2 min read
Medium
Feel free to check it out. So essentially the hook we would be needing is the post-receive
hook.
As the name implies, It runs after (post-) git objects are received from a remote.
Below is a typical post-receive
file:
#! /bin/bash
# we have to set GIT_DIR env var to the bare repo
WORK_TREE=$HOME/server_source
GIT_DIR=$HOME/server_repo.git
# next up we have to checkout from our bare repo
git --work-tree=$WORKTREE --git-dir=$GIT_DIR checkout -f
# from here on we can do any other processes like building and
# deploying the app
cd $WORK_TREE
docker-compose up --build -d
Now all we need to do is add this file to our git hooks. In our bare repo server_repo.git
we need to create a new file post-receive
under the hooks
folder and then store the above in it.
We also need to make it executable on linux using chmod
.
chmod a+x post-receive
After this we are good to go! Anytime we push to our production remote from our local, it will run the post-receive
script and deploy our app.
If you have any questions, I'll be waiting in the comment sections to deal with it ποΈββοΈποΈββοΈ
Top comments (1)
Nice and understandable explanation of the feature!
Do I understand correctly that the work tree on the server will contain the source code of the last branch which is pushed to it? So in your case the master, but it could be a test branch which is pushed and thereby also included in the work tree of the server.