cat ~/projects/homelab/README
Homelab na Proxmoxie
Około 30 usług w kontenerach LXC i maszynach wirtualnych: własny Git z CI, synchronizacja z GitHubem, kopie zapasowe, sekrety i inwentarz aktualizacji.
Cel
Utrzymywać własne usługi (Git, CI, bazy, media, serwery gier, modele AI) na jednym serwerze tak, jak utrzymuje się produkcję: z kopiami zapasowymi, kontrolą miejsca na dyskach, inwentarzem aktualizacji i niezależnością od zewnętrznych platform.
Rozwiązanie
Proxmox z kontenerami LXC i kilkoma maszynami wirtualnymi. Forgejo jest głównym repozytorium wszystkich projektów, a GitHub kopią synchronizowaną co 5 minut własnym skryptem. CI działa na Forgejo Actions z runnerem w osobnym kontenerze. Sekrety są w OpenBao, kopie zapasowe robi vzdump i nocny pg_dump na NAS.
Architektura
- Proxmox VE: kontenery LXC dla usług, osobne kontenery dla testów, CI, bazy PostgreSQL i modeli AI.
- Forgejo jako główny Git; forge-sync (Python, timer systemd co 5 minut) przenosi zmiany fast-forward w obie strony, a tagi wydań tylko z Forgejo na GitHub.
- Forgejo Actions z runnerem LXC buduje i testuje projekty, w tym paczki .deb, AppImage i APK.
- OpenBao przechowuje sekrety aplikacji, gitleaks pilnuje, żeby nie trafiły do repozytoriów.
- Kopie zapasowe: vzdump kontenerów (7 dziennych, 4 tygodniowe) i niezależny nocny pg_dump bazy na NAS.
- Inwentarz w aplikacji ariku.pl zbiera stan hostów, dysków (SMART), kontenerów i pakietów do aktualizacji.
Decyzje techniczne
- Własny skrypt synchronizacji zamiast push mirrora
- Wbudowany mirror Forgejo robi git push --mirror i kasuje na GitHubie gałęzie, których nie ma na Forgejo, w tym gałęzie sesji pracujących tylko na GitHubie. forge-sync przenosi tylko fast-forward, a rozjechaną historię zgłasza jako konflikt i niczego nie nadpisuje.
- Tagi wydań tylko w jedną stronę
- Tag v* na Forgejo uruchamia wdrożenie produkcyjne. Tagi z GitHuba są ignorowane, więc nic spoza głównego repozytorium nie wywoła deployu.
- CI u siebie
- Potoki przeszły z GitHub Actions na Forgejo Actions z lokalnym runnerem: buildy nie zależą od limitów i rozliczeń zewnętrznej platformy.
Problemy i rozwiązania
- Baza PostgreSQL bez kopii zapasowej
- Kontener bazy nie był w żadnym zadaniu backupu. Dodałem go do codziennego vzdump i postawiłem niezależny nocny pg_dump na NAS.
- Błędy w zadaniu backupu
- Zadanie vzdump odwoływało się do usuniętej maszyny i co miesiąc kończyło się błędem. Usunąłem nieistniejący identyfikator z konfiguracji.
- Pełny dysk
- Pula dyskowa i NAS doszły do granicy zajętości. Porządki według spisanego planu: osierocone obrazy i pliki tymczasowe, fstrim, a każde usunięcie potwierdzane osobno.