Setting up a Raspberry Pi as a Git server

I was looking for a way to set up a private git server that I could access from anywhere, to synchronize my work across several computers. I remembered I had a Raspberry Pi lying around that wasn’t getting any real use, so I figured this would be a perfect use case!

My first idea was to install GitLab on it – this would allow me to have a web-interface to my git repos, much like the ones offered by GitHub.com, BitBucket.com and GitLab.com. While this is certainly possible, it seems to be more suitable for the Pi 2 or 3, which have much more RAM available than my Raspberry Pi B. Having only 512MB of RAM would make the entire service very, very slow.

So I settled on a standard, bare-bones Git server instead. This doesn’t have the fancy UI and extra functionality of GitLab, but for a small private project, it’s definitely enough. Here’s how I went about setting my little server up!

Get the latest Raspbian distribution installed on the Pi

As you probably already know, the Raspberry Pi has a dedicated operating system called Raspbian, which needs to be installed on an SD card in order for the Pi to boot. So I headed over to the official download page and grabbed the latest version of Raspbian Stretch Lite. This version of the OS is very bare-bones, and has no desktop GUI. This is fine, as we’ll only be using the Pi as a remote server, and the GUI would only take up space on the SD card.

Next I plugged my 8GB SD card into my laptop and flashed it with Etcher, a nifty little piece of software that even supports flashing from a zipped file.

Having done this, I was able to hook the Raspberry Pi with the freshly flashed SD card installed to a monitor and keyboard for the initial setup. Oh, and an ethernet cable to the router for internet access.

Basic setup: preparing the Pi for remote access

I booted the Raspberry Pi up (by plugging it into the power) and waited patiently for the startup to complete. When prompted to log in, the default user is pi and the password is raspberry.

As a first step, I ran some updates with sudo apt update and sudo apt upgrade. This ensured all of my software packages were up to snuff.

Next I performed some basic configuration. By running the command sudo raspi-config I was greeted with a basic UI screen. This has many configuration options. The exact layout and list of options varies between versions of Raspbian, but here are the menu entries I used myself:

  • Internationalization Options: set the correct keyboard layout, as well as time zone and language
  • Enable Boot to Desktop/Scratch: in case you didn’t install the “lite” version of Raspbian, this is where you can se the Pi to boot into the command line instead of the GUI.
  • Advanced options: here you can, amongst other things, enable SSH access. This is important in our use case, as we need SSH access for the Git server!
  • Boot options: here we want to enable auto-logon. This way, the Pi will log on to the default user automatically should we reboot it, without the need to connect monitor and keyboard again.

Last but not least, I changed the password for the user pi by running passwd. This is an important step, as when we set up the Pi for remote access, it will be exposed to the big bad world, and you want a secure password to protect your network!

Testing the SSH connection

Now we have enabled SSH access, we want to test it. Using another computer, we want to find the Raspberry Pi’s local IP address. I used my router’s configuration interface, which lists all devices connected to it, but there are other software solutions too. Now we connect to the Pi by running

ssh pi@rpi.ip.address

If all goes well, this should prompt you for the password to the user pi, and then you should be greeted with a command prompt on the Raspberry Pi. If this works, it means you can disconnect the monitor and keyboard from the Raspberry Pi – we’ll be doing everything via SSH from now on!

Installing Git

This step is easy: connect to the Pi via SSH, then just run the following command to install git on the Raspberry Pi.

sudo apt install git

Creating a new user for Git

It is considered good practice to create a new user to manage our git server. I did this with

sudo adduser git

This will ask for a new password for the user – make it secure! – and some additional information about the user (I left those blank).

To remove a user, use the command

sudo userdel -r <username>

The -r flag will also delete the user’s directory and files.

Next I switched to the user git and navigated to his home directory with

su git
cd ~

Creating new repositories

Creating a new repository on the server side is simple:

git init --bare hello.git

Now if we want to clone this repository to one of our computers:

git clone git@rpi.ip.address

What if we already have code on the computer, and we’d like to create a new repo from that? Simply create a bare repository on the Pi as before, and then on the local machine:

cd /path/to/project/
git init
git add .
git commit -m 'Initial commit'
git remote add origin git@rpi.ip.address
git push --set-upstream origin master

This will create a new git repo, add all the current files to it with an “initial commit”, add a remote called “origin”, and finally, push the first commit to it whilst setting our master branch to track the remote’s master branch. Put simply, from now on, using git push will always push to the Raspberry Pi, and git pull will download updates from it.

Passwordless SSH access

As it is now, the repository is definitely usable, but we can still improve. The first thing I noticed was that every time I wanted to make a git push or git pull, it would ask me for the password to the user git on the Raspberry Pi. This is because git is opening an SSH connection to the server every time it needs to interact with it. So, is there no way to automate this process? Of course there is. The solution is SSH keys. This is a public/private key pair which will allow automatic authentication. Incidentally, it is much more secure than a simple password, as it is virtually impossible to brute-force an SSH key.

See this article for instructions on how to set up passworldess SSH access to a server, and optionally, how to disable password access completely (this increases security, as only a predetermined list of computers can access the server this way).

Accessing the git server remotely

Now what if I wanted to access the server remotely (i.e. from outside my home network)? By default, most home routers refuse incoming connections automatically, to protect from outside intruders. But if you’re aware of the risks, you can modify this behaviour with what is called “port forwarding”. Put simply, this adds an exception to the router’s “deny-all-access” policy by saying “if you receive an incoming request on port X, forward it to device Y on port Z”. What we want to do in our case is forward port 22 (the default port for SSH connections) on the router to port 22 on the Raspberry Pi. How exacly this is done depends on the individual router, and you may need to consult the user manual for this.

Once port forwarding is set up, you can access the Raspberry Pi by using the router’s IP address (which you can easily find by googling “what is my IP” whilst connected to the router’s network) instead of the local address we’ve been using so far.

Note that you may need to change the configuration of the remotes in git: for instance, my laptop handles all the SSH connections to the Pi using the router’s IP, whereas my desktop, which is always connected to the home network anyway, can use the Pi’s local IP without problems (though it could use the remote one without problems).