From b78654471eb7b43e76de3d801fc2f3424fe377ba Mon Sep 17 00:00:00 2001 From: ozpv <39195175+ozpv@users.noreply.github.com> Date: Sat, 30 May 2026 07:27:28 +0000 Subject: a post --- .../posts/how-to-setup-a-git-server-and-cgit.html | 140 +++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 public/posts/how-to-setup-a-git-server-and-cgit.html (limited to 'public/posts') diff --git a/public/posts/how-to-setup-a-git-server-and-cgit.html b/public/posts/how-to-setup-a-git-server-and-cgit.html new file mode 100644 index 0000000..9301701 --- /dev/null +++ b/public/posts/how-to-setup-a-git-server-and-cgit.html @@ -0,0 +1,140 @@ +

How to self-host a git server

+

This guide is pretty much a modified version of the git book instructions for Debian specifically.
+It also includes setting up a cgit web frontend that allows you to view your git repositories conveniently on the web.

+

I'm assuming you already have a VPS with Debian installed and a domain purchased with proper DNS records pointing git.example.com to your server IP. If not, I recommend you do research on what all that means.

+

Setting up a git server

+
ssh root@example.com
+apt install git
+sudo adduser git
+usermod -aG sudo git
+su git
+cd
+mkdir .ssh && chmod 700 .ssh
+touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys
+
+

To copy your home computer's ssh id to your server (assuming you have one generated), run this command on your home computer:

+
ssh-copy-id git@example.com
+
+

Now let's create an example git repository and try to push from our home computer.

+

On your server, as the git user, run these commands to create a repo.

+
sudo mkdir /srv/git
+cd /srv/git
+sudo mkdir repo.git
+cd repo.git
+git init --bare
+
+

Ensure the repo is owned by the git user and group. Otherwise, git commands on your home computer error.

+
chown -R git:git /srv/git
+
+

On your home computer, setup a git repo as well.

+
mkdir repo
+cd repo
+git init --bare
+git remote add origin git@example.com:/srv/git/repo.git
+
+

Make some changes. For example, create a file, and try git push. It should work.

+
touch file.txt
+git add .
+git commit -m "changes"
+git push origin master
+
+

Preventing shell access

+

The final step is to prevent a remote login as git@example.com from acquiring a normal shell on the server.
+This step isn't strictly necessary and can probably be skipped if you're the only one using git on your server.

+

First, check the location of the git shell. Then, append the output to /etc/shells.

+
which git-shell
+vim /etc/shells
+G
+o
+/usr/bin/git-shell
+:wq
+
+

Now set the shell for the git user to git-shell.

+
sudo chsh git -s $(which git-shell)
+
+

Finally, prevent port forwarding by prepending this to each key in ~/.ssh/authorized_keys in the git user directory.

+
no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty
+
+

Attempting to login as git using ssh git@example.com should output an error and close the connection, such as this one:

+
fatal: Interactive git shell is not enabled.
+hint: ~/git-shell-commands should exist and have read and execute access.
+Connection to example.com closed.
+
+

Perfect!

+

Conclusion

+

At this point, your git server is fully usable, and you can begin to push, pull, etc. However, you might also want a frontend to browse your repositories and make them discoverable on the web.

+

How to setup cgit for a git web frontend

+
apt install nginx certbot fcgiwrap cgit
+
+

Generate a tls certificate for your git domain, then create a cron job to auto renew it.

+
certbot certonly --standalone --register-unsafely-without-email -d git.example.com
+crontab -e
+
+

Append this line to the file crontab opens:

+
0 0 1 * * certbot --nginx renew
+
+

Next, edit the nginx config. This is an example of what works for me. My config file is located at /etc/nginx/nginx.conf.

+
http {
+	include /etc/nginx/mime.types;
+	default_type application/octet-stream;
+
+	server {
+		listen 443 ssl;
+		listen [::]:443 ssl;
+
+		ssl_certificate "/etc/letsencrypt/live/git.example.com/fullchain.pem";
+		ssl_certificate_key "/etc/letsencrypt/live/git.example.com/privkey.pem";
+		ssl_trusted_certificate "/etc/letsencrypt/live/git.example.com/chain.pem";
+
+		server_name git.example.com;
+
+		root /usr/share/cgit;
+
+		location ~* ^.+\.(css|js|png|ico)$ {
+			root /usr/share/cgit;
+			expires 30d;
+		}
+
+		location / {
+			try_files $uri @cgit;
+		}
+
+		location @cgit {
+			include fastcgi_params;
+			fastcgi_param SCRIPT_FILENAME /usr/lib/cgit/cgit.cgi;
+			fastcgi_param PATH_INFO $uri;
+			fastcgi_param QUERY_STRING $args;
+			fastcgi_param HTTP_HOST $server_name;
+			fastcgi_pass unix:/run/fcgiwrap.socket;
+		}
+	}
+}
+
+

Now it's time to edit the cgit config to make the frontend your own. Mine is located at /etc/cgitrc. Here's an example of my config:

+
#
+# cgit config
+# see cgitrc(5) for details
+
+# copy your logo into /usr/share/cgit and change the file name here
+logo=/logo.webp
+
+root-title=example
+root-desc=a web frontend for my git repositories
+
+favicon=
+css=/cgit.css
+
+# for clean repository names
+remove-suffix=1
+
+clone-prefix=https://git.example.com
+
+scan-path=/srv/git/
+virtual-root=/
+
+

It's possible you need to add the nginx user to the www-data group (root if you never created one). Otherwise, the frontend will display 502 Bad Gateway instead of cgit.

+

Run this command to do so:

+
usermod -aG www-data <nginx-user>
+
+

Closing

+

If you followed the steps, you now have a working self-hosted git server and read-only frontend to view and share your repositories. Personally, I feel like this was a pretty simple setup and is definitely worth investing time into for the purpose of decentralization (as long as you chose something like AWS as your cloud provider lol).

\ No newline at end of file -- cgit v1.2.3