git-selfhost

Self-hosted git server with auto-regenerating static stagit frontend
git clone git://git.deurzen.net/git-selfhost
Log | Files | Refs | README

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.