7.3 KiB
Self-hosted deploy: Gitea + Caddy + EMS (/opt/ems-deploy)
Runbook pro single-node Debian, Docker Compose, Gitea Actions bez Kubernetes. Doplňuje konkrétní stav serveru (ZFS, zfs storage driver, Caddy na hostu, Gitea v /opt/gitea-stack).
1. Co kde běží
| Oblast | Cesta / adresa | Poznámka |
|---|---|---|
| Gitea (HTTP) | https://git.vojacek.eu → Caddy → 127.0.0.1:3000 |
Gitea publikuje HTTP jen na loopback. |
| Gitea (Git SSH) | git.vojacek.eu:2222 → kontejner :22 |
Host SSH zůstává na :22. V app.ini: START_SSH_SERVER = false (kvůli SSH v base image). |
| Gitea stack | /opt/gitea-stack |
postgres, gitea, gitea-runner; vlastní docker-compose + .env. |
| Gitea runner | stejný stack | act_runner s přepsaným entrypoint/command; registrace ručně → runner/runner.json. |
| EMS deploy | /opt/ems-deploy |
Oddělený Compose projekt od Gitea. |
| EMS checkout | /opt/ems-deploy/app |
Git clone stejného repa jako v Gitea. |
| EMS Compose (runtime) | /opt/ems-deploy/docker-compose.yml |
Kopíruje se ze app/deploy/docker-compose.yml při každém deployi (deploy.sh). |
| EMS secrets | /opt/ems-deploy/.env |
Není v gitu; vzor .env.example v repu. |
PostgREST v produkčním deploy/docker-compose.yml: služba naslouchá v Docker síti na :3000, bez mapování na host — frontend v kontejneru volá postgrest:3000. Tím se vyhne kolizi s Gitea na hostovém 127.0.0.1:3000. Pokud někdy přidáš ports pro ladění, použij jiný host port než 3000.
2. Architektonický verdikt
Směr (push → Actions → skript na hostu → docker compose build && up) je správný pro cíl „jeden server, žádný registry, žádný DinD“.
Tvrdá fakta / rizika
- Job Gitea Actions neběží na hostu, ale ve job kontejneru (Docker executor). Kroky typu
run: /opt/ems-deploy/deploy.shtedy neuvidí hostovské cesty, dokud je nepřimountuješ do job kontejneru a nepřidáš je dovalid_volumesu runneru. - Mount Docker socketu do jobu = plná moc nad hostovským Dockerem (ekvivalent root pro kontejnery). Je to běžný pattern u self-hosted runnerů; bezpečnost = důvěra k přístupu do repa a k labelům runneru, ne veřejný runner.
docker: command not foundv jobu je očekávané u defaultního image — buď použij image sdocker+docker compose, nebo vůbec nevolaj docker uvnitř jobu (u tebe stačí spustitdeploy.sh, který mluví s hostovským daemonem přes socket).- ZFS + Docker
zfsdriver: snapshoty azfs listrostou s image vrstvami;deploy.shuž děládocker image prune -f(dangling). Hlídej místo na poolu a případně periodickýdocker system prune(opatrně — nesmí mazat věci, co potřebuješ). git reset --hard origin/main: rychlé a deterministické; jakýkoli lokální drift v/opt/ems-deploy/appna serveru se ztratí. Na produkční app adresář nesahat ručně — vždy přes git + deploy.- Dvě síťě:
ems_netvsgitea_net— služby se defaultně nevidí; pro EMS to obvykle nevadí. Integrovat Gitea DB s EMS nechceš.
3. Tok deploye (cílový)
flowchart LR
dev[Dev laptop] -->|git push| gitea[Gitea main]
gitea --> act[Gitea Actions]
act --> runner[act_runner + Docker]
runner --> job[Job container Alpine + sock + /opt mount]
job --> sh[deploy.sh]
sh --> git[git fetch / reset main]
sh --> sync[install compose.yml]
sh --> dc["docker compose build && up -d"]
dc --> hostd[Host Docker Engine]
hostd --> ems[EMS stack]
- Vývoj lokálně, merge do
main, push nagit.vojacek.eu:2222. - Workflow
.gitea/workflows/deploy.yml(labelself-hosted) spustí job. - Job kontejner má
docker.socka rw mount/opt/ems-deploy; nainstalujegit,bash,docker-cli,docker-cli-compose(Alpine). /opt/ems-deploy/deploy.sh:flock,gitvapp/, syncdocker-compose.yml,docker compose config,build,up -d,image prune -f.
Build probíhá na hostovském Dockeru (stejný daemon jako Gitea stack), bez DinD.
4. Bootstrap serveru (jednorázově)
Přesně podle hlavičky v deploy/deploy.sh:
sudo mkdir -p /opt/ems-deploy/app
sudo chown -R "$USER:$USER" /opt/ems-deploy
git clone ssh://git@git.vojacek.eu:2222/vojacekd/ems.git /opt/ems-deploy/app
cp /opt/ems-deploy/app/.env.example /opt/ems-deploy/.env
chmod 600 /opt/ems-deploy/.env
# doplnit secrets / DB / JWT / …
install -m 755 /opt/ems-deploy/app/deploy/deploy.sh /opt/ems-deploy/deploy.sh
/opt/ems-deploy/deploy.sh
Uživatel, pod kterým běží runnerův job (root v Alpine job image), musí mít právo číst .env, psát do app/.git a volat Docker. Typicky runner běží jako root → ověř oprávnění na /opt/ems-deploy.
5. Gitea runner — nutná úprava config.yaml
Aby job směl přimountovat hostové cesty, v runner/config.yaml (na serveru v /opt/gitea-stack/runner/config.yaml) musí být v container.valid_volumes povolené alespoň:
container:
network: host
privileged: false
valid_volumes:
- /opt/ems-deploy
- /var/run/docker.sock
Bez toho Actions mounty odmítnou / job spadne. Po změně restart runner kontejneru.
labels při registraci runneru musí odpovídat runs-on ve workflow (např. výchozí self-hosted).
6. Caddy a EMS (až bude veřejná doména)
Gitea blok v Caddyfile zůstává. Pro EMS přidej samostatný site blok, např.:
ems.vojacek.eu {
encode gzip
@api path /rest*
handle @api {
uri strip_prefix /rest
reverse_proxy 127.0.0.1:8080
}
handle {
reverse_proxy 127.0.0.1:8080
}
}
Upřesnění podle skutečného nginx ve frontend image: pokud API jde přes stejný origin a path /rest, výše může stačit jeden reverse_proxy na 127.0.0.1:8080 bez stripu — ověř v frontend konfiguraci. Pro PostgREST OpenAPI nastav v .env / PGRST_OPENAPI_SERVER_PROXY_URI veřejnou bázi URL.
Produkční compose mapuje frontend na 127.0.0.1:8080, backend na 127.0.0.1:8000.
7. CI: test vs deploy
| Workflow | Účel | Poznámka |
|---|---|---|
.gitea/workflows/test.yml |
Smoke (soubory, layout) | runs-on: ubuntu-latest stáhne image; nepotřebuje Docker. |
.gitea/workflows/deploy.yml |
Deploy po pushi na main |
Job kontejner + mounty + viz sekce 5. |
workflow_dispatch na deploy umožňuje ruční opakování bez prázdného commitu.
8. Co záměrně neděláme (zatím)
- Privátní Docker registry na stejném stroji.
- Buildkit cache export / remote cache.
- k3s/Kubernetes.
- Spouštění
docker composeuvnitř jobu bez přístupu k jednomu hostovskému daemonu (tj. bez soku bys musel do DinD nebo remote docker).
9. Rychlá kontrola po deployi
docker compose -f /opt/ems-deploy/docker-compose.yml --env-file /opt/ems-deploy/.env ps
curl -sf http://127.0.0.1:8000/docs >/dev/null && echo backend OK
curl -sf http://127.0.0.1:8080/ >/dev/null && echo frontend OK
10. Odkazy v repu
deploy/deploy.sh— jediný produkční vstup „co se na serveru spouští“.deploy/docker-compose.yml— šablona runtime Compose (kopíruje se do/opt/ems-deploy)..gitea/workflows/deploy.yml— napojení na runner + job kontejner.