Community
0
HostiServer
2026-09-30 11:19

Docker + CI/CD: automatický deploy

⏱️ Doba čtení: ~12 minut | 📅 Aktualizováno: září 2026

Docker + CI/CD: automatický deploy

Stack z předchozího článku je už připravený na produkci: Nginx, SSL, automatické spuštění po restartu. Deploy nové verze ale pořád vypadá stejně jako v úplně první části série — změnili jste kód, provedli git push, přihlásili se přes SSH na server a ručně spustili docker compose build && docker compose up -d. Je to monotónní, náchylné k chybám a vůbec se to neškáluje, jakmile nasazuje víc než jeden člověk.

CI/CD pipeline přesně tento ruční krok odstraní. Každý push do větve main automaticky spustí sekvenci akcí: sestavení image, publikaci do registru a aktualizaci služby na serveru — bez ručního přihlášení přes SSH.

Tento článek se záměrně neváže na konkrétní CI platformu. Koncept CI/CD, rozdíl mezi Continuous Integration, Delivery a Deployment a strukturu pipeline (trigger, stage, job, artifact) jsme už rozebrali v samostatné sérii — začít se vyplatí u „Co je CI/CD: od ručního nasazení k automatizovaným pipeline". docker compose z článku 2 a Nginx se SSL z článku 3 této série se také považují za známé. Tady je jen ta část, která je specifická právě pro Docker: jak se image dostane z CI na server a co přesně se mění v docker-compose.yml.

Výsledek na konci článku: git push do main — a za dvě až tři minuty už na serveru běží nová verze.

2. Docker image registry

2.1 K čemu je registr potřeba

CI sestaví image ve svém vlastním, dočasném prostředí — a tento image tam po dokončení úlohy zmizí. Server ho musí odněkud získat. Registr je mezičlánek: CI do něj image publikuje hned po sestavení, server ho odtud později stáhne příkazem pull.

2.2 Varianty registru

Registr Kdy se hodí
Docker Hub Zdarma, existuje rate limit na anonymní pull požadavky; stačí pro osobní a malé projekty
GitHub Container Registry (ghcr.io) Zdarma pro veřejné repozitáře, pohodlné, pokud je CI už nastavené na GitHub Actions
GitLab Registry / Gitea Registry Vestavěné přímo v platformě — pohodlné pro self-hosted scénáře bez další služby
Self-hosted (registry:2) Plná kontrola, bez vnějších limitů; potřebuje samostatný server nebo zdroje stejného VPS

2.3 Pojmenování image a tagy

Typický formát je registry/namespace/app:tag. Jako tag se používá buď krátký git SHA (git rev-parse --short HEAD), nebo latest. SHA dává reprodukovatelnost — vždy víte, který commit přesně běží na serveru; latest je pohodlný pro rychlý přístup k nejnovější verzi. V praxi CI pushuje oba tagy najednou, na stejný image.

2.4 Soukromý registr a autorizace

Pokud je registr soukromý, musí se před prací s ním autorizovat jak CI, tak server — docker login s přihlašovacími údaji. Tyto údaje se předávají jen přes secrets CI platformy, nikdy se nezapisují přímo do pipeline souboru ani do kódu.

3. Změny v docker-compose.yml

3.1 Jak to bylo dřív

Před zavedením automatického deploye měla služba app build: . — Compose si sám sestavoval image přímo na serveru z lokálního Dockerfile při každém spuštění.

3.2 Jak to bude s CI/CD

build: . se nahradí image: registry/namespace/app:latest. Compose na serveru už nic nesestavuje — jen stáhne hotový image, který CI sestavilo a publikovalo.

Přechod docker-compose.yml z build: na image: — CI sestaví a publikuje image, server jen stáhne hotový výsledek

3.3 Dva compose soubory

Praktické řešení je držet dva soubory: docker-compose.yml pro produkci s image:, a docker-compose.override.yml (nebo docker-compose.dev.yml) pro lokální vývoj s build:. Oba se ukládají do gitu — v .gitignore není potřeba nic navíc vylučovat, a pipeline na serveru explicitně určuje použít právě produkční soubor.

3.4 Tag přes proměnnou

