diff --git a/posts/software/hosting-a-git-server.html b/posts/software/hosting-a-git-server.html new file mode 100644 index 0000000..0abee38 --- /dev/null +++ b/posts/software/hosting-a-git-server.html @@ -0,0 +1,137 @@ + + + + + + + + + + + + + hosting a git server + + + +
+
+
+

hosting a git server

+ +
+
+

why

+

+ No reason. Perhaps to host personal files in the future. AWS's + micro free tier is great, too. +

+

what

+
    +
  • Write my own git web ui
  • +
  • Support clones from my own website
  • +
  • Host private files on my git ui
  • +
+

the process

+
    +

    + I detail self-hosting a git server on an AWS t2.micro instance + ("free" for 1 year) as of May 2025. + Git's instructions + were vastly outdated so hopefully this saves a lucky reader some + time. +

    +
  1. + Create the ec2 instance with setup wizard and add {in,out}bound + rules for {SSH,HTTP,HTTPS,your ip} in the wizard security group. +
  2. +
  3. + Use an elastic ip (free) to address public ip + reassigning—this is a bother when ssh'ing (new verb?) into + the box locally and/or configuring an Apache HTTP server. +
  4. +
  5. Understand bare git repositories and the ssh protocol.
  6. +
  7. + Configure an keypair and ssh in (the official instructions are + fine for this). I moved it to ~/.ssh and added an + alias in ~/.ssh/config for convenience. Clone a repo + on the server to test. +
  8. +
  9. + Set up a git daemon for git:// protocol cloning at + your own risk. +
  10. +
  11. Set up an Apache HTTPD server.
  12. +
  13. + Configure file permissions for the new user: +
      +
    1. sudo chown -R git:git /srv/git
    2. +
    3. sudo chgrp -R apache /srv/git
    4. +
    +
  14. +
  15. + To deal with "dubious ownership" issues when cloning with HTTPS, I + needed to add exactly the following configuration to + /etc/gitconfig. + No group permission finagling will work! Git only allows + cloning repositories that are owned by the user. If you wish to + clone via SSH with, say, user A, this same user must also be + employed by your HTTP server to clone the files (customize + HTTPD/whatever you're using accordingly). +
  16. +
    +
  17. + Security-wise, set up TLS/HTTPS with + Let's Encrypt. Further, only allow authorized people to actually + push to the server. The following is my HTTPD configuration + file + /etc/apache/conf.d/git-server.conf + hosting the web ui at the root and clone urls at + /git: +
  18. +
    +
  19. + There are a variety of choices for web ui, including + cgit, + gitweb + (I do not recommend this—the scripts are ancient and require + manual tuning), and some even heavier options that allow for + further customization. I am not a fan of viewing code on the web, + so you cannot in + my custom ui. I spin up a simple python server to walk the projects in + /srv/git and configured a systemd service to run it + in the ec2 box: +
  20. +
    +
    +
+

lessons

+
    +
  • + It feels great to do things yourself: I used GPT-4o for + linux server command help, that was about it +
  • +
  • + Always ask "what is this?" before using something: this + would've saved me hours of realizing a 12 year old perl script + should not have been running my git ui. +
  • +
+
+
+
+ + + + + diff --git a/public/code/software/hosting-a-git-server/git-server-ui.systemd b/public/code/software/hosting-a-git-server/git-server-ui.systemd new file mode 100644 index 0000000..c2c77d1 --- /dev/null +++ b/public/code/software/hosting-a-git-server/git-server-ui.systemd @@ -0,0 +1,12 @@ +[Unit] +Description=Git Server UI +After=network.target + +[Service] +User=apache +WorkingDirectory=/srv/git/git-server-ui +ExecStart=/root/.local/bin/gunicorn --workers 3 --bind 0.0.0.0:8000 --chdir /srv/git wsgi:app +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/public/code/software/hosting-a-git-server/git-server.apacheconf b/public/code/software/hosting-a-git-server/git-server.apacheconf new file mode 100644 index 0000000..8c8c62e --- /dev/null +++ b/public/code/software/hosting-a-git-server/git-server.apacheconf @@ -0,0 +1,30 @@ + + ServerName + + SSLEngine on + SSLCertificateFile /etc/letsencrypt/live//fullchain.pem + SSLCertificateKeyFile /etc/letsencrypt/live//privkey.pem + + SetEnv GIT_PROJECT_ROOT /srv/git + SetEnv REMOTE_USER $REDIRECT_REMOTE_USER + + ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/ + + + Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch + Require all granted + AllowOverride None + + + + AuthType Basic + AuthName "Git Access" + AuthUserFile /srv/git/.htpasswd + Require expr !(%{QUERY_STRING} -strmatch '*service=git-receive-pack*' || %{REQUEST_URI} =~ m#/git-receive-pack$#) + Require valid-user + + ProxyPassMatch ^/git/ ! + ProxyPreserveHost On + ProxyPass / http://127.0.0.1:8000/ + ProxyPassReverse / http://127.0.0.1:8000/ + diff --git a/public/code/software/hosting-a-git-server/gitconfig.git b/public/code/software/hosting-a-git-server/gitconfig.git new file mode 100644 index 0000000..2735de2 --- /dev/null +++ b/public/code/software/hosting-a-git-server/gitconfig.git @@ -0,0 +1,2 @@ +[safe] + directory = *