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:
- work over SSH (clone, push)
- work with SELinux
- work over HTTPS (clone)
- able to fetch an archive pointing to a specific commit
Installation
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 \
highlight
The Python components are required to convert markdown files to HTML, i.e. the
README.md 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.
Configuration
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 git@github.com:/fkooman/php-oauth2-client.git
$ 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
cgit
Now all that is left is point cgit to this repository, add at the bottom of
the file /etc/cgitrc
:
repo.url=php-oauth2-client
repo.path=/var/lib/git/php-oauth2-client.git
repo.desc=Simple OAuth 2.0 Client
repo.owner=fkooman@tuxed.net
Some other changes in /etc/cgitrc
are helpful:
readme=:README.md
clone-url=https://HOST/cgit/$CGIT_REPO_URL git@HOST:$CGIT_REPO_URL
snapshots=zip tar.xz
about-filter=/usr/libexec/cgit/filters/about-formatting.sh
source-filter=/usr/libexec/cgit/filters/syntax-highlighting.sh
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/*