Místo pevně zapsaného latest je pohodlnější nastavit tag proměnnou: image: registry/namespace/app:${APP_VERSION:-latest}. To umožňuje nasadit konkrétní verzi, prostě předáním hodnoty APP_VERSION přes .env nebo přímo z pipeline, bez úpravy samotného compose souboru.

4. Pipeline: kroky a logika

4.1 Trigger

Deploy se spouští při push do větve main (nebo samostatné production). Pull requesty a feature větve se sestavují a testují, jak je popsáno v sérii o CI/CD, ale nenasazují se — to odpovídá rozdílu mezi Continuous Integration a Continuous Deployment.

4.2 Obecná sekvence

  1. Checkout kódu
  2. Autorizace v registru (docker login)
  3. Sestavení image: docker build -t registry/namespace/app:sha .
  4. Publikace image do registru (tag sha a tag latest)
  5. SSH spojení se serverem
  6. docker compose pull app — stáhne nový image
  7. docker compose up -d --no-deps app — restartuje jen app

Kompletní CI/CD pipeline pro Docker: od checkoutu kódu po SSH deploy na server

4.3 Proč je --no-deps kriticky důležité

Bez přepínače --no-deps příkaz up -d restartuje nejen app, ale i všechny služby, na kterých závisí přes depends_on — tedy db i cache. Jde o krátkou, ale zcela zbytečnou nedostupnost databáze při běžné aktualizaci aplikace. Při rolling deployi nové verze je potřeba restartovat jen samotný app.

4.4 SSH přístup z CI

Pro deploy se zakládá samostatný pár SSH klíčů, ne osobní klíč kohokoli z týmu. Veřejný klíč se přidá do ~/.ssh/authorized_keys na serveru, soukromý se ukládá výhradně v secrets CI platformy.

4.5 Alternativa k SSH

Místo přímého SSH spojení lze na samotném serveru rozjet malou HTTP službu — webhook, který přijme POST požadavek od CI a uvnitř provede pull a up -d. Tento přístup dává CI platformě míň práv nad serverem (žádný přímý shell přístup), ale vyžaduje samostatné nastavení a údržbu samotné webhook služby.

5. Secrets a bezpečnost

5.1 Co ukládat do secrets CI

Minimální sada: REGISTRY_USER, REGISTRY_PASSWORD, SSH_PRIVATE_KEY, SERVER_HOST, SERVER_USER.

5.2 Co nesmí být v kódu

Žádná z těchto hodnot nesmí být ani v samotném kódu, ani v Dockerfile, ani v docker-compose.yml, ani v historii gitu — dokonce ani v .env souborech uvnitř repozitáře. V repozitáři má ležet jen .env.example s prázdnými nebo zástupnými hodnotami, jako orientace, jaké proměnné jsou vůbec potřeba.

5.3 Omezení SSH klíče pro deploy

Klíč pro deploy se vyplatí mít samostatný ode všech ostatních a podle možností omezit, co přesně smí provést, direktivou command= v authorized_keys na serveru — pak i kompromitovaný klíč neumožní spustit libovolný příkaz. Pokud ke kompromitaci přece jen dojde, takový samostatný klíč lze odvolat, aniž by to ovlivnilo přístup ostatních lidí nebo služeb.

5.4 Přihlašovací údaje registru na serveru

docker login na serveru se provede jednou ručně a přihlašovací údaje se uloží lokálně v ~/.docker/config.json. Automatický opakovaný login v rámci deploye je potřeba jen tehdy, když se přihlašovací údaje pravidelně rotují.

6. Verzování a rollback

6.1 Proč jeden latest nestačí

Pokud deploy nové verze něco rozbije, tag latest je už přepsaný — nelze se o něj opřít pro návrat zpět. Je potřeba jiný, neměnný identifikátor konkrétní verze.

6.2 SHA tag jako záchranná síť

Každý push uloží do registru image s tagem, který se už nikdy znovu nepoužije — krátkým git SHA daného commitu. Rollback pak znamená předat předchozí SHA zpátky do pipeline, nebo ho provést ručně:

docker compose pull
APP_VERSION=abc1234 docker compose up -d

6.3 Uchovávání starých image

Registr sám místo neuvolňuje — vyplatí se nastavit politiku uchovávání posledních N image (přes vestavěné retention policies registru nebo samostatný cron skript na úklid). To je zvlášť aktuální tam, kde se úložiště registru tarifikuje — neomezená historie tagů se postupně stává placenou zátěží.

