Self-hosting vanilla Git on a Synology NAS

· by Steve · Read in about 8 min · (1497 Words)

The case for self-hosting

One of my favourite things about Git is how easy it is to turn any old server into a remote for collaboration & backup. Sure there are fully-fledged Git web services that manage projects, user access, pull requests etc, and these are a must for larger teams.

But if you have a super-simple team like I do now (2 people, both co-located), there is beauty in simplicity. I started looking at self-hosting again because our next game (after Washed Up!) is going to be significantly more asset-heavy, and the benefits of on-site self-hosting include:

  • much faster access (local ethernet speeds)
  • billing for Git LFS data ramps up pretty quickly on cloud hosts

You can of course self-host with more full-fledged git hosting solutions, like:

But as I said, I like simplicity. I don’t need all that project/user management, pull request support, issue management etc, so why burn the resources for it, and add all the complexity of a large server package, with its inevitable maintenance overhead?

Really I just need bare Git repos on a server, accessed via SSH, and LFS storage. No frills, but I know exactly what’s going on, and there are fewer moving parts to go wrong. This is how I like to do things.

NAS setup

I happen to have a couple of Synology NAS servers in the office, and to be honest they’re pretty under-utilised. I have a ton of space on them and plenty of spare offsite backup space. I used to self-host Git on an x86 Linux box years ago; these are pretty modest boxes but they’re perfectly capable of plain Git. One has a dual-core Celeron, the other a single-core ARM variant, and they were both capable enough for my needs.

My self-imposed constraints were:

  • Use standard packages only, no unofficial sources, Docker installs etc
  • Support Git and Git-LFS
  • SSH support only, no web service

I’ll go through the steps needed to set this up with plain Git on a Synology NAS, since the documentation is a bit spotty.

There are potentially simpler setup routes (such as installing the GitLab package Synology includes), but I’m focussed on keeping the running setup simple more than anything. I want the software dependencies and ongoing maintenance to be trivial to non-existent, and am OK with a slightly more manual initial setup to achieve that.

Ensure User Homes are enabled

We need these for SSH key auth. In the Synology DSM admin UI:

  1. Open Control Panel
  2. Click User
  3. Select the Advanced tab
  4. Scroll down and ensure that Enable user home service is enabled
  5. Click Apply

Enable SSH access

  1. Still in Control Panel, select Terminal & SNMP in the sidebar
  2. Check “Enable SSH Service”
  3. You can keep the default port of 8222, but if your NAS is only visible to the local network you could change it to the standard port 22 instead for simplicity. I’ll assume you’ve left it at 8222.
  4. Click Apply

Install Git

We just need regular Git installed, nothing else for this. Again in the DSM admin:

  1. Open Package Manager
  2. Type “git” in the search box
  3. Locate “Git Server” and click “Install”
  4. After installation, click “Open”
  5. Check the “Allow access” box for every user you want to have access

Now, what DSM does here is give every user you check a restricted shell which can only execute Git commands. This is a sensible precaution, but it does mean that if you used to SSH in as one of those users for general purposes before (and DSM only actually allows that if the user is marked as an admin), then that user will now be more limited. Use different user names for admin / git access if that’s the case.

Create git-shell-commands

This step isn’t strictly necessary, but it makes testing things much easier. If a git-shell-commands directory (empty) is present in a user’s home directory, then git-shell allows an interactive login (limited to git commands), which means you can independently test whether SSH is working or not. I find that very useful.

  1. SSH into your NAS as an admin
  2. Navigate to each user home directory with git access, e.g. /volume1/homes/steve
  3. If there is no directory called “git-shell-commands”, then create it using mkdir git-shell-commands

Create Git project root

It’s best to keep our git repositories in a common folder, so create one somewhere. Mine is /volume1/gitrepos and I created it like this:

  • SSH into the NAS as an admin
  • mkdir -p /volume1/gitrepos
  • chown root:users /volume1/gitrepos
  • chmod g+rws /volume1/gitrepos

