JZ Handbook v3.1
Výukový materiál · Git · Cloudflare · Claude Code · Docker · NiFi
Obsah tématu

Git — jak to funguje
od základů

Výukový materiál pro technicky zdatného začátečníka. Od instalace přes interní model až po práci v GUI a řešení problémů.

1 Instalace Gitu

Git je samostatný nástroj — není součástí VS Code ani jiného editoru, musí se nainstalovat zvlášť. Po instalaci ho používají všechny GUI klienty i terminál.

Doporučeno: Git for Windows — instaluje Git, Git Bash (terminál), Git Credential Manager (bezpečné ukládání hesel) a volitelně GUI nástroj.

Možnost 1 — winget (Windows 10/11, doporučeno)
# Spusťte PowerShell nebo CMD jako běžný uživatel
winget install --id Git.Git -e --source winget

# Po instalaci ověřte — zavřete a znovu otevřete terminál!
git --version
git version 2.47.1.windows.1
Možnost 2 — instalátor (.exe)
# Stáhněte instalátor z git-scm.com/download/win
# Při instalaci doporučená nastavení:
  Default editor:       Visual Studio Code (nebo Notepad++)
  Initial branch name:  main  ← ZMĚŇTE z "master"
  PATH environment:     Git from command line (doporučeno)
  Line ending:          Checkout Windows / Commit Unix (výchozí)
  Credential helper:    Git Credential Manager
Co je Git Bash? Git for Windows přináší Git Bash — emulátor linuxového terminálu pro Windows. Fungují v něm všechny příkazy z tohoto materiálu. Alternativně používejte PowerShell nebo Windows Terminal — Git tam funguje stejně.

Doporučeno: Homebrew. macOS sice Git obsahuje, ale jeho verze je zastaralá (Apple ji neaktualizuje). Homebrew nainstaluje aktuální verzi.

Instalace přes Homebrew (doporučeno)
# Nejdřív nainstalujte Homebrew (pokud ho nemáte)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# Pak nainstalujte Git
brew install git

# Ověření — musí to zobrazit Homebrew cestu, ne /usr/bin/git
which git
/opt/homebrew/bin/git   ← správně (Apple Silicon)
git --version
git version 2.47.1
Alternativa: Xcode Command Line Tools
# Nainstaluje Git spolu s vývojářskými nástroji Apple
xcode-select --install
# Nevýhoda: starší verze Gitu, aktualizace jen s macOS updatem
Git Credential Manager na macOS brew install --cask git-credential-manager — bezpečné ukládání přihlašovacích údajů do systémové klíčenky (Keychain). Bez něj budete zadávat heslo při každém push/pull.

Na Linuxu je Git dostupný přímo v balíčkovacím systému distribuce.

Debian / Ubuntu / Mint
sudo apt update
sudo apt install git
# Nebo kompletní balík s extra nástroji:
sudo apt install git-all
Fedora / RHEL / CentOS
sudo dnf install git
Arch Linux
sudo pacman -S git
Ověření na všech distribucích
git --version
git version 2.47.1

2 Výběr Git klienta

Git samotný je jen nástroj příkazového řádku. Klient je aplikace, která ho obaluje grafickým rozhraním. Použití klienta není povinné — vše jde dělat v terminálu — ale pro denní práci s kódem kombinace editoru a terminálu funguje nejlépe.

KlientTypOSPro kohoCena
Terminál (Git Bash, PowerShell, zsh) CLI Všechny Přesná kontrola, scripty, CI/CD — základ, který by měl znát každý zdarma
VS Code (vestavěný + rozšíření) GUI v editoru Všechny Vývojáři, kteří chtějí Git přímo v editoru — doporučeno pro tento materiál zdarma
GitHub Desktop GUI standalone Win, macOS Absolutní začátečníci na GitHubu, velmi jednoduchý workflow zdarma
GitKraken GUI standalone Všechny Vizualizace složitých branch grafů, týmová spolupráce freemium
SourceTree GUI standalone Win, macOS Uživatelé Atlassian stacku (Jira, Bitbucket) zdarma
TortoiseGit Shell extension Windows Uživatelé Průzkumníka Windows, zvyklí na TortoiseSVN zdarma
IntelliJ / Rider / WebStorm GUI v editoru Všechny Uživatelé JetBrains IDE — velmi propracovaná integrace placené
Doporučení pro tento materiál Používejte VS Code pro denní práci (staging, commit, zobrazení diff, řešení konfliktů) a terminál pro složitější operace (rebase, reset, reflog). Sekce D (11–14) pokrývá VS Code detailně.

3 První nastavení po instalaci

Po instalaci Gitu je potřeba nastavit identitu — Git ji připisuje každému commitu. Toto nastavení je globální (platí pro všechny projekty na počítači).

Povinná prvotní konfigurace (všechny OS)
# Vaše jméno — zobrazí se u každého commitu
git config --global user.name "Jan Novák"

# Váš e-mail — měl by odpovídat účtu na GitHubu/GitLabu
git config --global user.email "jan@example.com"

# Výchozí název hlavní větve (moderní standard)
git config --global init.defaultBranch main

# Výchozí editor pro zprávy commitů (vyberte jeden)
git config --global core.editor "code --wait"    ← VS Code
git config --global core.editor "notepad"           ← Poznámkový blok
git config --global core.editor "nano"              ← nano (macOS/Linux)

# Ověření — zobrazí všechna nastavení
git config --list --global
user.name=Jan Novák
user.email=jan@example.com
init.defaultbranch=main
core.editor=code --wait
Kde se ukládá konfigurace?

--global nastavení se ukládají do souboru ~/.gitconfig (macOS/Linux) nebo C:\Users\VašeJméno\.gitconfig (Windows). Lze ho otevřít a editovat přímo jako textový soubor.

Nastavení bez --global platí jen pro aktuální repozitář a ukládají se do .git/config ve složce projektu.

Nastavení přihlašování k GitHubu / GitLabu

Pro push a pull potřebujete způsob autentizace. Doporučujeme SSH klíč — heslo zadáte jen jednou (při vytvoření klíče) a dál vše funguje automaticky.

Generování SSH klíče a připojení k GitHubu
# 1. Vygenerujte SSH klíč (funguje na Windows i macOS i Linux)
ssh-keygen -t ed25519 -C "jan@example.com"
# Potvrďte výchozí cestu (Enter), nastavte heslo (nebo nechte prázdné)

# 2. Zkopírujte veřejný klíč
# Windows:
cat ~/.ssh/id_ed25519.pub ← zkopírujte celý výstup
# macOS:
pbcopy < ~/.ssh/id_ed25519.pub  ← uloží do schránky

# 3. Přidejte klíč na GitHub:
#    github.com → Settings → SSH and GPG keys → New SSH key
#    Vložte zkopírovaný klíč a uložte

# 4. Ověřte připojení
ssh -T git@github.com
Hi jan! You've successfully authenticated.
HTTPS s Personal Access Tokenem
# GitHub již nepřijímá heslo — potřebujete Personal Access Token (PAT)
# github.com → Settings → Developer settings → Personal access tokens → Fine-grained
# Nastavte oprávnění: Contents (Read and write), Metadata (Read)

# Git Credential Manager (součást Git for Windows) uloží token automaticky
# Při prvním push/pull se zobrazí přihlašovací okno — vložte token jako heslo

# Manuální uložení tokenu (macOS/Linux bez GCM):
git config --global credential.helper store
# Token se uloží při příštím push/pull (pozor: ukládá nešifrovaně)

4 Jak číst příkazy v tomto materiálu

Legenda barev
git commit -m "zpráva commitu"
# Toto je komentář — vysvětluje co příkaz dělá. Do terminálu ho nepište.
On branch main   ← toto Git vypsal jako odpověď
CONFLICT: ...    ← varování nebo chybová zpráva
   ← kurzíva = naše vysvětlivka, ne součást příkazu
ZkratkaCo znamená v praxi
HEAD~1„o jeden commit zpět" — HEAD~3 = o tři zpět. HEAD je vždy aktuální pozice.
originVýchozí název vzdáleného repozitáře (GitHub/GitLab). Nastavuje se automaticky při git clone.
origin/mainLokální záložka stavu větve main na serveru — aktualizuje se jen při git fetch.
upstreamVazba mezi vaší lokální větví a větví na serveru. Po nastavení (git push -u origin main) stačí psát jen git push.
a1b2c3dZkrácený hash commitu (7 znaků). Git si domyslí zbytek 40znakového hashe.

5 Jak Git interně ukládá data

Git ukládá vše do skryté složky .git/ ve vašem projektu jako čtyři typy objektů. Každý objekt je jednoznačně identifikován kryptografickým hashem svého obsahu.

TypCo obsahujePříklad
blobObsah jednoho souboru — jen data, bez názvu a cestyObsah README.md
treeAdresář: seznam názvů + hash blobu nebo podadresářeSložka src/
commitSnímek projektu: hash tree, hash předchozího commitu, autor, čas, zprávaKaždý váš git commit
tagNepohyblivý, pojmenovaný ukazatel na commitv1.0.0
Proč blob neobsahuje název souboru? Blob ukládá jen obsah. Dva soubory se stejným obsahem kdekoliv v projektu sdílí jediný blob — žádné kopírování, žádné plýtvání místem. Název souboru ukládá nadřazený objekt tree.
Obsah commit objektu — git cat-file -p HEAD
tree   4b825dc642cb6eb9a060e54bf8d69288fbee4904  ← snímek souborů
parent f3a9b1c8d27e44f1a5c3b9e0d7f2a6c4b8e1d5f9  ← předchozí commit
author Jan Novák <jan@example.com> 1706000000 +0100
committer Jan Novák <jan@example.com> 1706000000 +0100

feat: přidán modul pro autentizaci
Co najdete ve složce .git/
.git/
├── objects/         ← všechny objekty (blob/tree/commit/tag)
│   ├── a1/b2c3d4...  ← první 2 znaky hashe = složka
│   └── pack/         ← zabalené objekty po automatické optimalizaci
├── refs/heads/main  ← soubor s jedním řádkem: hash posledního commitu větve
├── refs/remotes/    ← stav větví na serveru (aktualizuje se při fetch)
├── HEAD              ← "ref: refs/heads/main" = kde se právě nacházíte
├── index             ← staging area — seznam souborů připravených ke commitu
└── config            ← nastavení tohoto repozitáře

6 Tři oblasti a klíčové pojmy

Soubor může existovat ve třech různých „stavech" zároveň. Toto je nejdůležitější věc k pochopení — zdroj většiny zmatení u začátečníků.

Cesta změny — od úpravy souboru až na server
Working Directory
soubory na disku,
jak je vidíte v editoru
git add
Index / Staging
„fronta" připravených
změn k zapsání
git commit
Lokální repozitář
trvalá historie
ve složce .git/
git push
Remote repozitář
GitHub / GitLab
sdíleno s týmem
TermínVysvětleníAnalogie
Working DirectorySoubory na disku — jak je vidíte v editoru. Git je sleduje, ale zatím nic nezapsal.Rozepsaný dokument
Index / StagingPřechodná oblast pro sestavení commitu. Přidáváte sem pomocí git add. Umožňuje zařadit jen část změn.Krabice připravená k odeslání
CommitTrvalý, neměnný záznam stavu souborů s unikátním hashem a zprávou.Odeslaná zásilka s razítkem
Branch (větev)Pojmenovaný ukazatel na commit. Po každém commitu se automaticky posune vpřed.Záložka v knize
HEADSpeciální reference říkající „kde teď jsem". Ukazuje na aktuální větev.„Jste zde" na mapě
RemoteVzdálený repozitář (GitHub…). Lokálně vidíte jeho stav jako origin/main — aktualizuje se jen při git fetch.Sdílená schránka pro tým
TagNepohyblivý štítek na commitu — neposouvá se při nových commitech. Pro označení verzí.Trvalá etiketa

7 Commit workflow

Inicializace nového repozitáře
mkdir muj-projekt && cd muj-projekt
git init
Initialized empty Git repository in /muj-projekt/.git/

echo "# Můj projekt" > README.md
git add README.md
git commit -m "chore: initial commit"
[main (root-commit) a1b2c3d] chore: initial commit
Klonování existujícího repozitáře
# Stáhne kompletní historii a nastaví "origin" automaticky
git clone https://github.com/org/repo.git

# SSH varianta (po nastavení SSH klíče, viz 03)
git clone git@github.com:org/repo.git

git remote -v
origin  git@github.com:org/repo.git (fetch)
origin  git@github.com:org/repo.git (push)
Denní commit cyklus
# 1. Zjistěte stav
git status
  modified:   src/auth.py   ← upraveno, není ve staging
  Untracked:  docs/api.md   ← nový soubor, Git ho nezná

# 2. Přidejte do staging
git add src/auth.py docs/api.md

# 3. Zkontrolujte co půjde do commitu
git diff --staged

# 4. Zapište commit
git commit -m "feat(auth): přidána podpora JWT tokenů"

# 5. Odešlete na server
git push

8 Větvení

Branch je jen soubor s hashem commitu — vytvoření trvá milisekundy. Pro každou novou funkci nebo opravu si vytvořte samostatnou větev.

Práce s větvemi
# Vytvořte novou větev a přepněte se na ni
git switch -c feature/prihlaseni

# Seznam větví (* = aktuální)
git branch -a
* feature/prihlaseni
  main
  remotes/origin/main

# Přepnutí zpět
git switch main

# Smazání po mergi (Git hlídá, aby byla větev sloučena)
git branch -d feature/prihlaseni
Detached HEAD Pokud se přepnete přímo na hash commitu (git checkout a1b2c3d), HEAD přestane ukazovat na větev. Nové commity v tomto stavu nemají větev — Git je po čase smaže. Okamžitá záchrana: git switch -c nova-vetev.

9 Merge & Rebase

Aspektgit mergegit rebase
Co uděláVytvoří nový „merge commit" se dvěma rodičiPřepíše commity vaší větve od vrcholu jiné větve
Výsledná historieZachová skutečný průběh vývojeLineární — jako by větvení nebylo
Bezpečné na sdílenou větev?✓ Ano✗ Ne — přepíše hashe
Kdy použítIntegrace feature do mainČištění feature větve před PR

Nejjednodušší případ: main se od odbočení nezměnil. Git jen posune ukazatel vpřed — žádný merge commit.

Fast-forward merge
git switch main
git merge feature/prihlaseni
Fast-forward   ← žádný merge commit, jen posunutí ukazatele

# Pokud chcete merge commit i přesto (pro přehlednost v historii):
git merge --no-ff feature/prihlaseni

Obě větve měly vlastní commity. Git najde společného předka, porovná obě větve a vytvoří merge commit.

3-way merge
git switch main
git merge feature/prihlaseni
Merge made by the 'ort' strategy.

# Výsledný graf:
*   e5f6a7b Merge branch 'feature/prihlaseni'
|\
| * d2e3f4a feat: JWT tokeny
* | f1g2h3i docs: README
|/
* b5c6d7e feat: auth module

Konflikt nastane, když obě větve upravily stejné řádky stejného souboru. Git se zastaví a čeká na vaše rozhodnutí.

1

Git ohlásí konflikt

Výstup při konfliktu
git merge feature/prihlaseni
CONFLICT (content): Merge conflict in src/config.py
Automatic merge failed; fix conflicts and then commit.

git status
Unmerged paths:
  both modified:   src/config.py   ← tento soubor má konflikt
2

Otevřete soubor — Git v něm označil obě verze

src/config.py — jak soubor vypadá po konfliktu
DEBUG = False
<<<<<<< HEAD
TIMEOUT = 30 # vaše verze (větev main)
═══════════════════════
TIMEOUT = 60 # příchozí verze (feature/prihlaseni)
>>>>>>> feature/prihlaseni
MAX_RETRIES = 3

Sekce od <<<<<<< HEAD po ═══ je vaše verze. Sekce od ═══ po >>>>>>> je příchozí verze.

3

Ručně upravte soubor — vyberte nebo zkombinujte obě verze

Smažte všechny markery (<<<<<<<, =======, >>>>>>>) a ponechte výsledný kód:

src/config.py — po vyřešení
DEBUG = False
TIMEOUT = 60 # přijato z feature větve
MAX_RETRIES = 3
4

Označte soubor jako vyřešený a dokončete commit

Dokončení merge
git add src/config.py       ← říká Gitu: „konflikt vyřešen"
git commit                   ← Git nabídne výchozí zprávu, potvrďte

# Chcete vše vrátit a začít merge znovu?
git merge --abort            ← vrátí stav přesně před merge
Tip: Merge Editor ve VS Code VS Code zobrazí konflikt graficky — tlačítka Accept Current, Accept Incoming, Accept Both. Viz 14 pro detailní postup.
Rebase feature větve na aktuální main
git switch feature/prihlaseni
git rebase main
Successfully rebased and updated refs/heads/feature/prihlaseni.

# Interaktivní — přepis posledních 3 commitů (squash, rename, drop…)
git rebase -i HEAD~3

# Pokud nastane konflikt:
git add soubor.py
git rebase --continue   ← nebo --abort pro zrušení celého rebase
Zlaté pravidlo rebase Rebase přepíše SHA hashe commitů. Nikdy nerebazujte větve sdílené s ostatními — main, develop ani jiné společné větve. Pouze vaše vlastní feature větve.

10 Remote a sdílení s týmem

