I’ve successfully shifted everything from forgejo (gitea) to gitolite and pgit. My entire web presense is now static content, so the spiders can keep going nuts without killing my CPU as it endlessly renders pages for them to slurp down.
Here’s how I did it!
Gitolite
I was hesitant to use it, but now I’m a big fan of gitolite. It allowed me to keep multiple users, automate publishing to my static git site.
Gitolite stores its configuration in the gitolite-admin
git repo,
which is neato burrito.
I set up some post-receive hooks to update pgit for each repo,
and to rebuild the index of repos every time (it’s really fast).
Aaaand that’s it. That’s all I had to do.
If I want to make a repo public, or make it clone-able with http,
ssh git@oscar perms neale/repo + READERS gitweb # Publish
ssh git@oscar perms neale/repo + READERS daemon # Allow cloning
git-http-backend
I’m running git-http-backend so people can git clone a repo. Once I figured out how, it was pretty simple. I’ve attached the Dockerfile below for running it as a TCP-bound fastcgi server. Then I told my Caddy server to use it for git clone requests. Easy as pie.
What’s Improved
Creating a new repo is super easy now, I just push, and it makes it for me if the repo didn’t already exist.
The web site is nice and peppy, with 100% static content, and there are a finite number of URLs that return anything. Forgejo was fast for a dynamic site, but this is faster.
Setting up the CI/CD-type things to build the static site was so much easier than any CI/CD thing I’ve used before: I just write a shell script. I run the shell script on the server to test it, then check it in when it’s working. So much simpler than the CI/CD debugging dance on a forge.
What’s Missing
I’m missing one or two CI/CD things,
so I’ll have to remember to run ./build.sh
or make publish
before I commit.
I’ve also lost the ability to do anything useful with my repos in the browser. I wasn’t using that anyhow, but a lot of people don’t understand git well enough to use it outside of a forge, so this solution won’t work for everyone.
I no longer have issue tracking, so I’ll have to go back to doing that in the repo itself, in something like TODO.md.
Forgejo did some other stuff that I never looked into, so I won’t miss any of that.
Configuration Files
gitolite-admin/conf/gitolite.conf
repo gitolite-admin
RW+ = neale
repo woozle
RW+ = neale
RW = @family
repo CREATOR/..*
C = @family
RW+ = CREATOR
RW = WRITERS
R = READERS
repo neale/..*
option hook.post-receive.50 = neale-pgit
option hook.post-receive.60 = neale-git-index
gitolite-admin/local/hooks/repo-specific/neale-pgit
#! /bin/sh
set -e
cd $(dirname $0)/..
repo=$(basename $(pwd) .git)
desc=$(cat description || echo "No description provided")
out=/srv/sys/www/git.woozle.org/neale/$repo
# Only write output if gitweb is a reader
if ! grep -F -q "READERS gitweb" gl-perms; then
rm -rf $out
exit 0
fi
# If we're exporting it, include a clone URL
if [ -f git-daemon-export-ok ]; then
clone_flag="-clone-url https://git.woozle.org/neale/$repo.git"
fi
# Build!
/home/git/bin/pgit \
-out /srv/sys/www/git.woozle.org/neale/$repo \
-root-relative /neale/$repo/ \
-label "$repo" \
-desc "$desc" \
-max-commits 5 \
$clone_flag \
-repo .
gitolite-admin/local/hooks/repo-specific/neale-git-index
#! /bin/sh
set -e
INDEX=/srv/sys/www/git.woozle.org/neale/index.html.new
cd $(dirname $0)/..
repo=$(basename $(pwd) .git)
cat <<EOD >$INDEX
<!DOCTYPE html>
<html lang="en">
<head>
<title>Neale's Git Repositories</title>
<link rel="stylesheet" href="https://woozle.org/assets/css/default.css">
</head>
<body>
<h1>Neale's Git Repositories</h1>
<dl>
EOD
cat /home/git/projects.list | while read project; do
repo=${project%.git}
case "$repo" in
neale/*)
repo=${repo#neale/}
desc=$(cat /srv/repos/$project/description || echo "No description provided")
cat <<EOD >>$INDEX
<dt><a href='$repo/'>$repo</a></dt>
<dd>$desc</dd>
EOD
;;
esac
done
cat <<EOD >>$INDEX
</dl>
</body>
</html>
EOD
mv $INDEX ${INDEX%.new}
git-fcgi-backend Dockerfile
FROM alpine
RUN apk add --no-cache git-daemon fcgiwrap
USER 101:101
CMD [ "fcgiwrap", "-s", "tcp:0.0.0.0:9000" ]
Caddy configuration
git.woozle.org {
root * /srv/sys/www/git.woozle.org
@daemon {
query service=git-upload-pack
}
handle @daemon {
reverse_proxy git:9000 {
transport fastcgi {
root /usr/libexec/git-core/
env SCRIPT_NAME git-http-backend
env SCRIPT_FILENAME /usr/libexec/git-core/git-http-backend
env GIT_PROJECT_ROOT /repos
}
}
}
file_server
}