X
Popular Searches

How to Set Up a Private Git Server

Git logo

If you want to set up source control for a project, but prefer not to host it on a service like GitHub, you can run your own git server on a VPS to store your code and act as a master repository for any collaborators.

Why Run Your Own Server?

With how many free hosted git providers there are, such as GitHub, GitLab, and Bitbucket, it doesn’t make much sense to do it yourself. But, there are a few situations where it’s a viable solution.

First off, running your own server is far more private, especially if you’re working on code you’d rather not store on someone else’s “cloud.” This isn’t to say providers like GitLab aren’t secure, but hosting everything yourself may give some people more peace of mind.

Also, if you’re using a third-party service, there are restrictions on file size that may not be ideal. GitHub does not allow files over 100 MB, which can be a major problem for projects with large binary files. Using your own server removes this limit, assuming you can pay for more hard drive space.

Whatever your use case is, you probably can do better than barebones git. GitLab’s Community Edition is free and open source, and is easy to set up on your own server. This gives you all the benefits of hosting it yourself along with a very nice web interface and numerous CI/CD tools. We highly recommend you use GitLab if you have spare server space. (It does require around 3 GB of RAM.) You can read our guide to installing and configuring it to learn more.

But, if you don’t want all the bells and whistles, and just want to run a simple git remote, you can continue reading.

Git Remotes Are Just Someone Else’s Repository

The first thing to note about git is that hosting a server isn’t actually very complicated. Git uses a distributed source control model; your local clone of a repository doesn’t connect to all of your coworkers at all, but it does connect to a “remote,” usually on an external central server or service. When you push and pull, you make modifications to the remote’s official master copy. When your coworkers fetch from the remote, they download your commits.

You can technically run git as a completely decentralized service. If you had two people, they’d each pull updates from each other. (Pushing to non-server repositories isn’t advised in this setup.) This isn’t really usable in practice, unless both parties have static IP addresses and are always online, so most people opt for the server-client model.

So, all that a git server is then is just a regular repository that’s configured as the master copy and open to the internet. It’s surprisingly simply to set up. First, we’ll need to create a new user. Git uses SSH for authentication and all traffic between servers and clients, so we’ll need a service user to manage the repo.

sudo useradd git

Next, switch to the git user for the rest of the setup:

su git

You’ll need to add your SSH keys to the git user’s authorized_keys file:

nano ~/.ssh/authorized_keys

This is one area where services like GitHub and GitLab have command line Git beat. Access management isn’t easily handled this way, as you’ll need to give everyone access to the same service user, which isn’t ideal, or you’ll need to set up seperate users for each person, which also isn’t ideal. Either way, commits will show up with whatever username and email the end user has configured in their git settings.

Anyway, to create the actual repository, simply run git init in the git user’s home directory:

git init --bare repository.git

The --bare option is necessary here. Usually, when you’re cloning a repository, git stores all of the files it uses to manage versions in the hidden .git folder, and it keeps a usable version of wherever your currently checked out HEAD is at. This usually makes your repo folder about twice as big as it would be without git, though it can be larger if you have large binary files and a lot of changes over time.

A bare repository is simply a repo without the usable versions of the currently checked out files. Instead, the repository folder is just the contents of what would be the .git folder. This saves storage space, and configures the repository as a master server. Because there’s no local content, there will be no conflicts with the branch HEAD. It’s convention to name bare repositories with the .git file extension, but it isn’t explicitly required.

That’s all that is required on the server side. From your local machine, you’ll need to clone the repo or add a new remote:

git remote add origin git@example.com:repository.git

The URL starts with git@ because it’s connecting over SSH as the git user. The :repository.git on the end is actually a path name, not just an identifier. The path is relative to the git user’s home directory, so if you placed the repo somewhere else, you’ll want to move it here or use the full pathname.

After you’ve connected your local repo, you should have full access to push and pull as normal. Keep in mind though that default git has no built permissions system, so there’s nothing preventing anyone with access to the git user from having full control over your master repository.

Anthony Heddings Anthony Heddings
Anthony Heddings is the resident cloud engineer for LifeSavvy Media, a technical writer, programmer, and an expert at Amazon's AWS platform. He's written hundreds of articles for How-To Geek and CloudSavvy IT that have been read millions of times. Read Full Bio »

The above article may contain affiliate links, which help support CloudSavvy IT.