PříkazCo děláMění lokální větve?
git fetchStáhne nové commity ze serveru, aktualizuje origin/mainNe
git pullfetch + automatický merge do aktuální větveAno
git pushOdešle lokální commity na server
Push & Pull — praktické příklady
# První push větve — -u nastaví upstream (vazbu na server)
# Po nastavení stačí příště psát jen "git push"
git push -u origin feature/prihlaseni
Branch set up to track 'origin/feature/prihlaseni'.

# Bezpečné stažení: nejdřív fetch, pak se podívejte co přišlo
git fetch origin
git log main..origin/main --oneline  ← co přibylo na serveru
git merge origin/main

# Nebo zkratkou (= fetch + merge)
git pull origin main

# Vynucený push po rebase (jen pro VLASTNÍ větve)
# --force-with-lease selže, pokud někdo jiný mezitím pushnul — bezpečnější než --force
git push --force-with-lease origin feature/prihlaseni

10b .gitignore — co nesledovat

Soubor .gitignore říká Gitu, které soubory a složky má ignorovat — neřadit je do staging ani do commitů. Typicky se jedná o sestavovací výstupy, dočasné soubory, citlivé informace a závislosti stažené ze správce balíčků.

Vzorový .gitignore

.gitignore — vzorový soubor pro obecný projekt
# OS
.DS_Store
Thumbs.db

# Logs
*.log
logs/

# Temp
tmp/
temp/
*.tmp

# IDE
.vscode/
.idea/
*.user

# Secrets
.env
*.key
*.pfx

# Build
bin/
obj/
dist/
build/

# Node
node_modules/

# Python
__pycache__/
*.pyc

# Misc
*.bak
*.swp
Kde soubor umístit? Do kořene repozitáře, vedle složky .git/. Pravidla platí rekurzivně pro všechny podsložky — pokud chcete omezit pravidlo jen na jednu složku, přidejte lomítko na začátek: /build/.

Cleanup — odebrání souborů, které Git už sleduje

Přidání pravidla do .gitignore nezastaví sledování souborů, které Git již zná. Nejprve je musíte odebrat z indexu příkazem git rm --cached.

Postup cleanup — odebrání sledovaných souborů z indexu
# 1. Přidejte (nebo doplňte) pravidlo do .gitignore
echo ".env" >> .gitignore

# 2. Odeberte konkrétní soubor z indexu (soubor na disku zůstane)
git rm --cached .env

# Alternativa: odebrání celé složky rekurzivně
git rm --cached -r node_modules/

# 3. Ověřte stav — soubor by měl zmizet ze sledovaných
git status
Changes to be committed:
  deleted:    .env   ← bude odstraněn z Gitu, ale fyzicky zůstane

# 4. Zacommitujte změnu
git commit -m "chore: remove .env from tracking, update .gitignore"

# Hromadný cleanup — přepsat celý index podle aktuálního .gitignore
# Pozor: dočasně odebere vše a znovu přidá jen neignorvané soubory
git rm --cached -r .
git add .
git commit -m "chore: apply .gitignore cleanup"
Pozor na historii! Soubory odstraněné z indexu zůstanou ve starších commitech viditelné. Pokud omylem commitnete citlivá data (hesla, klíče), nestačí je přidat do .gitignore — musíte přepsat historii (git filter-repo) a zneplatnit všechna kompromitovaná tajemství.

11 Git ve VS Code — orientace v GUI

VS Code má Git integraci vestavěnou — nepotřebujete žádné rozšíření pro základní operace. Tato sekce popisuje, kde co najít.

Source Control panel (Ctrl+Shift+G)

muj-projekt — Visual Studio Code
🗂
🔍
🐛
🧩
Source Control ↻ ✓ …
A docs/api.md docs
M src/auth.py src
M README.md .
+
⎇ main
↑2 ↓0
0 1
Prvek UICo znamená
Staged ChangesSoubory přidané do staging (git add) — půjdou do příštího commitu
ChangesUpravené soubory, které ještě nejsou ve staging
A / M / D / UAdded / Modified / Deleted / Untracked — stav souboru
↑2 ↓0Stavový řádek: máte 2 lokální commity, které jste nepushnuli; 0 stažených ze serveru
⎇ mainAktuální větev — kliknutím ji změníte nebo vytvoříte novou
Pole pro zprávu commituSem napište zprávu a stiskněte Ctrl+Enter (nebo Cmd+Enter na macOS) pro commit
Ikona v paneluCommit tlačítko (alternativa k Ctrl+Enter)
Ikona v paneluRozbalovací menu — Push, Pull, Fetch, Branch, Stash a další

Zobrazení rozdílů (diff)

Klikněte na soubor ve Changes — VS Code otevře diff editor s původní verzí vlevo a upravenou vpravo. Kliknutím na soubor ve Staged Changes uvidíte, co přesně půjde do commitu (ekvivalent git diff --staged).

12 GUI ↔ CLI — ekvivalenty operací

Každou operaci z terminálu lze provést i ve VS Code. Tabulka ukazuje obě cesty pro nejčastější úkony.

