Docker spouští aplikace v izolovaných kontejnerech, které si s sebou nesou vše potřebné. Nainstalujeme ho z oficiálního repozitáře, přes Docker Compose spustíme WordPress s databází a projdeme správu, aktualizace, firewall a zálohy.
Co budete potřebovat
- VPS u StormHostu s Ubuntu 24.04 nebo Debianem 13
- Připojení přes SSH jako root (návod)
- Pro WordPress s HTTPS doménu nasměrovanou na VPS
- Asi 25 minut
Jak to funguje#
| Pojem | Co to je |
|---|---|
| Obraz (image) | Připravená šablona aplikace: systémové knihovny, program a jeho nastavení. Stahuje se z registru, nejčastěji z Docker Hubu (například wordpress, mariadb). |
| Kontejner (container) | Běžící instance obrazu. Má vlastní souborový systém a síť, ale sdílí jádro systému s VPS. Kontejner jde kdykoli smazat a vytvořit znovu ze stejného obrazu. |
| Volume | Trvalé úložiště dat mimo kontejner. Data ve volume přežijí smazání i aktualizaci kontejneru. Všechno, co se má zachovat, musí být ve volume. |
| Port | Kontejner má vlastní síť. Aby byl dostupný zvenku, jeho port se „publikuje“ na port VPS. |
| Docker Compose | Nástroj, který podle jednoho souboru compose.yaml spustí celou aplikaci složenou z více kontejnerů (například web a databázi). |
Instalace#
Docker instalujte z oficiálního repozitáře Dockeru. Balíček docker.io z repozitáře distribuce bývá starší a koliduje s oficiálními balíčky.
Nejdřív odstraňte případné kolidující balíčky. Na čisté VPS příkaz nic nenajde, to je v pořádku.
Ubuntu 24.04
apt remove $(dpkg --get-selections docker.io docker-compose docker-compose-v2 docker-doc docker-buildx podman-docker containerd runc | cut -f1)Debian 13
apt remove $(dpkg --get-selections docker.io docker-compose docker-doc docker-buildx podman-docker containerd runc | cut -f1)dpkg --get-selections …– vypíše z uvedených balíčků ty, které jsou nainstalované.| cut -f1– nechá z výpisu jen názvy balíčků.apt remove $(…)– odinstaluje je. Data v/var/lib/dockerzůstanou.
Pak přidejte repozitář Dockeru a nainstalujte ho:
Ubuntu 24.04
apt update
apt -y install ca-certificates curl
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
apt update
apt -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginDebian 13
apt update
apt -y install ca-certificates curl
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
apt update
apt -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginCo jednotlivé řádky dělají:
| Příkaz | Co dělá |
|---|---|
apt -y install ca-certificates curl | Certifikáty pro HTTPS a stahovací program. |
install -m 0755 -d /etc/apt/keyrings | Vytvoří složku pro podpisové klíče repozitářů s právy 0755. |
curl -fsSL …/gpg -o /etc/ | Stáhne podpisový klíč Dockeru. -f = při chybě HTTP skončit chybou, -s = tiše, -S = ukázat chyby, -L = následovat přesměrování. |
chmod a+r …/docker.asc | Klíč smí číst všichni (apt ho čte pod jiným uživatelem). |
tee /etc/ | Zapíše popis repozitáře do souboru. |
Types: deb | Repozitář s binárními balíčky. |
URIs: | Adresa repozitáře pro váš systém. |
Suites: $(…) | Kódové jméno systému (noble pro Ubuntu 24.04, trixie pro Debian 13), doplní se samo. |
Components: stable | Jen stabilní vydání. |
Architectures: $(dpkg --print-architecture) | Architektura procesoru (amd64). |
Signed-By: | Balíčky musí být podepsané tímto klíčem, jinak je apt odmítne. |
apt -y install docker-ce … | Nainstaluje Docker Engine (docker-ce), příkazový řádek (docker-ce-cli), běhové prostředí kontejnerů (containerd.io), sestavování obrazů (docker-buildx-plugin) a Compose (docker-compose-plugin). |
Docker se po instalaci sám spustí a zapne po startu VPS. Ověřte instalaci:
docker run --rm hello-world
docker compose versiondocker run --rm hello-world– stáhne testovací obraz a spustí ho;--rmkontejner po skončení smaže. UvidíteHello from Docker!.docker compose version– vypíše verzi Compose, napříkladDocker Compose version v5.…. Po verzi 2 přešel Compose rovnou na číslo 5, starší instalace proto ukazujív2.…. Příkazy v návodu fungují v obou.
Skupina docker = práva roota
Kdo je ve skupině docker, může spouštět kontejnery s přístupem k celému disku VPS, tedy má fakticky práva roota. Do skupiny přidávejte jen lidi, kterým byste dali i root. Pokud pracujete jako root, skupinu nepotřebujete.
První aplikace: WordPress s MariaDB#
Projekt a hesla#
Vytvořte složku projektu a přejděte do ní:
bash mkdir -p /opt/wordpress cd /opt/wordpressNázev složky (
wordpress) se stane názvem projektu Compose a předponou názvů kontejnerů a volumes.Vytvořte soubor s hesly
nano .env. Hesla vygenerujte v generátoru hesel (jen písmena a číslice):/opt/ wordpress/ ini.env DB_PASSWORD=<HESLO_DATABAZE> DB_ROOT_PASSWORD=<HESLO_ROOT_DATABAZE>DB_PASSWORD– heslo databázového uživatele WordPressu.DB_ROOT_PASSWORD– heslo uživatele root uvnitř databázového kontejneru (pro zálohy a správu).
Omezte čtení souboru jen na roota:
bash chmod 600 .env
Soubor compose.yaml#
Vytvořte nano compose.yaml s obsahem:
services:
db:
image: mariadb:lts
restart: unless-stopped
environment:
MARIADB_DATABASE: wordpress
MARIADB_USER: wordpress
MARIADB_PASSWORD: ${DB_PASSWORD}
MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
volumes:
- db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
start_period: 10s
interval: 10s
timeout: 5s
retries: 3
wordpress:
image: wordpress:latest
restart: unless-stopped
depends_on:
db:
condition: service_healthy
ports:
- "127.0.0.1:8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
WORDPRESS_DB_NAME: wordpress
volumes:
- wp_data:/var/www/html
volumes:
db_data:
wp_data:Řádek po řádku:
| Řádek | Co dělá |
|---|---|
services: | Seznam kontejnerů aplikace. Název služby (db, wordpress) slouží i jako jméno v síti projektu. |
image: mariadb:lts | Oficiální obraz MariaDB, značka lts = poslední verze s dlouhodobou podporou. |
restart: unless-stopped | Kontejner se po pádu i po restartu VPS spustí znovu, pokud jste ho sami nezastavili. |
MARIADB_DATABASE, MARIADB_USER, MARIADB_PASSWORD | Při prvním startu vytvoří databázi a uživatele s heslem. |
MARIADB_ROOT_PASSWORD | Heslo roota databáze, nastaví se při prvním startu. |
${DB_PASSWORD} | Hodnota se doplní ze souboru .env ve stejné složce. Hesla tak nejsou přímo v compose.yaml. |
volumes: - db_data:/var/lib/mysql | Data databáze se ukládají do volume db_data, takže přežijí aktualizaci kontejneru. |
healthcheck: | Docker každých 10 s zkontroluje skriptem healthcheck.sh z obrazu MariaDB, že databáze přijímá spojení a je inicializovaná. |
depends_on: db: condition: service_healthy | WordPress se spustí až ve chvíli, kdy je databáze připravená. |
image: wordpress:latest | Oficiální obraz WordPressu (Apache + PHP). |
ports: - "127.0.0.1:8080:80" | Port 80 kontejneru bude dostupný na portu 8080 VPS, ale jen z VPS samotné (127.0.0.1). Zvenku se k němu dostane jen přes Nginx. |
WORDPRESS_DB_HOST: db | Adresa databáze: jméno služby db v síti projektu. |
WORDPRESS_DB_USER, …_PASSWORD, …_NAME | Přihlášení k databázi; musí odpovídat hodnotám u služby db. |
volumes: - wp_data:/var/www/html | Soubory WordPressu (pluginy, šablony, nahrané obrázky) jsou ve volume wp_data. |
volumes: na konci | Deklarace pojmenovaných volumes, které projekt používá. |
Spuštění#
docker compose up -d
docker compose psdocker compose up -d– stáhne obrazy, vytvoří síť, volumes a kontejnery a spustí je na pozadí (-d, detached).docker compose ps– vypíše kontejnery projektu a jejich stav. Udbuvidítehealthy, uwordpressUp.
Kontrola z VPS: curl -I http://127.0.0.1:8080 vrátí hlavičky odpovědi WordPressu (přesměrování na instalaci).
Proměnné MARIADB_* platí jen při prvním startu
Databáze se vytvoří při prvním spuštění s prázdným volume. Pozdější změna hesla v .env heslo v databázi nezmění. Heslo změňte v databázi příkazem ALTER USER (viz MariaDB na VPS) a teprve pak v .env.
Zpřístupnění přes Nginx a HTTPS#
WordPress teď poslouchá jen na 127.0.0.1:8080. Zpřístupníte ho přes Nginx jako reverse proxy podle návodu Nginx a HTTPS: v konfiguraci použijte proxy_pass http://127.0.0.1:8080; a doménu, například blog.example.cz, a pak získejte certifikát přes certbot --nginx -d blog.example.cz.
Obraz WordPressu sám rozpozná HTTPS z hlavičky X-Forwarded-Proto, kterou Nginx podle návodu posílá. Nakonec otevřete https://blog.example.cz a dokončete instalaci WordPressu v prohlížeči.
Správa kontejnerů#
Příkazy docker compose spouštějte ve složce projektu (cd /opt/wordpress).
| Příkaz | Co dělá |
|---|---|
docker compose ps | Stav kontejnerů projektu. |
docker compose logs -f | Výpis logů všech služeb; -f = sledovat průběžně (ukončíte Ctrl+C). Jen jedna služba: docker compose logs -f wordpress. |
docker compose restart | Restartuje kontejnery. |
docker compose stop / start | Zastaví / spustí kontejnery, nic nemaže. |
docker compose up -d | Po změně compose.yaml vytvoří znovu jen změněné kontejnery. |
docker compose down | Zastaví a smaže kontejnery a síť. Volumes s daty zůstanou. |
docker compose exec db mariadb -uroot -p | Spustí příkaz uvnitř běžícího kontejneru (tady konzoli MariaDB). |
docker compose config | Zkontroluje compose.yaml a vypíše ho s doplněnými hodnotami z .env (pozor, ukáže i hesla). |
Aktualizace na nové verze obrazů:
docker compose pull
docker compose up -d
docker image prune -fdocker compose pull– stáhne nové verze obrazů.docker compose up -d– vytvoří znovu kontejnery, které mají novější obraz. Data ve volumes zůstanou.docker image prune -f– smaže staré, už nepoužívané obrazy;-fbez potvrzení.
docker compose down -v smaže data
Přepínač -v u docker compose down smaže i volumes projektu, tedy databázi a soubory WordPressu. Nejde to vrátit. Používejte ho jen tehdy, když chcete aplikaci odstranit úplně a máte zálohu.
Možnosti nastavení restart::
| Hodnota | Kdy se kontejner spustí znovu |
|---|---|
no | Nikdy (výchozí). |
always | Vždy, i když jste ho ručně zastavili (po restartu Dockeru nebo VPS). |
on-failure | Jen když skončí chybou. |
unless-stopped | Vždy, kromě případu, kdy jste ho zastavili sami. Doporučeno pro služby. |
Porty a firewall#
Docker publikuje porty kontejnerů vlastními pravidly firewallu, která obcházejí UFW. Port publikovaný jako 8080:80 je dostupný z internetu, i když ho v UFW nepovolíte. Podrobně to vysvětluje návod Firewall UFW.
Zápis v ports: | Kdo se na port dostane |
|---|---|
"8080:80" | Kdokoli z internetu, bez ohledu na UFW. |
"127.0.0.1:8080:80" | Jen procesy na VPS (například Nginx). Doporučeno pro weby za Nginxem. |
bez ports: | Jen ostatní kontejnery ve stejné síti projektu (typicky databáze). |
Databázi a další interní služby nepublikujte vůbec. Porty, které mají být veřejné (například herní server v kontejneru), omezujte firewallem v zákaznické zóně (návod). Ten stojí před VPS a Docker ho obejít nemůže.
Úklid místa na disku#
Obrazy, zastavené kontejnery a logy časem zaberou hodně místa.
docker system df
docker system prunedocker system df– kolik místa zabírají obrazy, kontejnery, volumes a cache.docker system prune– po potvrzení smaže zastavené kontejnery, nepoužívané sítě, obrazy bez názvu a cache sestavování. Volumes s daty bez přepínače--volumesnemaže.
Opatrně s mazáním volumes a s -a
docker system prune --volumes smaže i nepoužívané anonymní volumes (bez jména, vznikají například při docker run bez -v). Pokud v nich byla data kontejneru, který je zrovna smazaný nebo zastavený, jsou pryč. docker volume prune -a smaže i pojmenované volumes jako wordpress_db_data, když je nepoužívá žádný kontejner, například po docker compose down. docker system prune -a smaže všechny obrazy, které nepoužívá žádný kontejner. Před potvrzením si přečtěte, co příkaz vypíše, že smaže.
Logy kontejnerů se ve výchozím nastavení neotáčejí a můžou zaplnit disk. Nastavte ovladač local, který staré logy maže sám (ve výchozím stavu drží nejvýš 5 souborů po 20 MB na kontejner). Vytvořte soubor nano /etc/docker/daemon.json s obsahem níže. Pokud soubor už existuje, nepřepisujte ho, jen do něj doplňte řádek "log-driver" (položky oddělené čárkou):
{
"log-driver": "local"
}Pak restartujte Docker (systemctl restart docker) a kontejnery vytvořte znovu (docker compose up -d --force-recreate). Nastavení platí jen pro nově vytvořené kontejnery.
Zálohy#
Zálohujte volumes, ne kontejnery. Kontejner vytvoříte znovu z obrazu, data ne.
Vytvořte složku pro zálohy:
mkdir -p /root/zalohy.Databázi zálohujte exportem (konzistentnější než kopie souborů):
bash cd /opt/wordpress docker compose exec -T db sh -c 'exec mariadb-dump --single-transaction --all-databases -uroot -p"$MARIADB_ROOT_PASSWORD"' > /root/zalohy/wp-db-$(date +%F).sqldocker compose exec -T db– spustí příkaz v kontejnerudb;-Tvypne terminál, aby šel výstup přesměrovat do souboru.sh -c '…'– příkaz proběhne v shellu kontejneru, kde je proměnná$MARIADB_ROOT_PASSWORDnastavená.mariadb-dump --single-transaction --all-databases– export všech databází bez zamykání.> /root/zalohy/…– výstup se uloží na VPS mimo kontejner.
Soubory WordPressu zálohujte zabalením volume:
bash docker run --rm -v wordpress_wp_data:/data:ro -v /root/zalohy:/backup alpine tar czf /backup/wp-files-$(date +%F).tar.gz -C /data .docker run --rm– spustí jednorázový kontejner, který se po skončení smaže.-v wordpress_– připojí volumewp_ data:/ data: ro wp_dataprojektuwordpressjen pro čtení (ro).-v /root/zalohy:/backup– připojí složku záloh z VPS.alpine tar czf … -C /data .– v malém obrazu Alpine zabalí obsah volume do archivu.
Přesné názvy volumes vypíše
docker volume ls.
Automatické spouštění záloh cronem a jejich přenos mimo VPS popisuje návod Zálohy na VPS.
Ověření#
docker compose psukazuje oba kontejnery jako běžící, databázi jakohealthy.https://blog.example.czzobrazí WordPress se zámkem v adresním řádku.- Po restartu VPS (
reboot) se kontejnery spustí samy. - Z jiného počítače se na
http://nepřipojíte (port je jen na<IP_ ADRESA_ VPS>: 8080 127.0.0.1).
Když něco nefunguje#
permission denied while trying to connect to the Docker daemon socket#
Nejste root a váš uživatel není ve skupině docker. Spusťte příkaz přes sudo, nebo se přihlaste jako root.
Bind for 127.0.0.1:8080 failed: port is already allocated nebo address already in use#
Port 8080 už používá jiný kontejner (první hláška) nebo jiný program na VPS (druhá hláška). Zjistěte který (ss -tlnp | grep 8080, docker ps) a v compose.yaml zvolte jiný port, například 127.0.0.1:8081:80. Pak upravte i proxy_pass v Nginxu.
WordPress hlásí „Error establishing a database connection“#
Databáze ještě není připravená nebo nesedí přihlašovací údaje. Podívejte se do logu databáze (docker compose logs db). Pokud jste měnili heslo v .env až po prvním startu, databáze má pořád staré heslo (viz upozornění v kapitole Spuštění).
Kontejner je stále ve stavu Restarting#
Aplikace v kontejneru hned po startu padá. Příčinu najdete v logu: docker compose logs --tail 50 <NAZEV_SLUZBY>.
toomanyrequests: You have reached your unauthenticated pull rate limit#
Docker Hub omezuje stahování obrazů bez přihlášení na 100 za 6 hodin z jedné IP adresy. Počkejte, nebo se přihlaste svým účtem Docker Hubu: docker login.
no space left on device#
Došlo místo na disku. Zjistěte, co ho zabírá (docker system df, df -h), a ukliďte podle kapitoly Úklid místa na disku. Pokud místo opravdu chybí, navyšte RAM v záložce Změna balíčku, disk roste s pamětí.
Shrnutí
- Docker instalujte z oficiálního repozitáře
download.docker.com, ne balíčekdocker.io. - Data patří do volumes; kontejnery jde kdykoli smazat a vytvořit znovu.
- Weby publikujte na
127.0.0.1a zpřístupněte přes Nginx s HTTPS; Docker jinak obchází UFW. - Aktualizace:
docker compose pulladocker compose up -d. docker compose down -vaprune --volumesmažou data, zálohujte volumes pravidelně.
Další zdroje#
- Docker: Install Docker Engine on Ubuntu (otevře se v novém okně)
- Docker: Install Docker Engine on Debian (otevře se v novém okně)
- Docker: Packet filtering and firewalls (otevře se v novém okně)
- Docker: Port publishing (otevře se v novém okně)
- Docker: Compose file reference (otevře se v novém okně)
- Docker Hub: wordpress (otevře se v novém okně)
- Docker Hub: mariadb (otevře se v novém okně)