bastien-mrq/gitfed / INSTALL.md
INSTALL.md
Code Preview
# Installer gitfed sur un VPS, de zéro
Guide pas à pas pour monter une instance gitfed sur un VPS tout neuf, sans
rien présupposer d'installé au préalable. Si k3s/Traefik/cert-manager
tournent déjà chez toi (par exemple à côté d'ess-helm), regarde plutôt
[`deploy/k8s/README.md`](deploy/k8s/README.md), qui suppose exactement ça.
Compte environ 15-20 minutes, DNS mis à part (la propagation peut prendre
un peu de temps).
**Plus simple : `gitfed-install`.** Un assistant terminal qui fait
exactement les étapes ci-dessous à ta place — détecte ce qui existe déjà,
demande domaine/email, installe/construit/déploie, et diagnostique
lui-même le blocage `ErrImageNeverPull` s'il survient. Sur le VPS :
```sh
git clone https://git.neuromancer.ovh/bastien-mrq/gitfed.git && cd gitfed
go build -o gitfed-install ./cmd/gitfed-install
./gitfed-install
```
(nécessite Go — `curl -sfL https://go.dev/dl/go1.25.4.linux-amd64.tar.gz \|
sudo tar -C /usr/local -xz` puis `export PATH=$PATH:/usr/local/go/bin` si
ce n'est pas déjà installé sur le VPS.) Le reste de ce document explique
les mêmes étapes en détail, à la main — utile pour comprendre ce que
l'assistant fait, ou si ta situation ne rentre pas dans son parcours.
## Ce qu'il te faut avant de commencer
- Un VPS avec une IP publique (ce guide suppose Ubuntu/Debian), accès root
ou sudo.
- Un nom de domaine (ou sous-domaine) que tu contrôles, pour pouvoir y
ajouter un enregistrement DNS.
- Les ports suivants ouverts vers le VPS (pare-feu du fournisseur/`ufw`) :
`22` (ton propre SSH), `80` et `443` (Traefik/HTTPS), `2222` (git+ssh de
gitfed — volontairement pas sur le port 22 pour ne pas entrer en
conflit avec le SSH du VPS lui-même).
- Docker installé **sur le VPS lui-même**, pas sur ta machine de travail —
voir pourquoi à l'étape 4.
## 1. Installer k3s
Sur le VPS :
```sh
curl -sfL https://get.k3s.io | sh -
sudo k3s kubectl get nodes # doit afficher un nœud "Ready"
```
k3s embarque Traefik comme contrôleur d'ingress par défaut — rien à
installer en plus pour ça. Pour éviter de taper `sudo k3s kubectl` à
chaque fois, exporte `KUBECONFIG` ou copie
`/etc/rancher/k3s/k3s.yaml` :
```sh
mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $(id -u):$(id -g) ~/.kube/config
kubectl get nodes # doit marcher sans sudo maintenant
```
## 2. Installer cert-manager + un émetteur Let's Encrypt
```sh
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml
kubectl -n cert-manager rollout status deployment/cert-manager-webhook
```
(l'URL `/releases/latest/download/...` pointe toujours vers la dernière
version stable — pas besoin de connaître le numéro de version à jour.)
Puis crée un `ClusterIssuer` Let's Encrypt — **remplace `toi@example.com`
par ta vraie adresse**, Let's Encrypt s'en sert pour les alertes
d'expiration :
```sh
cat <<'EOF' | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: toi@example.com
privateKeySecretRef:
name: letsencrypt-prod-key
solvers:
- http01:
ingress:
ingressClassName: traefik
EOF
```
`deploy/k8s/ingress.yaml` (utilisé plus bas) référence cet émetteur par
son nom exact `letsencrypt-prod` — s'il s'appelle autrement ici, il faudra
aussi changer l'annotation dans `ingress.yaml`.
## 3. Pointer le DNS
Ajoute un enregistrement A (et AAAA si le VPS a une IPv6) pointant vers
l'IP du VPS :
```
git.tondomaine.fr -> <IP publique du VPS>
```
Vérifie que ça a propagé avant de continuer (`dig git.tondomaine.fr` doit
renvoyer la bonne IP) — sinon le défi ACME de l'étape 6 échouera.
## 4. Récupérer gitfed et construire l'image
**Construis l'image directement sur le VPS, pas sur ta machine de
travail.** Si ta machine est un Mac Apple Silicon (ou n'importe quelle
machine ARM) et que le VPS tourne en x86_64 (le cas le plus courant chez
les hébergeurs), une image construite en local et copiée sur le VPS ne
sera tout simplement pas la bonne architecture — `docker build` construit
par défaut pour l'architecture de la machine qui exécute la commande.
Construire sur le VPS élimine complètement ce risque.
Installe Docker sur le VPS s'il n'y est pas déjà (script officiel) :
```sh
curl -fsSL https://get.docker.com | sudo sh
```
Puis récupère le code et construis :
```sh
git clone <url-du-dépôt-gitfed>
cd gitfed
sudo docker build -f deploy/docker/Dockerfile -t gitfed:$(cat VERSION) .
sudo docker save gitfed:$(cat VERSION) | sudo k3s ctr images import -
```
**Point important, source du blocage le plus courant à ce stade** :
`deploy/k8s/deployment.yaml` référence l'image par un tag précis
(`gitfed:X.Y.Z`, visible avec `grep image: deploy/k8s/deployment.yaml`) et
le pod est configuré en `imagePullPolicy: Never` — k3s n'ira jamais la
chercher ailleurs. Construire avec `-t gitfed:latest` au lieu du tag exact
attendu fait planter le pod en `ErrImageNeverPull` indéfiniment. La
commande `docker build -t gitfed:$(cat VERSION)` ci-dessus construit
justement avec le bon tag — ne pas la remplacer par `:latest`.
## 5. Configurer gitfed pour ton domaine
Deux fichiers ont des valeurs à adapter à ton domaine :
**`deploy/k8s/configmap.yaml`** — champ `domain` (et `contact`, ton email,
optionnel) :
```json
"domain": "git.tondomaine.fr",
"contact": "toi@example.com",
```
**`deploy/k8s/ingress.yaml`** — l'hôte, à deux endroits :
```yaml
tls:
- hosts: ["git.tondomaine.fr"]
secretName: gitfed-tls
rules:
- host: git.tondomaine.fr
```
## 6. Déployer
Toujours sur le VPS, dans le dossier `gitfed` cloné à l'étape 4 (avec les
fichiers modifiés à l'étape 5) :
```sh
kubectl apply -f deploy/k8s/namespace.yaml
kubectl apply -f deploy/k8s/configmap.yaml
kubectl apply -f deploy/k8s/pvc.yaml
kubectl apply -f deploy/k8s/deployment.yaml
kubectl apply -f deploy/k8s/service.yaml
kubectl apply -f deploy/k8s/ingress.yaml
```
Observe le démarrage :
```sh
kubectl -n gitfed get pods -w
```
Les deux conteneurs du pod doivent finir à `2/2 Running` — `web` attend le
socket admin de `server` en boucle avant de démarrer, donc un `0/2` bref
au tout début est normal. S'il reste bloqué, voir « Pannes courantes »
plus bas.
## 7. Vérifier
```sh
curl https://git.tondomaine.fr/.well-known/gitfed.json
curl https://git.tondomaine.fr/ # page d'accueil de gitfed-web
```
Le premier doit renvoyer un petit JSON avec ton domaine et une clé
publique de CA ; le second, du HTML. Si `curl` refuse le certificat ou
timeout, le souci est probablement DNS ou le défi ACME (voir plus bas).
## 8. Créer le premier compte (admin)
Il n'y a aucun compte au démarrage, et pas d'auto-inscription — c'est
volontaire. On le crée directement contre le socket admin du pod :
```sh
kubectl -n gitfed exec -it deployment/gitfed -c server -- \
gitfed-tui -config /etc/gitfed/gitfed.json
```
**Users → a** (add user) : nom d'utilisateur, ta clé SSH publique, un mot
de passe, puis répondre `y` à la question admin. Connecte-toi ensuite sur
`https://git.tondomaine.fr/login` avec ce compte — tu dois voir un lien
**Admin** dans le menu. À partir de là, cet admin peut créer d'autres
comptes depuis **Admin → Utilisateurs** dans l'interface web ;
`gitfed-tui` ne sert plus qu'en secours (interface web injoignable).
## 9. Cloner pour de vrai
Le login web n'ouvre qu'une session web — `git clone`/`push` passe
toujours par SSH, indépendamment :
```sh
git clone ssh://git@git.tondomaine.fr:2222/<utilisateur>/<dépôt>
```
Si ça fonctionne, l'installation est terminée.
## Pannes courantes
- **Pod bloqué en `ErrImageNeverPull`** — c'est presque toujours un tag
d'image qui ne correspond pas (voir étape 4). Vérifie avec
`kubectl -n gitfed describe pod <nom-du-pod>` (section Events) et
compare `grep image: deploy/k8s/deployment.yaml` avec
`sudo k3s ctr images ls | grep gitfed` sur le VPS — le tag doit
apparaître identique des deux côtés.
- **Certificat qui ne s'obtient jamais (`ingress` reste en HTTP, pas de
cadenas)** — vérifie que le DNS a bien propagé (`dig`), puis regarde les
logs du pod solver : `kubectl get pods | grep acme-http-solver` doit
exister brièvement pendant la validation ; s'il traîne en `Pending`,
c'est que le port 80 n'est pas joignable depuis l'extérieur (pare-feu,
ou DNS pas encore propagé).
- **`web` reste à `0/2` ou `1/2` longtemps** — `web` attend que `server`
crée le socket admin ; si `server` lui-même ne démarre pas, regarde ses
logs : `kubectl -n gitfed logs deployment/gitfed -c server`.
- **`kubectl` : `connection refused`** — as-tu bien fait
`sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config` (étape 1) ? Sinon,
préfixe toutes les commandes `kubectl` par `sudo k3s kubectl` à la
place.
## Pour la suite
- **Mises à jour** : ne pas refaire les étapes 4/6 à la main après la
première fois — utilise
[`deploy/update.sh`](deploy/update.sh), qui construit et importe une
image taguée avec la vraie version, bascule `deployment.yaml` dessus, et
attend que le rollout soit prêt. Ce script se lance depuis **ta machine
de travail** (il pousse le code sur le VPS via `rsync` puis construit
là-bas par SSH, il ne dépend donc pas de son architecture) — il te
faudra un clone de gitfed en local à ce moment-là, en plus de celui sur
le VPS créé à l'étape 4.
D'abord, indique-lui où déployer — obligatoire, rien n'est pré-rempli :
```sh
export GITFED_VPS_HOST=toi@ton-vps
```
(ou mets cette ligne dans `deploy/update.env`, gitignoré, pour ne pas
avoir à l'exporter à chaque session.)
Deux façons de l'utiliser ensuite, selon ta situation :
- **Tu modifies le code toi-même** (un fork, tes propres changements) :
`deploy/update.sh` / `deploy/update.sh minor` / `deploy/update.sh
X.Y.Z` — ajoute d'abord une entrée `## X.Y.Z` à `CHANGELOG.md`
décrivant le changement, le script refuse de continuer sans ça.
- **Tu suis juste les mises à jour de quelqu'un d'autre** (tu n'as rien
modifié, tu veux juste la dernière version) : `deploy/update.sh
current` — récupère le code (`git pull --ff-only`, refuse si le
répertoire de travail n'est pas propre) puis construit et déploie,
sans toucher à `VERSION` ni committer quoi que ce soit. Se lance
toujours depuis ta machine de travail, comme les autres modes.
Plus simple : **`gitfed-ctl`**, un utilitaire pensé pour ce cas
précis — il tourne directement sur le VPS (pas de `rsync`/SSH vers
soi-même, donc pas de mot de passe redemandé à chaque étape), affiche
les nouvelles versions disponibles avec leur changelog, et fait
acquitter individuellement tout changement cassant avant de continuer.
Le VPS n'a pas `go` installé (le build de gitfed se fait dans un
conteneur, pas besoin de `go` sur l'hôte normalement) — installe-le
via un conteneur Go jetable, qui écrit le binaire directement dans
`/usr/local/bin` :
```sh
docker run --rm -e GOPRIVATE=git.neuromancer.ovh/* -e GOBIN=/out -v /usr/local/bin:/out \
golang:1.25-bookworm go install git.neuromancer.ovh/bastien-mrq/gitfed/cmd/gitfed-ctl@latest
cd ~/gitfed-src # ou ton propre checkout sur le VPS
sudo gitfed-ctl
```
- **Sauvegardes** : tout ce qui compte vit sur le volume `gitfed-data`
(base, clé de CA, clé d'hôte SSH, dépôts). Voir la section « Backups »
de [`deploy/k8s/README.md`](deploy/k8s/README.md#backups) pour
`deploy/backup.sh` et la procédure de restauration.
- **Pourquoi le déploiement est structuré ainsi** (un seul pod, deux
conteneurs, pourquoi `replicas` doit rester à `1`, etc.) — c'est expliqué
en détail dans [`deploy/k8s/README.md`](deploy/k8s/README.md).