OperacePříkaz (terminál)VS Code GUI
Zobrazit stav git status Source Control panel — automaticky, vždy aktuální
Přidat soubor do staging git add soubor.py Klik na + vedle souboru ve Changes
Přidat vše do staging git add . Klik na + vedle nadpisu Changes
Odebrat ze staging git restore --staged soubor.py Klik na vedle souboru ve Staged Changes
Zahodit lokální změny git restore soubor.py Klik na (Discard Changes) vedle souboru
Zobrazit diff souboru git diff soubor.py Klik na soubor ve Changes
Commit git commit -m "zpráva" Napsat zprávu do pole → Ctrl+Enter
Push git push menu → Push nebo tlačítko Sync Changes (↑↓) ve stavovém řádku
Pull git pull menu → Pull
Fetch git fetch menu → Fetch
Vytvořit větev git switch -c nova-vetev Klik na název větve ve stavovém řádku → Create new branch…
Přepnout větev git switch jina-vetev Klik na název větve ve stavovém řádku → vyberte větev ze seznamu
Merge větve git merge feature/xyz menu → BranchMerge Branch…
Stash (odložit změny) git stash push -m "popis" menu → StashStash All Changes
Stash pop (obnovit) git stash pop menu → StashApply Latest Stash
Zobrazit historii git log --oneline --graph Rozšíření Git Graph (viz 13) — vestavěná integrace je omezená
Anotace řádků (blame) git blame soubor.py Rozšíření GitLens → inline anotace při najetí myší
Integrovaný terminál Pro operace, které v GUI nejsou — rebase, reset, reflog — otevřete terminál přímo ve VS Code: Ctrl+` (backtick). Pracujete ve stejné složce projektu, GUI a terminál se navzájem vidí a synchronizují.

13 Doporučená rozšíření a jejich konfigurace

Instalace rozšíření: Ctrl+Shift+X → vyhledejte název → Install.

GitLens — inline anotace a rozšířená historie

eamodio.gitlens

Nejpopulárnější Git rozšíření pro VS Code. Zobrazuje inline anotace (kdo a kdy změnil řádek), procházení historie souboru, porovnávání větví a vizuální commit graph.

Klíčové funkce

  • Inline blame: při najetí na řádek vidíte autora, datum a zprávu commitu
  • File History: pravý klik na soubor → Open File History
  • Commit Graph: vizuální přehled větví (GitLens → Commit Graph)
  • Revision Navigation: tlačítka ← → pro procházení verzí souboru

Doporučená konfigurace (settings.json)

VS Code settings.json — GitLens
{
  "gitlens.currentLine.enabled": true,        ← blame na aktuálním řádku
  "gitlens.hovers.currentLine.over": "line",  ← detail při hoveru
  "gitlens.codeLens.enabled": false,          ← vypnout pokud ruší v kódu
  "gitlens.statusBar.enabled": true           ← stav v stavovém řádku
}
Git Graph — vizualizace commit grafu

mhutchie.git-graph

Zobrazí interaktivní commit graph přímo ve VS Code — větvení, merges, tagy. Spustíte přes menu → View Git Graph nebo příkazovou paletou (Ctrl+Shift+PGit Graph: View Git Graph).

Co v grafu lze dělat

  • Klik na commit — zobrazí detail a diff souborů
  • Pravý klik na commit — Checkout, Cherry Pick, Revert, Tag
  • Pravý klik na větev — Merge, Rebase, Delete
  • Filtrování podle větve nebo autora
Tip Git Graph je nejrychlejší způsob, jak pochopit stav repozitáře — otevřete ho vždy, když nevíte „kde teď jste".
Git History — procházení změn v souborech

donjayamanne.githistory

Doplňuje vestavěnou integraci o procházení historie konkrétního souboru nebo řádku. Pravý klik na soubor → Git: View File History.

  • Zobrazení všech commitů, které dotýkaly daného souboru
  • Porovnání libovolných dvou verzí souboru
  • Zobrazení commitu, který změnil konkrétní řádek
GitHub Pull Requests — PR přímo v editoru

github.vscode-pull-request-github

Pokud pracujete s GitHubem, toto rozšíření přináší Pull Request workflow přímo do VS Code: vytvoření PR, code review s komentáři inline, merge — vše bez otevírání prohlížeče.

Po instalaci: přihlaste se přes GitHub Account (ikona účtu v sidebar) a repozitář musí mít origin nastavený na GitHub.

Nastavení VS Code specifická pro Git

Doporučená settings.json pro Git workflow
{
  // Automatický fetch každých 3 minuty (zobrazí ↓ v stavovém řádku)
  "git.autofetch": true,
  "git.autofetchPeriod": 180,

  // Potvrzení před synchronizací (push + pull najednou)
  "git.confirmSync": true,

  // Automatický commit po stage (vypnuto — lepší mít kontrolu)
  "git.enableSmartCommit": false,

  // Zobrazit počet commitů čekajících na push v stavovém řádku
  "scm.countBadge": "all",

  // Výchozí větev pro nové repozitáře
  "git.defaultBranchName": "main",

  // Řádkové konce — důležité pro týmy s různými OS
  "files.eol": "\n"
}

14 Řešení merge konfliktu ve VS Code

VS Code vs Git VS Code je jen grafické rozhraní nad Gitem. Konflikty detekuje a označuje Git — VS Code je pouze zobrazuje a usnadňuje výběr. Výsledek se vždy zapíše příkazem git commit.

VS Code (od verze 1.69) obsahuje Merge Editor — grafické rozhraní pro řešení konfliktů. Aktivuje se automaticky při otevření konfliktního souboru.

Jak Merge Editor vypadá

Merge Editor zobrazí tři panely vedle sebe:

PanelObsahOdpovídá
Current (vlevo)Vaše aktuální verze (větev, kam mergujete)Sekce <<<<<<< HEAD
Incoming (vpravo)Verze přicházející z mergované větveSekce >>>>>>> v souboru
Result (dole)Výsledný soubor — zde vidíte a editujete konečnou podobuCo bude zapsáno

Postup řešení konfliktu krok za krokem

1

Otevřete Merge Editor

VS Code zobrazí v horní části souboru banner s konfliktem. Klikněte na tlačítko Resolve in Merge Editor.

2

Pro každý konflikt vyberte akci

Nad každým konfliktem se zobrazí tlačítka — vyberte jedno:

TlačítkoCo udělá
Accept CurrentZachová vaši verzi (levý panel)
Accept IncomingPřijme příchozí verzi (pravý panel)
Accept BothVloží obě verze za sebou (nejdřív Current, pak Incoming)
(ruční editace)Klikněte přímo do panelu Result a upravte text libovolně
Pozor: Current/Incoming se liší podle operace Při merge: Current = HEAD vaší větve, Incoming = mergovaná větev.
Při rebase: Current = commit, který se přehrává (z vaší větve), Incoming = větev, na kterou rebazujete. Termíny jsou v rebase kontextu opačně intuitivní — ověřte si vždy v panelu Result.
3

Dokončete v panelu Result

Zkontrolujte panel Result — musí být syntakticky správný, bez zbylých markerů. Pak klikněte Complete Merge v pravém dolním rohu Merge Editoru.

4

Commitněte

VS Code automaticky přidá vyřešený soubor do staging. Napište zprávu do Source Control panelu a stiskněte Ctrl+Enter.

Tip: Zobrazení tří panelů vedle sebe Pokud preferujete místo Merge Editoru přímou editaci souboru, klikněte v banneru na Resolve in Editor. Uvidíte soubor s markery a kontextové akce (CodeLens) přímo nad každým konfliktem.

15 Troubleshooting — časté problémy

💥 Potřebuji vrátit poslední commit (ale zachovat změny)
Tři varianty resetu
# Zruší commit, soubory zůstanou ve staging (připravené ke commitu)
git reset --soft HEAD~1

# Zruší commit, soubory zůstanou na disku ale ne ve staging
git reset HEAD~1

# Zruší commit A smaže i změny na disku (DESTRUKTIVNÍ — nelze vrátit)
git reset --hard HEAD~1
💥 Opravuji commit, který jsem právě zapsal
git commit --amend
# Přidejte zapomenuté soubory do staging, pak:
git commit --amend              ← přepíše poslední commit (nový hash)
git commit --amend -m "nová zpráva"  ← jen změna zprávy

# Pokud jste commit již pushnuli na VLASTNÍ feature větev:
git push --force-with-lease

# Pushnuto na sdílenou větev? Amend NEPROVÁDĚJTE.
# Místo toho vytvořte nový opravný commit:
git revert HEAD   ← nový commit, který předchozí bezpečně „odvolá"
💥 Omylem smazaná větev nebo ztracené commity

Git málokdy opravdu smaže data — jen je přestane referencovat. git reflog zaznamenává všechny pohyby HEAD za posledních 90 dní.

Záchrana přes reflog
git reflog
d2e3f4a HEAD@{0}: merge: Fast-forward
b5c6d7e HEAD@{1}: checkout: moving to main
c9d0e1f HEAD@{2}: commit: fix: login bug  ← tento commit hledáte

# Obnovte smazanou větev z konkrétního commitu:
git branch zachrana c9d0e1f

# Nebo se přepněte přímo:
git switch -c zachrana HEAD@{2}
💥 git push odmítnut — remote je napřed

Někdo jiný pushnul změny na server dříve než vy. Vaše větev a serverová větev se „rozcházejí".

Řešení odmítnutého push
! [rejected] main -> main (non-fast-forward)
hint: Updates were rejected because the remote contains work you do not have.

# Stáhněte a integrujte cizí změny, pak znovu pushnul:
git pull --rebase origin main
git push origin main
💥 git pull selhává — divergentní větve (divergent branches)

Git 2.27+ odmítá automaticky rozhodnout strategii při divergentních větvích — je nutné ji specifikovat explicitně.

StrategiePříkazKdy použít
Rebase (doporučeno pro solo projekty)git pull --rebase origin <větev>Čistá lineární historie
Mergegit pull --no-rebase origin <větev>Zachování merge commitu
Fast-forward onlygit pull --ff-only origin <větev>Jen pokud je FF možný
Diagnostika před rozhodnutím
git fetch origin
git log --oneline --graph master origin/master
Doporučené řešení + nastavení defaultu
git pull --rebase origin master
# Nastavit jako trvalý default pro tento repozitář:
git config pull.rebase true
Bezpečný abort
git rebase --abort   # vrátí stav přesně před git pull --rebase
💥 Potřebuji dočasně odložit rozdělanou práci
git stash
# Uloží všechny neuložené změny do zásobníku (working dir + staging)
git stash push -m "WIP: přihlašovací formulář"

# Přepněte, udělejte jiný úkol, vraťte se…
git stash list
stash@{0}: On feature/prihlaseni: WIP: přihlašovací formulář

# Obnovte a smažte ze zásobníku
git stash pop
💥 Jsem uprostřed merge nebo rebase a chci to přerušit

Pokud jste spustili merge nebo rebase a situace je nepřehledná, můžete celou operaci zrušit a vrátit repozitář přesně do stavu před ní.

Přerušení merge nebo rebase
# Zrušit probíhající merge (včetně všech konfliktů)
git merge --abort

# Zrušit probíhající rebase
git rebase --abort

# Ověřte stav — mělo by hlásit čistý stav
git status
On branch main
nothing to commit, working tree clean
💥 Potřebuji přenést konkrétní commit z jiné větve
git cherry-pick
# Aplikuje konkrétní commit na aktuální větev (bez přepínání)
git cherry-pick c9d0e1f

# Více commitů najednou:
git cherry-pick c9d0e1f d2e3f4a

# Bez okamžitého commitu (pro ruční úpravu před zápisem):
git cherry-pick -n c9d0e1f

17 git-crypt — šifrování souborů v repozitáři

git-crypt umožňuje transparentně šifrovat vybrané soubory přímo v repozitáři pomocí GPG nebo sdíleného symetrického klíče. Ostatní soubory zůstávají nešifrované — spolupráce na nich funguje normálně.

Jak to funguje

Šifrování probíhá přes Git smudge/clean filtry: při git add se soubor zašifruje, při git checkout automaticky dešifruje. Pro kohokoli bez klíče vypadají chráněné soubory v repozitáři jako binární šum.

Instalace

Instalace git-crypt
# macOS (Homebrew)
brew install git-crypt

# Debian / Ubuntu
sudo apt install git-crypt

# Windows — přes WSL nebo Scoop
scoop install git-crypt

Inicializace a konfigurace .gitattributes

Inicializace a nastavení šifrovaných souborů
# 1. Inicializujte git-crypt v repozitáři (vytvoří symetrický klíč)
git-crypt init

# 2. Nastavte, které soubory se mají šifrovat — editujte .gitattributes
#    Přidejte řádky ve formátu: <vzor> filter=git-crypt diff=git-crypt

.gitattributes !filter !merge !diff
secretfile filter=git-crypt diff=git-crypt
*.key filter=git-crypt diff=git-crypt
secrets/** filter=git-crypt diff=git-crypt

# 3. Zacommitujte .gitattributes (samotná pravidla nejsou tajná)
git add .gitattributes
git commit -m "chore: add git-crypt config"

Správa klíčů — symetrický klíč (jednoduchý přístup)

Export a import symetrického klíče
# Export klíče do souboru — tento soubor NIKDY necommitujte!
git-crypt export-key ./git-crypt-key

# Na jiném počítači / pro kolegu — odemknutí repozitáře klíčem
git-crypt unlock ./git-crypt-key

Správa klíčů — GPG (pro týmy)

Přidání GPG uživatele
# Přidejte GPG klíč kolegy (musí mít veřejný klíč v keyring)
git-crypt add-gpg-user KLÍČ_ID_NEBO_EMAIL

# git-crypt automaticky přidá zašifrovanou kopii klíče do .git-crypt/
# Kolega pak odemkne repozitář svým GPG klíčem:
git-crypt unlock

Ověření stavu šifrování

git-crypt status
# Zobrazí, které soubory jsou šifrované a které ne
git-crypt status
    encrypted: secrets/api.key
not encrypted: README.md
not encrypted: src/main.py

# Zamknout repozitář (šifrované soubory se znovu zakódují)
git-crypt lock
Pozor: git-crypt šifruje pouze obsah souborů — názvy souborů a cesty jsou viditelné pro každého, kdo má přístup k repozitáři. Také: pokud omylem commitnete soubor před nastavením pravidla v .gitattributes, zůstane v historii nešifrovaný (viz 18 pro vyčištění).
Tipy:
  • Klíčový soubor (git-crypt-key) uchovávejte v password manageru nebo bezpečném úložišti — bez něj jsou data nenávratně ztracená.
  • Přidejte git-crypt-key do .gitignore, aby se klíč nikdy nedostal do repozitáře.
  • Před přidáním nového souboru vždy ověřte pomocí git-crypt status, zda je správně označen k šifrování.

18 Vyčištění Git historie

Pokud do repozitáře omylem projde citlivý soubor (heslo, API klíč, binárka), samo odstranění souboru nestačí — data zůstávají dostupná ve starší historii. Tato sekce popisuje dvě metody vyčištění.

Nevratná operace! Přepis Git historie mění SHA hashe commitů. Pokud repozitář sdílíte s dalšími lidmi, musí všichni smazat svou lokální kopii a znovu klonovat. Vždy si nejprve vytvořte zálohu (git clone --mirror).

Metoda A — Orphan branch (nejrychlejší reset celé historie)

Hodí se tehdy, kdy chcete zachovat aktuální stav souborů, ale celou historii zahodit — například při startu open-source projektu z interního repozitáře.

Kompletní reset historie přes orphan branch
# 1. Vytvoř orphan branch (nová větev bez jakékoli historie)
git switch --orphan clean-main

# 2. Přidej všechny aktuální soubory do staging
git add -A

# 3. Vytvoř nový initial commit
git commit -m "Initial clean commit"

# 4. Smaž starou větev
git branch -D main

# 5. Přejmenuj novou větev na main
git branch -m main

# 6. Force push na GitHub (přepíše vzdálenou historii)
git push origin main --force

# 7. Smaž ostatní vzdálené větve, které už nepotřebuješ
git push origin --delete <název-větve>
Stará historie zůstává lokálně dostupná Smazání staré větve ji okamžitě neodstraní — commity zůstávají dostupné přes git reflog a git fsck --unreachable, dokud neproběhne garbage collection. Pro skutečné odstranění z lokálního repozitáře spusťte: git reflog expire --all --expire=now && git gc --prune=now --aggressive

Metoda B — git filter-repo (chirurgické odstranění konkrétního souboru)

Hodí se tehdy, kdy chcete zachovat historii, ale z každého commitu vymazat jeden konkrétní soubor (nebo složku).

Odstranění souboru z celé historie pomocí git filter-repo
# Instalace (git filter-repo není součástí Gitu)
brew install git-filter-repo          ← macOS
pip install git-filter-repo           ← cross-platform

# Odstraň soubor z celé Git historie (--invert-paths = "vše kromě")
git filter-repo --path secrets.env --invert-paths

# Odstraň celou složku z celé Git historie
git filter-repo --path config/secrets/ --invert-paths

# Ověř, že soubor v historii opravdu chybí
git log --all --full-history -- secrets.env
← prázdný výstup = soubor byl úspěšně smazán ze všech commitů

# Force push — přepíše vzdálený repozitář
git push origin --force --all
git push origin --force --tags
Po vyčištění vždy:
  • Zneplatněte a rotujte všechna kompromitovaná tajemství (API klíče, hesla) — je možné, že je někdo již stáhl.
  • Na GitHubu kontaktujte podporu pro vynucené smazání cache (cached views).
  • Informujte spolupracovníky — musí smazat lokální klony a znovu klonovat.

16 Cheatsheet — rychlá reference

KategoriePříkazPopis
Nastavení git config --global user.name "X"Nastavit jméno
git config --list --globalZobrazit globální konfiguraci
git config --global core.editor "code --wait"Nastavit VS Code jako editor
Staging git statusStav working directory
git add souborPřidat soubor do staging
git add -pInteraktivní přidávání po částech
git diffZměny na disku oproti staging
git diff --stagedStaging oproti poslednímu commitu
Historie git log --oneline --graph --allKompaktní vizuální log
git show HEADDetail posledního commitu
git blame souborKdo a kdy upravil každý řádek
Vrácení git restore souborZahodit změny na disku (od posl. commitu)
git restore --staged souborVyjmout ze staging (zachová změny)
git reset --soft HEAD~1Zrušit commit, zachovat staging
git revert HEADNový opravný commit (bezpečné)
Tagy git tag v1.0.0 -m "Release 1.0"Annotovaný tag
git push origin --tagsOdeslat tagy na remote
Záchrana git reflogHistorie všech pohybů HEAD (90 dní)
git stash popObnovit naposledy odložené změny

Cloudflare Workers – průvodce pro statický web na vlastní doméně

Pro nasazení statického webu existují dvě časté cesty: kontejner (Docker + hosting) nebo serverless edge. Kontejner dává plnou kontrolu, ale vyžaduje správu serveru, škálování a platbu za běžící instanci i v době nulového provozu. Cloudflare Workers fungují jinak — kód nebo soubory běží na hraničních uzlech sítě Cloudflare, spouštějí se jen při požadavku a pro statický obsah jsou zdarma do 100 000 požadavků denně. Pro jednoduché weby bez backendu je to nejjednodušší volba: žádný server, žádná údržba, globální CDN v ceně.


Přehled a koncepty

Cloudflare Workers je serverless platforma servírující statické soubory nebo spouštějící kód na globální CDN síti. Pro statický web jsou požadavky zdarma a bez limitu.

Poznámka: Cloudflare Pages byl deprecated v dubnu 2025. Cloudflare doporučuje Workers pro všechny nové projekty.

Klíčové pojmy

PojemPopis
WorkerServerless funkce nebo statický web nasazený na Cloudflare
WranglerCLI nástroj Cloudflare pro správu Workers
wrangler.tomlKonfigurační soubor projektu
Static AssetsStatické soubory (HTML, CSS, JS, obrázky) servírované přímo
RoutesPravidla pro mapování URL na Worker
Custom DomainVlastní doména nebo subdoména napojená na Worker
ZoneDoménová zóna spravovaná Cloudflare
Proxied (oranžový mrak)DNS záznam prochází přes Cloudflare proxy
RedirectHTTP přesměrování — prohlížeč změní adresu
RewriteInterní přepis URL — prohlížeč adresu nezmění

Architektura

Uživatel → DNS (Cloudflare) → Worker (redirect / rewrite / logika) → Static Assets

Předpoklady

Software

Potřebný software: Node.js v20+ (včetně npm) a Git.

winget (Windows 10/11, doporučeno)
# PowerShell nebo CMD jako běžný uživatel
winget install OpenJS.NodeJS.LTS
winget install Git.Git

# Po instalaci zavřete a znovu otevřete terminál
node --version   # očekáváno v20+
git --version
nvm-windows (správa více verzí Node.js)
# Stáhněte nvm-setup.exe z github.com/coreybutler/nvm-windows/releases
nvm install lts
nvm use lts
node --version
Homebrew (doporučeno)
brew install node git
node --version   # očekáváno v20+
Debian / Ubuntu (nvm — doporučeno)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
# Znovu načtěte shell (source ~/.bashrc nebo nové okno terminálu)
nvm install --lts
sudo apt install git
node --version
Fedora / RHEL
sudo dnf install nodejs npm git
node --version

Účty a domény

  • Aktivní Cloudflare účetdash.cloudflare.com
  • Doména přidaná do Cloudflare jako zone (nameservery musí ukazovat na Cloudflare)

Instalace a přihlášení

mkdir muj-web && cd muj-web
npm init -y
npm install -D wrangler
npx wrangler --version   # ověření
npx wrangler login    # otevře prohlížeč, token se uloží do ~/.wrangler/
npx wrangler whoami   # ověření přihlášení

Struktura projektu

Minimální projekt (statický web)

muj-web/
├── .git/                  ← Git repozitář
├── .gitignore
├── wrangler.toml          ← konfigurace Workers
├── package.json
└── public/
    ├── index.html
    ├── style.css
    └── 404.html

Projekt s Worker scriptem (redirect, rewrite)

muj-web/
├── .git/
├── .gitignore
├── wrangler.toml
├── package.json
├── src/
│   └── worker.js          ← Worker script
└── public/
    ├── index.html
    ├── style.css
    └── 404.html

Konfigurace wrangler.toml

5.1 Čistě statický web

name = "muj-web"
compatibility_date = "2025-04-01"

[assets]
directory = "./public"
not_found_handling = "404-page"

5.2 Statický web s vlastní doménou

name = "muj-web"
compatibility_date = "2025-04-01"

[assets]
directory = "./public"
not_found_handling = "404-page"

[[routes]]
pattern = "www.jan-zak.cz/*"
zone_name = "jan-zak.cz"

[[routes]]
pattern = "jan-zak.cz/*"
zone_name = "jan-zak.cz"

5.3 Statický web na subdoméně

name = "wtest-jan-zak"
compatibility_date = "2025-04-01"

[assets]
directory = "./public"
not_found_handling = "404-page"

[[routes]]
pattern = "wtest.jan-zak.cz/*"
zone_name = "jan-zak.cz"

5.4 Statický web + Worker script (redirect / rewrite)

name = "jan-zak-web"
compatibility_date = "2025-04-01"
main = "src/worker.js"

[assets]
directory = "./public"
not_found_handling = "404-page"

[[routes]]
pattern = "jan-zak.cz/*"
zone_name = "jan-zak.cz"

[[routes]]
pattern = "www.jan-zak.cz/*"
zone_name = "jan-zak.cz"

[[routes]]
pattern = "tools.jan-zak.cz/*"
zone_name = "jan-zak.cz"

Přehled klíčových polí

PolePopisPříklad
nameInterní název Workeru (bez teček)"muj-web"
compatibility_dateDatum kompatibility runtime"2025-04-01"
mainCesta k Worker scriptu"src/worker.js"
assets.directorySložka se statickými soubory"./public"
assets.not_found_handlingChování při 404"404-page"
routes[].patternURL vzor (vždy s /*)"jan-zak.cz/*"
routes[].zone_nameApex doména (zone v Cloudflare)"jan-zak.cz"

Lokální vývoj

npx wrangler dev   # → http://localhost:8787, live reload

Ukázka: public/index.html

<!DOCTYPE html>
<html lang="cs"><head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Jan Novák</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <h1>Jan Novák</h1>
  <nav><a href="/">Úvod</a> <a href="/o-mne.html">O mně</a></nav>
</body></html>

Ukázka: public/404.html

<!DOCTYPE html><html lang="cs"><head><meta charset="UTF-8"><title>404</title></head>
<body><h1>404 – Stránka nenalezena</h1><p><a href="/">Zpět na úvod</a></p></body></html>

Nasazení (deploy)

npx wrangler deploy                 # nasazení na Cloudflare
npx wrangler deployments list       # výpis verzí

Po úspěšném deployi Wrangler vrátí URL ve tvaru https://muj-web.<nazev>.workers.dev. Každý deploy vytváří novou verzi — Cloudflare uchovává posledních 100 verzí.


Vlastní doména a DNS

8.1 Přidání domény do Cloudflare

  1. dash.cloudflare.comAdd a Site → zadej doménu → Free plan
  2. Nastav nameservery dle pokynů Cloudflare u registrátora
  3. Počkej na aktivaci (obvykle do hodiny)

8.2 DNS záznam pro subdoménu (placeholder)

TypNameValueProxy status
AAAAwtest100::Proxied

Pokud CNAME již existuje: Zkontroluj, že je Proxied. Worker přes [[routes]] CNAME nemodifikuje — pouze zachytí provoz. Původní CNAME zůstane zachováno.

PowerShell
Resolve-DnsName wtest.jan-zak.cz   # ověření DNS
CMD / Git Bash
nslookup wtest.jan-zak.cz
Terminál
dig wtest.jan-zak.cz   # ověření DNS
Terminál
dig wtest.jan-zak.cz   # ověření DNS
# Pokud dig chybí: sudo apt install dnsutils  (Debian/Ubuntu)
#                  sudo dnf install bind-utils (Fedora/RHEL)

Přesměrování (redirecty)

Redirecty vyžadují Worker script. Čistý wrangler.toml přesměrování neumí.

9.1 Jednoduchý redirect subdomény

export default {
  async fetch(request, env) {
    const url = new URL(request.url);

    if (url.hostname === "tools.jan-zak.cz") {
      return Response.redirect("https://jan-zak.cz/tools/jz-tools.html", 301);
    }
    return env.ASSETS.fetch(request);
  }
};

9.2 Více redirectů (tabulkový přístup)

const redirects = {
  "tools.jan-zak.cz": "https://jan-zak.cz/tools/jz-tools.html",
  "blog.jan-zak.cz":  "https://jan-zak.cz/blog/",
  "cv.jan-zak.cz":    "https://jan-zak.cz/dokumenty/cv.pdf",
};

export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    const target = redirects[url.hostname];
    if (target) return Response.redirect(target, 301);
    return env.ASSETS.fetch(request);
  }
};

9.3 Redirect www → apex (zachování cesty)

if (url.hostname === "www.jan-zak.cz") {
  url.hostname = "jan-zak.cz";
  return Response.redirect(url.toString(), 301);
}

9.4 Redirect s přenesením cesty

// tools.jan-zak.cz/neco → jan-zak.cz/tools/neco
if (url.hostname === "tools.jan-zak.cz") {
  const newUrl = `https://jan-zak.cz/tools${url.pathname}${url.search}`;
  return Response.redirect(newUrl, 301);
}

9.5 Rozdíl mezi 301 a 302

KódTypCachováníPoužití
301TrvalýAnoTrvalé přejmenování, migrace
302DočasnýNeTestování, dočasné přesměrování

Upozornění: 301 redirect si prohlížeč zakešuje. Při testování vždy nejprve používej 302.


URL Rewrite

URL rewrite servíruje jiný obsah, než odpovídá adrese v prohlížeči — adresa v adresním řádku se nemění.

Redirect vs. Rewrite

Redirect (301/302)Rewrite
Adresa v prohlížečiZmění se na cílovou URLZůstane původní
HTTP odpověď301 / 302200 (obsah cíle)
Viditelnost pro uživateleAnoNe
Vhodné proTrvalé přejmenování, SEOHezké URL, skrytí struktury

10.1 Základní rewrite cesty

Uživatel vidí /tools, Worker interně načte /tools/jz-tools.html:

export default {
  async fetch(request, env) {
    const url = new URL(request.url);

    if (url.pathname === "/tools") {
      url.pathname = "/tools/jz-tools.html";
      return env.ASSETS.fetch(url.toString()); // prohlížeč stále vidí /tools
    }
    return env.ASSETS.fetch(request);
  }
};

10.2 Rewrite subdomény na jinou cestu

Uživatel vidí https://tools.jan-zak.cz, Worker interně servíruje /tools/jz-tools.html:

export default {
  async fetch(request, env) {
    const url = new URL(request.url);

    if (url.hostname === "tools.jan-zak.cz") {
      const rewriteUrl = new URL(request.url);
      rewriteUrl.hostname = "jan-zak.cz";
      rewriteUrl.pathname = "/tools/jz-tools.html";
      return fetch(rewriteUrl.toString());
    }
    return env.ASSETS.fetch(request);
  }
};

10.3 Tabulkový rewrite více cest

const rewrites = {
  "/tools":   "/tools/jz-tools.html",
  "/cv":      "/dokumenty/jan-zak-cv.pdf",
  "/kontakt": "/stranky/kontaktni-formular.html",
};

export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    const target = rewrites[url.pathname];

    if (target) {
      const rewriteUrl = new URL(request.url);
      rewriteUrl.pathname = target;
      return env.ASSETS.fetch(rewriteUrl.toString());
    }
    return env.ASSETS.fetch(request);
  }
};

