Tutorial

How To Set Up a Private Git Server on a VPS

Published on August 2, 2013
author

Brian Rogers

How To Set Up a Private Git Server on a VPS

Introduction

This tutorial will show you how to set up a fully fledged Git server using SSH keys for authentication. It will not have a web interface, this will just cover getting Git installed and your access to it set up. We'll use the host "git.droplet.com" in place of the domain you will use for your VPS.

This can be a great option if you want to keep your code private while you work. While open-souce tends to be the status quo, there are some times when you don't want to have your code freely available. An example would be if you are developing a mobile app, especially a paid one. Keep in mind this code can be read by anyone if they know the URL address to use for a clone, but that is only if they know it.

There is one major concern for many and that is a web interface to your repositories. GitHub accomplishes this amazingly well. There are applications that you can install such as Gitosis, GitList, and Goblet. We don't go over those in this tutorial, but if you rely heavily on a graphic interface then you may want to look over those and think about installing one of them as soon as you done installing your Git server.

Create the SSH Key Pair

First, we need to generate a SSH key pair. If you are using Mac or Linux, you can simply issue the following command in a terminal, but replace the email address with your own:

ssh-keygen -C "youremail@mailprovider.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/flynn/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again: 
Your identification has been saved in foo_rsa.
Your public key has been saved in foo_rsa.pub.
The key fingerprint is:
ab:cd:ef:01:23:45:67:89:0a:bc:de:f0:12:34:56:78 flynn@en.com
The key's randomart image is:
+--[ RSA 2048]----+
|    o+-+  ..     |
|  E o            |
|   . ++.o..      |
|    o o H .      |
|   . .   =       |
|    . =o.o=      |
| o .             |
|  .              |
|     = o  .      |
+-----------------+

I highly recommend putting a password on the key files, it is one more layer of security and has a very minimal impact. If you are using Windows based operating system, there are tools available to generate key pairs, such as PuTTY Gen, though it does come with a disclaimer that you need to check with your local laws before using it as some countries have banned it's use. If that isn't the case, you may log into your VPS, create the key pair, and download both id_rsa and id_rsa.pub for your use.

Next, the VPS will need a user specifically for Git. Most people will simply create a user called "Git", and that is what we'll do for this tutorial but feel free to name this user whatever you'd like.

Setup a Git User and Install Git on your VPS

Log into your VPS, and gain root*:

su -

*Some people feel uncomfortable using root in this manner. If your VPS is set up to use sudo, then do so.

Add the Unix user (not necessarily Git user names) to handle the repositories:

useradd git

Then give your Git user a password:

passwd git

Now it's as easy as:

  • CentOS/Fedora: yum install git
  • Ubuntu/Debian: apt-get install git

Add your SSH Key to the Access List

At this point, you'll want to be logged in as the Git user. If you haven't already logged in to that user, use this command to switch to it:

su git

Now you need to upload your id_rsa.pub file to your Git user's home directory. Once you have done that, we need let the SSH daemon know what SSH keys to accept. This is done using the authorized keys file, and it resides in the dot folder "ssh". To create this, input:

mkdir ~/.ssh && touch ~/.ssh/authorized_keys

Note: Using the double '&' in your command chains them, so it tells the system to execute the first command and then the second. Using the 'tilde' at the beginning of the path will tell the system to use your home directory, so '~' becomes /home/git/ to your VPS.

We are going to use the 'cat' command, which will take the contents of a file and return them to the command line. We then use the '>>' modifier to do something with that output rather than just print it in your console. Be careful with this, as a single '>' will overwrite all the contents of the second file you specify. A double '>' will append it, so make sure you know what you want to do and in most cases it will be easier to just use ">>" so that you can always delete what you append rather than looking to restore what you mashed over.

Each line in this file is an entry for a key that you wish to have access to this account. To add the key that you just uploaded, type the following, replacing :

cat .ssh/id_rsa.pub | ssh user@123.45.56.78 "cat >> ~/.ssh/authorized_keys"

Now you can see the key there if you use cat on the authorized key file:

cat ~/.ssh/authorized_keys

If you want to add others to your access list, they simply need to give you their id_rsa.pub key and you append it to the authorized keys file.

Setup a Local Repository

This is a pretty simple process, you just call the Git command and initialize a bare repository in whichever directory you'd like. Let's say I want to use "My Project" as the project title. When creating the folder, I'd use all lower case, replace any spaces with hyphens, and append ".git" to the name. So "My Project" becomes "my-project.git".

