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?
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:
You’ll need to add your SSH keys to the
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
Anyway, to create the actual repository, simply run
git init in the
git user’s home directory:
git init --bare repository.git
--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 firstname.lastname@example.org: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.