README.md (3447B)
1 ## Self-hosted git server with static stagit frontend 2 3 0. Set up a server, open ports {22,80,443,9418}, and configure {A,AAAA} DNS records. 4 5 1. Make sure the necessary software dependencies are in place. 6 7 ``` 8 gcc 9 make 10 libgit2 11 nginx 12 ufw (optional) 13 ``` 14 15 2. Install `stagit`. 16 17 ``` 18 test $UID = 0 || exit # assert(`whoami` == non-root admin user) 19 cd 20 git clone git://git.codemadness.org/stagit && cd stagit 21 make 22 sudo make install 23 ``` 24 25 3. Set up a `git` user. 26 27 ``` 28 sudo adduser git 29 sudo chsh git -s $(which git-shell) 30 sudo su git -s /bin/bash <<EOF 31 cd 32 mkdir .ssh && chmod 700 .ssh 33 touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys 34 EOF 35 ``` 36 37 4. Authenticate (write-authorized) client-side public keys with restricted access. 38 39 ``` 40 sudo su - 41 >> ~git/.ssh/authorized_keys <<EOF 42 no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAAB3Nz...== first client 43 no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAAB3Nz...== second client 44 no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAAB3Nz...== third client 45 EOF 46 ``` 47 48 5. Set up the git daemon (e.g. through `systemd`). 49 50 ``` 51 >| /etc/systemd/system/git-daemon.service <<EOF 52 [Unit] 53 Description=Start Git Daemon 54 55 [Service] 56 ExecStart=/usr/bin/git daemon --reuseaddr --base-path=/srv/git/ /srv/git/ 57 58 Restart=always 59 RestartSec=500ms 60 61 StandardOutput=syslog 62 StandardError=syslog 63 SyslogIdentifier=git-daemon 64 65 User=git 66 Group=git 67 68 [Install] 69 WantedBy=multi-user.target 70 EOF 71 systemctl enable --now git-daemon 72 ``` 73 74 6. Create a data store for git repositories. 75 76 ``` 77 mkdir -p /srv/git 78 chown -R git:git /srv/git 79 ``` 80 81 7. Add our global post-receive hook for automated static page {,re}generation. 82 83 ``` 84 su git -s /bin/bash <<EOF 85 cd /srv/git 86 >| post-receive <<EOF2 87 # contents of this repo's post-receive 88 EOF2 89 chmod +x ./post-receive 90 EOF 91 ``` 92 93 8. Allow the `git` user write access to public directory. 94 95 ``` 96 mkdir -p /var/www/html 97 usermod -a -G www-data git 98 chown -R root:www-data /var/www/html 99 ``` 100 101 9. Generate LetsEncrypt SSL certificates. 102 103 ``` 104 which ufw && ufw allow 80 && ufw allow 443 && ufw allow 9418 # if using ufw 105 certbot --nginx # dependency: python3-certbot-nginx 106 crontab -l | { cat; echo "0 0 1 * * certbot --nginx renew"; } | crontab - 107 ``` 108 109 10. Prepare the public directory for static page generation. 110 111 ``` 112 su git -s /bin/bash <<EOF 113 cd /var/www/html 114 >| ./style.css <<EOF2 115 # contents of this repo's style.css 116 EOF2 117 >| ./generate.sh <<EOF2 118 # contents of this repo's generate.sh 119 EOF2 120 chmod +x ./generate.sh 121 # add a custom ./logo.png 122 # add a custom ./favicon.png 123 EOF 124 ``` 125 126 11. Add convenience script for adding new {public,private} git repositories. 127 128 ``` 129 exit # back to non-root admin user 130 mkdir ~/bin 131 echo 'export PATH="$HOME/bin:$PATH"' >> ~/.profile 132 >| ~/bin/new-repo <<EOF 133 # contents of this repo's new-repo 134 EOF 135 chmod +x ~/bin/new-repo 136 sudo install ~/bin/new-repo /usr/local/bin/ 137 ``` 138 139 12. Add new repositories remotely. 140 141 ``` 142 # client-side 143 ssh admin@git.mydomain.net new-repo <public|private> <name> <description> 144 ``` 145 146 13. Push changes to self-hosted server; static pages are henceforth regenerated automatically by virtue of our custom `post-receive` git hook.