To create that folder as an empty Git repository:

git init --bare my-project.git

Thats it! You now have a Git repository set up on your VPS. Let's move on to how to use it with your local computer.

Using your Git Server from your Local Computer

On Linux or Mac OS, you need to change the remote origin to your newly created server. If you already have a local repo that you want to push to the server, change the remote using this command:

git remote set-url origin git@git.droplet.com:my-project.git

If this is a new repository you are setting up, use this:

git init && git remote add origin git@git.droplet.com:my-project.git

Now you may add, push, pull, and even clone away knowing that your code is only accessible to yourself.

But what if you want a few trusted people to have access to this server and you want to keep things simple by sorting them by the names of your users? A simple and effective way to do that is to create a folder named after each person, so in the home folder for your Git user list, input:

mkdir user1 user2

Now when you specify the remote repository, it would look like this:

git remote add origin git@git.droplet.com:user1/user-project.git

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the author(s)

Category:
Tutorial
Tags:

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
60 Comments
Leave a comment...

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

How I can configure apache to access /home/git/repo.git ?

I have configured it like that /etc/apache2/sites-enabled/git.x.xxx

<VirtualHost *:80> ServerAdmin webmaster@server DocumentRoot /home/git/ <Directory /home/git/> Options ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch AllowOverride All order allow,deny Allow from all </Directory> Servername x.xxx ServerAlias www.x.xxx </VirtualHost>

But I.ve got 403 error (also via $git clone git.x.xxx/repo.git ). What I.m doing wrong?

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
August 16, 2013

@Leo: repo.git doesn’t contain your code – it only contains info useful to git.

Clone it somewhere else:

<pre># as user git: cd ~ git clone repo.git </pre>

That should clone it to /home/git/repo - set DocumentRoot to /home/git/repo

Very nice tutorial! I love using GIT and currently have a few repositories hosted over at bitbucket. Its always nice learning how to do things like this yourself though.

@Leo

Along with the response of Kamal Nasser above. If you want to turn this into a continuous deployment solution, all you need to do (as user git)

cd ~/my-project.git/hooks

In that folder:

touch post-receive && nano post-receive

In that file, add the following script

#!/bin/sh
cd /var/www/whatever
git pull my-project.git

Done. Instant deployment when you commit to the repository.

I’m curious, how many other people are using (or have heard) of gitolite? I have a git+gitolite+deploy environment setup. Curious if people would be interested in an article about that.

I had a notorious problem with gitolite setup, ended up being a missing command on your workstation - ssh-add