I’ve just assigned a simple group users here because my setup is super-simple.

Create a Git LFS share

I use a plain file share as my Git LFS storage on the server, using a client-side custom transfer plugin I wrote. This means all LFS uploads/downloads are just simple file copies to a shared NAS folder.

  1. Open DSM admin UI
  2. Open Control Panel > Shared Folder
  3. Create a new folder, say called git-lfs
  4. Give access to the same users you enabled Git for

Giving users access via SSH Keys

If you want to allow users to log in with SSH keys (and you do, trust me, it’s so much more convenient than passwords), then you need to grant access to them.

I won’t talk about how to generate or use SSH keys on the client here, there are plenty of online guides about that. I’ll assume you have a public key to put on the server.

  1. SSH into the NAS as an admin
  2. Navigate to each user home directory with git access, e.g. /volume1/homes/<username>
  3. Create a directory “.ssh” if it doesn’t exist already
  4. Add your public key (should be a single, long line of text) to file .ssh/authorized_keys (create if needed)
  5. Set permissions (this is very important):
    • chown -R <username>:users .ssh
    • chmod 700 .ssh
    • chmod 600 .ssh/authorized_keys

A good way to test if this is working:

  1. ssh -P 8222 username@host
  2. You should be let in via your key
  3. You’ll get a prompt that simply says git>
  4. You won’t be able to do anything except git commands

If this doesn’t work, check the previous steps and ensure you did them all correctly.

Create a Git project

Each time you start a new project you need to create a repo for it.

  • SSH into the NAS as an admin
  • git init --bare --shared /volume1/gitrepos/<projectname>

If creating projects and giving access to users like this bothers you, you might want to try Gitolite as a thin layer above this (you control projects and users via a master repo). Personally I need to do this infrequently enough that I prefer the directness of the vanilla approach.

Client setup

Let’s say you have a local Git repo you want to push to your new local Git server.

  1. Open a console and cd to your local project folder
  2. git remote add origin ssh://user@host:8222/volume1/gitrepos/projectname
    • Obviously replace user, host and projectname with the appropriate values
    • If you chose to use 22 as the SSH port instead of 8222 you could use the simpler form user@host:/volume1/gitrepos/projectname

If you have Git LFS data as well:

  1. Make sure you have downloaded and installed lfs-folderstore
  2. Determine the path you want to use for the LFS share, options include:
    • //host/git-lfs/projectname on Windows if you want to use direct UNC version, but see below
    • Z:/projectname on Windows if you’ve already mapped Z: to //host/git-lfs
      • This can be beneficial to ensure the NAS wakes up on login & the first push/pull doesn’t fail
    • /Volumes/git-lfs on Mac or /mnt/git-lfs on Linux if you’ve mounted the share that way
  3. In the same local console:
    • git config --replace-all lfs.standalonetransferagent folder
    • git config --replace-all lfs.customtransfer.folder.path lfs-folderstore
    • git config --replace-all lfs.customtransfer.folder.args /path/to/git-lfs/projectname

Then you can just git push origin master to upload everything to your NAS.

Backups

Since all the data is just files, and there are no services caching anything to worry about, backups are very simple.

I rsync data to my hot backup NAS (which is set up identically) so that in the event of non-disk failure we still have an accessible server. Offsite backup is similarly exactly the same as any other file system.

Conclusion

This setup is pretty unsophisticated - but that’s also its strength in my opinion.

Since it only depends on Git, SSH and plain file shares, there’s not a lot to go wrong. I don’t want to spend time on system admin, patching software and investigating the inevitable upgrade issues and data management complexities that inherently come with more complex Git hosting packages. The fact that it’s just a few bits of well-understood, very stable software means I can mostly just leave it alone. Yes, when adding a new user or project I have to check my notes to confirm the 2-3 lines of script I’ll need to run, but I do that so infrequently I don’t consider it a downside.

If you’re like me and appreciate ruthless simplicity, I hope this helps.