Co je CI/CD a proč ho zavést
CI/CD je soubor postupů a nástrojů pro automatizaci sestavování, testování a nasazování. Cílem je zkrátit „lead time“ od commitu do produkce, zvýšit kvalitu a snížit rizika díky malým, opakovatelným krokům. V praxi to znamená, že každý commit spustí sestavení, testy a statickou analýzu (CI) a ověřený artefakt se automaticky propaguje mezi prostředími (CD) až do produkce, a to s kontrolami a případně i s podmíněným schválením.
Architektura CI/CD pipeline: stavební bloky
- Spouštěče (triggery) – události jako
push,pull_request/merge_request, plán (CRON), ruční spuštění. - Fáze – typicky validate → build → test → package → scan → deploy → verify.
- Joby – konkrétní kroky (kompilace, testy, publikování artefaktů).
- Artefakty – výsledky sestavení (balíčky, image Dockeru, generovaná dokumentace).
- Prostředí – dev → test → staging → production, ideálně co nejvíce izomorfní.
- Tajné údaje – přístupové klíče, tokeny a certifikáty v trezoru (vault/secrets).
- Audit a telemetrie – logy, metriky, upozornění a trasování.
Předpoklady a příprava repozitáře
- Standardizace struktury – soubory v kořenovém adresáři:
README,LICENSE,CONTRIBUTING,CHANGELOG. - Manifest a lockfile –
package.json+package-lock.json,pyproject.toml+poetry.lockapod. - Testovací rámec – jednotkové a integrační testy s jasně definovanými příkazy (
npm test,pytest,mvn test). - Nástroje kvality – lintery (ESLint, Flake8), formátovače (Prettier, Black), SAST (semgrep, CodeQL).
- Konfigurace CI – soubory YAML/DSL v kořenovém adresáři, např.
.github/workflows/ci.ymlči.gitlab-ci.yml.
Strategie větvení a verzování
- Trunk-based – krátké větve pro funkce, časté slučování do
main, feature flagy pro nedokončené funkce. - GitFlow – oddělené větve
develop,release/*,hotfix/*; vhodné pro regulované prostředí. - Semantické verzování –
MAJOR.MINOR.PATCH+ automaticky generovaný changelog z konvenčních commitů (Conventional Commits).
Krok 1: Validace commitu (pre-commit a CI lint)
Začněte nejrychlejšími kontrolami: formátováním, lintingem, statickou analýzou a bezpečnostními skeny závislostí. Tyto kroky odhalí chyby dříve, než spustíte nákladné sestavení a testy.
# Příklad npm skriptů "scripts": { "lint": "eslint src", "format:check": "prettier -c .", "sast": "semgrep --config p/ci", "audit": "npm audit --production" }
Krok 2: Deterministické sestavení
Zajistěte reprodukovatelnost: definujte přesné verze závislostí, používejte cache (např. cache sestavení v CI), dodržujte princip build once a archivujte artefakty. V kontejnerech využijte vícestupňové sestavení Dockeru.
# Vícefázový Dockerfile (Node.js) FROM node:20 AS deps WORKDIR /app COPY package*.json ./ RUN npm ci
FROM node:20 AS build
WORKDIR /app
COPY --from=deps /app/node_modules node_modules
COPY . .
RUN npm run build
FROM gcr.io/distroless/nodejs20-debian12
WORKDIR /app
COPY --from=build /app/dist dist
COPY package*.json .
CMD ["dist/server.js"]
Krok 3: Automatické testování (unit, integration, e2e)
- Jednotkové – rychlé, izolované.
- Integrační – proti skutečným službám nebo kontejnerům (Docker Compose).
- End-to-end – proti testovacímu prostředí (Playwright/Cypress), paralelizace a rozdělení testů do skupin („sharding“).
# docker-compose.test.yml (lokálně/v CI) services: db: image: postgres:16 environment: POSTGRES_PASSWORD: test app: build: . command: npm run test:integration depends_on: [db]
Krok 4: Bezpečnostní a kvalitativní brány
- SAST/Secrets scan – hledání tajných údajů a zranitelností v kódu.
- Skenování závislostí – kontrola CVE ve verzích.
- DAST – dynamické skeny běžící aplikace (ZAP, automatizace Burp).
- Dodržování licencí – povolené licence, reporty pro audit.
Krok 5: Artefakty a registry
Sestavení by mělo vytvořit artefakt (balíček, image), který je podepsaný a uložený v repozitáři artefaktů (Nexus/Artifactory/Package Registry) nebo v registru kontejnerů (GHCR/ECR/GCR). Při propagaci znovu nesestavujte stejný commit – sestavte jednou, nasaďte vícekrát.
Krok 6: Nasazení do prostředí (CD)
- Dev/Test – automatické nasazení po úspěšném CI.
- Staging – automatické po schválení (ruční job, ochrana prostředí).
- Production – řízené (schvalování, servisní okno) nebo plně automatické s postupným nasazováním typu canary/blue-green.
# Nasazení na Kubernetes (výřez z Helm values.yaml) image: repository: ghcr.io/org/app tag: "1.4.2" # připnutí na verzi artefaktu replicaCount: 3 autoscaling: enabled: true minReplicas: 3 maxReplicas: 10 targetCPUUtilizationPercentage: 70
Krok 7: Ověření nasazení a návrat k předchozí verzi
- Smoke testy – syntetické kontroly stavu služby po nasazení.
- Testy po nasazení – e2e proti nasazené verzi.
- Automatický návrat k předchozí verzi – při neúspěšném ověření nebo zhoršení metrik (rozpočet chyb SLO, latence, míra chyb).
Ukázka: CI pipeline v GitHub Actions
name: ci on: push: branches: [ main ] pull_request: jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: 20, cache: 'npm' } - run: npm ci - run: npm run format:check - run: npm run lint - run: npm run test -- --ci --reporters=jest-junit - name: Upload test report uses: actions/upload-artifact@v4 with: { name: junit, path: junit.xml }
build_and_push_image:
needs: validate
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}/app:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
Ukázka: GitLab CI s prostředími a ručním schválením
stages: [validate, build, deploy]
validate:
stage: validate
image: node:20
script:
- npm ci
- npm run lint
- npm test
artifacts:
when: always
reports:
junit: junit.xml
build:
stage: build
image: gcr.io/kaniko-project/executor:latest
script:
- >/kaniko/.docker/config.json echo '{"credHelpers":{"registry.gitlab.com":"gcloud"}}'
- /kaniko/executor --context $CI_PROJECT_DIR --destination $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
needs: [validate]
deploy_staging:
stage: deploy
environment:
name: staging
url: https://staging.example.com
script:
- helm upgrade --install app chart/ --set image.tag=$CI_COMMIT_SHA
when: manual
needs: [build]
deploy_prod:
stage: deploy
environment:
name: production
url: https://app.example.com
script:
- helm upgrade --install app chart/ --set image.tag=$CI_COMMIT_SHA
when: manual
only:
- tags
Ukázka: deklarativní pipeline v Jenkinsu
pipeline { agent any options { timestamps() } triggers { pollSCM('@daily') } stages { stage('Validate') { steps { sh 'npm ci' sh 'npm run lint' sh 'npm test' } } stage('Build Image') { steps { sh 'docker build -t registry/app:${GIT_COMMIT} .' sh 'docker push registry/app:${GIT_COMMIT}' } } stage('Deploy Staging') { when { branch 'main' } steps { sh 'helm upgrade --install app chart/ --set image.tag=${GIT_COMMIT}' } } } post { always { junit 'junit.xml' } } }
Ukázka: Azure DevOps (YAML)
trigger: branches: { include: [ main ] }
stages:
stage: Validate
jobs:
job: LintTest
pool: { vmImage: 'ubuntu-latest' }
steps:
task: NodeTool@0
inputs: { versionSpec: '20.x' }
script: npm ci && npm run lint && npm test
stage: Build
dependsOn: Validate
jobs:
job: BuildImage
steps:
task: Docker@2
inputs:
command: buildAndPush
repository: org/app
dockerfile: '**/Dockerfile'
tags: $(Build.SourceVersion)
Správa tajných údajů a konfigurací
- Správa tajných údajů – nativní trezory (GitHub Secrets, GitLab CI Variables, Azure Key Vault) nebo HashiCorp Vault.
- Konfigurace pro jednotlivá prostředí – oddělte konfiguraci od kódu; používejte
ConfigMap/Secretv Kubernetes, přístup 12-Factor „config in the environment“. - Rotace a audit – pravidelná výměna klíčů, audit přístupů a udělování oprávnění „just-in-time“ (federace OIDC namísto statických tokenů).
Strategie nasazování: blue-green, canary, progressive delivery
- Blue-green – dvě identická prostředí; přesměrování provozu minimalizuje výpadek a usnadňuje návrat k předchozí verzi.
- Canary – postupné směrování části provozu na novou verzi (např. 1 % → 10 % → 50 % → 100 %).
- Progressive delivery – řízené metrikami (Argo Rollouts/Flagger), automatické zastavení při regresi.
Feature flagy a dark launching
Oddělte vydávání od nasazování. Pomocí feature flagů aktivujte funkce pro podskupiny uživatelů, umožněte A/B testování a bezpečný návrat na úrovni funkcionality bez opětovného nasazení.
Observabilita a kontrola kvality po nasazení
- Metriky – latence, chybovost, saturace (SRE „zlaté signály“), sledování SLO/SLI.
- Logy a tracing – korelace vydání s událostmi; OpenTelemetry pro jednotné trasování.
- Upozornění – integrace CI/CD se Slackem/Teams; upozornění na selhání i úspěšná vydání.
Matice sestavení, ukládání do cache a paralelizace
Zrychlete pipeline pomocí paralelních jobů, matic (více verzí jazyka/OS) a cache pro jednotlivé joby (např. ~/.m2, ~/.npm, pip cache). Pozor na zneplatnění cache při změně lockfile.
# GitHub Actions – strategie testování pomocí matice: matrix: node: [18, 20, 22] steps: - uses: actions/setup-node@v4 with: { node-version: ${{ matrix.node }}, cache: 'npm' }
Infrastructure as Code (IaC) v pipeline
- Terraform/Ansible – správa cloudových zdrojů, aplikace schválených plánů (plan → review → apply).
- GitOps – deklarativní stav clusteru (Argo CD/Flux), pipeline pouze odesílá manifest/Helm chart.
- Policy as Code – OPA/Conftest/Kyverno ověřují konfigurace před jejich použitím.
Bezpečnost CI/CD
- Princip minimálních oprávnění – oddělené identity pro sestavení a nasazení, časově omezené tokeny, federace OIDC.
- Dodavatelský řetězec – podepisování artefaktů (Sigstore/cosign), SBOM (Syft), ověřování při nasazení (policy).
- Izolace runnerů – vlastní běhová prostředí provozovaná v sandboxu, neprivilegované kontejnery, omezení síťových přístupů.
Průběžné zlepšování a měření (metriky DORA)
- Frekvence nasazování – jak často nasazujete.
- Lead time for changes – doba od commitu do nasazení.
- Change failure rate – procento vydání vyžadujících zásah nebo návrat k předchozí verzi.
- MTTR – průměrná doba obnovení služby.
CI/CD pipeline pravidelně revidujte: vyhodnocujte nestabilitu testů, optimalizujte kroky, odstraňujte duplicity a sledujte náklady (minuty běhu, úložiště artefaktů).
Typické anti-patterny a jak se jim vyhnout
- Monolitická pipeline – vše v jednom jobu; rozdělte ji do fází a paralelizujte.
- Nedeterministická sestavení – chybějící lockfile, proměnlivé základní image.
- Opětovné sestavení při propagaci – porušení principu „sestavte jednou“; nasazujte stejný artefakt.
- Tajné údaje v proměnných prostředí bez omezení – použijte trezor a krátkodobé tokeny.
- Nestabilní testy – izolujte je, revidujte a stabilizujte; dočasně používejte opakované pokusy s omezeným počtem opakování.
Kompletní příklad „end-to-end“ (shrnutí kroků)
# 1) CI: validate → build → test → scan → publish # 2) CD: deploy dev → staging (manual approval) → prod (canary) # 3) Observabilita: smoke test + návrat k předchozí verzi při zhoršení SLO
Závěr
CI/CD pipeline je průběžně rozvíjený produkt, nikoli jednorázový projekt. Začněte jednoduchou validací a sestavením, přidejte testy a bezpečnostní skeny, zaveďte registr artefaktů a automatizované nasazování s postupným ověřováním. S růstem týmu doplňujte GitOps, progressive delivery a zásady bezpečného dodavatelského řetězce. Cílem je krátký a spolehlivý tok změn od vývojáře k uživateli – měřený a průběžně zlepšovaný.