few more hrs spent, think I’m gonna have to give up on gitolite :( unstable

cat .ssh/id_rsa.pub | ssh user@123.45.56.78 “cat >> ~/.ssh/authorized_keys” could you explain this sentence,please?

if it run in root mode: ‘~’ becomes /home/root/ so I will cat>> run file if it run in git user mode I cant access ssh/id_rsa.pub because it in root mode

I am freshman for linux, I am not sure is that true for my desciption

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
September 27, 2013

@shyandsy: <strong>cat .ssh/id_rsa.pub | ssh user@123.45.56.78 “cat >> ~/.ssh/authorized_keys”</strong> is split into two parts:

<ol><li><strong>cat .ssh/id_rsa.pub</strong> reads the id_rsa.pub file and outputs its contents</li><li><strong>ssh user@123.45.56.78 “cat >> ~/.ssh/authorized_keys”</strong> appends the input text to the authorized_keys file in your user’s home directory</li></ol>

No home/git directory was created when I used “useradd git”

Is it safe to use “adduser git” ?

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
November 3, 2013

@stevejbayer: Yes, it is safe to user adduser instead of useradd.

@stevejbayer: You should use -m switch to create home directory.

or mkhomedir_helper git

you can use ssh-copy-id command it’s clean and sharp:

 ssh-copy-id git@gitserver

it asks git password and it automatically copy your public to authorized_keys’ of git

In this line: cat .ssh/id_rsa.pub | ssh user@123.45.56.78 “cat >> ~/.ssh/authorized_keys”

Does “user@123.45.56.78” refer to the username of the newly created git account and the IP address of the git server?

@patrick Yes it is.

This tutorial is way too confusing.

  1. I got a directory error because ‘useradd’ didn’t make the proper folders. mkdir: cannot create directory `/home/git/.ssh’: No such file or directory
  2. Why the heck am I using a separate user for my repositories?
  3. Am I supposed to use my usual user on this command or the recently created git user? cat .ssh/id_rsa.pub | ssh user@123.45.56.78 “cat >> ~/.ssh/authorized_keys”
  4. Is the git@git.droplet.com supposed to be the named URL or the droplet IP address? git remote set-url origin git@git.droplet.com:my-project.git

some small snags that may help others:

you need to follow the steps EXACTLY.

From beginning of tutorial “Create the SSH Key Pair” - you cannot be root - you are copying a id_rsa from a regular user.

I was unable to do this line logged in as user git cat .ssh/id_rsa.pub | ssh user@123.45.56.78 “cat >> ~/.ssh/authorized_keys”

but if you go back to your non-git and non-root user…

you can run it as ~/.ssh/authorized_keys | ssh git@DOMAIN.com “cat >> ~/.ssh/authorized_keys”

@matthew_gall Thank you for that time-saving suggestion.

A small tweak is suggested at http://toroid.org/ams/git-website-howto

The post-receive file would be: #!/bin/sh GIT_WORK_TREE=/var/www/www.example.org git checkout -f

make sure the post-receive file is executable by the git user chmod +x hooks/post-receive

and that the web directory is writable

This worked like a charm for me.

Yea, this tutorial is not as the clear as the other DigitalOcean tutorials, and I am quite disappointed about it. Had to finish setting up the Git server by reading this tutorial: http://ofjamescole.com/blog/2013/05/11/setup-a-private-git-server-on-digital-ocean/.

I created a script using Overcast to fully automate the process of spinning up and configuring a Git server on DigitalOcean: https://github.com/andrewchilds/overcast/tree/master/recipes/git-server

<3 Digital Ocean

I’ve read else where that the command is now apt-get install git-core because git is now some other package.

you can use ssh-copy-id command it’s clean and sharp:

 ssh-copy-id git@gitserver

it asks git password and it automatically copy your public to authorized_keys’ of git

In this line: cat .ssh/id_rsa.pub | ssh user@123.45.56.78 “cat >> ~/.ssh/authorized_keys”

Does “user@123.45.56.78” refer to the username of the newly created git account and the IP address of the git server?

@patrick Yes it is.

This tutorial is way too confusing.

  1. I got a directory error because ‘useradd’ didn’t make the proper folders. mkdir: cannot create directory `/home/git/.ssh’: No such file or directory
  2. Why the heck am I using a separate user for my repositories?
  3. Am I supposed to use my usual user on this command or the recently created git user? cat .ssh/id_rsa.pub | ssh user@123.45.56.78 “cat >> ~/.ssh/authorized_keys”
  4. Is the git@git.droplet.com supposed to be the named URL or the droplet IP address? git remote set-url origin git@git.droplet.com:my-project.git

some small snags that may help others:

you need to follow the steps EXACTLY.

From beginning of tutorial “Create the SSH Key Pair” - you cannot be root - you are copying a id_rsa from a regular user.

I was unable to do this line logged in as user git cat .ssh/id_rsa.pub | ssh user@123.45.56.78 “cat >> ~/.ssh/authorized_keys”

but if you go back to your non-git and non-root user…

you can run it as ~/.ssh/authorized_keys | ssh git@DOMAIN.com “cat >> ~/.ssh/authorized_keys”

@matthew_gall Thank you for that time-saving suggestion.

A small tweak is suggested at http://toroid.org/ams/git-website-howto

The post-receive file would be: #!/bin/sh GIT_WORK_TREE=/var/www/www.example.org git checkout -f

make sure the post-receive file is executable by the git user chmod +x hooks/post-receive

and that the web directory is writable

This worked like a charm for me.

Yea, this tutorial is not as the clear as the other DigitalOcean tutorials, and I am quite disappointed about it. Had to finish setting up the Git server by reading this tutorial: http://ofjamescole.com/blog/2013/05/11/setup-a-private-git-server-on-digital-ocean/.

I created a script using Overcast to fully automate the process of spinning up and configuring a Git server on DigitalOcean: https://github.com/andrewchilds/overcast/tree/master/recipes/git-server

<3 Digital Ocean

I’ve read else where that the command is now apt-get install git-core because git is now some other package.

you can use ssh-copy-id command it’s clean and sharp:

 ssh-copy-id git@gitserver

it asks git password and it automatically copy your public to authorized_keys’ of git

In this line: cat .ssh/id_rsa.pub | ssh user@123.45.56.78 “cat >> ~/.ssh/authorized_keys”

Does “user@123.45.56.78” refer to the username of the newly created git account and the IP address of the git server?

@patrick Yes it is.

This tutorial is way too confusing.

  1. I got a directory error because ‘useradd’ didn’t make the proper folders. mkdir: cannot create directory `/home/git/.ssh’: No such file or directory
  2. Why the heck am I using a separate user for my repositories?
  3. Am I supposed to use my usual user on this command or the recently created git user? cat .ssh/id_rsa.pub | ssh user@123.45.56.78 “cat >> ~/.ssh/authorized_keys”
  4. Is the git@git.droplet.com supposed to be the named URL or the droplet IP address? git remote set-url origin git@git.droplet.com:my-project.git

some small snags that may help others:

you need to follow the steps EXACTLY.

From beginning of tutorial “Create the SSH Key Pair” - you cannot be root - you are copying a id_rsa from a regular user.

I was unable to do this line logged in as user git cat .ssh/id_rsa.pub | ssh user@123.45.56.78 “cat >> ~/.ssh/authorized_keys”

but if you go back to your non-git and non-root user…

you can run it as ~/.ssh/authorized_keys | ssh git@DOMAIN.com “cat >> ~/.ssh/authorized_keys”

@matthew_gall Thank you for that time-saving suggestion.

A small tweak is suggested at http://toroid.org/ams/git-website-howto

The post-receive file would be: #!/bin/sh GIT_WORK_TREE=/var/www/www.example.org git checkout -f

make sure the post-receive file is executable by the git user chmod +x hooks/post-receive

and that the web directory is writable

This worked like a charm for me.

Yea, this tutorial is not as the clear as the other DigitalOcean tutorials, and I am quite disappointed about it. Had to finish setting up the Git server by reading this tutorial: http://ofjamescole.com/blog/2013/05/11/setup-a-private-git-server-on-digital-ocean/.

I created a script using Overcast to fully automate the process of spinning up and configuring a Git server on DigitalOcean: https://github.com/andrewchilds/overcast/tree/master/recipes/git-server

<3 Digital Ocean

I’ve read else where that the command is now apt-get install git-core because git is now some other package.

Andrew SB
DigitalOcean Employee
DigitalOcean Employee badge
May 27, 2014

@kache2k: Installing the <code>git-core</code> package will install git, but it’s not needed anymore. It exists to provide backwards compatibility. These days, you can just install the <code>git</code> package itself.

Thank you for the great article.

Do you know how can I let people who are registered in my database to create their own repositories and private repositories using their username and password like github?

I know how to manage the git using Python or Ruby. However, I really need a way to control the access of the git files using python.

– Without using another software like gitlab.

@digitalocean

It seemed that this line :

cd /var/www/whatever

should be

GIT_DIR="/var/www/whatever/.git"

If you have followed the Initial Server Setup with Ubuntu 12.04 tutorial, you will probably have allowed ssh access to only one user:

UseDNS no
AllowUsers demo

In that case, remember to add the git user to the list of allowed ssh logins:

UseDNS no
AllowUsers demo git

and reload

reload ssh

If you have changed the port, you will have to add the -p parameter to the ssh command.

For security reasons you should use git-shell as a default shell for git user.

sudo usermod --shell `which git-shell` git

What does this sentence mean: Keep in mind this code can be read by anyone if they know the URL address to use for a clone, but that is only if they know it.

Does it mean by using the method introduced in this article, my source code will be read only to everybody, and read/write to the one who has the private key? What did you mean by the URL?

How can I assign multiple users on

git init --bare my-project.git

so that they can collaborate?

It’s important to mention that after doing this:

mkdir ~/.ssh && touch ~/.ssh/authorized_keys

you will need to verify/change permissions on /.ssh/authorized_keys file and ~/.ssh folder. So execute these as well:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys 

Otherwise you will be asked for password every time you push or open ssh session.

Normally I love the DO articles. So far, they’ve all been just awesome. I really can’t thank DO enough for all of the ones that I’ve gone through so far. But this one really needs some help - and I haven’t even gotten 1/2 way through it.

Ok - create an ssh key, create a git user, install git - so far it’s pretty clear. That is, unless you’re a complete newbie and need exact steps, because there were a few minor details glossed over. Most DO articles I’ve read so far have literally had every command and alternate option spelled out. This one just says “run this command and substitute an email address” vs. “you can leave the file name prompt blank, and if you don’t you’ll need to keep that in mind for future steps”, etc. Maybe I’m spoiled at the quality of those articles, but thankfully this portion didn’t cause me any issues.

Next we’re supposed to upload our ssh key to our git user’s home directory… but it doesn’t exist? You’ll see the same thing if you decide to revisit that step later and run the command to create ~/.ssh. The command given to create the git user doesn’t create a home folder. Why not? You have to go on a side tangent to figure out how to fix it. Many search results pretty much say “duh - you should have just read the manual to begin with because that’s what you get for running useradd instead of adduser

Anyway. Now I’ve figured out how to create my git user WITH a home directory, so I think I’m all good. I follow the instructions to a) “upload your id_rsa.pub file to your Git user’s home directory” and then b) create ~/.ssh and the authorized_keys file.

Now I’m trying to run cat on my ssh key, and I’ve uploaded it to exactly the place I was instructed to - but the command provided is failing… because the file’s in the wrong place.

Come on guys. I mean, you go into really good detail about what the tilde means, and about using && and >> … but you can’t add -m to the useradd command, or state to copy the ssh key to the .ssh folder after it’s created?

Can we also use server side git hooks using this setup?

This is much simpler if you’ve already got root access to a droplet using an SSH key:

On the droplet:

git init --bare ~/my-repo.git

On your local machine:

git remote add ocean root@1.2.3.4:my-repo.git
git push -u ocean master

Hey! Thanks for the very informative article, really appreciate it. Just a somewhat pedantic correction:

In Note: Using the double '&' in your command chains them, so it tells the system to execute the first command and then the second

The correct thing to say is that the colon (;) operator is what actually chains commands together i.e. ./someProgram; echo hello will always output hello to the screen. The logical AND operator (&&) evaluates an expression with the purpose of returning a boolean value, so returning to our previous example, ./someProgram && echo hello will only print hello to the screen if ./someProgram finished with no errors. If it, for any reason, returns an error code or finishes abnormally, “echo hello” will not execute because && will evaluate ./someProgram to be false and therefore there is no point in evaluating the second part of the statement, “echo hello” in this case, because false && anything evaluates to false, so bash optimizes.

tl;dr - in bash, the colon character (;) chains commands together, not the AND operator (&&). The AND operator only evaluates a boolean expression.

Alex.

Nothing happens when i enter the following command: cat .ssh/id_rsa.pub | ssh user@myipaddress “cat >> ~/.ssh/authorized_keys”

Hello ,

i am totally new in linux environment . as we want to configure one server in local in which we want this integration .

We use github ,developers needs to pull push the code in which they get stuck due to bandwidth speed fr-actuation and all work get really bad ,so we wanted to configure one local sever so developers will work offline on the local sever in the network ,so end of the day or off time we can push the data to github server .

I can’t get this to work, can’t add ssh-keys to the git user because it doesn’t have ssh access to the droplet. Is this still valid? Or am I just doing something wrong?

The tutorial should make clear that for these commands:

git remote set-url origin git@git.droplet.com:my-project.git
git init && git remote add origin git@git.droplet.com:my-project.git

The last field should be the full and absolute path to the repository. So if you created my-project.git in /opt/git then the path should be /opt/git/my-project.git.

e.g.

git remote set-url origin git@git.droplet.com:/opt/git/my-project.git
git init && git remote add origin git@git.droplet.com:/opt/git/my-project.git

I found this doc to be a better explanation:

https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server

In the end of second paragraph, you write: Keep in mind this code can be read by anyone if they know the URL address to use for a clone, but that is only if they know it. How can we do this ?

is it up to date ? I failed executing this on ubuntu 18.04, the home was not and the user has no permissions to execute cat…

There seems to be some steps missing when setting up a Git user.

on Ubuntu switching to this user through su presents a different: ‘$’. You are still sitting in the home directory of the previous user, not in the home directory of the user, git.

The Git user has been granted no privileges. Should it be added to sudo?

This tutorial clearly needs to be reviewed and updated by Digital Ocean.

Can this be done without a domain? Using only the IP address of the server?

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.