125 lines
4.3 KiB
Markdown
125 lines
4.3 KiB
Markdown
---
|
|
title: 'Hosting your own Git "server"'
|
|
date: "2022-09-30T14:27:31+02:00"
|
|
author: "$HUMANOID"
|
|
tags: ["git", "ssh"]
|
|
description: "The basis of a Git server is a machine accessible in a way that git understands with a bunch of bare git repositories"
|
|
toc: true
|
|
---
|
|
|
|
# Introduction
|
|
|
|
Pretty much the moment I started to work with Git a few years ago, I've wanted to host my own server.
|
|
I didn't really bother looking into how that could work for a very long time.
|
|
I assumed it would be rather complex considering Git itself is an extremely complex (set of) tool(s) to work with.
|
|
I was hilariously wrong.
|
|
It's _so_ simple to me that I'm under the impression that the lack of posts regarding the topic on blogs like this, is because it's so simple.
|
|
Still, I'm going to spend the rest of this post explaining how to set up a server and why even calling a basic configuration a server, is a bit of an exaggeration.
|
|
|
|
# Setting up the server
|
|
|
|
The first step is to set up a Unix box of any kind.
|
|
Linux, any of the BSDs and probably even Darwin will work (hell, even Haiku might suffice).
|
|
The rest of this post assumes a Debian system.
|
|
Basics requirements are quite few:
|
|
|
|
- It needs to be accessible using SSH.
|
|
- It needs Git installed.
|
|
|
|
## Adding an account
|
|
|
|
Common practice dictates that you have a dedicated account for managing your Git repositories.
|
|
Common practice again dictates that this account be called `git`.
|
|
Its home directory doesn't really matter, but I like tossing it into `/srv/git`.
|
|
Login shell also doesn't matter _yet_, I tend to change it to `bash` for when I need to do things as the `git` user.
|
|
|
|
You can create an account with the following:
|
|
```sh
|
|
sudo useradd git -md /srv/git -s /bin/bash
|
|
```
|
|
- `-d` specifies where the home directory should be
|
|
- `-m` creates the home directory
|
|
- `-s` specifies what binary to use as login shell
|
|
|
|
## Setting up SSH
|
|
|
|
### Client side
|
|
|
|
On the machine from where you want to push your git repositories, generate a new SSH key to access your Git server:
|
|
```sh
|
|
ssh-keygen -t ed25519 -f ~/.ssh/<git-key>
|
|
```
|
|
I also recommend creating an entry in `~/.ssh/config` for your Git server:
|
|
```ssh_config
|
|
Host <host>
|
|
Hostname <hostname>
|
|
User git
|
|
Identityfile ~/.ssh/<git-key>
|
|
```
|
|
|
|
### Server side
|
|
Next step is to make the `git` account accessible over SSH.
|
|
To do this, log in as the `git` user and create a `.ssh` directory with an `authorized_keys` file with the public half of the `<git-key>` keypair:
|
|
```sh
|
|
sudo su - git
|
|
umask 077 # strict read write permissions
|
|
mkdir ~/.ssh
|
|
cat <git-key>.pub >> ~/.ssh/authorized_keys
|
|
```
|
|
|
|
## Adding a repository
|
|
|
|
You should now be able to log into your host as the `git` user with using `<git-key>`.
|
|
Setting up the route from client to server is half the work.
|
|
|
|
Next step, to make this actually server a Git repository, is to create one.
|
|
All this requires is a bare Git repository somewhere within `/srv/git`.
|
|
To do this, log in as the `git` user and run:
|
|
```sh
|
|
git init --bare <repo-name>.git
|
|
```
|
|
|
|
That's it.
|
|
|
|
You now have a Git "server" with a repo named `<repo-name>`.
|
|
|
|
To add something to this repo, on your client machine create a new repository and add `<host>:/srv/git/<repo-name>.git` as remote and push your project to it.
|
|
Common practice dictates that this remote be called `origin`:
|
|
```sh
|
|
mkdir my-fancy-project
|
|
cd my-fancy-project
|
|
git init
|
|
git remote add origin <host>:/srv/git/<repo-name>.git
|
|
echo "# Self-hosted repo!" > README.md
|
|
git add -A
|
|
git commit -m "Initial commit"
|
|
git push -u origin main # assuming you use main as your default branch name
|
|
```
|
|
|
|
To clone this repository on another machine, add the `<git-key>` SSH keypair and related configuration section in `~/.ssh/config` so said machine and run:
|
|
```sh
|
|
git clone <host>:/srv/git/<repo-name>.git
|
|
```
|
|
|
|
# Automation
|
|
|
|
Creating bare repositories by hand gets annoying quite quickly.
|
|
I have an SSH forced command for another key that runs a script with the following:
|
|
```sh
|
|
#!/bin/sh
|
|
|
|
BASELOC="/srv/git"
|
|
echo "Enter new repo name:"
|
|
read REPONAME
|
|
[ -z $REPONAME ] && echo "No repo initialised" && exit 1
|
|
git init --bare $BASELOC/$REPONAME.git
|
|
```
|
|
`authorized_keys` entry for `git` user:
|
|
|
|
```authorized_keys
|
|
command="/srv/git/.bin/new-repo" ssh-ed25519 <new-repo-git-key>.pub
|
|
```
|
|
|
|
Another thing you could do is change the login shell binary to a script that does something similar.
|
|
I haven't bothered to do so for reasons that presently escape me.
|