You Don't Need Forgejo
+People + ditching + GitHub after recent issues + are looking to self-hosting Forgejo as an alternative.
+Despite some (poorly disclosed) security issues, I think there's a more fundemental reason why you shouldn't use Forgejo.
+If you're just a single person trying to publish your independent coding projects, why do you need: CI, Issue Tracking, Pull Requests, Multi-user account management, etc?
+just use cgit.
+ +How do git forges (like GitHub) even work?
+A git forge is basically just a directory of git repositories, served over http or ssh, with a fancy web frontend.
+On the server, since the repos don't need to store mutable state (local commits, staged files, etc) they're stored in a special format that's basically just the .git
+ directory of a normal git repository.
This is called a bare repository.
+ +What is cgit?
+cgit is essentially just a web-based frontend for these bare repos.
+While full-on software forges (like GitHub or Forgejo) give you many extra features, cgit is just the read-only frontend, with nothing else included.
+Interested?
+ +cgit Setup Guide
+The cgit setup process is fairly involved, but if you were planning on self-hosting Forgejo, then you can handle it.
+I'll be using Caddy as the webserver for this setup, but I'll link tutorials for NGINX and Apache if prefer xml configuration files and manual https certificates ;)
+ +To keep everything organized, I'll run cgit under a user called "git". Our git repos will be stored in this directory.
+$ useradd -r -d /var/lib/cgit -s /usr/bin/git-shell git
fcgiwrap
+cgit is served as a cgi application.
+A long time ago in a galaxy far far away, web servers had builtin support for cgi, but now its often delegated to fcgiwrap.
+So our first step will be setting up fcgiwrap.
+ +-
+
Install fcgiwrap with a package manager. This will create two systemd files: fcgiwrap.service and fcgiwrap.socket.
+ Open fcgiwrap.service in a text editor (
$ systemctl edit fcgiwrap.service) and set the User and Group to be our "git" user.
+ Open fcgiwrap.socket (
$ systemctl edit fcgiwrap.socket) and add "SocketUser=caddy" and "SocketGroup=caddy" under the [Socket] section. (replace with the correct Caddy user for your system)
+
cgit
+Since cgit is a cgi application, it does not run as its own service. It is simply a script that gets executed by Caddy and piped into fcgiwrap. As such, the setup is pretty simple:
+-
+
Install cgit with a package manager. This will place the cgit files at /var/www/htdocs/cgit
+ -
+
Make sure that location is owned by "git", but is readable by all users:
+
+$ chown -R git /var/www/htdocs/cgit && chmod -R 764 /var/www/htdocs/cgit
+
Caddy
+To complete the set up, add this block to the Caddyfile to serve cgit.
+git.my.tld {
+ @assets path /cgit.css /cgit.js /favicon.svg /robots.txt
+ handle @assets {
+ root * /var/www/htdocs/cgit
+ file_server
+ }
+
+ reverse_proxy unix//run/fcgiwrap-cgit.sock {
+ transport fastcgi {
+ env SCRIPT_FILENAME /var/www/htdocs/cgit/cgit.cgi
+ }
+ }
+}
+
+ Lock down SSH access
+Using git-shell
+ blocks normal shell access and allows only git-style SSH commands.
-
+
Create an SSH directory for the
git+ user:$ install -d -o git -g git -m 700 /var/lib/cgit/.ssh
+ Add your public key to
/var/lib/cgit/.ssh/authorized_keys+ with mode600.
+
Create some repos
+Create a bare repository:
+$ sudo -u git git init --bare /var/lib/cgit/example
Push to it from your local machine:
+$ git remote add origin git@git.my.tld:example
+$ git push -u origin main
+
+ cgitrc
+A clean default /etc/cgitrc file might look like this:
+css=/cgit.css
+logo=
+virtual-root=/
+
+enable-index-owner=0
+enable-http-clone=1
+scan-path=/var/lib/cgit
+
+root-title=git.my.tld
+root-desc=Personal git repositories
+snapshots=tar.gz zip
+
+ Tradeoffs
+You lose integrated issues, pull requests, built-in CI, orgs, and a social graph.
+In return, you get a tiny stack, fewer moving parts, lower attack surface, lower resource use, and a setup you can understand.
+For my personal projects, that trade is acceptable.
+