10.4 Kombinace redirect + rewrite v jednom Workeru

const redirects = { "tools.jan-zak.cz": "https://jan-zak.cz/tools" };
const rewrites   = { "/tools": "/tools/jz-tools.html", "/cv": "/dokumenty/cv.pdf" };

export default {
  async fetch(request, env) {
    const url = new URL(request.url);

    // 1. Redirect subdomény (prohlížeč změní adresu)
    const redirectTarget = redirects[url.hostname];
    if (redirectTarget) return Response.redirect(redirectTarget, 301);

    // 2. Rewrite cesty (prohlížeč adresu nezmění)
    const rewritePath = rewrites[url.pathname];
    if (rewritePath) {
      const rUrl = new URL(request.url);
      rUrl.pathname = rewritePath;
      return env.ASSETS.fetch(rUrl.toString());
    }

    return env.ASSETS.fetch(request);
  }
};

10.5 Kdy použít redirect a kdy rewrite

ScénářDoporučení
Trvalé přejmenování stránky (SEO)Redirect 301
Hezká URL (/tools místo /tools/jz-tools.html)Rewrite
Subdoména jako alias sekce (transparentní)Rewrite
Subdoména jako alias sekce (viditelný přesun)Redirect
Testování nové verze stránkyRedirect 302
Skrytí interní struktury souborůRewrite

Git a verzování projektu

Git a Wrangler jsou zcela nezávislé nástroje — nedochází mezi nimi ke konfliktům.

Proč nedochází ke konfliktům

NástrojCo spravujeKde ukládá data
GitVerzování souborů projektu.git/ (v adresáři projektu)
WranglerDeploy na Cloudflare, tokeny~/.wrangler/ (globálně, mimo projekt)

Doporučený .gitignore

# npm závislosti
node_modules/

# Wrangler lokální cache
.wrangler/

# macOS
.DS_Store

Co patří do Gitu

Soubor / složkaDo Gitu?Důvod
wrangler.tomlAnoKonfigurační soubor, ne citlivá data
src/worker.jsAnoZdrojový kód
public/AnoStatické soubory webu
package.jsonAnoDefinice projektu
node_modules/NeGenerováno npm install
.wrangler/NeLokální cache Wrangleru
.DS_StoreNemacOS systémový soubor

Praktický důsledek pro rollback: Routes v wrangler.toml se při Cloudflare rollbacku neobnoví — Worker rollback vrátí pouze kód. Verzování wrangler.toml v Gitu to řeší: git restore --source=<commit> -- wrangler.toml + nový deploy.

Inicializace Git repozitáře

cd muj-web
git init
# vytvoř .gitignore
git add .
git commit -m "Initial commit: Cloudflare Workers static site"

Rollback

Cloudflare Workers uchovává posledních 100 verzí pro každý Worker.

npx wrangler deployments list                         # výpis verzí
npx wrangler rollback --message "Důvod rollbacku"     # poslední stabilní
npx wrangler rollback <version-id> --message "Popis"  # konkrétní verze

Rollback přes Dashboard

  1. dash.cloudflare.com → Workers & Pages → vyber Worker
  2. Záložka Deployments → u požadované verze tři tečky → Rollback

Limity rollbacku

OmezeníPopis
Počet verzíPosledních 100 verzí
RoutesRollback nevrátí změny routes — pouze kód
KV / R2 / D1Data se nerolují zpět
SecretsPoužije aktuální hodnoty, ne historické

Praktický důsledek: Routes obnoví Git (git restore --source=<commit> -- wrangler.toml + wrangler deploy), ne Cloudflare rollback.


Další běžné scénáře

13.1 Vlastní HTTP hlavičky (security headers)

Správný vzor: definuj hlavičky jako konstantu a aplikuj je přes pomocnou funkci. Přepisuj jen ty, které CF Assets sám nenastavuje.

const SECURITY_HEADERS = {
  // Zabraňuje MIME sniffingu — prohlížeč respektuje Content-Type bez hádání.
  "X-Content-Type-Options": "nosniff",

  // Vypíná legacy XSS auditor (IE/starý Chrome). Hodnota "1; mode=block" je dnes nebezpečná.
  "X-XSS-Protection": "0",

  // Omezuje obsah Referer při navigaci na jiné domény.
  "Referrer-Policy": "strict-origin-when-cross-origin",

  // Nahrazuje X-Frame-Options — CSP frame-ancestors má vyšší prioritu, XFO se pak ignoruje.
  "Content-Security-Policy": "frame-ancestors 'none'",

  // Zakazuje přístup k browser API, která stránka nepotřebuje.
  "Permissions-Policy": "geolocation=(), camera=(), microphone=()",

  // Izoluje browsing context — mitigace Spectre přes sdílenou paměť.
  "Cross-Origin-Opener-Policy": "same-origin",

  // Zabraňuje načtení zdrojů této domény cross-origin stránkami.
  "Cross-Origin-Resource-Policy": "same-origin",

  // Cache-Control — CF Assets ho sám nenastavuje; 7 dní v prohlížeči i CDN.
  "Cache-Control": "public, max-age=604800",
};

function addSecurityHeaders(response) {
  const headers = new Headers(response.headers);
  for (const [key, value] of Object.entries(SECURITY_HEADERS)) {
    headers.set(key, value);
  }
  return new Response(response.body, { status: response.status, statusText: response.statusText, headers });
}

export default {
  async fetch(request, env) {
    const response = await env.ASSETS.fetch(request);
    return addSecurityHeaders(response);
  },
};
Poznámky:
  • Strict-Transport-Security přidává Cloudflare automaticky — ve Workeru je zbytečná.
  • X-Frame-Options je zastaralé; pokud jsou přítomny oba, prohlížeč ignoruje XFO ve prospěch CSP frame-ancestors.
  • Content-Security-Policy: default-src 'self' je příliš restriktivní pro statické weby načítající fonty nebo CDN skripty — uprav dle potřeby.

13.2 Vynucení HTTPS

Nastavení v dashboardu: SSL/TLS → Edge Certificates → Always Use HTTPS. Worker script není potřeba.

13.3 HTTP autentizace – přehled

Worker může chránit obsah nebo API různými způsoby. Každá metoda odpovídá jinému use-case:

MetodaVhodné proKde se ověřuje
Basic AuthJednoduchá ochrana stránky heslemHlavička Authorization: Basic …
Bearer tokenOchrana API endpointu statickým tokenemHlavička Authorization: Bearer …
API key v hlavičceStrojový přístup (M2M), třetí stranyVlastní hlavička, např. X-Api-Key
Cookie / session tokenPřihlášení přes formulář, SPACookie session=…

Tajné hodnoty (hesla, tokeny) nikdy nevkládejte přímo do kódu — ukládejte je jako Worker Secrets (npx wrangler secret put NAZEV) a čtěte přes env.NAZEV.

Basic Auth (ochrana stránky dialogem prohlížeče)

export default {
  async fetch(request, env) {
    const auth = request.headers.get("Authorization");
    const expected = "Basic " + btoa("uzivatel:" + env.HESLO);

    if (!auth || auth !== expected) {
      return new Response("Přístup odepřen", {
        status: 401,
        headers: { "WWW-Authenticate": 'Basic realm="Sekce"' },
      });
    }
    return env.ASSETS.fetch(request);
  }
};

Bearer token (ochrana API endpointu)

export default {
  async fetch(request, env) {
    const url = new URL(request.url);

    if (url.pathname.startsWith("/api/")) {
      const auth = request.headers.get("Authorization") ?? "";
      if (!auth.startsWith("Bearer ") || auth.slice(7) !== env.API_TOKEN) {
        return new Response("Unauthorized", { status: 401 });
      }
    }
    return env.ASSETS.fetch(request);
  }
};

API key ve vlastní hlavičce

const key = request.headers.get("X-Api-Key");
if (key !== env.API_KEY) {
  return new Response("Forbidden", { status: 403 });
}

Cookie / session token

// Pomocná funkce pro čtení cookie ze záhlaví
function getCookie(request, name) {
  const header = request.headers.get("Cookie") ?? "";
  const match = header.match(new RegExp(`(?:^|;\\s*)` + name + `=([^;]*)`));
  return match?.[1] ?? null;
}

export default {
  async fetch(request, env) {
    const session = getCookie(request, "session");
    if (session !== env.SESSION_SECRET) {
      return Response.redirect("/login", 302);
    }
    return env.ASSETS.fetch(request);
  }
};

13.3b Autentizace při volání externích služeb

Worker může sám volat externí API (databáze, notifikace, třetí strany). Tajné klíče předávejte vždy přes env, nikdy napevno v kódu.

API key v hlavičce (nejčastější)

const response = await fetch("https://api.sluzba.cz/data", {
  headers: {
    "X-Api-Key": env.SLUZBA_API_KEY,
    "Content-Type": "application/json",
  },
});
const data = await response.json();

Bearer token (OAuth 2.0 statický přístupový token)

const response = await fetch("https://api.sluzba.cz/items", {
  headers: { "Authorization": "Bearer " + env.ACCESS_TOKEN },
});

Basic Auth (volání legacy API)

const credentials = btoa(env.API_USER + ":" + env.API_PASS);
const response = await fetch("https://legacy.api.cz/endpoint", {
  headers: { "Authorization": "Basic " + credentials },
});

OAuth 2.0 Client Credentials (získání tokenu před voláním)

// 1. Získej přístupový token
const tokenRes = await fetch("https://auth.sluzba.cz/oauth/token", {
  method: "POST",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body: new URLSearchParams({
    grant_type:    "client_credentials",
    client_id:     env.CLIENT_ID,
    client_secret: env.CLIENT_SECRET,
    scope:         "read",
  }),
});
const { access_token } = await tokenRes.json();

// 2. Zavolej chráněné API s tokenem
const data = await fetch("https://api.sluzba.cz/resource", {
  headers: { "Authorization": "Bearer " + access_token },
}).then(r => r.json());

Poznámka k caching: OAuth token má životnost (typicky 3 600 s). Worker je bezstavový — token se získává znovu při každém požadavku. Pro omezení počtu token requestů použijte Cloudflare KV jako cache: uložte token s TTL a čtěte ho při dalším požadavku.

13.4 Geograficky podmíněný obsah

const country = request.cf?.country;
if (country === "CZ" || country === "SK") {
  if (!url.pathname.startsWith("/cs/")) {
    url.pathname = "/cs" + url.pathname;
    return Response.redirect(url.toString(), 302);
  }
}

13.5 JSON endpoint

if (url.pathname === "/api/status") {
  return new Response(
    JSON.stringify({ status: "ok", timestamp: new Date().toISOString() }),
    { headers: { "Content-Type": "application/json" } }
  );
}

13.6 Zpracování více subdomén pod jedním Workerem

const routes = {
  "jan-zak.cz":       null,
  "www.jan-zak.cz":   "https://jan-zak.cz",
  "tools.jan-zak.cz": "https://jan-zak.cz/tools/jz-tools.html",
  "blog.jan-zak.cz":  "https://jan-zak.cz/blog/",
};

export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    const target = routes[url.hostname];
    if (target) {
      if (target === "https://jan-zak.cz") {
        url.hostname = "jan-zak.cz";
        return Response.redirect(url.toString(), 301);
      }
      return Response.redirect(target, 301);
    }
    return env.ASSETS.fetch(request);
  }
};

Doporučení a best practices

