Github’s most recent shenanigans with Github Copilot essentially laundering GPL code (read more here) have made me finally decide to give up the service for most of my code. This is something I maybe should have done back when Microsoft bought Github, but better late than never. From now on I will be hosting all my new public repositories on http://code.swisschili.sh.

Ever since I first considered moving off Github, I’ve been looking for good Git web front-ends. I’ve tried the light-weight but ugly Gitweb and CGit, and the nicer looking but bloated Gitlab. Even Gitea did too much. Then recently I discovered Gitiles, a no-nonsense Git web front-end made by google. No javascript, no write access, just a nice looking read-only front-end.

Installing Gitiles

Gitiles is pretty easy to install. It’s written in Java as a servlet, but it’s easy to set up with Jetty out of the box. You will also probably want a reverse proxy like Nginx.

First download the latest Gitiles release:

mkdir /opt/gitiles
cd /opt/gitiles
wget <recent gitiles release tarball>
tar -xvf gitiles.tar.gz

Then install Java, Maven, and Bazel

apt install maven openjdk-8-jdk
echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | tee /etc/apt/sources.list.d/bazel.list
curl https://bazel.build/bazel-release.pub.gpg | apt-key add -
apt update
apt install bazel
# You will also need to install the specific bazel version that the gitiles
# release is built with. Bazel will prompt you to do this.

Once that is all installed you can build gitiles

cd /opt/gitiles
bazel build //:gitiles

Once built, you can run Gitiles with /opt/gitiles/tools/run_dev.sh. Repositories in the working directory will be served.

Setting up a Git server

Setting up a Git server is very easy. This is what will allow you to actually clone and push repositories to your server:

useradd -m git -d /var/git -s /bin/bash
su -l git # -l changes into ~git
# as git
git init --bare hello-world.git
mkdir .ssh
# as root
cp ~/.ssh/authorized_keys /var/git/.ssh/ # or add keys manually
chown -R git:git /var/git

This is already enough for you to push repositories to your new server. In an existing repository on your local machine, try:

git remote add my-server [email protected]:hello-world.git # where hello-world.git is a bare repository you already created
git push my-server master

Hopefully everything should push without error. If you have issues, make sure the repository directory on the server is owned by git:git and writable.

If you want to allow people to clone your repository anonymously, you will need to also enable the Git daemon. This serves over TCP on the git:// protocol. See man git daemon for details.

Basically, to allow anonymous cloning of all the repositories in /var/git, you can use the command

git daemon --reuseaddr --base-path=/var/git/ --export-all /var/git/

To start this on boot, create a systemd service /etc/systemd/system/git-daemon.service:

[Unit]
Description=Start Git Daemon

[Service]
ExecStart=/usr/bin/git daemon --reuseaddr --base-path=/var/git/ --export-all /var/git/

Restart=always
RestartSec=500ms

StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=git-daemon

User=git
Group=git

[Install]
WantedBy=multi-user.target

And that should be it! Now users should be able to clone urls like git://example.com/repo and that will clone /var/git/repo.git.

Configuring Gitiles

Once you have the Git side of things working, you will need to configure a few things with Gitiles. First, check that it runs without issue:

chown -R git:git /opt/gitiles
su -l git
/opt/gitiles/tools/run_dev.sh # should serve on :8080

Gitiles reads its configuration from the gitiles.config file in the working directory. Here’s the config I use:

[gitiles]
canonicalHostname=code.swisschili.sh
port=8989
baseGitUrl=git://code.swisschili.sh/
siteTitle=Git - code.swisschili.sh

[markdown]
githubFlavor=true

The baseGitUrl option is used as the prefix for clone URLs. Make sure you have the trailing slash there. A few of the other options are documented, but most aren’t. If you want to change something you might need to grep around the code a bit.

You also might want to create a systemd service to start Gitiles automatically. Here’s a simple gitiles.service:

[Unit]
Description=Start Gitiles

[Service]
WorkingDirectory=/var/git
ExecStart=/opt/gitiles/tools/run_dev.sh

Restart=always
RestartSec=500ms

StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=gitiles

User=git
Group=git

[Install]
WantedBy=multi-user.target

And if you want to use Nginx as a reverse proxy:

server {
	server_name code.swisschili.sh;

	location / {
		proxy_pass http://127.0.0.1:8989/;
		proxy_set_header X-Real-IP $remote_addr;
	}
}

Make sure the port on the proxy_pass line is the same as the one you configured in gitiles.config.

And that should be it! If all went well you should now have a self-hosted Git server with a new web UI.

Leave a Reply

Your email address will not be published. Required fields are marked *