No description
|
|
||
|---|---|---|
| .ansible | ||
| group_vars | ||
| inventory | ||
| roles | ||
| vault | ||
| .gitignore | ||
| README.md | ||
| site.yml | ||
infra-ansible — Hetzner Server Infrastructure
Ansible Playbooks für den Hetzner-Server zentral (195.201.29.96).
Betrieb mit Podman (rootful) und Traefik als Reverse Proxy.
Architektur
graph TD
Internet((Internet))
subgraph Hetzner ["🖥️ Hetzner Server zentral — 195.201.29.96"]
UFW[UFW Firewall\nPort 80, 443, 2222, 22022]
subgraph PodmanNet ["Podman Network: proxy-net 10.89.0.0/24"]
Traefik["🔀 Traefik v3.3\nHTTP→HTTPS Redirect\nLet's Encrypt ACME\nDocker Provider via podman.sock"]
Forgejo["🐙 Forgejo 10\nPort 3000 intern\nSSH Port 22 intern\nUID 1000 git"]
Postgres["🐘 PostgreSQL 16\nPort 5432 intern"]
end
SSHD["sshd\nPort 22022\nCurve25519"]
end
subgraph HomeServer ["🏠 Home Server (geplant)"]
Immich["📷 Immich\nnoch nicht deployed"]
end
Internet -->|":80 HTTP"| UFW
Internet -->|":443 HTTPS"| UFW
Internet -->|":2222 Git SSH"| UFW
Internet -->|":22022 Admin SSH"| UFW
UFW --> Traefik
UFW --> SSHD
Traefik -->|"git.freemind.de\nX-Forwarded-Proto: https"| Forgejo
Traefik -.->|"immich.freemind.de\ngeplant"| HomeServer
Forgejo -->|"postgres-forgejo:5432"| Postgres
Netzwerk & Ports
flowchart LR
Browser["🌐 Browser"]
GitClient["💻 Git Client"]
Admin["🔑 Admin"]
Browser -->|"HTTP :80"| Traefik
Browser -->|"HTTPS :443"| Traefik
GitClient -->|"SSH :2222"| Traefik
Admin -->|"SSH :22022"| SSHD["sshd Host"]
Traefik -->|"HTTP :3000"| Forgejo["Forgejo\n10.89.0.x"]
Traefik -->|"TCP :22"| Forgejo
Forgejo -->|"TCP :5432"| Postgres["PostgreSQL\n10.89.0.x"]
Repo-Struktur
infra-ansible/
├── inventory/
│ └── localhost.yml # Ansible Inventory (localhost)
├── group_vars/
│ └── all.yml # Globale Variablen (Images, Ports, Pfade)
├── vault/
│ └── secrets.yml # Ansible Vault (verschlüsselt)
├── roles/
│ ├── common/ # System-Grundkonfiguration
│ │ ├── tasks/main.yml # Packages, UFW, Podman, aardvark-dns
│ │ └── handlers/main.yml
│ ├── traefik/ # Traefik Reverse Proxy
│ │ ├── tasks/main.yml
│ │ ├── handlers/main.yml
│ │ └── templates/
│ │ ├── traefik.yml.j2 # Traefik Hauptkonfig
│ │ └── traefik.service.j2 # systemd Service
│ └── forgejo/ # Forgejo Git Server
│ ├── tasks/main.yml
│ ├── handlers/main.yml
│ └── templates/
│ ├── app.ini.j2 # Forgejo Konfiguration
│ ├── forgejo.service.j2 # systemd Service
│ └── postgres.service.j2
├── site.yml # Master Playbook
├── .vault_pass # Vault-Passwort (nicht im Repo!)
└── .gitignore
Deployment
Voraussetzungen
apt install ansible podman aardvark-dns ufw
Erstes Deployment
# 1. Domain in group_vars anpassen
nano group_vars/all.yml
# 2. Secrets anlegen
ansible-vault create vault/secrets.yml --vault-password-file .vault_pass
# Inhalt: vault_acme_email, vault_db_password, vault_forgejo_secret_key, vault_domain
# 3. DNS A-Record setzen (beim Provider)
# git.freemind.de → 195.201.29.96
# 4. Playbook ausführen
ansible-playbook -i inventory/localhost.yml site.yml --vault-password-file .vault_pass
Updates & Wiederholung
ansible-playbook -i inventory/localhost.yml site.yml --vault-password-file .vault_pass
Das Playbook ist idempotent — mehrfach ausführen ist sicher.
Variablen (group_vars/all.yml)
| Variable | Wert | Beschreibung |
|---|---|---|
domain |
git.freemind.de |
Hauptdomain Forgejo |
traefik_image |
docker.io/traefik:v3.3 |
Traefik Image — kein latest! |
forgejo_image |
codeberg.org/forgejo/forgejo:10 |
Forgejo Image — kein latest! |
postgres_image |
docker.io/postgres:16-alpine |
PostgreSQL Image |
podman_network |
proxy-net |
Podman Bridge Network |
traefik_data_dir |
/opt/traefik |
Traefik Daten (acme.json) |
forgejo_data_dir |
/opt/forgejo |
Forgejo Repos & Daten |
postgres_data_dir |
/opt/forgejo/db |
PostgreSQL Daten |
ssh_port |
2222 |
Forgejo Git SSH Port |
web_port |
80 |
HTTP Port |
web_secure_port |
443 |
HTTPS Port |
Vault Secrets (vault/secrets.yml)
| Variable | Beschreibung |
|---|---|
vault_acme_email |
E-Mail für Let's Encrypt |
vault_db_password |
PostgreSQL Passwort für Forgejo |
vault_forgejo_secret_key |
Forgejo interner Secret Key |
vault_domain |
Domain (muss mit domain übereinstimmen) |
Secrets generieren:
python3 -c "import secrets; print(secrets.token_hex(32))"
Container-Management
# Status
systemctl status traefik forgejo postgres-forgejo
# Logs
journalctl -u forgejo -f
journalctl -u traefik -f
# Alle Container
podman ps
# Restart
systemctl restart forgejo
# Update (Image-Version in group_vars anpassen, dann):
ansible-playbook -i inventory/localhost.yml site.yml --vault-password-file .vault_pass
SSH Zugang
# Admin-Zugang zum Server
ssh root@195.201.29.96 -p 22022
# Git via SSH (nach SSH-Key in Forgejo hinterlegen)
git clone ssh://git@git.freemind.de:2222/USERNAME/repo.git
# ~/.ssh/config empfehlenswert:
# Host git.freemind.de
# Port 2222
# User git
# IdentityFile ~/.ssh/forgejo_ed25519
Bekannte Fixes & Gotchas
timeline
title Deployment-Probleme und Lösungen
section DNS
aardvark-dns fehlte : Container konnten sich nicht gegenseitig auflösen
UFW blockierte Port 53 : ufw allow in on podman1 nötig
section Netzwerk
UFW FORWARD DROP : Container hatten kein Internet
: DEFAULT_FORWARD_POLICY=ACCEPT in /etc/default/ufw
section Traefik
Falscher Socket-Pfad : unix varrun podman.sock statt docker.sock
: Mount als /var/run/docker.sock im Container
X-Forwarded-Proto fehlt : Forgejo dachte es läuft auf HTTP
: Middleware Label + USE_PROXY_HEADERS=true
section Forgejo
Volume-Pfad falsch : /etc/gitea/conf statt /data/gitea/conf
Permissions : Verzeichnisse brauchen owner 1000 git-user
Theme 404 : forgejo-auto statt auto in Forgejo v10
DB User-Theme : UPDATE user SET theme=forgejo-auto in PostgreSQL
Geplante Erweiterungen
- Immich auf Home Server deployen
- Traefik Ingress für Immich via Reverse Proxy einrichten
- Auf Podman rootless migrieren
- Backup-Strategie für Forgejo Repos + PostgreSQL
- SSH-Keys für Workstation und Laptop in Forgejo hinterlegen
- Dieses Repo in Forgejo selbst pushen 🐙
Lizenz
MIT