Setting up a Git server in three simple steps

andrew profile image Andrew O'Rourke ・2 min read

This is a little thing I discovered which is pants-on-head simple to do, but is probably not known by a lot of people: How to host your own Git remotes on any *nix box with sshd and git installed.


  • A development machine with git installed.
  • A server machine with git and sshd installed.


Step 1

Create a git repository on your development machine, you can skip this step if you already have a repo you want to upload.

16:01 andrew@hermes Development$ mkdir sample && cd sample
16:02 andrew@hermes sample$ git init
Initialized empty Git repository in /Users/andrew/Development/sample/.git/
16:02 andrew@hermes sample$ echo "# Sample Project" > readme.md
16:02 andrew@hermes sample$ git add .
16:02 andrew@hermes sample$ git commit
[master (root-commit) 4612ba6] Initial commit.
 Committer: Andrew <andrew@hermes.local>
 1 file changed, 1 insertion(+)
 create mode 100644 readme.md
16:02 andrew@hermes sample$

Step 2

Log on to your server and create the git remote.

16:04 andrew@hermes sample$ ssh andrew@tesseract.local
16:05 andrew@tesseract ~$ mkdir git && cd git
16:05 andrew@tesseract git$ mkdir sample && cd sample
16:05 andrew@tesseract sample$ git init --bare
Initialised empty Git repository in /raid/home/andrew/git/sample/
16:05 andrew@tesseract sample$ logout
16:06 andrew@hermes sample$

Step 3

Add the new remote to your git project and push.

16:12 andrew@hermes sample$ git remote add origin andrew@tesseract.local:git/sample
16:12 andrew@hermes sample$ git push --set-upstream origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 228 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To tesseract.local:git/sample
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.
16:12 andrew@hermes sample$ 


That's it. All you need to have a git remote is a bare repository on a remote host and ssh. You can now even delete your local repo and check it out again.

16:12 andrew@hermes sample$ cd ..
16:14 andrew@hermes Development$ rm -rf sample
16:14 andrew@hermes Development$ git clone andrew@tesseract.local:git/sample
Cloning into 'sample'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.
16:14 andrew@hermes Development$ cat sample/readme.md 
# Sample Project
16:14 andrew@hermes Development$ 

Posted on by:

andrew profile

Andrew O'Rourke


Been coding for 15 years, breathing for 27. Likes finding simple solutions to complicated problems. Jack of all trades.


markdown guide

I have a question
For now, I have my remote set to be a github repo, so I push to it, then ssh into my server where my project (a discord bot) is, and then pull

Does setting my server as the remote prevents me from pulling each time ?


I'm not entirely sure what you mean, but it's worth mentioning that you can have more than one remote for a git repo. You can pull and push from whichever remotes you want.


Well, "origin", though default, is just a name. Name of a "Remote repo" wherever that is ;)

Git is great because it's f simple!

You can have multiple remotes, and the situation will be like github forks, only may differ from it in permissions.

I think auth and permissions are not git's direct responsibility, though I many be wrong about it.


This is really cool! I've been contemplating doing this as an alternative to Bitbucket, for projects that I don't want to open-source.


You don't need to open source stuff you put on Bitbucket. They support unlimited private repositories, although there's a five account limit on who can access them if you don't pay them.


Oops, I mis-worded my comment. I had meant to say that I was considering self-hosting a git-server, rather than relying on Bitbucket for my own private repositories. Of which I have a few.

Nice catch. 👍


My version of "lazy deployments" is SSH'ing in to the remote serve, git cloning the project from github and then pushing and fetching each time there's a change. If i set up the server as a remote and pushed to it instead, and then set up a post commit hook to restart pm2 for example (node process manager) can you see that introducing any additional risk? Seems easier especially in smaller projects rather than SSH'ing in to the server each time and fetching the latest changes. Im thinking the server would be something other than origin so that i could still keep a safe remote copy elsewhere...


The remote is a bare repository, it doesn't have a working copy, so I don't think what you're thinking of is possible; at according to my (likely limited) knowledge of Git. 😿


I didn't realize it was this easy 😻 Thanks!


How do you share git repositories with this solution?


The same way you'd share files on any Linux server. For a development team, I'd probably make a team account and add all users keys to that user.


Right, but then the time comes when not all repos should be accessible to all developers. And access by SSH means more than just be able to do a git push/pull/clone. Those "easy" solutions tend to get quite problematic over time.

You can change the shell for the git user to git-shell, which will prevent them from running anything but git commands (As far as I'm aware that's all GitHub does on their servers).

If you're after something that doesn't give devs access to certain repos, you can always symlink like Håvard Pedersen mentioned; although if you're wanting something like that, you're probably better off with a solution like GitLab anyway.


It's realy simple, but is more usual have a server with gogs or git lab installed


I love GitLab! And their CI is so easy to setup!