François' Blog

Running a Git server on CentOS

Published on 2018-05-24 | Last modified on 2019-08-08

This should really be easier. I guess that is why so many software exists to make this "work", adding more bloat in the process. So, I spent some time using only the basic tools to make hosting your own Git repositories work.

All software is available in the default repository or EPEL. Everything should also work in Fedora.

We'll be using:

The features that should work:


Make sure you have the EPEL repository enabled:

$ sudo yum -y install epel-release

Install the software:

$ sudo yum -y install git \
    cgit \
    python36-pygments \
    python36-markdown \

The Python components are required to convert markdown files to HTML, i.e. the file with the about-filter option. The highlight is for syntax hightlighting, the source-filter option. If you are not interested in either of that you can leave those dependencies out.


Add git-shell to list of shells:

$ echo '/bin/git-shell' | sudo tee -a /etc/shells

Add system user git, but leave the default shell for now:

$ sudo adduser git -m -r -d /var/lib/git

We'll switch to the git user to perform the following steps:

$ sudo -i -u git

The following commands are run as the git user in the directory /var/lib/git, you should be put in the directory automatically because of the -i flag.

Now create the SSH directory to configure the public key(s) that have access to the repositories:

$ mkdir ${HOME}/.ssh
$ chmod 0700 ${HOME}/.ssh
$ echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAag0uPObPcRcVf4h2gRioOBGdXVZkc98NtQ5U4BsQol fkooman@fralen-tuxed-net' | tee ${HOME}/.ssh/authorized_keys
$ chmod 0600 ${HOME}/.ssh/authorized_keys

Create a bare repository:

$ mkdir php-oauth2-client.git
$ cd php-oauth2-client.git
$ git --bare init

Return to our 'normal' account:

$ exit

Now we are almost there, except for a little SELinux issue where sshd won't be able to read the /var/lib/git/.ssh/authorized_keys file:

$ sudo semanage fcontext -a -t ssh_home_t '/var/lib/git/\.ssh(/.*)?'
$ sudo restorecon -R /var/lib/git

Modifying the policy this way will make sure it also "survives" a relabling of the filesystem.

Make sure the file permissions of /var/lib/git are correct for cgit to access them:

$ sudo chmod 0711 /var/lib/git

Change the shell for the git user now:

$ sudo chsh -s /bin/git-shell git

Now you are ready to test SSH login from your host with the private key that belongs to the public key that you configured above:

$ ssh git@HOST

You'll get this error if all is correct:

fatal: Interactive git shell is not enabled.
hint: ~/git-shell-commands should exist and have read and execute access.

After this, it is possible to mirror your existing repository to your own server:

$ git clone --bare
$ cd php-oauth2-client.git
$ git push --mirror git@HOST:php-oauth2-client.git

If you want to add your own server as a remote to an existing clone:

$ git remote add my-server git@HOST:php-oauth2-client.git
$ git push my-server master


Now all that is left is point cgit to this repository, add at the bottom of the file /etc/cgitrc:

repo.desc=Simple OAuth 2.0 Client

Some other changes in /etc/cgitrc are helpful:
clone-url=https://HOST/cgit/$CGIT_REPO_URL git@HOST:$CGIT_REPO_URL
snapshots=zip tar.xz

Now restart Apache:

$ sudo systemctl restart httpd

Now you can browse to https://HOST/cgit assuming you set up your HTTP server with TLS.

If you want to run cgit on its own (sub)domain, you can use the following configuration directives in the Apache virtual host, don't forget to update the clone-url as well:

DocumentRoot /usr/share/cgit
Alias /cgit-data /usr/share/cgit
ScriptAlias / /var/www/cgi-bin/cgit/

If you are playing with the configuration options, you may need to remove the cache as cgit will cache the output it sends to the browser:

$ sudo rm -f /var/cache/cgit/*