CD – nasazení
Workflow deploy.yml – přes Tailscale a SSH spustí na VM deploy.sh, který nasadí commit a při chybě vrátí předchozí verzi.
Na této stránce
V jedné větě: Po úspěšném CI na
mainse runner GitHubu připojí do soukromé sítě Tailscale, přes SSH pošle VM jen SHA commitu a skriptminishop-deployna VM udělá zbytek – včetně návratu při chybě.
Kód: deploy.yml, deploy.sh
Průběh
sequenceDiagram
autonumber
participant GA as GitHub Actions (production)
participant TS as Tailscale
participant VM as VM – minishop-deploy
participant GH as GitHub (raw soubory)
participant R as GHCR
GA->>GA: kontrola vstupu – celý SHA (40 znaků)
GA->>TS: připojení jako tag:ci (OAuth klient)
GA->>VM: ssh deploy@VM "SHA", secrets na stdin
VM->>VM: zámek (jedno nasazení najednou), kontrola tvaru secrets
VM->>GH: stáhnout deploy/ přesně pro daný commit
VM->>VM: sestavit .env = production.env + IMAGE_TAG + secrets
VM->>VM: změnilo se heslo RabbitMQ? → rabbitmqctl change_password
VM->>R: docker compose pull (sha-…)
VM->>VM: docker compose up --wait (čeká na healthchecky)
alt něco selhalo
VM->>VM: rollback na předchozí .env a soubory
end
VM->>VM: změnil se Caddyfile? → caddy reload
GA->>GA: smoke test zvenku – HTTPS 401/200, /health = Healthy
Bezpečnost nasazení
| Opatření | Proč |
|---|---|
| SSH jen přes Tailscale, port 22 v cloudu zavřený | server není z internetu dostupný pro SSH útoky |
Runner se do Tailscale připojí dočasně jako tag:ci |
ACL mu povolí jen port 22 na VM |
Uživatel deploy s vynuceným příkazem (command="/usr/local/bin/minishop-deploy" v authorized_keys) |
klíč z GitHubu neumí nic jiného než nasadit commit – ani otevřít shell |
| Vstup = jen SHA (regulární výraz) | žádné mezery, středníky ani cesty – nejde podstrčit příkaz |
Pevný otisk serveru (DEPLOY_KNOWN_HOSTS) |
kdyby se za adresou ozval jiný server, SSH odmítne spojení |
| Secrets na stdin, ne v příkazu | nejsou vidět v logu ani v seznamu procesů; GitHub je v logu zamaskuje |
| Skript přijme jen známé klíče v očekávaném tvaru | do .env se nedostane nic neočekávaného |
concurrency: production, bez přerušení |
nikdy dvě nasazení najednou, rozběhnuté se nedá zrušit v půlce |
Rollback
- Automaticky:
deploy.shsi před nasazením uloží předchozí.enva soubory doprevious/. Kdyžpullneboup --waitselže, vrátí je a spustí předchozí verzi – bez spojení s GitHubem. - Ručně: GitHub → Actions → Deploy → Run workflow → SHA staršího commitu. Nebo na VM
sudo -u deploy minishop-deploy <SHA>.
Změna samotného deploy.sh
Skript na VM leží jako /usr/local/bin/minishop-deploy (vlastník root) – nestahuje se sám. Změnu je potřeba na VM
nainstalovat ručně a před sloučením, pokud na ní závisí její vlastní nasazení. Nová VM ho dostane z cloud-init.
Proč takhle
- Continuous Deployment bez ručního schválení – výukový projekt, testy prošly. Schvalování (Required reviewers) jde v environmentu zapnout kdykoli – pak je to Continuous Delivery.
- Konfigurace z GitHubu podle commitu – na VM vždy běží přesně ta konfigurace, která patří k image. Funguje, protože je repozitář veřejný.
- Rollback na VM, ne v pipeline – skript zná předchozí stav a funguje i bez GitHubu.
- Smoke test zvenku – ověří DNS, certifikát, Caddy a zdraví obou služeb tak, jak je vidí uživatel.