HostiServer
2026-10-09 11:19
Gitea / Forgejo v Dockeru: kompletní self-hosted stack
📚 Série „Docker na VPS", část 5 z 5:
- Docker na VPS: instalace a první kontejner
- Docker Compose: několik služeb najednou
- Docker v produkci
- Docker + CI/CD: automatické nasazení s GitHub Actions / GitLab CI
- Gitea / Forgejo v Dockeru: kompletní self-hosted stack ← jste zde
Gitea / Forgejo v Dockeru: kompletní self-hosted stack
Všechny čtyři předchozí články série se opíraly o to, že kód žije někde vně — na GitHubu, GitLabu nebo jiné externí platformě. Self-hosted Git tuto závislost zcela odstraňuje: plnou kontrolu nad kódem, soukromí bez výjimek pro cizí služby, žádná licenční omezení pro interní nebo uzavřené projekty, a k tomu navíc — vlastní Docker registry a vlastní CI, které nepočítá minuty sestavení a neomezuje privátní repozitáře.
Výsledkem tohoto článku bude na jednom VPS plnohodnotná platforma ze čtyř služeb: Forgejo (samotný Git server a webové rozhraní), PostgreSQL, act runner (vykonavatel CI pipeline) a Nginx — vše v jednom docker-compose.yml.
Tento článek uzavírá hned dvě série. Z Docker série se opírá o vše probrané dříve: Compose s několika službami (článek 2), Nginx a SSL (článek 3), princip automatického nasazení (článek 4). Ze série „CI/CD od nuly" — na koncept self-hosted runneru a syntaxi pipeline podobných Actions.
2. Gitea vs Forgejo
Forgejo je fork Gitea, který se oddělil v roce 2022 kvůli neshodám ohledně otevřenosti řízení projektu. Vyvíjí se jako komunitní iniciativa pod záštitou Codebergu, zatímco Gitea zůstává pod samostatným vedením.
Funkčně jsou oba projekty dnes prakticky identické a API je plně kompatibilní — migrace databáze a repozitářů v obou směrech proběhne bez ztrát. Rozdíl je většinou v názvech Docker image a v detailech governance modelu. Vše, co je dále v tomto článku popsáno, platí pro obě varianty stejně; jako hlavní příklad je zde použito Forgejo.
3. Architektura stacku
Stack se skládá ze čtyř služeb:
| Služba | Role |
|---|---|
forgejo |
Webové rozhraní a samotný Git server |
db |
PostgreSQL — úložiště dat Forgejo |
runner |
act runner — vykonavatel CI pipeline |
nginx |
Reverse proxy a terminace SSL |
Síť forgejo-net izoluje forgejo, db a runner v jednom interním prostoru; navenek vystupuje pouze nginx, přes porty 80 a 443. Za uchování dat odpovídají dva volumes: forgejo-data uchovává samotné repozitáře, konfiguraci a Git LFS objekty, pgdata databázi. SSH pro git operace vystupuje navenek samostatným portem (typicky 2222 → 22 uvnitř kontejneru), nebo je přesměrováno na hosta přes samostatný mechanismus — o tom níže.
4. docker-compose.yml
Celý stack v jednom souboru:
services:
forgejo:
image: codeberg.org/forgejo/forgejo:9
environment:
FORGEJO__server__ROOT_URL: https://git.example.com
FORGEJO__server__SSH_DOMAIN: git.example.com
FORGEJO__server__SSH_PORT: "2222"
FORGEJO__database__DB_TYPE: postgres
FORGEJO__database__HOST: db:5432
FORGEJO__database__NAME: forgejo
FORGEJO__database__USER: forgejo
FORGEJO__database__PASSWD: ${DB_PASSWORD}
volumes:
- forgejo-data:/data
ports:
- "2222:22"
depends_on:
db:
condition: service_healthy
networks: [forgejo-net]
restart: unless-stopped
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: forgejo
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: forgejo
volumes: [pgdata:/var/lib/postgresql/data]
healthcheck:
test: ["CMD-SHELL", "pg_isready -U forgejo -d forgejo"]
interval: 5s
timeout: 5s
retries: 10
networks: [forgejo-net]
restart: unless-stopped
runner:
image: code.forgejo.org/forgejo/runner:3
environment:
FORGEJO_INSTANCE_URL: https://git.example.com
FORGEJO_RUNNER_REGISTRATION_TOKEN: ${RUNNER_TOKEN}
volumes:
- runner-data:/data
- /var/run/docker.sock:/var/run/docker.sock
networks: [forgejo-net]
restart: unless-stopped
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- /etc/letsencrypt:/etc/letsencrypt:ro
depends_on: [forgejo]
networks: [forgejo-net]
restart: unless-stopped
volumes:
forgejo-data:
pgdata:
runner-data:
networks:
forgejo-net:
Závislost forgejo na db přes condition: service_healthy funguje na stejném principu jako vazba app → db v článku 2 této série: bez healthchecku by se Forgejo mohlo pokusit připojit k databázi dříve, než je PostgreSQL skutečně připraven přijímat spojení.
Konfigurace Forgejo přes proměnné prostředí s prefixem FORGEJO__ je doporučený způsob, pohodlnější než bind-mount hotového app.ini: všechna nastavení zůstávají vidět přímo v docker-compose.yml, bez samostatného souboru, na jehož synchronizaci při přesunu na jiný server se snadno zapomene. Klíčové proměnné jsou SERVER__ROOT_URL (veřejná adresa), SERVER__SSH_DOMAIN (domén pro git klony přes SSH), blok database__* s typem a přístupem k PostgreSQL, a v případě potřeby sekce mailer pro e-mailová oznámení. Služba runner se registruje k Forgejo pomocí tokenu (podrobněji v kapitole 8) a svůj stav ukládá do vlastního volume.
5. SSH a klonování
Forgejo ve výchozím nastavení naslouchá SSH uvnitř kontejneru na standardním portu 22. Navenek je tento port mapován na 2222, aby nekolidoval se systémovým SSH serverem samotného hosta, který už port 22 využívá pro administraci serveru.
V konfiguraci Forgejo se to projevuje dvojicí SSH_PORT=2222 a SSH_DOMAIN=git.example.com — přesně tyto hodnoty určují, jak bude vypadat příkaz pro klonování jakéhokoli repozitáře:
git clone git@git.example.com:2222/user/repo.git
Existuje i alternativní cesta — SSH passthrough přes AuthorizedKeysCommand na samotném hostu, kdy systémové SSH hosta přesměrovává git požadavky do kontejneru. To umožňuje nechat standardní port 22 pro git klony bez přídavného :2222 v adrese, ale konfigurace je výrazně složitější než jednoduché přesměrování portu.
6. První spuštění a nastavení
Při prvním startu Forgejo ve výchozím nastavení zobrazí Installation wizard přímo v prohlížeči — několik kroků pro nastavení databáze, administrátora a obecných parametrů. Tento krok lze zcela obejít tak, že předem předáte všechny potřebné hodnoty přes proměnné prostředí a přidáte INSTALL_LOCK=true — pak se kontejner spustí okamžitě ve stavu připraveném k práci, bez interaktivního průvodce.
První účet zaregistrovaný v systému se ve výchozím nastavení automaticky stane administrátorem; alternativně lze admina nastavit explicitně přes FORGEJO__security__ADMIN_USER. Zbytek — SSH klíče uživatelů, organizace, viditelnost repozitářů — se už konfiguruje přes běžné webové rozhraní stejně jako u cloudových obdob.
7. Nginx + SSL
Konfigurace Nginx zde téměř jedna k jedné opakuje článek 3 série: proxy_pass http://forgejo:3000; a stejná sada hlaviček — Host, X-Real-IP, X-Forwarded-Proto. SSL se získává stejným způsobem přes Let's Encrypt a Certbot v režimu webroot, se stejným deploy hookem pro reload po obnovení certifikátu.
Důležitá nuance právě pro Git server: Nginx proxuje pouze webový provoz (HTTP/HTTPS). SSH provozu pro git operace se vůbec nedotýká — ten jde přímo na port 2222, mimo Nginx, přímo do kontejneru forgejo.
8. Act Runner
Act runner je oficiální vykonavatel CI pipeline od týmu Gitea/Forgejo. Vykonává soubory z .forgejo/workflows/*.yml, jejichž formát je kompatibilní se syntaxí GitHub Actions — převážná většina jednoduchých workflow se přenese téměř beze změn.
Registrace runneru k instanci Forgejo probíhá přes token: Settings → Actions → Runners → New runner ve webovém rozhraní vydá jednorázový token, který se při prvním startu předá kontejneru runneru přes proměnnou prostředí.
Existují dva režimy vykonávání úloh. Docker-in-Docker izoluje runner zcela — úlohy se vykonávají ve vnořeném Docker démonu, nedostupném zbytku hosta, ale konfigurace je složitější. Jednodušší varianta je přesměrovat hostitelský /var/run/docker.sock přímo do kontejneru runneru: nastavení je minimální, runner však v takovém případě získá faktický přístup k Dockeru hosta, podle stejné rizikové logiky jako Traefik v článku 3 této série.
Labels přiřazené runneru při registraci určují, které hodnoty runs-on: ve workflow souborech dokáže obsluhovat — stejný princip jako u self-hosted runnerů GitHub Actions nebo GitLab CI.
9. První pipeline
Soubor .forgejo/workflows/deploy.yml se píše syntaxí identickou s GitHub Actions. Standardní tok je stejný abstraktní pipeline z článku 4 série: trigger na push, checkout kódu, sestavení Docker image, publikace — jen teď se to vše vykonává na vlastním runneru, nikoli na cizí infrastruktuře cloudové CI platformy.
ℹ️ Detailní syntaxe: podrobné nastavení workflow souborů pro Gitea/Forgejo Actions je rozebráno v samostatném materiálu série „CI/CD od nuly", věnovaném přímo této platformě.
10. Forgejo Container Registry
Forgejo má vestavěný OCI kompatibilní container registry, dostupný přímo na adrese vaší instance — git.example.com — jako alternativu k Docker Hub nebo ghcr.io z článku 4. Image se ukládají přímo u samotných repozitářů a autorizace používá stejný token jako git operace — samostatný účet pro registry zřizovat není nutné.
Tím se stack uzavírá do jednoho celku: Forgejo zároveň plní roli Git serveru, CI platformy a registry — všechny tři komponenty, které v předchozím článku série byly rozmístěny po různých externích službách, nyní žijí na jednom VPS pod vaší plnou kontrolou.
11. Zálohy a aktualizace
Spolehlivá záloha se skládá ze tří kroků: zastavit Forgejo, zazálohovat volume forgejo-data (repozitáře, konfigurace, LFS objekty), samostatně provést dump databáze přes pg_dump. Oba soubory je vhodné uchovávat společně, s označením data — obnova z časově nesladěného archivu repozitářů a dumpu databáze může vést k nekonzistentnímu stavu.
Aktualizace verze následuje vzor obvyklý v celé sérii: docker compose pull, poté docker compose up -d. Forgejo automaticky podporuje rolling migrace databáze při startu nové verze, takže ve většině případů nejsou potřeba žádné další manuální kroky. Výjimkou jsou major aktualizace: před nimi je vhodné nahlédnout do CHANGELOGu konkrétní verze, protože některé major přechody vyžadují samostatný manuální krok před spuštěním nového image.
12. Závěr a shrnutí série
Cesta celé série — od docker run hello-world v prvním článku až po kompletní self-hosted stack, který spojuje Git, CI, registry a SSL v jednom docker-compose.yml na jednom serveru. Každý další článek odstranil jedno konkrétní omezení předchozího: manuální spouštění kontejnerů → deklarativní popis stacku → produkční připravenost → automatické nasazení → plná nezávislost na externích platformách.
Celý tento stack lze znovu vytvořit na jakémkoli novém VPS přibližně za třicet minut: git clone konfiguračního repozitáře s docker-compose.yml a .env, poté docker compose up -d — a platforma běží.
Logickým pokračováním pro ty, kterým už jeden server nestačí, je Docker Swarm: stejný přístup k popisu stacku, ale rozložený napříč několika nody, s automatickým failoverem při výpadku jednoho z nich.
📚 Navigace sérií:
Čtete část 5 z 5 „Gitea / Forgejo v Dockeru: kompletní self-hosted stack" — závěrečný článek série.
Předchozí: Část 4. Docker + CI/CD: automatické nasazení ←
🚀 VPS pro váš vlastní Git + CI + registry
Čtyři služby najednou — Git server, databáze, CI runner a reverse proxy — to je už znatelná zátěž na CPU a disk, zejména v okamžiku běhu pipeline. Hostiserver poskytuje zdroje navržené právě pro takový self-hosted stack.
🖥️ Dedikované servery
- Od $90/měs, plná kontrola nad hardwarem pro aktivní CI zátěž
- Žádní sousedé ve zdrojích: sestavení image na runneru nezávisí na cizích kontejnerech
- Podpora 24/7: pomůžeme se sítěmi, SSH portem a registrací runneru
💻 Cloud (VPS) Hosting
- Od $19.95/měs, KVM izolace, dedikované vCPU a RAM
- NVMe disky: rychlé git operace, LFS a sestavení Docker image přímo na runneru
- Dedikovaná IP adresa: stabilní domén pro git klony přes SSH a pro SSL
- Snadné škálování: více zdrojů pro runner, jak přibývá pipeline
💬 Nejste si jisti, kterou variantu potřebujete?
💬 Napište nám a pomůžeme vám s výběrem!
Často kladené otázky
- Gitea nebo Forgejo — co zvolit pro nový projekt?
Funkční rozdíl je minimální, takže výběr závisí spíše na governance modelu: Forgejo se vyvíjí jako komunitní projekt pod Codebergem, Gitea pod samostatným vedením. Protože je API plně kompatibilní, tato volba není nezvratná — přejít z jednoho na druhé lze i později bez ztráty dat.
- Lze migrovat existující instanci Gitea na Forgejo beze ztrát?
Ano, díky plné kompatibilitě API a struktury databáze probíhá migrace v obou směrech bez ztráty repozitářů, issues nebo nastavení. V praxi se to zužuje na výměnu Docker image a opětovné spuštění stacku se stejným volume databáze.
- Proč je SSH navenek vystaveno na portu 2222, a ne na standardním 22?
Port 22 na samotném VPS je už obsazen systémovým SSH serverem, přes který se administruje samotný host. 2222 → 22 uvnitř kontejneru je nejjednodušší způsob, jak se vyhnout konfliktu. Pokud potřebujete přesně standardní port 22 pro git klony, existuje alternativa přes
AuthorizedKeysCommandna hostu, ta je ale na nastavení složitější.
- Docker-in-Docker nebo hostitelský docker socket pro act runner — co zvolit?
Hostitelský docker socket je jednodušší na nastavení — stačí přesměrovat
/var/run/docker.sock— ale dává runneru faktický přístup k Dockeru hosta, a tedy nepřímý root přístup. Docker-in-Docker je plně izolovaný, ale složitější na konfiguraci. Pro jeden důvěryhodný projekt na vlastním serveru je hostitelský socket obvykle přijatelný kompromis; pro CI, které vykonává kód z externích pull requestů, je lepší zvolit izolovanou variantu.
- Je potřeba samostatný Docker registry, pokud už existuje Docker Hub?
Není to nutné, ale vestavěný registry Forgejo odstraňuje další externí závislost a další účet pro autorizaci — token je stejný jako pro git operace. Pokud je cílem právě plná nezávislost na externích službách, použití vestavěného registry tuto myšlenku logicky dotahuje.
- Jak správně zálohovat Forgejo, aby nevznikl nekonzistentní stav?
Klíčovým bodem je časová shoda: archiv volume
forgejo-dataa dump databáze přespg_dumpse pořizují v jednom okamžiku, nejlépe při krátce zastavené službě, a uchovávají se společně se stejným datovým označením. Obnova ze starého dumpu databáze a nového archivu repozitářů (nebo naopak) může vést k rozdílům mezi metadaty v databázi a skutečným stavem Git repozitářů.
- Je povinné projít Installation wizardem v prohlížeči?
Ne. Pokud jsou všechny potřebné parametry (databáze, administrátor, domén) zadány předem přes proměnné prostředí s prefixem
FORGEJO__a je také nastavenoINSTALL_LOCK=true, kontejner se spustí okamžitě v připraveném stavu — vhodné pro reprodukovatelné nasazení z konfigurace, bez manuálního procházení průvodcem pokaždé.