Konfigurace

  • Vždy používej /* v route pattern — bez hvězdičky Worker neobsluhuje podsložky.
  • Název Workeru (name) nesmí obsahovat tečky — používej pomlčky.
  • compatibility_date nastav na aktuální datum při vytváření projektu; neměň bez důvodu.
  • Udržuj wrangler.toml v Git repozitáři.

DNS a domény

  • Vždy ověř, že DNS záznam je Proxied — bez toho Worker není zavolán.
  • Pro subdomény bez záznamu vytvoř placeholder AAAA 100:: (Proxied).
  • Pokud existuje CNAME, použij [[routes]], ne custom_domain = true.

Redirecty a rewrite

  • Při testování používej 302, na produkci přepni na 301 až po ověření.
  • Pro hezké URL bez změny adresy použij rewrite (env.ASSETS.fetch(rewriteUrl.toString())).

Bezpečnost

  • API klíče a hesla ukládej jako Wrangler secrets, ne přímo do kódu:
npx wrangler secret put MOJE_HESLO   # přístup přes env.MOJE_HESLO
  • Přidej security headers (viz scénář 13.1).
  • Aktivuj Always Use HTTPS v Cloudflare dashboardu.

Git a verzování

  • Verzuj wrangler.toml — routes se při Cloudflare rollbacku neobnoví, Git je má.
  • Přidej node_modules/ a .wrangler/ do .gitignore.
  • Před větší změnou si zapiš version ID (npx wrangler deployments list).

Přehled příkazů Wrangler

PříkazPopis
npx wrangler loginPřihlášení ke Cloudflare
npx wrangler whoamiZobrazení přihlášeného uživatele
npx wrangler logoutOdhlášení od Cloudflare
npx wrangler devLokální dev server (localhost:8787)
npx wrangler deployNasazení Workeru na Cloudflare
npx wrangler deployments listVýpis posledních deploymentů
npx wrangler rollbackRollback na poslední stabilní verzi
npx wrangler rollback <id>Rollback na konkrétní verzi
npx wrangler secret put <NAZEV>Uložení citlivého parametru
npx wrangler secret listVýpis názvů uložených secrets
npx wrangler secret delete <NAZEV>Smazání secretu
npx wrangler tailŽivý log requestů (streaming)
npx wrangler --versionVerze Wrangleru

Řešení častých problémů

Worker není volán po deployi

  • DNS záznam musí existovat a být Proxied.
  • Ověř zone_name — musí odpovídat apex doméně.
  • Route pattern musí obsahovat /*.

Chyba origin_conflict_existing_dns_record

  • Nastává při custom_domain = true s existujícím CNAME.
  • Řešení: použij [[routes]].

404 na všech stránkách kromě indexu

  • Ověř, že assets.directory ukazuje na správnou složku a index.html je přímo v ní.

Redirect neplatí (zakešovaný 301)

  • Zkus anonymní okno nebo vymaž cache prohlížeče. Při testování vždy 302.

Rewrite vrací 404

  • Ověř, že cílový soubor existuje v public/.
  • Předávej URL jako string: env.ASSETS.fetch(url.toString()).

wrangler dev nefunguje (chyba autentizace)

npx wrangler logout && npx wrangler login

Lokální dev nevidí soubory z public/

  • Cesta v assets.directory musí být "./public", nikoli "public".

Git a Wrangler — zdánlivý konflikt

  • Ke konfliktům nedochází. Přidej .wrangler/ a node_modules/ do .gitignore.

Zdroje

DokumentURL
Static Assets – Get Starteddevelopers.cloudflare.com/workers/static-assets/
Wrangler – instalace…/wrangler/install-and-update/
Wrangler – konfigurace…/wrangler/configuration/
Wrangler – příkazy…/wrangler/commands/
Routes…/routing/routes/
Custom Domains…/routing/custom-domains/
Fetch handler (rewrite)…/runtime-apis/handlers/fetch/
Rollbacks…/versions-and-deployments/rollbacks/
Ceny a limity…/platform/pricing/
GitHub Actions pro Workers…/ci-cd/external-cicd/github-actions/

Claude Code — průvodce AI asistentem v terminálu a VS Code


Co je Claude Code

Claude Code je interaktivní AI agent od Anthropic, který běží přímo v terminálu (nebo IDE). Rozumí celému repozitáři, čte a upravuje soubory, spouští příkazy a vykonává vícekrokové úlohy autonomně. Není to jen chatbot — vidí váš kód, git historii a filesystem.

Klíčový rozdíl od ChatGPT / Copilot: Claude Code má přístup k nástrojům (čtení souborů, spouštění příkazů, prohledávání kódu) a jedná autonomně. Sám procházíkódovou základnou a provádí změny.

1.1 Kde běží

ProstředíPopis
Terminál (CLI)Základní režim — příkaz claude v jakémkoli adresáři
VS Code rozšířeníIntegrovaný panel přímo v editoru
JetBrains pluginPodpora IntelliJ, PyCharm, WebStorm…
claude.ai/codeWebová verze s přístupem k souborům

1.2 Modely

Model IDDoporučení pro
claude-opus-4-6Architektura, složité plánování
claude-sonnet-4-6Implementace — výchozí volba
claude-haiku-4-5Rychlý boilerplate, jednoduché tasky

Instalace

Předpoklady

  • Node.js v18+
  • Účet na claude.ai nebo API klíč od Anthropic
# Instalace přes npm (globálně)
npm install -g @anthropic-ai/claude-code

# Ověření
claude --version
# První spuštění — přihlášení přes prohlížeč
claude

# Nebo nastavení API klíče přímo
export ANTHROPIC_API_KEY="sk-ant-..."

API klíč: Nikdy necommitujte API klíč do repozitáře. Používejte proměnné prostředí nebo .env soubory v .gitignore.


Interaktivní režim

Základní použití — spustíte claude v adresáři projektu a komunikujete v přirozeném jazyce. Claude vidí všechny soubory v pracovním adresáři.

# Spuštění v aktuálním projektu
cd muj-projekt
claude

# Jednorázový dotaz bez interaktivního režimu (-p = print)
claude -p "Vysvětli funkci parseConfig v src/config.ts"

# Pokračování v předchozí konverzaci
claude --resume

# Komprimace kontextu při dlouhých sezeních
# V interaktivním režimu zadejte:
/compact

Oprávnění nástrojů

Claude se před každou destruktivní akcí (zápis souboru, spuštění příkazu) zeptá na potvrzení. Toto chování lze upravit:

RežimChování
VýchozíPotvrzení před každou akcí mimo čtení
--dangerously-skip-permissionsBez potvrzení — jen pro CI/CD nebo izolovaná prostředí

Slash příkazy

Slash příkazy jsou zkratky pro časté operace. Zadávají se přímo v interaktivním režimu.

4.1 Vestavěné příkazy

PříkazPopis
/helpNápověda ke všem příkazům
/clearVymaže kontext konverzace
/compactKomprimuje dlouhou konverzaci — šetří kontext
/reviewCode review aktuálních změn (deprecated — doporučeno jako vlastní příkaz)
/initInicializuje CLAUDE.md pro aktuální projekt
/costZobrazí využití tokenů a odhadované náklady
/modelPřepne model (opus / sonnet / haiku)
/fastPřepne do rychlého režimu (Opus 4.6 s rychlejším výstupem)

4.2 Vlastní příkazy

Slash příkazy lze rozšířit vlastními soubory v .claude/commands/. Každý .md soubor se stane dostupným jako /nazev-souboru. Soubor obsahuje prompt, který se spustí při zavolání příkazu.

.claude/
└── commands/
    ├── codereview.md    → /codereview
    ├── deploy-check.md  → /deploy-check
    └── publish.md       → /publish
<!-- .claude/commands/codereview.md -->
Proveď code review změněných souborů. Zaměř se na:
- Bezpečnostní problémy
- Výkonnostní antipatterns
- Chybějící ošetření chyb
Výstup: odrážkový seznam, max 10 bodů.
<!-- .claude/commands/publish.md -->
Commituj všechny změny a nasaď web na Cloudflare.

## Kroky

1. Spusť `git status` — zjisti, co se změnilo.
2. Spusť `git add -A`.
3. Z diffu (`git diff --cached`) sestav výstižnou českou commit zprávu a spusť `git commit -m "..."`.
4. Spusť `npx wrangler deploy` z kořene repozitáře.
5. Vypiš nasazenou URL.

Pokud není co commitovat (čistý working tree), přeskoč na krok 4.

Konfigurační soubory

Claude Code používá několik souborů pro konfiguraci chování, kontextu projektu a přístupu k souborům. Každý slouží jinému účelu.

Přehled konfiguračních souborů

SouborÚčelCommitovat?
CLAUDE.mdKontext a pravidla projektu — načítá se automatickyano
CLAUDE.local.mdOsobní poznámky, lokální overrides — nepublikuje sene (.gitignore)
~/.claude/CLAUDE.mdGlobální kontext — platí pro všechny projekty
.claudeignoreSoubory a složky skryté před Claudem (jako .gitignore)ano
~/.claude/settings.jsonGlobální nastavení — hooks, MCP, oprávnění
.claude/settings.jsonProjektové nastavení — hooks, MCP specifické pro repoano
.claude/settings.local.jsonLokální přepisy projektového nastaveníne (.gitignore)
.claude/commands/Vlastní slash příkazy — každý .md soubor = jeden příkazano

5.1 CLAUDE.md

Automaticky načítaný „briefing" — říká Claudovi, co je projekt zač, jaká jsou pravidla a jak má pracovat.

# Název projektu — Claude Context

## Scope (NON-NEGOTIABLE)
- Edituj POUZE soubory relevantní k úloze
- Neptej se zbytečně — jednej autonomně

## Pravidla
- Kód v angličtině, obsah/data v češtině
- Žádné spekulativní abstrakce

## Projekt
Krátký popis — co projekt dělá, jak se buildí, jak se nasazuje.

## Apps / Moduly
| Modul | Popis |
|-------|-------|
| api   | REST backend, Node.js + Fastify |

Nedávejte do CLAUDE.md: Kódové vzory, architekturu, git historii — ty jsou v kódu samotném. CLAUDE.md je pro kontext a pravidla, ne pro dokumentaci.

5.2 .claudeignore

Funguje stejně jako .gitignore — soubory a složky uvedené v .claudeignore Claude při prohledávání kódové základny přeskočí. Hodí se pro velké složky s vygenerovanými daty, binárky nebo citlivé soubory.

# .claudeignore — soubory skryté před Claudem

# Závislosti
node_modules/
.venv/

# Buildy a generované soubory
dist/
build/
*.min.js

# Data a archivy
*.csv
*.zip
*.sqlite

# Lokální konfigurace
.env
.env.local

Poznámka: .claudeignore neovlivňuje, které soubory Claude smí editovat — pouze které vidí při prohledávání. Pro omezení editací použijte pravidla v CLAUDE.md.

5.3 Vlastní slash příkazy (.claude/commands/)

Každý .md soubor v .claude/commands/ se stane dostupným slash příkazem — viz sekci 4.2 pro příklady a strukturu souborů.


Hooks — automatizace akcí

Hooks jsou shell příkazy, které se spouštějí automaticky v reakci na události Claude Code (před/po volání nástroje, při odeslání zprávy…). Konfigurují se v settings.json.

6.1 Události

UdálostKdy se spustí
PreToolUsePřed každým voláním nástroje (čtení, zápis, bash…)
PostToolUsePo dokončení nástroje
UserPromptSubmitPři odeslání zprávy uživatelem
StopPři ukončení konverzace

6.2 Příklad konfigurace

// ~/.claude/settings.json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npm run lint --silent"
          }
        ]
      }
    ]
  }
}

Použití: Automatické spuštění linteru po každém zápisu souboru, notifikace, logování, formátování kódu…


MCP servery

MCP (Model Context Protocol) je otevřený standard pro připojení externích nástrojů a datových zdrojů k AI agentům. Claude Code podporuje MCP servery — přidají nové nástroje dostupné v konverzaci.

7.1 Příklady MCP serverů

ServerPřidá nástroje pro
GitHubSprávu issues, PR, repozitářů
Postgres / SQLiteDotazy přímo na databázi
SlackČtení a odesílání zpráv
FilesystemPřístup k souborům mimo pracovní adresář
PuppeteerOvládání prohlížeče, screenshoty

7.2 Konfigurace MCP serveru

// ~/.claude/settings.json
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_..."
      }
    }
  }
}
# Přidání MCP serveru přes CLI
claude mcp add github -- npx -y @modelcontextprotocol/server-github

# Výpis nakonfigurovaných serverů
claude mcp list

Best practices

8.1 Efektivní promptování

  • Buďte konkrétní — místo „oprav bug" uveďte soubor a řádek: „v src/auth.ts:42 oprav X"
  • Jeden prompt = jedna funkce/blok — nedávejte více nesouvisejících úloh najednou
  • Sdělte kontext — popište proč, ne jen co: „refaktoruj kvůli výkonu, ne kvůli čitelnosti"
  • Používejte /compact u dlouhých sezení — ušetří kontext a zrychlí odpovědi

8.2 Správa kontextu

  • CLAUDE.md za projekt — přidejte do repozitáře, commitujte spolu s kódem
  • Scope rules — explicitně definujte, které soubory Claude smí/nesmí měnit
  • --resume pro pokračování předchozí konverzace po přerušení

8.3 Bezpečnost

  • Nikdy nespouštějte --dangerously-skip-permissions na produkčních systémech
  • API klíče patří do proměnných prostředí, nikdy do kódu
  • Zkontrolujte každou dávku změn před potvrzením — Claude dělá chyby

8.4 Výběr modelu podle úlohy

ÚlohaDoporučený model
Architektura, plánování, složitý refaktoringopus
Implementace, opravy bugů, přidání featuresonnet
Boilerplate, jednoduché překlady, formátováníhaiku

Zdroje

ZdrojURL
Dokumentace Claude Codedocs.anthropic.com/…/claude-code
Model Context Protocolmodelcontextprotocol.io
GitHub — claude-codegithub.com/anthropics/claude-code
Anthropic API dokumentacedocs.anthropic.com/en/api
MCP servery (komunita)github.com/modelcontextprotocol/servers

Docker — Architektura & Principy

Kontejnerizační platforma postav na Linux kernel namespaces + cgroups

Co Docker řeší

Docker obaluje aplikaci a všechny její závislosti do izolované jednotky — kontejneru — která běží identicky na jakémkoli hostu s Docker daemonem. Eliminuje problém "na mém stroji to funguje" a přináší reprodukovatelné buildy, rychlé nasazení a efektivní využití zdrojů oproti VM.

VM vs. Kontejner

VM virtualizuje celý hardware včetně Guest OS (GiB overhead). Kontejner sdílí kernel hostu — izolace přes namespaces, overhead jen MiB.

Klíčové kernel technologie

Namespaces — izolace PID, NET, MNT, UTS, IPC, USER
cgroups v2 — limity CPU, RAM, I/O, PIDs
OverlayFS — vrstveného filesystemu

Architektura

┌─────────────────── Docker Host ───────────────────────────┐ │ │ │ CLI / REST API │ │ │ ▼ │ dockerd (Docker Daemon) │ │ │ │ ├──▶ containerd (container lifecycle manager) │ │ │ └──▶ runc (OCI runtime — fork/exec kontejner) │ │ │ │ │ ├──▶ Image Store (layer cache, OverlayFS) │ │ ├──▶ Volume Manager │ └──▶ Network plugins (bridge / overlay / macvlan / host)│ │ │ │ Kontejner A │ Kontejner B │ Kontejner C │ │ [namespace] │ [namespace] │ [namespace] │ │ [cgroup] │ [cgroup] │ [cgroup] │ └────────────────────────────────────────────────────────────┘ ┌─────────┴─────────┐ Docker Hub Private Registry (registry.hub) (Harbor, ECR, ACR…)

Vrstvy image (OverlayFS)

Každý RUN / COPY instrukce v Dockerfile přidá novou read-only vrstvu. Kontejner přidá přes ně thin read-write vrstvu (Copy-on-Write). Sdílené vrstvy jsou na hostu uloženy pouze jednou — šetří disk i čas pull.

# Příklad vrstev image node:20-alpine
Layer 0 (base):     alpine 3.19     ← sdíleno všemi alpine images
Layer 1:            node 20 runtime
Layer 2:            npm dependencies (package.json)
Layer 3:            app source
───────────────────────────────────────────────
Container layer:    R/W (dočasný, ztracen po rm)
  

Terminologie

Klíčové pojmy Docker ekosystému

TermínDefiniceAnalogie
ImageNeměnná, vrstevnatá šablona kontejneru. Vzniká buildem Dockerfile. Uložena v registry.ISO / VM šablona
ContainerBěžící instance image. Má vlastní PID, NET, filesystem namespace. Po docker rm zaniká.Spuštěná VM
DockerfileTextový recept pro build image. Sekvence instrukcí (FROM, RUN, COPY…).Kickstart / Packer template
RegistryServer pro ukládání a distribuci image. Docker Hub = výchozí veřejný. Harbor/ACR = privátní.NuGet / npm registry
TagLabel verze image. nginx:1.27-alpine = repo:tag. latest je jen konvence, ne "nejnovější stable".Git tag
VolumePerzistentní úložiště spravované Dockerem, nezávislé na životním cyklu kontejneru.Datový disk VM
Bind mountPřímé namapování adresáře hostu do kontejneru. Vhodné pro dev, ne pro prod.SMB share mount
NetworkVirtuální síť propojující kontejnery. Typy: bridge, overlay, host, macvlan, none.vSwitch / VNet
LayerJedna přírůstková vrstva filesystemu v image. Sdílena mezi images (dedup).Git commit / delta
DigestSHA256 hash image manifestu. Imutable reference — vždy přesně určí verzi.Git commit SHA
dockerdDocker daemon — background service, přijímá API požadavky.Windows Service
containerdCNCF project, podkomponenta dockerd pro lifecycle kontejnerů. Také standalone (K8s).Hypervisor pod VMM
runcOCI-kompatibilní runtime — vytvoří namespace, cgroup, spustí proces.Kernel VM entry
ComposeYAML definice multi-kontejnerové aplikace. docker compose up = celý stack.ARM/Bicep template
ContextNastavení CLI pro přepínání mezi Docker hosts (local / remote / Swarm).kubectl context

Image naming

# Plný formát:
registry.example.com/namespace/repo:tag@sha256:abc123...

# Příklady:
nginx:1.27-alpine                        # Docker Hub, official
mycompany/api:v2.1.0                    # Docker Hub, org namespace
harbor.corp.local/prod/app:latest      # Private registry
mcr.microsoft.com/dotnet/aspnet:8.0    # Microsoft Container Registry
  

Instalace & First steps

Docker Engine (Linux) vs Docker Desktop (macOS/Win)

PlatformaProduktRuntimePoznámka
Linux (Ubuntu/Debian)Docker EnginenativníDoporučeno pro servery/CI
macOS / WindowsDocker DesktopVM (LinuxKit / WSL2)Licence req. pro firmy >250 zaměst.
Linux (rootless)Docker Engine rootlessnativní, user nsBez root — bezpečnější pro dev

Instalace Dockeru

Doporučeno: Docker Desktop — obsahuje Docker Engine, CLI, Compose i GUI. Kontejnery běží přes WSL2 (odlehčené linuxové jádro), který je proto potřeba mít zapnutý.

winget (Windows 10/11, doporučeno)
# Spusťte PowerShell jako správce
winget install --id Docker.DockerDesktop -e

# Pokud WSL2 ještě není nainstalován:
wsl --install

# Po instalaci a restartu ověřte (v novém terminálu):
docker --version
docker run --rm hello-world
Licence: Docker Desktop je zdarma pro osobní použití, výuku a malé firmy. Pro firmy nad 250 zaměstnanců nebo 10 M USD obratu je vyžadováno placené předplatné.

Doporučeno: Docker Desktop přes Homebrew. Podporuje Apple Silicon (M-čipy) i Intel; kontejnery běží v odlehčeném Linux VM.

Homebrew (cask)
# Nainstaluje Docker Desktop.app do /Applications
brew install --cask docker

# Spusťte Docker Desktop z Applications (poprvé povolte oprávnění), poté ověřte:
docker --version
docker run --rm hello-world
Alternativy bez Docker Desktop: colima nebo podman — odlehčené runtime poskytující Docker-kompatibilní CLI bez GUI a bez licenčního omezení.

Docker Engine — nativní, bez VM, ideální pro servery a CI. Níže oficiální repozitář pro Ubuntu/Debian.

Ubuntu / Debian (apt)
# 1. Přidání oficiálního repozitáře
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
  | sudo tee /etc/apt/sources.list.d/docker.list

# 2. Instalace
sudo apt update && sudo apt install -y \
  docker-ce docker-ce-cli containerd.io docker-compose-plugin

# 3. Přidání uživatele do skupiny (aby nebylo nutné sudo)
sudo usermod -aG docker $USER
newgrp docker

# 4. Ověření
docker info
docker run --rm hello-world

Základní workflow

# Pull image z registry
docker pull nginx:1.27-alpine

# Spustit kontejner interaktivně
docker run -it --rm ubuntu bash

# Spustit jako daemon, mapovat port, pojmenovat
docker run -d --name webserver \
  -p 8080:80 \
  -v /srv/html:/usr/share/nginx/html:ro \
  nginx:1.27-alpine

# Výpis běžících / všech kontejnerů
docker ps
docker ps -a

# Logy, exec, stats
docker logs -f webserver
docker exec -it webserver sh
docker stats

# Stop / remove
docker stop webserver
docker rm webserver
  
Tip: Vždy pinovat konkrétní tag (nikdy jen latest) — jinak pull přepíše image při update a rozbije reprodukovatelnost.

Image & Dockerfile

Build pipeline, best practices, multi-stage

Dockerfile — instrukce

InstrukceFunkceNová vrstva?
FROMBase image (nebo scratch pro minimalismus)ne (metadata)
RUNSpustí příkaz při builduano
COPYZkopíruje soubory z build contextuano
ADDJako COPY + rozbaluje archivy + URL (preferovat COPY)ano
ENVNastaví env proměnnou (i pro runtime)ne
ARGBuild-time proměnná (není v runtime image)ne
EXPOSEDokumentuje port (nepublikuje ho!)ne
ENTRYPOINTHlavní proces kontejneru (preferovat exec form)ne
CMDVýchozí argumenty pro ENTRYPOINT, nebo příkazne
USERNastaví uživatele pro RUN/CMD/ENTRYPOINTne
WORKDIRPracovní adresář (vytvoří, pokud neexistuje)ne
VOLUMEDeklaruje mount pointne
HEALTHCHECKPříkaz pro health probene

Multi-stage build (production pattern)

# ── Stage 1: Builder (velký image s toolchain) ──────────────
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json .
RUN npm ci --omit=dev
COPY . .
RUN npm run build

# ── Stage 2: Runtime (minimální image) ──────────────────────
FROM node:20-alpine
WORKDIR /app
# Pouze dist + prod deps z builder stage
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules

# Bezpečnost: non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

EXPOSE 3000
ENTRYPOINT ["node", "dist/server.js"]
  

Build příkazy

# Základní build
docker build -t myapp:1.0 .

# S build argumentem a konkrétním Dockerfile
docker build -f Dockerfile.prod \
  --build-arg APP_ENV=production \
  -t registry.corp.cz/myapp:1.0 .

# BuildKit (výchozí od Docker 23.x) — paralelní stages, cache mount
docker buildx build --platform linux/amd64,linux/arm64 \
  --push -t registry.corp.cz/myapp:1.0 .

# Zobrazit vrstvy & velikosti
docker history myapp:1.0
docker image inspect myapp:1.0
  

.dockerignore

# Vždy vytvořit – omezí build context zasílaný daemonu
.git
node_modules
*.md
.env
dist
__tests__
  

Správa kontejnerů

Lifecycle, resource limits, health checks, logging

Lifecycle

created ──▶ running ──▶ paused │ ├──▶ restarting │ ▼ exited ──▶ dead

Resource limits (cgroups)

docker run -d \
  --memory=512m \          # hard limit RAM
  --memory-swap=512m \     # swap=0 (disabled)
  --cpus="1.5" \            # max 1.5 CPU
  --pids-limit=100 \        # ochrana fork bomb
  --restart=unless-stopped \ # restart policy
  myapp:1.0
  

Restart policies

PolicyChování
noVýchozí — bez restartu
alwaysVždy restartuj (i po docker start daemonu)
unless-stoppedJako always, ale respektuje manuální stop
on-failure[:N]Jen při nenulové exit code, max N pokusů

Health check

# V Dockerfile
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
  CMD wget -qO- http://localhost:3000/health || exit 1

# CLI override
docker run --health-cmd='curl -f http://localhost/ || exit 1' \
  --health-interval=30s nginx
  

Logging drivers

DriverDestinationPoužití
json-fileLokální JSON souborVýchozí; docker logs funguje
journaldsystemd journalLinux servery, centrální log
syslogsyslog daemonSyslog infrastruktura
fluentdFluentd collectorEFK stack
awslogsCloudWatch LogsAWS deployment
noneŽádný outputDebug / test
# Limit velikosti JSON log souborů (daemon.json nebo per-container)
docker run --log-driver=json-file \
  --log-opt max-size=50m \
  --log-opt max-file=3 \
  myapp:1.0
  

Síťování

Network drivers, DNS, port mapping

Network drivers

DriverIzolacePoužití
bridgeNAT přes docker0 / custom bridgeVýchozí pro single-host. User-defined bridge = DNS resolution by name.
hostŽádná — sdílí síť hostuHigh-throughput, monitoring. Bez port mapping.
overlayVXLAN mezi hostyDocker Swarm, multi-host cluster
macvlanVlastní MAC adresa — kontejner jako fyzický hostLegacy apps, potřeba přímého L2 přístupu
ipvlanSdílí MAC hostu, vlastní IPNízkolatentní, VLAN trunk
nonePouze loopbackIzolované zpracování, batch jobs

User-defined bridge (doporučeno)

# Výchozí bridge (docker0) NEMÁ embedded DNS — nepoužívat pro prod
# Vytvořit vlastní síť:
docker network create \
  --driver bridge \
  --subnet 172.20.0.0/24 \
  --gateway 172.20.0.1 \
  myapp-net

# Kontejnery ve stejné network se vidí jménem:
docker run -d --name db --network myapp-net postgres:16
docker run -d --name api --network myapp-net myapp:1.0
# api kontejner může pingovat "db" — DNS name = container name

# Port publishing
-p 8080:80             # host:container (all interfaces)
-p 127.0.0.1:8080:80   # jen localhost (security!)
-p 8080:80/udp         # UDP
  
Bezpečnost: Výchozí -p 8080:80 binduje na 0.0.0.0 — obchází iptables/UFW pravidla hostu. Vždy specifikovat 127.0.0.1: pro interní služby nebo použít reverse proxy.

Úložiště & Volumes

Volumes, bind mounts, tmpfs — kdy co použít

TypUmístěníLifecycleVýkonPoužití
Volume/var/lib/docker/volumes/Nezávislý na kontejneruNejlepší (nativní)DB data, shared data, prod
Bind mountLibovolná cesta hostuZávisí na hostuDobrý (OS cache)Dev: live reload kódu
tmpfsRAM hostuZtracen po stopuNejrychlejšíCitlivá data, cache, secrets

Volumes — příkazy

# Vytvoření named volume
docker volume create pgdata

# Použití ve run
docker run -d \
  -v pgdata:/var/lib/postgresql/data \
  --name postgres \
  postgres:16-alpine

# Inspect, seznam, cleanup
docker volume inspect pgdata
docker volume ls
docker volume prune   # odstraní nepřipojené volumes!

# Backup volume → tar
docker run --rm \
  -v pgdata:/data:ro \
  -v $(pwd):/backup \
  alpine tar czf /backup/pgdata-backup.tar.gz -C /data .
  

Volume drivers (plugins)

Pro vzdálené úložiště (NFS, S3, Azure Blob, vSAN) existují volume driver pluginy:

local driver

Výchozí. Podporuje NFS mount options přímo:

--opt type=nfs --opt o=addr=nfs.host,rw

Třetí strany

rexray/s3fs (S3), Azure File driver, NetApp Trident, Portworx. Vhodné pro Swarm / on-prem clustery.

Registry & Distribuce

Docker Hub, privátní registry, Harbor, MCR, ACR

RegistryTypAuthPoznámka
Docker HubPublic / privatePAT / OIDCRate limit: 100 pull/6h anon, 200 free user
GitHub Container Registry (ghcr.io)Public / privatePATIntegrovaný s GitHub Actions
Azure Container Registry (ACR)PrivateEntra ID / adminGeo-replication, Tasks, Cosign
AWS ECRPrivateIAMPer-region, token refresh 12h
HarborSelf-hostedLDAP/OIDCRBAC, vulnerability scan (Trivy), proxy cache
Microsoft MCRPublicanonVšechny Microsoft images

Push / Pull workflow

# Login (ukládá credential do ~/.docker/config.json nebo credential helper)
docker login registry.corp.cz
docker login -u USERNAME -p $(cat token.txt) ghcr.io

# Tag local image pro push
docker tag myapp:1.0 registry.corp.cz/prod/myapp:1.0
docker tag myapp:1.0 registry.corp.cz/prod/myapp:latest

# Push
docker push registry.corp.cz/prod/myapp:1.0
docker push registry.corp.cz/prod/myapp:latest

# Pull explicitně (nebo implicitně při run)
docker pull registry.corp.cz/prod/myapp:1.0

# Pull by digest (imutable, pro prod doporučeno)
docker pull registry.corp.cz/prod/myapp@sha256:abc123...
  

Harbor — self-hosted registry

Harbor je CNCF graduated projekt. Přidává nad distribution/registry: RBAC projekty, vulnerability scanning (Trivy), image signing (Cosign/Notary), proxy cache pro Docker Hub (eliminuje rate limit), retention policies a audit log. Doporučená volba pro enterprise on-prem.

Content trust / Signing (Cosign)

# Sigstore Cosign — moderní alternativa k Docker Content Trust
cosign sign --key cosign.key registry.corp.cz/prod/myapp:1.0
cosign verify --key cosign.pub registry.corp.cz/prod/myapp:1.0

# Docker Content Trust (legacy Notary v1)
export DOCKER_CONTENT_TRUST=1
docker pull nginx:1.27-alpine   # ověří signaturu
  

TLS & Certifikáty

Docker daemon TLS, privátní registry s interní CA, Cosign

Scénáře kde TLS vstupuje do hry

1. Docker daemon TCP (remote)

Výchozí socket je UNIX (/var/run/docker.sock). Při expozici TCP portu nutno TLS — jinak root přístup k hostu přes síť.

2. Privátní registry

Docker odmítá push/pull na registry bez platného TLS (nebo explicitně nakonfigurovaného insecure). Interní CA musí být důvěryhodná.

3. Kontejner jako TLS endpoint

Nginx / Traefik v kontejneru terminuje TLS. Certifikát do kontejneru via volume nebo secret.

4. Image signing (Cosign)

Podpis image artefaktu pro supply chain security. Klíče nebo keyless (Sigstore/OIDC).

Privátní registry s interní CA

Nejčastější problém v enterprise: interní registry (Harbor, ACR on-prem) podepsáno interní CA — Docker daemon ji nezná a vrátí x509: certificate signed by unknown authority.

Řešení A — Přidat CA do OS trust store (doporučeno)

# Ubuntu / Debian
sudo cp corp-root-ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
sudo systemctl restart docker

# RHEL / Rocky
sudo cp corp-root-ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust extract
sudo systemctl restart docker
  

Řešení B — Per-registry certifikát adresář

# Docker hledá certy v /etc/docker/certs.d/{registry-host}/
sudo mkdir -p /etc/docker/certs.d/harbor.corp.cz

# Zkopírovat CA certifikát
sudo cp corp-root-ca.crt /etc/docker/certs.d/harbor.corp.cz/ca.crt

# Pro mTLS (client cert auth):
sudo cp client.cert /etc/docker/certs.d/harbor.corp.cz/
sudo cp client.key  /etc/docker/certs.d/harbor.corp.cz/
# Soubory musí mít příponu .cert a .key

# Restart NENÍ nutný pro certs.d — platí okamžitě
  

Docker daemon — TCP s mTLS

# Generování CA, server cert, client cert (ukázka OpenSSL)
# Pro prod: použít AD CS / ACME / Vault PKI

# /etc/docker/daemon.json
{
  "hosts":    ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2376"],
  "tls":      true,
  "tlsverify": true,
  "tlscacert": "/etc/docker/ca.pem",
  "tlscert":   "/etc/docker/server-cert.pem",
  "tlskey":    "/etc/docker/server-key.pem"
}

# Klientský přístup
docker --tlsverify --tlscacert=ca.pem \
  --tlscert=cert.pem --tlskey=key.pem \
  -H docker.corp.cz:2376 ps
  

Certifikáty uvnitř kontejnerů

# Varianta 1: Docker Secret (Swarm)
docker secret create tls_cert server.crt
docker secret create tls_key server.key
# Secret namountován jako /run/secrets/{name}

# Varianta 2: Volume mount (Compose / standalone)
-v /etc/ssl/corp:/certs:ro

# Varianta 3: Certbot/ACME sidecar kontejner
# Traefik / Caddy zvládnou ACME nativně

# Nikdy: COPY cert do image — certy se mění, rebuild = antipattern
  
Interní CA v Dockerfile: Pokud image potřebuje důvěřovat interní CA při buildu (npm/apt přes interní proxy), přidejte CA do image — ale jen do build stage, ne do final image pokud to není nutné.
# Přidání interní CA do Alpine image
RUN apk add --no-cache ca-certificates
COPY corp-root-ca.crt /usr/local/share/ca-certificates/
RUN update-ca-certificates
  

Docker Compose

Multi-container definice jako kód

Struktura compose.yaml

# compose.yaml (nová konvence, starší: docker-compose.yml)
name: myapp

services:
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: appdb
      POSTGRES_USER: app
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    volumes:
      - pgdata:/var/lib/postgresql/data
    secrets:
      - db_password
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app"]
      interval: 10s
      retries: 5
    networks:
      - backend

  api:
    build:
      context: .
      dockerfile: Dockerfile.prod
    image: registry.corp.cz/prod/myapp:1.0
    depends_on:
      db:
        condition: service_healthy
    environment:
      DB_HOST: db
      DB_PORT: 5432
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 512M
    networks:
      - backend
      - frontend
    ports:
      - "127.0.0.1:3000:3000"

  proxy:
    image: traefik:v3
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./traefik.yaml:/etc/traefik/traefik.yaml:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - certs:/certs
    networks:
      - frontend

volumes:
  pgdata:
  certs:

networks:
  backend:
    internal: true       # bez přístupu k internetu
  frontend:

secrets:
  db_password:
    file: ./secrets/db_password.txt
  

Compose příkazy

docker compose up -d           # start na pozadí
docker compose up --build -d   # rebuild images + start
docker compose down            # stop + rm containers + networks
docker compose down -v        # + smaže volumes!
docker compose ps
docker compose logs -f api
docker compose exec api sh
docker compose scale api=3    # scale (bez orchestrace = local only)
  

Prostředí — override files

compose.yaml              # base
compose.override.yaml     # auto-mergeováno při dev (live reload, debug ports)
compose.prod.yaml         # explicitní: docker compose -f compose.yaml -f compose.prod.yaml up
  

Hardening & Bezpečnost

Attack surface, best practices, scanning

Top hardening opatření

OblastOpatřeníPriorita
Runtime userUSER nonroot v Dockerfile; nikdy root v produkciKritická
Read-only rootfs--read-only + tmpfs pro writable dirsKritická
No new privileges--security-opt no-new-privileges:trueKritická
Docker socketNikdy mountovat /var/run/docker.sock do prod kontejneru (= root hostu)Kritická
Capabilities--cap-drop ALL --cap-add NET_BIND_SERVICE (jen co je nutné)Vysoká
SeccompVýchozí Docker profil blokuje 44 syscalls; custom pro striktní workloadsVysoká
Image scanningTrivy / Grype v CI pipeline, Harbor scanner, ACR DefenderVysoká
Base imageDistroless / Alpine / scratch — minimální útočná plochaVysoká
SecretsDocker secrets / env z Vault; nikdy v Dockerfile nebo ENV pro prod credentialsVysoká
Resource limits--memory --cpus --pids-limit vždy v prodStřední
Network isolationinternal: true pro backend sítě, least-privilege port publishingStřední
Content trustCosign / DCT pro verifikaci image integrityStřední

daemon.json — produkční konfigurace

# /etc/docker/daemon.json
{
  "icc": false,                        // zakáže inter-container comm na default bridge
  "no-new-privileges": true,
  "live-restore": true,               // kontejnery přežijí restart daemonu
  "userland-proxy": false,            // výkon: iptables místo userland proxy
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  }
}
  

Vulnerability scanning — Trivy

# Scan local image
trivy image myapp:1.0

# Scan s threshold (exit 1 při HIGH/CRITICAL)
trivy image --exit-code 1 --severity HIGH,CRITICAL myapp:1.0

# Scan Dockerfile (IaC check)
trivy config Dockerfile

# SBOM generování
trivy image --format cyclonedx --output sbom.json myapp:1.0
  

Rootless Docker

# Instalace (jako běžný uživatel)
dockerd-rootless-setuptool.sh install

# Spuštění (user systemd)
systemctl --user start docker
export DOCKER_HOST=unix:///run/user/1000/docker.sock

# Kontejnery nemohou bind-mountovat porty <1024 bez sysctl
  

Reference & Zdroje

Oficální dokumentace, standardy, nástroje

Klíčové příkazy — cheatsheet

KategoriePříkazPopis
Imagesdocker pull / push / build / tag / rmiLifecycle image
Imagesdocker images / image ls / image pruneVýpis a čištění
Containersdocker run / start / stop / rm / pauseLifecycle
Containersdocker ps / logs / exec / inspect / stats / topMonitoring
Containersdocker cpKopírování souborů
Networkdocker network create / ls / inspect / rmSíťová správa
Volumedocker volume create / ls / inspect / rm / pruneVolume správa
Registrydocker login / logout / searchRegistry auth
Systemdocker system df / prune / info / versionDisk usage, cleanup
Builddocker buildx build --platform / --pushMulti-arch build
Contextdocker context create / use / lsPřepínání hostů

Cleanup

# Agresivní cleanup (dev prostředí)
docker system prune -af --volumes

# Selektivní
docker container prune   # stopped containers
docker image prune -a   # untagged + unused images
docker volume prune      # unused volumes
docker network prune     # unused networks

# Zjistit disk usage
docker system df -v
  

Standardy a reference

Standard / ProjektURL
Docker docs (oficální)https://docs.docker.com
OCI Image Spechttps://github.com/opencontainers/image-spec
OCI Runtime Spec (runc)https://github.com/opencontainers/runtime-spec
CIS Docker Benchmarkhttps://www.cisecurity.org/benchmark/docker
NIST SP 800-190 (Container Security)https://csrc.nist.gov/publications/detail/sp/800/190/final
Sigstore / Cosignhttps://docs.sigstore.dev/cosign/overview
Harbor CNCFhttps://goharbor.io/docs
Trivy (scanner)https://trivy.dev/latest/docs
Docker Compose spechttps://compose-spec.io
containerdhttps://containerd.io/docs

Doporučená base images

ImageVelikostPoužití
scratch0 MBGo statically-linked binaries
distroless/static~2 MBGo / compiled apps, zero shell
alpine:3.x~5 MBShell + musl libc, interaktivní debug
debian:slim~75 MBGlibc závislosti, Python/Node
ubuntu:24.04~80 MBKomplexní aplikace, .deb závislosti
node:20-alpine~50 MBNode.js apps (multi-stage final)
python:3.12-slim~130 MBPython, slim = bez dev headers

Apache NiFi — Architektura & Principy

Dataflow platforma pro spolehlivý, škálovatelný přenos a transformaci dat

Co NiFi řeší

Apache NiFi je vizuální dataflow nástroj původem z NSA (projekt Niagarafiles, open-source 2014). Řeší integraci heterogenních datových zdrojů — přijímá, transformuje, směruje a doručuje data bez nutnosti psát integrační kód. Klíčové vlastnosti:

Guaranteed Delivery

Perzistentní fronta na disku (Write-Ahead Log). Data se neztratí při výpadku — každý FlowFile je sledován od vstupu po výstup.

Data Provenance

Kompletní auditní stopa každého záznamu — kdy, kde, kým byl modifikován. Klíčová vlastnost pro compliance a debugging.

Back Pressure

Automatické řízení toku — pokud downstream nestíhá, upstream se zpomalí. Zabrání memory exhaustion bez ztráty dat.

Visual Flow Design

Drag-and-drop canvas v prohlížeči. Flows jsou verzovatelné přes NiFi Registry. Žádné restarty při změně flow.

Architektura — komponenty

┌─────────────────────────────────────────────────────────────────────┐ │ Apache NiFi JVM Process │ │ │ │ ┌──────────────┐ ┌─────────────────┐ ┌──────────────────────┐ │ │ │ Web Server │ │ Flow Controller │ │ FlowFile Repository │ │ │ │ (Jetty HTTPS)│ │ (Scheduler/Timer)│ │ (WAL — disk) │ │ │ └──────┬───────┘ └────────┬────────┘ └──────────────────────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌─────────────────────────────────────┐ │ │ │ Processor Threads │ ┌──────────────────────┐ │ │ │ [P1]──▶[P2]──▶[P3]──▶[P4]──▶[P5] │ │ Content Repository │ │ │ │ │ │ (actual data bytes) │ │ │ └─────────────────────────────────────┘ └──────────────────────┘ │ │ │ │ │ ┌──────────┴───────────┐ ┌──────────────────────┐ │ │ │ Connection Queues │ │ Provenance Repository│ │ │ │ (back pressure, │ │ (audit trail) │ │ │ │ prioritization) │ └──────────────────────┘ │ │ └──────────────────────┘ │ └─────────────────────────────────────────────────────────────────────┘ NiFi Registry ZooKeeper (cluster koordinace)

Tři úložiště (repositories)

RepositoryCo ukládáVýchozí umístěníPoznámka
FlowFile RepositoryMetadata FlowFiles (atributy, stav, pointer do Content Repo)./flowfile_repositoryWAL (Write-Ahead Log), malý, rychlý. Ztráta = ztráta in-flight dat.
Content RepositoryFyzická data (obsah FlowFiles)./content_repositoryMůže být rozděleno na více disků (zvyšuje propustnost). Immutable bloky.
Provenance RepositoryAuditní události každého FlowFile./provenance_repositoryMůže rapidně růst — nastavit retention. Lze použít Lucene-backed pro vyhledávání.

NiFi vs. konkurence

NástrojModelSilná stránkaOmezení
Apache NiFiPush/Pull, visual flowProvenance, guaranteed delivery, 300+ processorsLatence (batch-oriented), komplexní cluster setup
Apache KafkaLog-based messagingExtrémní throughput, replayNení ETL — potřebuje Kafka Connect/Streams
Apache CamelCode-first EIPFlexibilita, lightweightŽádné GUI, žádný provenance
MuleSoft / BoomiiPaaSEnterprise connectors, SLALicence, vendor lock-in
LogstashLog pipelineELK integracePrimárně pro logy, omezené routing

Terminologie

Klíčové pojmy NiFi ekosystému

TermínDefiniceAnalogie
FlowFileZákladní datová jednotka v NiFi. Obsahuje content (payload) a attributes (metadata jako key-value páry).Zpráva / paket / řádek
ProcessorKomponenta provádějící konkrétní akci s FlowFiles — čtení, zápis, transformace, routing, volání API. Přes 300 built-in.Funkce / mikroslužba
ConnectionFronta FlowFiles mezi dvěma procesory. Nese relationship name (success, failure, …). Má back-pressure nastavení.Message queue / pipe
RelationshipVýsledek zpracování procesoru (success, failure, retry, matched, unmatched…). Processor může mít 1–N relationships.Exit code / podmínka
Process GroupLogické seskupení processorů a connections. Lze vnořovat — hierarchická organizace flow. Verzovatelnév registru.Namespace / modul
Controller ServiceSdílená konfigurace dostupná processorům — DB connection pool, SSL kontext, schema registry. Lifecycle nezávislý na processorech.Dependency injection / singleton
Reporting TaskPeriodicky běžící úloha reportující metriky (do Prometheus, InfluxDB, Elasticsearch…).Scheduled task / exportér
NiFi RegistryVerzovací systém pro NiFi flows (Process Groups). Git-backed nebo filesystem backend. CI/CD pro data pipelines.Git repo pro kód
Data ProvenanceKompletní auditní stopa — kde byl FlowFile vytvořen, modifikován, klonován, odeslán. Vyhledatelná v UI.Audit log / blockchain
Back PressureMechanismus zastavení upstream processoru pokud connection překročí limit (počet objectů nebo velikost dat).TCP flow control
BulletinDiagnostická zpráva procesoru (warning/error). Zobrazena v UI, historicky uložena.Application log event
Expression LanguageMini-jazyk pro dynamické hodnoty v property hodnotách: ${attribute:toUpper()}. Přístup k atributům a funkcím.Jinja2 / EL template
TemplateExport/import část flow jako XML. Starší mechanismus — v moderním NiFi nahrazen Registry + Versioned Process Group.ARM template (legacy)
FunnelVizuální spojovací bod — slučuje více connections do jedné. Žádná logika, pouze routování v canvasu.Merge junction
Port (Input/Output)Vstupní nebo výstupní bod Process Group — propojuje vnější flow s vnitřkem grupy.Interface / API endpoint
Cluster CoordinatorRole v NiFi clusteru — koordinuje změny flow, health heartbeaty. Volena přes ZooKeeper.Primary node / leader
Primary NodeSpeciální role v clusteru — procesory označené "Primary Node Only" běží jen zde (deduplikace zdrojů).Active node v HA páru

UI & Canvas

Orientace v rozhraní, navigace, klávesové zkratky

Hlavní části UI

🗂 Canvas

Pracovní plocha pro stavbu flow. Nekonečný plán — zoom kolečkem, pan táhnutím. Shift+klik = vícenásobný výběr.

📊 Summary

Přehled všech processorů, connections, remote process groups v celém clusteru. Filtrování, řazení, bulk akce.

🔍 Data Provenance

Vyhledávání v auditní stopě FlowFiles. Filtr dle FlowFile UUID, atributu, procesoru, časového rozsahu.

📋 Bulletin Board

Centrální výpis varování a chyb ze všech processorů. Nenahrazuje logy, ale rychlý přehled problémů.

🔧 Controller Settings

Správa Controller Services a Reporting Tasks na úrovni celého NiFi instance (root scope).

⚙️ Global Menu

Nastavení, šablony, flow konfigurace, cluster info, uživatelé a přístupová práva (pokud Ranger/vlastní auth).

Processor — stavy a indikátory

Stav / SymbolPopis
▶ RunningProcessor aktivně zpracovává nebo čeká na trigger (timer/event)
⏸ StoppedProcessor zastaven — FlowFiles se hromadí ve vstupní queue
⚠ InvalidChybí povinná property nebo Controller Service není enabled
⏳ ValidatingPřechodný stav při startu nebo po změně konfigurace
🔴 BulletinČervená ikona v rohu = nedávná chyba. Hover = detail. Zmizí po timeout.

Processor — konfigurace dialog

ZáložkaObsah
SettingsNázev, scheduling strategy (Timer / CRON / Event), concurrent tasks, run duration, penalty duration, yield duration
SchedulingRun schedule (interval nebo CRON výraz), execution node (all / primary)
PropertiesSpecifické vlastnosti procesoru. Podporují Expression Language. Sensitive values jsou šifrovány.
RelationshipsZaškrtnutí "Auto-terminate" = FlowFile se zahazuje (nutno ošetřit všechny relationships)
CommentsPoznámky — zobrazeny jako tooltip v canvasu

Klávesové zkratky (Canvas)

ZkratkaAkce
Ctrl + AVybrat vše
Ctrl + C / VKopírovat / vložit výběr
Del / BackspaceSmazat výběr
Ctrl + ZUndo (omezená hloubka)
Shift + clickPřidat do výběru
Ctrl + scrollZoom
Ctrl + Shift + FFind / Filter processorů
RRefresh statistik (bez reload stránky)
Tip: Double-click na Process Group = vstup dovnitř. Breadcrumb nahoře ukazuje aktuální úroveň hierarchie. Tlačítko „Leave group" nebo Escape = návrat.

Processors

Katalog nejdůležitějších vestavěných procesorů podle kategorie

Ingress — příjem dat

GetFile ListFile / FetchFile GetHTTP / ListenHTTP ConsumeKafka GetSFTP / ListSFTP / FetchSFTP QueryDatabaseTable GenerateFlowFile GetS3Object / ListS3 ConsumeAMQP / ConsumeJMS TailFile ListenSyslog / ListenTCP / ListenUDP ConsumeAzureEventHub

Transformace

JoltTransformJSON TransformXml (XSLT) ConvertRecord UpdateAttribute ReplaceText SplitJSON / SplitXML / SplitText MergeContent / MergeRecord ExecuteScript (Groovy/Python/JS) ExecuteGroovyScript AttributesToJSON FlattenJson ConvertAvroToJSON EncryptContent / DecryptContent CompressContent

Routing & Filtering

RouteOnAttribute RouteOnContent FilterAttribute ValidateRecord DetectDuplicate Wait / Notify ControlRate SampleRecord

Egress — výstup dat

PutFile PutSFTP PublishKafka PutDatabaseRecord InvokeHTTP PutS3Object PutEmail PutAzureBlobStorage PutElasticsearchRecord PublishAMQP / PublishJMS PutHDFS LogAttribute / LogMessage

Systémové a utility

ExecuteProcess ExecuteStreamCommand InvokeHTTP GetHTTP HashContent IdentifyMimeType ExtractText Base64EncodeContent

List / Fetch pattern

Moderní pattern pro příjem souborů ze vzdálených zdrojů (SFTP, S3, HDFS, Azure) — nahrazuje starší GetXxx procesory:

ListSFTP
FetchSFTP
ConvertRecord
PutDatabaseRecord

ListXxx vytvoří FlowFile pro každý nalezený objekt (s atributy jako path, filename, size). FetchXxx pak stáhne obsah. Výhoda: List běží na Primary Node, Fetch se paralelizuje na celý cluster.

Scheduling strategies

StrategyTriggerPoužití
Timer DrivenInterval (0 sec = co nejrychleji)Výchozí. Polling, continuous processing.
CRON DrivenCRON výraz (0 0 * * * ?)Přesné plánování, batch v konkrétní čas.
Event DrivenPříchod FlowFile do vstupní queueReaktivní — nespotřebovává thread pokud není data. Ne všechny procesory podporují.
Concurrent Tasks: Výchozí = 1. Zvýšení = paralelní instance stejného procesoru. Pozor na procesory udržující stav (ListFile, DetectDuplicate) — ty nesmí běžet paralelně.

FlowFile & Atributy

Datová jednotka NiFi — content + metadata

Anatomie FlowFile

Content (payload)

Binární data uložená v Content Repository. FlowFile je na ně jen pointer — samotná data se nekopírují při klonování. Copy-on-Write při modifikaci.

Attributes (metadata)

Map<String, String> — klíč-hodnota páry. Ukládány v FlowFile Repository (rychlý přístup). Procesory čtou/píší atributy bez dotyku content.

Core atributy (vždy přítomné)

AtributPopisPříklad
uuidUnikátní identifikátor FlowFile (immutable)550e8400-e29b-41d4-a716-446655440000
filenameLogický název souboru (lze přepsat)orders_2024.csv
pathLogická cesta (nastavena GetFile/ListFile)/data/input/
entryDateČas vstupu do flow (epoch millis)1711900800000
lineageStartDateČas vzniku rodičovského FlowFile
fileSizeVelikost content v bytech4096
mime.typeMIME typ (nastaví IdentifyMimeType)application/json

Práce s atributy — UpdateAttribute

# UpdateAttribute — nejpoužívanější processor pro manipulaci atributů

# Přidání / přepis atributu:
destination  =  /archive/${now():format('yyyy/MM/dd')}/${filename}
record.count =  ${fragment.count}
env          =  production

# Podmíněná logika — Advanced tab (rules engine):
# Condition:  ${fileSize:gt(1000000)}
# Action:     size.category = large

# Smazání atributu:
# Přepsat na prázdno nebo použít "Delete Attributes" property
# Delete Attributes Expression: ^temp\..*$  (regex)

FlowFile lifecycle — klonování

OperaceContent zkopírován?Procesory
Clone / ForkNe (pointer)SplitJSON, MergeContent, RouteOnAttribute (fanout)
Modify contentAno (CoW)ReplaceText, TransformXml, ExecuteScript
Modify attributes onlyNeUpdateAttribute, AttributesToJSON (attr mode)
MergeNová kopieMergeContent, MergeRecord
Výkon: Zpracování samotných atributů je řádově rychlejší než čtení content. Pokud nepotřebuješ obsah, pracuj jen s atributy — šetří I/O a paměť.

Connections & Routing

Fronty, back pressure, prioritizace, podmíněné směrování

Connection — konfigurace

PropertyVýchozíPopis
Name(relationship)Volitelný label v canvasu
FlowFile Expiration0 sec (nikdy)Automaticky zahodit FlowFile starší než X — prevence zahlcení
Back Pressure Object Threshold10 000Počet FlowFiles, po jehož dosažení upstream processor přestane spouštět
Back Pressure Data Size Threshold1 GBCelková velikost dat v queue — alternativní trigger back pressure
Load Balance StrategyDo Not Load BalanceV clusteru: Round Robin / Single Node / Attribute / Partition by Attribute
PrioritizersFIFOPořadí zpracování: FirstIn, NewestFlowFile, OldestFlowFile, PriorityAttribute

Back Pressure — vizuální indikátory

Zelená

Queue pod 60 % obou thresholdů. Normální provoz.

Žlutá

Queue přes 60 %. Varování — sleduj trend.

Červená

Back pressure aktivní. Upstream processor se nespustí.

Podmíněné směrování

RouteOnAttribute

# Property = název relationship, hodnota = EL podmínka
is-json      ${mime.type:equals('application/json')}
is-large     ${fileSize:gt(10485760)}   # > 10 MB
from-prod    ${env:equals('production')}

# Routing Strategy:
#   Route to Property Name    — FlowFile jde do PRVNÍHO matched
#   Route to 'matched' / 'unmatched'  — binární boolean split

RouteOnContent

# Regex matching proti obsahu (content) FlowFile
has-error    (?s).*"status"\s*:\s*"error".*
has-warning  (?s).*"level"\s*:\s*"WARN".*

# Match Requirement: Content Must Match Exactly / Contain Match

Typické error-handling flow

InvokeHTTP
→ success →
PutDatabase
InvokeHTTP
→ failure →
UpdateAttribute
retries += 1
RouteOnAttribute
retries < 3?
→ retry →
InvokeHTTP
RouteOnAttribute
→ dead-letter →
PutFile
/errors/
Auto-terminate pozor: Pokud auto-terminate relationship "failure", chyba se tiše zahodí bez logu nebo alertu. Vždy zapoj alespoň LogAttribute nebo PutFile na failure path v produkci.

Controller Services

Sdílené zdroje a konfigurace — connection pooly, SSL, schémata

Proč Controller Services

Procesory nesmí udržovat vlastní long-lived připojení — to by vedlo k N×M problému (každý procesor × každý cíl). Controller Services poskytují sdílené, lifecycle-managed instance — DB connection pool, SSL context, schema registry — které jsou konfigurovány jednou a referencovány z processorů.

Nejdůležitější Controller Services

ServiceÚčelPoužití
DBCPConnectionPoolJDBC connection pool (HikariCP)ExecuteSQL, QueryDatabaseTable, PutDatabaseRecord
StandardSSLContextServiceTLS/SSL kontext (keystore, truststore)InvokeHTTP, PublishKafka, GetSFTP…
JsonTreeReader / JsonRecordSetWriterČtení/zápis JSON jako RecordConvertRecord, MergeRecord, ValidateRecord
CSVReader / CSVRecordSetWriterČtení/zápis CSVConvertRecord, PutDatabaseRecord
AvroReader / AvroRecordSetWriterApache AvroKafka Avro pipelines
SchemaRegistry (Confluent / NiFi built-in)Schema lookup pro Record procesoryAvro pipelines, schema evolution
HortonworksSchemaRegistryConfluent / HWX Schema Registry klientKafka + Avro
StandardHttpContextMapHTTP session stav pro HandleHttpRequest/ResponseNiFi jako HTTP server
AWSCredentialsProviderControllerServiceAWS auth (keys, IAM role, STS)S3, SQS, DynamoDB procesory
AzureStorageCredentialsServiceAzure authAzure Blob, ADLS, Event Hub procesory
DistributedMapCacheServer/ClientIn-memory distributed cacheDetectDuplicate, Wait/Notify pattern

Scope Controller Services

Process Group scope

Service konfigurovaná uvnitř Process Group je viditelná jen processorům ve stejné nebo vnořené skupině. Výchozí chování.

Root / Global scope

Service přidaná přes Controller Settings (hamburger menu) je dostupná všem processorům v celé instanci.

DBCPConnectionPool — konfigurace

# Příklad konfigurace pro PostgreSQL:
Database Connection URL:   jdbc:postgresql://db.corp.cz:5432/appdb
Database Driver Class:     org.postgresql.Driver
Database Driver Location:  /opt/nifi/drivers/postgresql-42.7.1.jar
Database User:             nifi_user
Password:                  {sensitive — použít NiFi sensitive props}

Max Total Connections:     10
Max Wait Time:             500 millis
Validation Query:          SELECT 1

# Ovladače (JDBC JAR) je nutno dodat ručně — NiFi je neobsahuje z licenčních důvodů
# Umístit do /opt/nifi/lib/drivers/ nebo nakonfigurovat cestu

Record-oriented procesory

Moderní pattern — místo práce s raw textem / JSON jako celkem, Record API parsuje data do strukturovaných řádků a umožňuje schema-aware transformace s výrazně vyšším výkonem:

ConsumeKafka
+ AvroReader
ConvertRecord
AvroReader → JsonWriter
PutDatabaseRecord
+ DBCPConnectionPool

NiFi Expression Language

Dynamické hodnoty v property polích — přístup k atributům, funkcím, systémovým proměnným

Syntaxe

# Základní přístup k atributu:
${filename}
${mime.type}
${uuid}

# Funkce (chaining):
${filename:toUpper()}
${filename:substring(0, 8):append('.processed')}
${fileSize:gt(1048576):ifElse('large', 'small')}

# Systémové proměnné:
${now()}                          # aktuální čas (epoch ms)
${now():format('yyyy-MM-dd')}     # formátovaný datum
${hostname()}                     # hostname NiFi node
${ip()}                           # IP NiFi node
${nextInt()}                      # auto-increment counter
${UUID()}                         # nový UUID

# Environment / System properties (z nifi.properties nebo OS):
${ENV_VAR_NAME}
${nifi.home}

# Podmíněné výrazy:
${attr:isNull():ifElse('default', ${attr})}
${status:equals('200'):and(${size:gt(0)})}
  

Nejpoužívanější funkce

KategorieFunkcePříklad
StringtoUpper() / toLower()${env:toUpper()}
trim()${filename:trim()}
replace(search, replace)${path:replace('/', '_')}
substring(start, end)${filename:substring(0,8)}
Booleanequals(value)${mime.type:equals('application/json')}
startsWith() / endsWith()${filename:endsWith('.csv')}
matches(regex)${filename:matches('order_.*\.csv')}
Numericgt() / lt() / ge() / le()${fileSize:gt(1048576)}
plus() / minus() / multiply()${retries:plus(1)}
toNumber()${count:toNumber():plus(1)}
Datenow():format(pattern)${now():format('yyyy/MM/dd')}
toDate(pattern)${date_str:toDate('yyyy-MM-dd')}
format(pattern)${entryDate:toNumber():toDate('ms'):format('HH:mm:ss')}
Null / DefaultisNull() / isBlank()${attr:isNull()}
ifElse(true, false)${isNull:ifElse('N/A', ${attr})}
Testování EL: Processor dialog → klikni na ikonu „EL" vedle property pole → otevře se Advanced EL editor kde lze vložit hodnoty atributů a vyhodnotit výraz v reálném čase bez spuštění flow.

Cluster & High Availability

Zero-master cluster, ZooKeeper koordinace, load balancing flows

Cluster architektura

┌──────────────────────────────────────────────────────────────┐ │ Apache ZooKeeper │ │ (koordinace, leader election) │ └──────┬────────────────────────┬──────────────────────────────┘ ┌──────┴──────────┐ ┌──────┴──────────┐ ┌────────────────┐ NiFi Node 1 │ │ NiFi Node 2 │ │ NiFi Node 3 Cluster Coord. │ │ Primary Node │ │ │ (elected) │ │ (elected) │ │ │ └────────┬────────┘ └────────┬────────┘ └───────┬────────┘ │ │ │ └──────────── Site-to-Site / HTTP ───────────┘ Load Balancer / Nginx (HTTPS 8443, sticky optional)

Role v clusteru

RolePočetFunkce
Cluster Coordinator1 (elected)Koordinuje změny flow (deploy, start/stop processorů). Všechny UI změny jdou přes něj — ostatní nody synchronizuje. Volba přes ZooKeeper.
Primary Node1 (elected)Procesory s "Execution = Primary Node" běží pouze zde. Zamezuje duplicitnímu čtení ze zdrojů (ListFile, ListSFTP, QueryDatabaseTable).
Standard NodeN-2Zpracovávají FlowFiles přijaté load balancerem nebo distribuované přes Connection load balancing.

Load Balancing Connections

StrategieChováníPoužití
Do Not Load BalanceFlowFile zůstane na původním noduVýchozí — stateless processing
Round RobinFlowFiles střídavě distribuovány mezi nodyParalelizace zpracování (Fetch, transformace)
Single NodeVšechny FlowFiles jdou na jeden nodeOperace vyžadující lokální stav
Partition by AttributeStejný atribut → vždy stejný nodeOrdering, session affinity

nifi.properties — klíčové cluster parametry

# Zapnutí cluster módu
nifi.cluster.is.node=true
nifi.cluster.node.address=nifi-node1.corp.cz
nifi.cluster.node.protocol.port=11443

# ZooKeeper
nifi.zookeeper.connect.string=zk1:2181,zk2:2181,zk3:2181
nifi.zookeeper.root.node=/nifi

# Load balancing komunikace mezi nody
nifi.cluster.load.balance.host=nifi-node1.corp.cz
nifi.cluster.load.balance.port=6342

# Site-to-Site (příjem dat z jiného NiFi)
nifi.remote.input.host=nifi-node1.corp.cz
nifi.remote.input.secure=true
nifi.remote.input.socket.port=10443
  
ZooKeeper embedded: NiFi obsahuje embedded ZooKeeper — lze použít pro dev/test (1 nebo 3 nody). Pro produkci doporučeno dedikované ZooKeeper ensemble (3 nebo 5 nodů) oddělené od NiFi JVM.

Bezpečnost & TLS

TLS povinné, autentizace uživatelů, autorizace, sensitive properties

TLS — základ

NiFi v produkci vždy běží na HTTPS — bez TLS jsou zakázány přihlašování uživatelů a internode komunikace. Keystore a truststore (JKS nebo PKCS12) jsou konfigurovány v nifi.properties.

# nifi.properties — TLS konfigurace
nifi.web.https.host=nifi.corp.cz
nifi.web.https.port=8443
nifi.web.http.port=           # prázdné = HTTP zakázáno

nifi.security.keystore=./conf/keystore.p12
nifi.security.keystoreType=PKCS12
nifi.security.keystorePasswd={encrypted}
nifi.security.keyPasswd={encrypted}
nifi.security.truststore=./conf/truststore.p12
nifi.security.truststoreType=PKCS12
nifi.security.truststorePasswd={encrypted}

# Šifrování hodnot v nifi.properties (bootstrap.conf klíč)
# Nástroj: ./bin/encrypt-config.sh
  

Autentizační metody

MetodaPopisVhodnost
Klientský certifikát (mTLS)Uživatel se přihlásí certifikátem v prohlížeči (CN = identita). Nejsilnější metoda.Interní enterprise
LDAP / Active DirectoryUsername + password ověřen přes LDAP bind. Skupiny mapovány na NiFi role.Korporátní prostředí
OIDC (OpenID Connect)SSO přes Keycloak, Azure AD, Okta. Token exchange, redirect flow.Moderní enterprise, cloud
Kerberos (SPNEGO)Hadoop/Kerberos prostředí — ticket-based SSO.Hadoop ekosystém
Single User (dev)Jedno username/heslo v nifi.properties. Pouze pro vývoj / test.Nikdy prod

Autorizace — NiFi Access Policies

Granulární přístupová práva na úrovni každé komponenty (processor, connection, process group). Definovány v authorizations.xml nebo delegovány na Apache Ranger.

PolicyOprávnění
view the componentVidět processor / connection v canvasu
modify the componentEditovat konfiguraci procesoru
view the dataProhlížet FlowFile content a atributy ve frontách
modify the dataMazat FlowFiles z front, replay z provenance
receive data via S2SPřijímat FlowFiles přes Site-to-Site
operateStart/stop komponenty (bez možnosti editace)
access provenanceProhlížet Data Provenance záznamy

Sensitive Properties Encryption

# Všechna citlivá property v processor konfiguraci jsou šifrována
# Klíč definován v bootstrap.conf:
nifi.bootstrap.sensitive.key=0123456789ABCDEF...  # 256-bit hex

# Šifrování nifi.properties (Jasypt / NiFi Encrypt-Config tool):
./bin/encrypt-config.sh \
  -n conf/nifi.properties \
  -b conf/bootstrap.conf \
  -k $MASTER_KEY

# NiFi 1.14+ podporuje HashiCorp Vault pro správu klíčů:
nifi.sensitive.props.provider=vault
nifi.sensitive.props.vault.token=s.xxx
  

Konfigurace LDAP (nifi-login-identity-providers.xml)

<provider>
  <identifier>ldap-provider</identifier>
  <class>org.apache.nifi.ldap.LdapProvider</class>
  <property name="Authentication Strategy">SIMPLE</property>
  <property name="Manager DN">CN=svc-nifi,OU=SA,DC=corp,DC=cz</property>
  <property name="Manager Password">{encrypted}</property>
  <property name="Url">ldaps://dc.corp.cz:636</property>
  <property name="User Search Base">OU=Users,DC=corp,DC=cz</property>
  <property name="User Search Filter">sAMAccountName={0}</property>
  <property name="TLS - Truststore">./conf/truststore.p12</property>
</provider>
  

Monitoring & Data Provenance

Metriky, alerting, auditní stopa, operační postupy

Klíčové metriky (per processor / connection)

MetrikaCo měříInterpretace
In / Out (FlowFiles/s)Průtok FlowFiles za 5 min oknoZákladní throughput. In >> Out = hromadění.
Read / Write (bytes/s)I/O content repositoryDisk bound procesory (komprese, šifrování, velké soubory).
Tasks/TimePočet spuštění procesoru / celkový časTime/Task = průměrná latence 1 iterace.
Queued (FlowFiles / bytes)Aktuálně čekající v connectionRostoucí queue = downstream bottleneck.
Active ThreadsAktuálně běžící vlákna procesoru= concurrent tasks v chodu. 0 s frontou = yieldovaný nebo čekající na resource.

Reporting Tasks — export metrik

Reporting TaskCíl
PrometheusReportingTaskPrometheus /metrics endpoint (scrape)
SiteToSiteProvenanceReportingTaskProvenance events → jiný NiFi flow
SiteToSiteBulletinReportingTaskBulletins → jiný NiFi / Elasticsearch
ElasticsearchReportingTaskMetriky processorů → Elasticsearch
ControllerStatusReportingTaskMetriky → log file
CassandraReportingTaskMetriky → Cassandra

Data Provenance — co zaznamenává

Pro každý FlowFile jsou zaznamenány tyto typy událostí:

RECEIVE CREATE CONTENT_MODIFIED ATTRIBUTES_MODIFIED ROUTE CLONE JOIN FORK REPLAY SEND DROP EXPIRE

Provenance — vyhledávání v UI

# Filtry v Data Provenance UI:
#   FlowFile UUID   — přesné dohledání konkrétního záznamu
#   Attribute       — hledání dle hodnoty atributu (filename, path...)
#   Processor       — všechny události pro daný processor
#   Event Type      — filtr dle typu (RECEIVE, SEND, DROP...)
#   Time Range      — od/do
#   Component Type  — filtr dle typu procesoru

# Lineage view:
# Klikni na event → "Show Lineage" → vizuální strom celého životního cyklu
# FlowFile vidíš od RECEIVE přes všechny CLONE/FORK/JOIN až po DROP/SEND
# Replay: ze záznamu lze znovu pustit FlowFile (z obsahu uloženého v provenance)
  

Logy

SouborObsah
logs/nifi-app.logHlavní application log — procesory, framework, startup
logs/nifi-bootstrap.logStart/stop JVM procesu — bootstrap wrapper
logs/nifi-user.logAuditní log uživatelských akcí (login, konfigurace změny)
logs/nifi-request.logHTTP access log pro REST API volání
LogAttribute processor: Nezapomeň při ladění zapojit LogAttribute — loguje všechny atributy FlowFile do nifi-app.log. Nastav Log Level = INFO a Log Payload = true (pro obsah). Nezapomeň odebrat nebo nastavit na WARN v produkci.

Operační best practices

Restart bezpečně

Zastav všechny procesory před restartem NiFi. In-flight FlowFiles v paměti (Event Driven) se přesunou zpět do front díky WAL — žádná ztráta.

Disk plný = fatální

Pokud disk s Content Repository nebo FlowFile Repository selže nebo se zaplní, NiFi se zastaví. Monitor disk usage jako kritický alert (>80 %).

Provenance retention

Výchozí retention může narůst na desítky GB. Nastavit v nifi.properties: nifi.provenance.repository.max.storage.size=5 GB a max.storage.time=30 days.

Back pressure tuning

Výchozí 10 000 objektů / 1 GB nemusí sedět. Pro velké soubory snížit object count, pro malé záznamy zvýšit nebo zvýšit data size threshold.

Reference & Zdroje

Konfigurace, dokumentace, nástroje

nifi.properties — klíčové parametry

PropertyVýchozí / PříkladPopis
nifi.web.https.port8443HTTPS port UI a API
nifi.flowcontroller.graceful.shutdown.period10 secČekání na dokončení zpracování při shutdownu
nifi.queue.swap.threshold20 000Nad tento počet FlowFiles v queue se přelévají na disk (swap)
nifi.content.repository.directory.default./content_repositoryCesta k Content Repo. Lze mít více (default, disk2…)
nifi.provenance.repository.max.storage.size1 GBMaximální velikost Provenance Repo
nifi.provenance.repository.max.storage.time24 hoursMaximální stáří provenance záznamů
nifi.flowfile.repository.directory./flowfile_repositoryCesta k FlowFile Repo (WAL)
nifi.sensitive.props.key{master key}Klíč pro šifrování sensitive properties v flow.xml
nifi.nar.library.directory./libAdresář s NAR soubory (processor balíčky)
nifi.variable.registry.propertiesCesta k souboru s globálními proměnnými (key=value)

NAR — NiFi Archive

NiFi procesory jsou baleny jako .nar soubory (speciální JAR s class-loader izolací). Vlastní procesory lze distribuovat jako NAR. Umístění: ./lib/ nebo ./extensions/. NiFi automaticky načte NARy při startu — hot-deploy není možné bez restartu.

# Výpis nainstalovaných NARů
ls -la $NIFI_HOME/lib/*.nar

# Přidání vlastního NARu (pak restart NiFi)
cp my-custom-processors.nar $NIFI_HOME/lib/
./bin/nifi.sh restart
  

NiFi Registry — flow versioning

# Připojení Registry k NiFi:
# Menu → Controller Settings → Registry Clients → přidat
# URL: http://nifi-registry.corp.cz:18080

# Verzování Process Group:
# Pravý klik na Process Group → Version → Start version control
# Vybrat Registry, Bucket, Flow name → Save

# Commit změn:
# Pravý klik → Version → Commit local changes → popis commitu

# Rollback:
# Pravý klik → Version → Change version → vybrat starší verzi
  

REST API — základní endpointy

EndpointMetodaPopis
/nifi-api/system-diagnosticsGETJVM heap, disk, thread pool stav
/nifi-api/flow/statusGETCelkový stav flow (active threads, queued)
/nifi-api/processors/{id}GET/PUTStav a konfigurace procesoru
/nifi-api/processors/{id}/run-statusPUTStart / Stop / Terminate procesoru
/nifi-api/process-groups/{id}/processorsGETVýpis processorů v process group
/nifi-api/provenancePOSTVyhledávání v Data Provenance
/nifi-api/connections/{id}/drop-requestsPOSTVyprázdnění connection queue
/nifi-api/countersGETČítače (Counter procesory)
# Příklad — získání Bearer tokenu (OIDC / username+password)
TOKEN=$(curl -sk -X POST https://nifi.corp.cz:8443/nifi-api/access/token \
  -d "username=admin&password=secret")

# Zastavení procesoru přes API:
curl -sk -X PUT \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"revision":{"version":5},"component":{"id":"abc-123","state":"STOPPED"}}' \
  https://nifi.corp.cz:8443/nifi-api/processors/abc-123/run-status
  

Zdroje a dokumentace

ZdrojURL
Apache NiFi docs (officální)https://nifi.apache.org/documentation.html
NiFi Expression Language Guidehttps://nifi.apache.org/docs/nifi-docs/html/expression-language-guide.html
NiFi User Guidehttps://nifi.apache.org/docs/nifi-docs/html/user-guide.html
NiFi Administration Guidehttps://nifi.apache.org/docs/nifi-docs/html/administration-guide.html
NiFi Developer Guide (custom NAR)https://nifi.apache.org/docs/nifi-docs/html/developer-guide.html
NiFi REST API (Swagger)https://nifi.apache.org/docs/nifi-docs/rest-api/index.html
NiFi Registry docshttps://nifi.apache.org/docs/nifi-registry-docs/
Apache NiFi GitHubhttps://github.com/apache/nifi
Awesome NiFi (community)https://github.com/jfrazee/awesome-nifi

Typické deployment topologie

Single Node (dev/test)

1× NiFi + embedded ZooKeeper. Instalace <5 min. Žádná HA. Vhodné pro vývoj flow a testování processorů.

3-node cluster

3× NiFi + 3× ZooKeeper (embedded nebo dedicated). Minimální prod konfigurace s HA a cluster coordinator election.

NiFi + Registry

Přidání NiFi Registry pro flow verzování a CI/CD. Flows nasazeny přes Registry API z pipeline (GitOps).

NiFi na Kubernetes (MiNiFi)

NiFi v K8s via Helm chart (nicholaswilkinson/nifi nebo Apache NiFi Operator). MiNiFi = lightweight agent pro edge/IoT.