Running cgit on Gentoo
cgit, a web interface for git
repositories, allows you to easily share your projects’ source code over a web
interface. It’s running on my desktop right now, so you can see for
yourself what it looks like. On
Gentoo, the ebuild for this software can be found as
www-apps/cgit
. However, after installation, a number of configuration steps
should be performed to make it accessible on $HOSTNAME/git
, and index your
repositories. This post will guide you through the steps I took.
Filesystem layout
In my setup, my (bare) git repositories reside in $HOME/.local/git
. But, some
of the repositories should not be public, such as the
pass
store. So, a different directory
for cgit to look in exists, at $HOME/.local/srv/cgit
. This directory contains
symlinks to the actual repositories I want publicly available.
Installing the required software
For this to work, there is more than just cgit to install. There are a number
of ways to set this up, but I chose for Nginx as web server, and uwsgi
as the
handler for the fastcgi requests.
emerge dev-python/pygments www-apps/cgit www-servers/nginx www-servers/uwsgi
Configuring all elements
After installation, each of these packages needs to be configured.
cgit
The configuration file for cgit resides in /etc/cgitrc
. After removing all
the comments, the contents of my /etc/cgitrc
can be found below.
# Fixes for running cgit in a subdirectory
css=/git/cgit.css
logo=/git/cgit.png
virtual-root=/git
remove-suffix=1
# Customization
root-desc=All public repos from tyil
enable-index-owner=0
cache-size=1000
snapshots=tar.gz tar.bz2
clone-prefix=https://home.tyil.nl/git
robots=index, follow
readme=master:README.md
readme=master:README.pod6
# Add filters before repos (or filters won't work)
about-filter=/usr/lib64/cgit/filters/about-formatting.sh
source-filter=/usr/lib64/cgit/filters/syntax-highlighting.py
# Scan paths for repos
scan-path=/home/tyil/.local/srv/cgit
You should probably update the values of root-desc
, clone-prefix
and
scan-path
. The first describes the small line of text at the top of the web
interface. clone-prefix
is the prefix URL used for git clone
URLs. The
scan-path
is the directory cgit
will look for repositories in.
Additionally, the readme=master:README.pod6
only positively affects
your setup if you also use my Raku customizations,
outlined in the next section.
For more information on the available settings and their impact, consult man cgitrc
.
Raku customizations
Since I love working with Raku, I made some changes and a couple modules to get
README.pod6
files rendered on the about tab on projects. You should ensure
the cgit
user can run raku
and has the
Pod::To::Anything
and
Pod::To::HTML::Section
modules installed (including any dependencies). How to achieve this depends on
how you installed Raku. Feel free to send me an email if you need help on this
part!
Once this works, however, the remaining step is quite simple. The
about-filter
configuration item in /etc/cgitrc
points to a small shell
script that invokes the required program to convert a document to HTML. In my
case, this file is at /usr/lib64/cgit/filters/about-formatting.sh
. Open up
this file in your favorite $EDITOR
and add another entry to the case
for
Pod6 to call Raku.
case "$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]')" in
*.markdown|*.mdown|*.md|*.mkd) exec ./md2html; ;;
*.pod6) exec raku --doc=HTML::Section; ;;
*.rst) exec ./rst2html; ;;
*.[1-9]) exec ./man2html; ;;
*.htm|*.html) exec cat; ;;
*.txt|*) exec ./txt2html; ;;
esac
Highlighting style
The syntax-highlighting.py
filter carries the responsibility to get your code
highlighted. This uses the Python library pygments,
which comes with a number of styles. cgit uses Pastie by default. To change
this, open the Python script, and look for the HtmlFormatter
, which contains
a style='Pastie'
bit. You can change Pastie
for any other style name. These
styles are available in my version (2.4.2):
- default
- emacs
- friendly
- colorful
- autumn
- murphy
- manni
- monokai
- perldoc
- pastie
- borland
- trac
- native
- fruity
- bw
- vim
- vs
- tango
- rrt
- xcode
- igor
- paraiso-light
- paraiso-dark
- lovelace
- algol
- algol_nu
- arduino
- rainbow_dash
- abap
- solarized-dark
- solarized-light
- sas
- stata
- stata-light
- stata-dark
For those interested, I use the emacs
theme.
uwsgi
Next up, uwsgi
. This needs configuration, which on Gentoo exists in
/etc/conf.d/uwsgi
. However, this file itself shouldn’t be altered. Instead,
make a copy of it, and call it /etc/conf.d/uwsgi.cgit
. The standard file
exists solely as a base template. For brevity, I left out all the comments in
the contents below.
UWSGI_SOCKET=
UWSGI_THREADS=0
UWSGI_PROGRAM=
UWSGI_XML_CONFIG=
UWSGI_PROCESSES=1
UWSGI_LOG_FILE=
UWSGI_CHROOT=
UWSGI_DIR=/home/tyil
UWSGI_PIDPATH_MODE=0750
UWSGI_USER=
UWSGI_GROUP=
UWSGI_EMPEROR_PATH=
UWSGI_EMPEROR_PIDPATH_MODE=0770
UWSGI_EMPEROR_GROUP=
UWSGI_EXTRA_OPTIONS="--ini /etc/uwsgi.d/cgit.ini"
That covers the service configuration file. When things don’t work the way you
expect, specify a path in UWSGI_LOG_FILE
to see its logs. Additionally, you
may want to alter the value of UWSGI_DIR
. This specifies the working
directory from which the process starts.
Now comes the application configuration, which will be read from
/etc/uwsgi.d/cgit.ini
, according to UWSGI_EXTRA_OPTIONS
. Create that file
with the following contents.
[uwsgi]
master = true
plugins = cgi
socket = 127.0.0.1:1234
uid = cgit
gid = cgit
procname-master = uwsgi cgit
processes = 1
threads = 2
cgi = /usr/share/webapps/cgit/1.2.1/hostroot/cgi-bin/cgit.cgi
Note that the cgi
value contains the version number of www-apps/cgit
. You
may need to come back after an upgrade and update it accordingly.
As last step for uwsgi
configuration, a service script, to manage it with
rc-service
. These scripts all exist in /etc/conf.d
, and the package
installed a script called uwsgi
in there. Just like with the conf.d
variant, its just a template. This time, however, don’t make a copy of it, but
a symlink. It does not need to be edited, but the name must be the same as the
conf.d
entry name. That would be uwsgi.cgit
.
cd /etc/conf.d
ln -s uwsgi uwsgi.cgit
Now you can start the service with rc-service uwsgi.cgit start
. If a
consequent status
notes the state as Started, you’re all good. If the state
says Crashed, you should go back and double-check all configuration files.
When those are correct and you can’t figure out why, feel free to reach out to
me via email.
rc-service uwsgi.cgit start
rc-service uwsgi.cgit service
# Start this after boot
rc-update add uwsgi.cgit
nginx
The final element to make it accessible, the web server, nginx
. How you
organize the configuration files here is largely up to you. Explaining how to
set up nginx from scratch is beyond the scope of this post. Assuming you know
how to configure this, add the following location
blocks to the server
definition for the vhost you want to make cgit
available on.
location "/git" {
alias /usr/share/webapps/cgit/1.2.1/htdocs;
try_files $uri @cgit;
}
location @cgit {
include uwsgi_params;
gzip off;
uwsgi_modifier1 9;
uwsgi_pass 127.0.0.1:1234;
fastcgi_split_path_info ^(/git/?)(.+)$;
uwsgi_param PATH_INFO $fastcgi_path_info;
}
Once saved, you can reload nginx
, and the $HOSTNAME/git
endpoint can be
reached, and should display an cgit page, detailing there are no repositories.
That can be easily solved by making some available in $HOME/.local/srv/cgit
,
through the power of symlinks.
Symlinking the repositories
Go nuts with making symlinks to the various repositories you have gathered over
the years. You don’t need to use bare repositories, cgit
will also handle
regular repositories that you actively work in. As with the nginx
configuration, explaining how to make symlinks is out of scope. In dire
situations, consult man ln
.
git-mkbare
While making the symlinks is easy, I found that it sheepishly boring to do. I go
to $HOME/.local/git
, make a directory, cd
to it, and create a bare
repository. Then off to $HOME/.local/srv/cgit
to make a symlink back to the
newly created bare repository. I think you can see this will get tedious very
quickly.
So, to combat this, I made a small shell script to do all of that for me. I
called it git-mkbare
, and put it somewhere in my $PATH
. This allows me to
call it as git mkbare repo-name
. It will ask for a small description as well,
so I that can also be skipped as a manual task. This script may be of use to
you if you want to more quickly start a new project.
You can find this script in my dotfiles repository.
Wrapping up
Now you should have cgit available from your site, allowing you to share the sources of all your projects easily with the world. No need to make use of a (proprietary) third-party service!
If you have questions or comments on my setup, or the post in general, please contact me through email or irc.