I’m transferring my git repos from Microsoft Github to self hosted repos on my server. Not relying on a big corporation and all that. I’ve decided to use ‘plain’ bare git repositories because I don’t need anything very complex and I can easily use ssh to push/pull.
Despite this I still want a website where I can see all my repos including the files and commits. This is where cgit comes in as a web interface for the ordinary git repos. It is written in C and designed to be fast which is great for my use case.
My server runs DietPi, a Debian derivative. It has cgit as a package so I could simply apt install cgit
. Then I needed to set up lighttpd (the web server that I use) to work with it.
My config files
# /etc/lighttpd/lighttpd.conf
# only for the src.tombrandis.uk domain
server.document-root = "/usr/lib/cgit"
server.indexfiles = ("cgit.cgi")
cgi.assign = ("cgit.cgi" => "")
$HTTP["url"] =~ ".*(\.css|\.png|\.well-known|robots\.txt).*" {
server.document-root = "/usr/share/cgit"
} else
{
url.rewrite = ( "(.*)" => "/cgit.cgi/$1")
}
The integration of the cgit CGI script and lighttpd still seems slightly incomprehensible to me, particually the cgi.assign
line. In the second part some paths are served as static files from the share directory. Everything else is sent to the cgit script which is in /usr/lib/cgit.cgi
.
# /etc/cgitrc
css=/cgit.css
logo=/cgit.png
enable-git-config=1
enable-index-owner=0
enable-commit-graph=1
enable-index-links=1
enable-log-linecount=1
enable-log-filecount=1
remove-suffix=1
side-by-side-diffs=1
virtual-root=/
root-title=Tom's repos
root-desc=git repositories self hosted by Tom Brandis (https://tombrandis.uk)
clone-prefix=https://src.tombrandis.uk ssh://git@tombrandis.uk/repos/public
scan-path=/repos/public/
The cgit configuration is fairly straight forward and you can find all the options in the man page.
Setting up repositories
I git clone --bare
‘d the repos that I wanted to move over and then copied the bare repos to /repos/public
on the server. They are owned by the git
user and the publicgit
group.
This means that I can use git clone ssh://git@tombrandis.uk/repos/public/repo_name
and everything just works. I could also add other people to the publicgit
group (or make more groups) if I wanted to give anyone else access.
git remote remove origin
git remote add origin git@tombrandis.uk/repos/public/repo_name
For repos that I was importing from github, I removed the current remote and added the new one seamlessly.
Scraping protection
The site is now dynamic meaning that I don’t really want a crawler clicking every link.
User-agent: *
Disallow: /
Allow: /$
Allow:/*/$
Disallow:/*/refs/
Disallow:/*/log/
Disallow:/*/tree/
Disallow:/*/commit/
Disallow:/*/diff/
I set my robots.txt to only allow the index page and one page for each repo.
Other guides
- cgit+lighttpd+alpine guide by Dhole. This also covers syntax highlighting and multiple configurations. It was a bit hard to understand but it was the most helpful guide that I found.
- cgit+apache guide by Andrew Marchetta
- cgit+apache+debian guide by Floating Octothorpe