how to run a git server on your local machine

Published on January 23rd, 2020

Let' see how you can install a git server locally on your development machine.

I see a couple of reasons why would you want to do that in the first place:

  • to have a safe playground to play with git
  • to see what is happening on the server when you execute git commands (what's what I did with the couple of git related articles on this blog)
  • and finally, why not?

Git in a docker container

The easiest way to run a git server is to run it inside a docker container.

There is a pretty popular Docker container to run git: jkarlos/git-server-docker

This container exposes the port 22 and 2 volumes:

  • /git-server/keys: Volume to store the users public keys
  • /git-server/repos: Volume to store the repositories

Directories setup

One simple way to set up this git image is to have a dedicated directory for the server data like: $HOME/git-server

In that directory, you can create 2 subdirectories:

  • keys to store the SSK key(s)
  • repos to host the git repositories directories

We will use the --volume to share those directories with the docker container.

SSH keys

Step #1 is to create the ssh keys: even though the server will be running locally on your machine, you still need ssh keys to allow the SSL connection.

The command to create the key is the usual ssh-keygen. For the sake of clarity, you may want to save the key in a different file:

tmp ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/pcarion/.ssh/id_rsa): /Users/pcarion/.ssh/id_mygit_id_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/pcarion/.ssh/id_mygit_id_rsa.
Your public key has been saved in /Users/pcarion/.ssh/id_mygit_id_rsa.pub.
The key fingerprint is:
SHA256:XOte9MwaBiso20TGI5ciPypWhjTcIyJhdF6MRvAN2oA pcarion@Pierres-MacBook-Pro.local
The key's randomart image is:
+---[RSA 2048]----+
|o+o+o.           |
|E.Bo+.           |
|ooo+ .    .      |
|o= o . o . .     |
|+ = + B S o .    |
| . = * o . + +   |
|  o + o . o + +  |
|.. . *   o o o   |
|... . .   . .    |
+----[SHA256]-----+

In order for the container to access the public key, you need to copy it to your keys directory

➜ cp ~/.ssh/id_mygit_id_rsa.pub $HOME/git-server/keys
➜ ls -l $HOME/git-server/keys
total 8
-rw-r--r--  1 pcarion  staff   415B Jan 23 18:59 id_mygit_id_rsa.pub

Starting the git docker container

We can start the server by setting the volumes and we will be using the port 2222 locally.

docker run -d -p 2222:22 -v ~/git-server/keys:/git-server/keys -v \
  ~/git-server/repos:/git-server/repos \
  jkarlos/git-server-docker

You can test that the server is properly running by trying to ssh connect to it, using your private key:

➜ ssh -i ~/.ssh/id_mygit_id_rsa git@127.0.0.1 -p 2222
Welcome to Alpine!

The Alpine Wiki contains a large amount of how-to guides and general
information about administrating Alpine systems.
See <http://wiki.alpinelinux.org>.

You can setup the system with the command: setup-alpine

You may change this message by editing /etc/motd.

Welcome to git-server-docker!
You've successfully authenticated, but I do not
provide interactive shell access.
Connection to 127.0.0.1 closed.

Network setup

In order to make it easy to access this git server from the command line, you can configure your ~/.ssh/config file to configure a pseudo remote host which will connect to your docker container:

Host remote.mygit.com
  Hostname 127.0.0.1
  Port 2222
  User git
  IdentityFile ~/.ssh/id_mygit_id_rsa

Create a bare repository

In order to create a repository on the server, you must create a so-called bare repository (the directory structure is not quite the same as the structure on the client side, mostly because there is no such thing as a working directory there).

pwd
/Users/pcarion/git-server/repos
➜  git init --bare  my-first-repo.git
Initialized empty Git repository in /Users/pcarion/git-server/repos/my-first-repo.git/

You can then clone that repository, in a different directory (obviously), with the command:

➜ git clone ssh://remote.mygit.com/git-server/repos/my-first-repo.git
Cloning into 'my-first-repo'...
warning: You appear to have cloned an empty repository.
➜ cd my-first-repo
➜ my-first-repo git:(master) date > README.txt
➜ my-first-repo git:(master) ✗ git add README.txt
➜ my-first-repo git:(master) ✗ git commit -m 'first commit'
[master (root-commit) e7195b5] first commit
 1 file changed, 1 insertion(+)
 create mode 100644 README.txt
➜ my-first-repo git:(master) git push
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 243 bytes | 243.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://remote.mygit.com/git-server/repos/my-first-repo.git
 * [new branch]      master -> master

and now, you are in business!