summaryrefslogtreecommitdiff
path: root/public/blog
diff options
context:
space:
mode:
authorozpv <39195175+ozpv@users.noreply.github.com>2026-05-30 02:44:31 -0500
committerozpv <39195175+ozpv@users.noreply.github.com>2026-05-30 03:44:19 -0500
commitea3b976d9e1638ddf9171b344648928fefe0799f (patch)
tree0e2823db87e2a8e86b2b7b982325419b819cb37f /public/blog
parentb78654471eb7b43e76de3d801fc2f3424fe377ba (diff)
finish the post
Diffstat (limited to 'public/blog')
-rw-r--r--public/blog/how-to-setup-a-git-server-and-cgit.html163
1 files changed, 163 insertions, 0 deletions
diff --git a/public/blog/how-to-setup-a-git-server-and-cgit.html b/public/blog/how-to-setup-a-git-server-and-cgit.html
new file mode 100644
index 0000000..6f381f2
--- /dev/null
+++ b/public/blog/how-to-setup-a-git-server-and-cgit.html
@@ -0,0 +1,163 @@
+<!DOCTYPE html>
+<html lang="en">
+ <body>
+ <main style="min-height: 100vh;">
+ <div class="center">
+ <div style="max-width: 720px;">
+<h1 style="text-align: center;">How to Self-Host a Git Server</h1>
+<p>This guide is a modified version of the <a href="https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server">git book</a> instructions for Debian specifically.<br>
+It also includes setting up a cgit web front-end that allows you to view your git repositories conveniently on the web just like <a href="https://git.haemolacriaa.com/">I do</a>.</p>
+<p>I'm assuming you already have a VPS with Debian installed and a domain purchased with proper DNS records pointing the git subdomain to your server IP. If not, you should research what all that means before continuing because you'll be unable to follow along.</p>
+<h2>Setting up a Git Server</h2>
+<p>The very first thing to do is connect to your server, install git, create a git user, and set up ssh for remote access to that git user.</p>
+<pre><code>ssh root@example.com
+apt install git
+sudo adduser git
+usermod -aG sudo git
+su git
+cd
+mkdir .ssh &amp;&amp; chmod 700 .ssh
+touch .ssh/authorized_keys &amp;&amp; chmod 600 .ssh/authorized_keys
+</code></pre>
+<p>To copy your home computer's ssh id to your server (assuming you have one generated), run this command on your home computer:</p>
+<pre><code>ssh-copy-id git@example.com
+</code></pre>
+<p>Now let's create an example git repository and try to push from our home computer.</p>
+<p>On your server, as the git user, run these commands to create a repo.</p>
+<pre><code>sudo mkdir /srv/git
+cd /srv/git
+sudo mkdir repo.git
+cd repo.git
+git init --bare
+</code></pre>
+<p>Ensure the repo (and really the entire git folder) is owned by the git user and group. Otherwise, git commands on your home computer will error.</p>
+<pre><code>chown -R git:git /srv/git
+</code></pre>
+<p>On your home computer, set up a git repo as well.</p>
+<pre><code>mkdir repo
+cd repo
+git init --bare
+git remote add origin git@example.com:/srv/git/repo.git
+</code></pre>
+<p>Make some changes. For example, create a file, and try git push. It should work.</p>
+<pre><code>touch file.txt
+git add .
+git commit -m "changes"
+git push origin master
+</code></pre>
+<p>The git user is no longer required to be a part of the sudo group. We just needed it for a few of the commands above. Remove it.</p>
+<pre><code>deluser git sudo
+</code></pre>
+<h3>Preventing Shell Access</h3>
+<p>The final step is to prevent a remote login as <a href="mailto:git@example.com">git@example.com</a> from acquiring a normal shell on the server.<br>
+This step isn't strictly necessary and can probably be skipped if you're the only one using git on your server.</p>
+<p>First, check the location of the git shell. Then, append the output to /etc/shells.</p>
+<pre><code>which git-shell
+vim /etc/shells
+G
+o
+/usr/bin/git-shell
+:wq
+</code></pre>
+<p>Now set the shell for the git user to git-shell.</p>
+<pre><code>sudo chsh git -s $(which git-shell)
+</code></pre>
+<p>Finally, prevent port forwarding by prepending this to each key in ~/.ssh/authorized_keys in the git user directory.</p>
+<pre><code>no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty
+</code></pre>
+<p>Attempting to login as git using ssh <a href="mailto:git@example.com">git@example.com</a> should output an error and close the connection, such as this one:</p>
+<pre><code>fatal: Interactive git shell is not enabled.
+hint: ~/git-shell-commands should exist and have read and execute access.
+Connection to example.com closed.
+</code></pre>
+<p>Perfect!</p>
+<h3>Next Steps</h3>
+<p>At this point, your git server is fully usable, and you can begin to push, pull, etc. However, you might also want a front-end to browse your repositories and make them discoverable on the web.</p>
+<h2>How to Set up Cgit for a Git Web Front-End</h2>
+<p>Install the necessary packages:</p>
+<pre><code>apt install nginx certbot fcgiwrap cgit
+</code></pre>
+<p>Generate a tls certificate for your git domain, then create a cron job to auto-renew it.</p>
+<pre><code>certbot certonly --standalone --register-unsafely-without-email -d git.example.com
+crontab -e
+</code></pre>
+<p>Append this line to the file crontab opens:</p>
+<pre><code>0 0 1 * * certbot --nginx renew
+</code></pre>
+<p>Next, edit the nginx config. This is an example of what works for me. My config file is located at /etc/nginx/nginx.conf.</p>
+<pre><code>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;
+ }
+ }
+}
+</code></pre>
+<p>Now it's time to edit the cgit config to make the front-end your own. Mine is located at /etc/cgitrc. Here's an example of my config:</p>
+<pre><code>#
+# 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 front-end 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=/
+</code></pre>
+<p>It's more than likely you will need to add the nginx user to the www-data group (root if you never created one). Otherwise, the front-end will display "502 Bad Gateway" instead of cgit.</p>
+<p>Run this command to do so:</p>
+<pre><code>usermod -aG www-data &lt;nginx-user&gt;
+</code></pre>
+<p>It's time to restart nginx and check out the front-end. Use this command to restart it:</p>
+<pre><code>systemctl restart nginx
+</code></pre>
+<p>If you open git.example.com now, you might notice under "Owner" it says "git." To change this to your name, enter the following command on your server:</p>
+<pre><code>usermod -c "new_name" git
+</code></pre>
+<h2>Conclusion</h2>
+<p>If you followed the steps, you now have a working self-hosted git server and read-only front-end to view and share your repositories. If you made it, I hope you agree this is a pretty simple setup and is definitely worth investing time into for many reasons.</p>
+ </div>
+ </div>
+ </main>
+ </body>
+</html>
+