6.4 Rollback přímo v pipeline

Nejpohodlnější varianta je samostatná úloha v CI, spouštěná ručně s parametrem SHA nebo verze, která provede stejné kroky deploye, jen se starým tagem. Bez takové úlohy se rollback vrací zpět k ručnímu přihlášení přes SSH — přesně k tomu, čeho měl automatický deploy zbavit.

7. Zero-downtime deploy

7.1 Realistická úroveň pro většinu projektů

docker compose up -d --no-deps app má krátkou, obvykle 1-2sekundovou, mezeru mezi zastavením starého kontejneru a startem nového. Pro naprostou většinu webů a interních služeb je to přijatelná úroveň — uživatel v nejhorším případě uvidí jednu pomalou odpověď místo znatelného výpadku.

7.2 Skutečný zero-downtime

Úplně tuto mezeru odstraní schéma blue/green: dva paralelní kontejnery (app_blue a app_green), a Nginx přepne upstream na nový až poté, co potvrdí připravenost. Jde o znatelně složitější infrastrukturu, a vyplatí se tam, kde SLA vyžaduje dostupnost nad 99,9 % — pro typický self-hosted projekt na jednom VPS je to zpravidla zbytečné.

7.3 Pojistka pro případ neúspěšného startu

restart: unless-stopped spolu s healthcheck na službě app je minimální, ale funkční pojistka: pokud nový kontejner nenaběhne (pád při startu, OOM kvůli nedostatečnému limitu paměti), Docker ho sám restartuje, a Nginx vrátí 502 jen na krátkou dobu restartu, ne natrvalo.

8. Praktický příklad pipeline (pseudokód)

8.1 Abstraktní schéma

Bez ohledu na konkrétní platformu vypadá logika pipeline stejně:

on: push to main
steps:
  - checkout
  - login to registry
  - build image
  - push image
  - ssh deploy

ℹ️ Implementace pro konkrétní platformu: krokový příklad přesně takové pipeline na GitHub Actions, GitLab CI a Gitea Actions je rozebraný v sérii „CI/CD od nuly" — tam je také vysvětleno, v čem se syntaxe platforem liší do detailu.

8.2 Proměnné prostředí pipeline

Název image a tag se obvykle vyčleňují do proměnných: IMAGE_NAME, IMAGE_TAG. Samotné SHA commitu předává každá platforma pod svým názvem — $GITHUB_SHA na GitHub Actions, $CI_COMMIT_SHORT_SHA na GitLab CI, svůj ekvivalent na Gitea Actions. Názvy proměnných se liší, koncept je stejný.

8.3 Samotný příkaz deploye

Poslední krok je SSH na server a spuštění příkazu aktualizace. To lze zapsat buď jako jeden složený příkaz přímo v pipeline souboru, nebo vyčlenit do samostatného skriptu deploy.sh v repozitáři. Druhá varianta je pohodlnější: skript lze otestovat lokálně dřív, než se dostane do produkční pipeline, a jeho změny jsou vidět v historii gitu stejně jako změny kódu.

9. Závěr

Teď každý git push do main znamená aktualizovanou verzi na serveru za dvě až tři minuty, bez ručního přihlášení přes SSH a bez rizika zapomenutí některého kroku.

Kompletní schéma vypadá takto: kód v gitu → CI sestaví image a publikuje ho do registru → server stáhne hotový image a restartuje jen službu aplikace → Nginx dál obsluhuje provoz úplně stejně jako předtím, ani si nevšimne, že za ním proběhla aktualizace.

Detaily nastavení samotné pipeline pro konkrétní platformu — GitHub Actions, GitLab CI nebo Gitea Actions — jsou nad rámec tohoto článku: podrobně jsou rozebrané v samostatné sérii „CI/CD od nuly". Tady jsme prošli jen tu část skládačky, která je specifická pro Docker: registr, změny v compose souboru, SSH deploy, verzování a rollback.

Kompletní cyklus — od kódu po kontejner na serveru — je teď sestavený. Poslední krok série je přivést na stejný server i samotný Git: další článek uzavírá sérii Gitea nebo Forgejo, rozjetými v Dockeru vedle CI runneru, jako plně self-hosted stack.

