CGIT-SETUP(7) Miscellaneous Information Manual CGIT-SETUP(7) NAME cgit setup – configuration notes DESCRIPTION I just set up cgit on https://git.causal.agency to replace an instance of gitea. After 30 days of uptime, gitea had accumulated over 11 hours of CPU time and was using hundreds of megabytes of memory. cgit is much more lightweight and much more in line with my aesthetic. I'm documenting how I set it up here mostly to remind myself in the future. slowcgi cgit is CGI software, but nginx(8) only supports FastCGI. I used slowcgi(8) as a compatibility layer by adding the following to /etc/rc.conf: slowcgi_enable="YES" slowcgi_flags="-p / -s /var/run/slowcgi.sock" nginx I added the following in a new server block to /usr/local/etc/nginx/nginx.conf: root /usr/local/www/cgit; location / { try_files $uri @cgit; } location @cgit { fastcgi_pass unix:/var/run/slowcgi.sock; fastcgi_param SCRIPT_FILENAME $document_root/cgit.cgi; fastcgi_param SCRIPT_NAME /; fastcgi_param PATH_INFO $uri; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param HTTPS $https if_not_empty; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; } The try_files directive causes nginx(8) to first try to serve static files from /usr/local/www/cgit before passing anything else on to FastCGI. The SCRIPT_FILENAME parameter tells slowcgi(8) the path of the CGI binary to run. Setting SCRIPT_NAME to / tells cgit its root URL and avoids it using query strings for everything. cgit cgit doesn't provide any configuration to start from, so you have to just read cgitrc(5). I added the following to /usr/local/etc/cgitrc: cache-size=1024 clone-url=https://$HTTP_HOST/$CGIT_REPO_URL snapshots=tar.gz zip remove-suffix=1 enable-git-config=1 scan-path=/home/june/pub The cache-size option enables caching, which by default is stored in /var/cache/cgit, so I made sure that directory exists and is writable by the www user. The clone-url option sets the clone URL to advertise. cgit will automatically serve git over HTTP. The snapshots option makes tarballs available for tags and commits. The scan-path option causes cgit to scan the given path for git repositories. I'm putting mine in ~/pub. The remove-suffix option causes cgit to remove the .git suffix from the URLs it uses for the repositories it finds, so that ~/pub/pounce.git is served at /pounce. The enable-git-config option allows controlling some cgit options from the git-config(1) of each repository. See git below. I also set up a filter to render mdoc(7) files and do syntax highlighting by adding the following to cgitrc: readme=:README.7 readme=:README about-filter=/usr/local/libexec/cgit-filter source-filter=/usr/local/libexec/cgit-filter The readme options tell cgit which files to look for to render the “about” page. The colon prefix causes it to look for them in the git tree. The /usr/local/libexec/cgit-filter script contains the following: #!/bin/sh case "$1" in (*.[1-9]) /usr/bin/mandoc -T utf8 | /usr/local/libexec/ttpre ;; (*) exec /usr/local/libexec/hi -t -n "$1" -f html -o anchor ;; esac Filter scripts are run with the filename as their first argument and the contents of the file on standard input. The ttpre(1) command is my own utility to convert man(1) output to HTML. The hi(1) command is my own syntax highlighter: https://causal.agency/bin/hi.html. git I create my repositories in ~/pub with ‘git init --bare’ and use git.causal.agency:pub/example.git locally as the remote. Descriptions are set by editing the description file in each repository. The section and homepage can be set with git-config(1) through the keys cgit.section and cgit.homepage, respectively, thanks to the enable-git-config option above. Redirects I added the following to the server block that used to serve gitea in nginx.conf: location ~* /june/([^.]+)[.]git(.*) { return 301 https://git.causal.agency/$1$2?$query_string; } location ~* /june/([^/]+) { return 301 https://git.causal.agency/$1; } location / { return 301 https://git.causal.agency; } This redirects any links to my gitea repos to the corresponding repo in cgit. The first location block also redirects gitea HTTP clone URLs to cgit so that git-pull(1) continues to work on existing clones. Update: fast HTTPS clones Someone pointed out that cloning my repos over HTTPS was incredibly slow, and this is because cgit only implements the “dumb” HTTP git transport. To speed up cloning, I send the URLs used by the “smart” HTTP transport to git-http-backend(1) instead: location ~ /.+/(info/refs|git-upload-pack) { fastcgi_pass unix:/var/run/slowcgi.sock; fastcgi_param SCRIPT_NAME /usr/local/libexec/git-core/git-http-backend; fastcgi_param GIT_HTTP_EXPORT_ALL 1; fastcgi_param GIT_PROJECT_ROOT /home/june/pub; include fastcgi_params; } I factored out the FastCGI parameters I'm using with cgit to be included here as well. AUTHORS June Bug Causal Agency December 15, 2019 Causal Agency