aboutsummaryrefslogtreecommitdiff
path: root/blog_src/git_server.md
diff options
context:
space:
mode:
Diffstat (limited to 'blog_src/git_server.md')
-rw-r--r--blog_src/git_server.md174
1 files changed, 174 insertions, 0 deletions
diff --git a/blog_src/git_server.md b/blog_src/git_server.md
new file mode 100644
index 0000000..4fc5505
--- /dev/null
+++ b/blog_src/git_server.md
@@ -0,0 +1,174 @@
+# How to make your own git server/website
+
+## Server setup
+
+We're going to create a `git` user and group, will be used for accessing our git repositories without needing to be root.
+
+```sh
+useradd -m git
+mkdir /srv/git
+chown git:git /srv/git
+```
+
+The repositories will be stored as bare, this mean that we will only store the `.git` folder to save space.
+
+>To create a bare repo: `git init --bare`
+
+>To clone a repo as bare: `git clone bare <location>`
+
+You can either add a password for the git user or put your ssh public key in `/home/git/.ssh/authentication_keys` and disable password authentication for ssh.
+
+You can now clone from your server with `git clone git@<hostname>:/srv/git/<reponame>`
+
+## Better server interaction with git-shell
+
+Permit the git user to have a regular shell can be a security issue,
+we would like that to restrict him to a few action,
+like creating/deleting a repository, importing a repository, listing the repo currently stored
+
+Make the git-shell a valid shell `echo $(which git-shell) >> /etc/shells`
+
+Change the shell of the git user `chsh -s $(which git-shell) git`
+
+If you try to ssh as the git user, you will be greeted with something along the line of:
+
+```
+fatal: Interactive git shell is not enabled.
+hint: ~/git-shell-commands should exist and have read and execute access.
+Connection to <host> closed.
+```
+
+As suggested by the hint we have to create the directory `/home/git/git-shell-commands` and put the commands (executable) that the git user is allowed to execute in.
+
+Here is a script to create a repo:
+
+```sh
+#!/bin/sh
+[ $# -ne 1 ] && echo "Usage: $0 name" && exit 1
+repo_path="/srv/git/$1.git"
+[ -d "$repo_path" ] && echo "$0: Error: $repo_path already exist" && exit 2
+mkdir "$repo_path"
+git -C "$repo_path" init --bare
+```
+
+Put it under `git-shell-commands/create` and make it executable then try to ssh as the git user once again.
+
+You should have a prompt like `git> `, you can call the `create` command with a repo name as the first argument and it should create a new repository for you.
+
+## Allow anyone to clone with git-daemon
+
+The git daemon will allow annone to clone your repos with something like `git clone git://<host>/<repo>`
+
+`git daemon --reuseaddr --base-path=/srv/git/ /srv/git/` and that's it
+
+You should make it a service in your service supervisor, example with systemctl:
+
+```
+[Unit]
+Description=Start Git Daemon
+[Service]
+ExecStart=/usr/bin/git daemon --reuseaddr --base-path=/srv/git/ /srv/git/
+Restart=always
+RestartSec=500ms
+StandardOutput=syslog
+StandardError=syslog
+SyslogIdentifier=git-daemon
+User=git
+Group=git
+[Install]
+WantedBy=multi-user.target
+```
+
+Put it in `/etc/systemctl/system/git-daemon.service` and run `systemctl enable git-daemon` then `systemctl start git-daemon`.
+
+### Public/private repo
+
+You may want to introduce a distiction of which repo is public and which is private
+
+A simple way to do this is by creating a `public` directory in `/srv/git` which will contain symbolic link to the repo in `/srv/git`
+
+```
+/srv/git
+|- foo.git
+|- bar.git
+|- qux.git
+|- public
+ |- foo.git -> /srv/git/foo.git
+ |- bar.git -> /srv/git/bar.git
+```
+
+You can change the git daemon to only serve the public repositories `git daemon --reuseaddr --base-path=/srv/git/public /srv/git/public`
+
+## Generate a static website
+
+Here we will create a site that look's like [this](https://git.suckless.org) with [nginx](https://nginx.org), [stagit](https://git.codemadness.org/stagit/) and a few scripts.
+
+If you don't like the minimalistic appearence of the site, [here](https://git.wiki.kernel.org/index.php/Interfaces,_frontends,_and_tools#Web_Interfaces) is a list of alternative.
+
+Install nginx (on Debian based distro): `apt install nginx`
+
+Create a basic configuration file for your site:
+
+```
+server {
+ root /var/www/git;
+ index index.html index.htm;
+
+ server_name git.<hostname> www.git.<hostname>;
+
+ location / {
+ try_files $uri $uri/ =404;
+ }
+}
+```
+
+It's a convention to put it in a `git.` subdomain.
+`systemctl enable nginx && systemctl start nginx`
+
+Install stagit:
+
+```
+git clone git://git.codemadness.org/stagit
+cd stagit
+make
+make install
+```
+
+To generate a static page for a repo `stagit /path/to/repo`.
+To generate an index for multiple repositories `stagit-index repo1 repo2 repo3 > index.html`
+
+Here is a script to generate a site for all repo in `/srv/git/public`
+
+```sh
+#!/bin/sh
+
+repos=$(find /srv/git/public/ -type l)
+current=$(pwd)
+
+for repo in $repos; do
+ repo_name=$(basename "$repo" | sed 's/\.git//')
+ repo_static_path="/var/www/git/$repo_name"
+ mkdir -p "$repo_static_path"
+ cd "$repo_static_path" || exit 1
+ echo "git://cacharle.xyz/$repo_name" > "$repo/url"
+ stagit "$repo"
+ ln -sf "$repo_static_path/log.html" "$repo_static_path/index.html"
+ echo "Generated $repo_static_path"
+done
+
+echo "Creating index"
+stagit-index $repos > /var/www/git/index.html
+
+cd "$current" || exit 1
+chown -R git:git /srv/git
+```
+
+There is more smart ways to handle this to rebuild the webpages each time someone pushes to the repo with [git hooks](https://git.codemadness.org/stagit/file/README.html#l92).
+
+## Sources
+
+* [Setting up \*Your Own\* Git Server](https://www.youtube.com/watch?v=ju9loeXNVW0)
+* [Git book - setting up the server](https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server)
+* [Git book - git daemon](https://git-scm.com/book/en/v2/Git-on-the-Server-Git-Daemon)
+* [stagit - Static website generator for git repository](https://git.codemadness.org/stagit/)
+* [git-shell man](https://git-scm.com/docs/git-shell.html)