📚 Navigace v sérii:
Čtete část 4 z 5 „Docker + CI/CD: automatický deploy".
Předchozí: Část 3. Docker v produkci ←
Dál: Část 5. Gitea / Forgejo v Dockeru: kompletní self-hosted stack →

🚀 Server připravený denně přijímat deploy z CI

Automatický deploy znamená pravidelné pully a restarty kontejnerů — a server to musí zvládnout bez propadů pro ty, kdo aplikaci v tu chvíli používají. Hostiserver pro to dává předvídatelné zdroje.

🖥️ Dedikované servery

  • Od $90/měsíc, plná kontrola nad hardwarem pro časté produkční deploye
  • Bez sousedů o zdroje: krátký moment restartu kontejneru nezávisí na cizí zátěži
  • Podpora 24/7: pomůžeme s SSH přístupem pro CI a nastavením self-hosted registru

💻 Cloud (VPS) hosting

  • Od $19.95/měsíc, KVM izolace, vyhrazené vCPU a RAM
  • NVMe disky: rychlý pull nových image bez zpoždění na disku
  • Stabilní síť: SSH deploy z CI nezávisí na nestabilním připojení
  • Snadné škálování: víc zdrojů, když deployů přibývá a jsou častější

💬 Nejste si jistí, kterou variantu potřebujete?
💬 Napište nám — pomůžeme s výběrem!

Časté dotazy

Docker Hub nebo self-hosted registr — co zvolit pro malý projekt?

Pro jeden až dva soukromé projekty je Docker Hub nebo vestavěný registr GitHubu/GitLabu/Gitea (podle toho, kde už kód žije) nejjednodušší start bez další infrastruktury. Self-hosted registry:2 dává smysl, když už limity bezplatných variant nestačí nebo existuje požadavek držet vše ve vlastním perimetru.

Proč nelze nasazovat jen podle tagu latest?

Tag latest se přepisuje každým novým pushem, takže se nehodí jako bod pro návrat — předchozí stav prostě zmizí. Paralelní tag s git SHA zůstává neměnný navždy, a právě ten dává možnost vrátit se ke konkrétní verzi, ne jen postupovat vpřed.

Proč je --no-deps při aktualizaci app bezpodmínečně nutné?

Bez tohoto přepínače docker compose up -d restartuje všechny služby propojené přes depends_on, včetně databáze a cache — i kdyby se změnil jen kód aplikace. --no-deps omezí restart jen na tu službu, která se skutečně aktualizovala.

Jak bezpečně uchovávat SSH klíč pro CI?

Samostatný klíč, který se používá jen pro deploy a nikde jinde, se soukromou částí výhradně v secrets CI platformy (nikdy v repozitáři). Na serveru se vyplatí omezit, co přesně tento klíč smí provést, direktivou command= v authorized_keys — pak kompromitace klíče útočníkovi nedá libovolný shell na serveru.

SSH deploy nebo webhook — s čím je jednodušší začít?

SSH je jednodušší nastavit hned: pár klíčů a několik příkazů v pipeline. Webhook vyžaduje rozjet a udržovat samostatnou malou službu na serveru, zato dává CI míň práv — bez přímého shell přístupu. Pro jeden projekt na jednom VPS obvykle stačí SSH.

Nový kontejner po deployi hned spadl — počítá se pipeline za úspěšný?

Formálně ano — docker compose up -d sám o sobě jen spustí kontejner a nečeká, až aplikace uvnitř skutečně bude připravená. Proto se vyplatí do pipeline přidat samostatnou kontrolu po deployi: krátký curl na health endpoint aplikace s malým zpožděním, ne spoléhat jen na exit kód příkazu.

Potřebuje malý projekt zero-downtime (blue/green) deploy?

Většinou ne. Standardní --no-deps restart dává přestávku jednu až dvě sekundy, což je přijatelné pro většinu webů a interních služeb. Blue/green se vyplatí, když existuje formální požadavek SLA nad 99,9 % nebo když je nepřípustný i krátký 502 — například u platební brány s vysokým provozem.

Contents

Sdílejte tento článek

MANAGED VPS STARTING AT

$19 95 / mo

NEW INTEL XEON BASED SERVERS

$80 / mo

CDN STARTING AT

$0 / mo

 

Tento web používá cookies. Používáním tohoto webu souhlasíte s politikou ochrany osobních údajů.