Máme tu další část našich návodů s Dockerem. V minulém díle jsme si ukázali základy a spustili základní Hello-World a NGINX. Nyní pokročíme o krok napřed směrem k základním příkazům a správě Docker Containerů.

V této části si ukážeme

  • Docker Cheetsheet
  • Základní subpříkazy pull, rm, attach, exec atd.
  • Stahování images a Docker Hub
  • Wejkův playground

Docker Cheetsheet

Jak to tak bývá, tak ke všemu bývají kartičky s návody nebo-li základními věcmi. Docker není vyjímkou a tak má officiální PDF kartičku, ve které jsou shrnuté všechny základní příkazy.

https://www.docker.com/sites/default/files/Docker_CheatSheet_08.09.2016_0.pdf

Některé už poznáme, k velké většině ale brzo nebo časem dojdeme. :)

Základní subpříkazy

Subpříkaz run

Tento typ již známe, představili jsme si ho kompletně v první části našich návodů o Dockerech. Jedná se o příkaz, který nám vytvoří container a spustí v něm zvolené image.

docker container run -d -p 80:80 nginx

Subpříkaz start

Narozdíl od příkazu run příkaz start funguje pouze na již vytvořené containery. Tedy nevytváří ale pouze spouští zastavené containery.

docker container start nginx

Subpříkaz stop

Opět známe a pamatujeme si z první části. Tento subpříkaz říká containeru, že se má vypnout, aplikace se tedy ukončí. Avšak stop pouze zastaví container a nic jiného s ním dál nedělá.

docker container stop nginx

Subpříkaz kill

No známe to všichni, né vždy vše funguje jak by mělo a někdy se prostě splaší všechny slepice a nejde to zastavit. Co v takovém případě? No nezbývá nám tedy nic jiného, než container doslova zabít. Tento příkaz tedy natvrdo ukončí container.

docker container kill nginx

Subpříkaz pull

Příkaz pull již také známe slouží ke stahování images z různých zdrojů na localhost, aby jej mohl container použít.

docker pull nginx

Subpříkaz attach

Spustili jsme container na pozadí, ale potřebujeme se na něj připojit a podívat se na průběh? Docílíme toho pomocí příkazu attach zcela jednoduše. Pokuď již nebudeš chtít sledovat log, stačí zmáčknout CMD/CTR + C.

docker container attach nginx

Poté již uvidíš v konzoli log z containeru.

Subpříkaz logs

Co když se ale nechceme podívat přímo do containeru ale potřebujeme pouze zobrazit poslední log. Od toho tu máme tento příkaz:

docker container logs nginx

Subpříkaz stats

Statistiky o tom, který container žere nejvíc CPU, RAM, disk paměti? Od toho slouží tento příkaz. Zobrazení statistik ukončíš pomocí CMD/CTRL + C

# Jeden container
docker container stats nginx

# Všechny containery
docker container stats -a

carbon--2-

Subpříkaz top

Tento příkaz nám zobrazí top příkazy spuštěné ve vybraném containeru. Něco jako Linuxový příkaz htop.

docker container top nginx

Subpříkaz ls

A v neposlední řadě, velmi důležitý příkaz, se kterým zobrazíme všechny spuštěné containery a image.

# Zobrazení spuštěných containerů
docker container ls

# Zobrazení všech (i vypnutých) containerů
docker container ls -a

# Zobrazení všech stažených image
docker image ls

carbon--3-

Jelikož se jedná o důležitý příkaz, tak si ho trochu rozebereme, tedy výpis.

  • CONTAINER ID - Je speciální UUID každého containeru, toto ID lze také používat místo názvů containeru. Př. v příkazech rm, stop atd.
  • IMAGE - Nám zobrazuje verzi spuštěného image v containeru.
  • COMMAND - Zobrazuje základní spouštějící příkaz, který je spuštěný na pozadí za pomoci docker container run nebo docker container start.
  • CREATED - Jak dlouho již container existuje.
  • STATUS - Jaký má aktuálně container status.
  • PORT - Jaké container používá porty, na obrázku vidíme že interní je 80 a venkovní je 80/tpc.
  • NAMES - Zobrazuje jak jsme container pojmenovali pomocí --name, na obrázku je náhodně vygenerované jméno Dockerem (o tom později).

Subpříkaz rm

Tento příkaz slouží k mazání prakticky všeho jak containerů tak images. Ovšem není to tak jednoduché jak se může zdát. Klasický příkaz tedy zní:

# Smazání containeru
docker container rm nginx nginx2 nginx3

# Smazání image
docker image rm nginx

Mazat jdou samozřejmě pouze vypnuté containery a image, které nejsou spuštěny a používány. Ovšem, co když máme takových containerů stovky? Od toho je tu systémová utilita, která to vše pročistí za nás.

docker system prune
WARNING! This will remove:
        - all stopped containers
        - all networks not used by at least one container
        - all dangling images
        - all build cache
Are you sure you want to continue? [y/N]

Stahování images

Různé verze

Pro to aby jsme mohli používat Docker pozřebujeme images. Jenže jako každý software, tak i images se časem updatují. V našem tutoriálu jsme doposud stahovali vždy poslední latest verzi, jelikož jsme neuvedli ID tagu verze.

# Stažení latest stable verze
docker pull nginx
docker pull nginx:latest

# Stažení NGINX verze 1.13
docker pulll nginx:1.13

Alpine images

Ne nejsou to Alpské hory, označují se tak images, které jsou mnoho násobně menší. V řádu pár megabajtů. Ukážeme si to na příkladu:

Stáhneme tedy (pokuď nemáš nebo jsi odstranil) image standartního NGINX (latest verzi).

docker pull nginx

# nebo

docker pull nginx:latest

Poté stáhneme Alpine verzi NGINX pomocí následujícího příkazu:

docker pull nginx:alpine

A nyní obě verze porovnáme pomocí příkazu docker image ls

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              ae513a47849c        2 weeks ago         109MB
nginx               alpine              ebe2c7c61055        5 weeks ago         18MB

Jak vidíš, rozdíl velikosti je doslova 90MB. Což aktuálně je sice zanedbatelné, ale představ si korporátní aplikace, které třeba běží pět tisíckrát. No to už je pár desítek gigabajtů navíc né-li terabajtů.

Proč je to ale tak malé, proč nedávají jenom alpine? Jde o to, že alpine verze obsahují pouze funkční základ. Kdežto standartní latest verze mohou obsahovat různé addony a vylepšení.

Docker Hub

Jedná se o stránku přímo od Dockeru, kde najdeš sbírku všech zdarma open-source stažitelných images. Mezi největší patří NGINX, Apache2, Redis, MySQL a mnoho a mnoho dalších.

Docker Hub najdeš na adrese: https://hub.docker.com/explore/

Nyní nebudeme řešit registrace a jiné věci okolo, o tom bude až další 3. část návodů.

Image-2018-05-18-at-1.32.54-AM

Jak vidíš, nejstahovanější je Alpine Linux. Tak si ho rozklikneme...

Image-2018-05-18-at-1.34.23-AM

Jedná se o Linux, který má pouhých 5MB. Což je opravdu málo... V popisku lze také vidět výpisy verzí dělených podle vydání nebo prostě latest.

Pokuď tedy budeme chtít stáhnout konkrétní verzi, tak si najdeme tag, který existuje a stáhneme třeba takto (nepovinné jenom ukázka):

docker pull alpine:3.5

Nachází se tam také verze edge, což je stejně jako u Dockeru označení pro poslední verze, které mohou obsahovat bugy.

Nyní se vrátíme a zabrousíme do větších repozitářů, třeba do našeho omýlaného NGINX - https://hub.docker.com/r/library/nginx/

Jak vidíš, tam je víc tagů. Proč ale, to jim jeden nestačí? Jde o to, že každá verze může x různých pod verzí.
Proto třeba podle NGINX tagy 1.13.2, mainline, 1, 1.13 jsou jedna a ta samá verze. Kdežto třeba 1.14.0, stable, 1.14 jsou tagy pro nejnovější verzi.

Nyní zabrousíme ještě hlouběji a najdeme si nějaké méně stahované image, třeba k PHPMyAdmin - https://hub.docker.com/r/phpmyadmin/phpmyadmin/

Image-2018-05-18-at-1.46.05-AM

Jak vidíš, něco se tu změnilo. Najednou je v názvu /? Proč?

Je to dáno tím, že NGINX, Alpine, Redis a mnoho dalších jsou oficiální spravovaný samotným Dockerem, který zajišťuje že vždy budou fungovat. Neoficiální images tedy (později) tvoje nebo cizí, mají v názvu uživatel/projekt:tag.

Wejkův playground

Co to je? Jedná se vždy o poslední část části daného tutoriálu. Tedy část, ve které si opravdu procvičíme a ukážeme, co jsme se naučili v šilené formě. Tak jdem na to...

5x NGINX na localhostu

Určitě jsi si všiml, že na některých obrázcích výše jsem měl spuštěný NGINX 2x, ale co ho takhle spustit 5x. Říkáš si, jak je to možné? Nu povíme si to...

Nyní tedy spustíme náš první NGINX na pozadí:

docker container run -d -p 80:80 nginx

Nyní spustíme druhý NGINX s jiným interním portem, třeba 81 a venkovní necháme na 80:

docker container run -d -p 81:80 nginx

A teď se do toho pustíme a spustíme si jich kolik chceme...

docker container run -d -p 82:80 nginx
docker container run -d -p 83:80 nginx
docker container run -d -p 84:80 nginx

Máš vše spuštěno? Tak si je zobraz pomocí známého příkazu docker container ls

CONTAINER ID        IMAGE               COMMAND                  CREATED                  STATUS              PORTS                NAMES
76782db710cc        nginx               "nginx -g 'daemon of…"   Less than a second ago   Up 2 seconds        0.0.0.0:80->80/tcp   pedantic_tesla
59f623dd86c4        nginx               "nginx -g 'daemon of…"   Less than a second ago   Up 5 seconds        0.0.0.0:81->80/tcp   laughing_thompson
b14d94d36fb0        nginx               "nginx -g 'daemon of…"   3 seconds ago            Up 8 seconds        0.0.0.0:82->80/tcp   awesome_hugle
fdfa54160e7d        nginx               "nginx -g 'daemon of…"   20 seconds ago           Up 25 seconds       0.0.0.0:84->80/tcp   wonderful_joliot
69924736fa04        nginx               "nginx -g 'daemon of…"   23 seconds ago           Up 28 seconds       0.0.0.0:83->80/tcp   quizzical_poitras

Nyní, když najedeš na localhost v prohlížeči, tak sice nevíš, jaký se ti ukáže, ale to je nám teď jedno. Jde o ukázku...

Spustili jsme 5x NGINX bez jména na interních docker portech 80-84 a venkovní je pouze 80. Jak to ale? To si nevadí ty 80kový porty? Paradoxně ne, jelikož Docker primárně řeší svůj Network (interní porty), venkovní porty si je potřeba ošéfovat přes různé proxy (ukážeme si v dalších tutoriálech).

Když se znova podíváš na výpis příkazu docker container ls, tak úplně vpravo jsou názvy containerů. My jsme ale žádný nezadali. Tyto jména jsou náhodně generované Dockerem. Je zhruba 12 milionů kombinací a někdy jsou fakt zajímavé.

Nyní containery vypneme pomocí subpříkazu stop. Zde pozor, jelikož jsme containery nepojmenovali, tak můžeme použít ID containeru nebo název vygenerovaný Dockerem, v mém případě tedy:

docker container stop pedantic_tesla laughing_thompson awesome_hugle wonderful_joliot quizzical_poitras

Teď když se koukneš do docker container ls, tak tabulka bude prázdná. Containery jsou vypnuté, nezobrazují se tedy v základu je potřeba dodat -a k ls.

Nyní už jenom smazat containery, prakticky stejný příkaz jenom místo stop dáme rm. Druhou možností je docker system prune.

docker container rm pedantic_tesla laughing_thompson awesome_hugle wonderful_joliot quizzical_poitras

Spuštění Ubuntu 18.04 LTS v containeru + připojení na konzoli

Myslíš si, že to je bláznivý nápad? No může to tak vypadat ale někdy, je potřeba se podívat přímo do containeru, co se tam děje nebo se na něj prostě napojit přes SSH, pokuď to umožňuje.

Jako první je potřeba stáhnout Ubuntu 18.04 image z Docker Hubu, jelikož už víš jak se orientovat na Docker Hubu, tak si ho zkus najít sám, je hned na první stránce jelikož je to oficiální image.

Po stažení Ubuntu 18.04 nebo kteréhokoliv jiného, je to prakticky jedno spustíme Ubuntu v containeru, pomocí následujícího příkazu:

docker container run -d --name ubuntu -p 22:22 ubuntu:18.04

Nyní se podíváme, zda container běží - docker container ls a ejhle on se vypnul? Tak se kouknem docker container ls -a, ano vypnul se ale proč?

Ubuntu totiž není jen tak obyčejná aplikace, jedná se o systém, který má svojí konzoli, tzn. že po spuštění prakticky killne sám sebe. Z toho důvodu je potřeba upravit spouštějící parametry tak, aby container ignoroval ubunťácký bash. Tedy pomocí parametru -t, což je zkratka pro TTY.

docker container run -t -d --name ubuntu ubuntu:18.04

A co se nám to stalo? Nastala chyba?!

docker: Error response from daemon: Conflict. The container name "/ubuntu" is already in use by container "480a518b0b0adb1ab5c7163b1f26b37f1ff882d8250eb1b80d963e7a835014a7". You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.

Ano, jelikož jsme již předtím vytvořili container a teď ho vytváříme znova pod stejným názvem ubuntu.
Jediné řešení je tedy ho smazat... docker container rm ubuntu. A teď znova:

docker container run -t -d --name ubuntu ubuntu:18.04

Nyní když se podíváš do docker container ls tak Ubuntu JEDE! Hurá, spustili jsme si Ubuntu v containeru! Jak se tam ale teď připojíme? Pomocí subpříkazu exec, který slouží k spouštění příkazů v containeru zvenku + zkratky -i, která nám dovolí se připojit na konzoli bez toho aby se při odpojení killnula.

docker container exec -it ubuntu bash

A nyní jsi v Ubuntu, ověříš si to pomocí klasického příkazu ls nebo uname -a. Nyní se tam můžeš vyřádit nebo prostě opustit container pomocí CMD/CTR + D.

No a nyní můžeš container zastavit, smazat a image taky.

Spuštění MySQL a vygenerování náhodného ROOT hesla

Nyní to už nebude tak složité, ale kdo ví... nyní si spustíme MySQL poslední verzi a použijeme tzv.Enviroment variables k nastavení, že chceme aby nám MySQL při startu vygenerovala náhodné heslo pro root. Jak ho ale zjistíme? Jednoduše z logu! Tak jdem na to...

docker container run -d -p 3306:3306 --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes mysql

Příkaz -e je zkratka pro variables, které může mít image. My je nyní nebudeme řešit, jelikož si je nemáme jak ukázat, prostě je teď pouze použijeme.
"Wejku, já ale nemám pullnutý mysql image" - to nevadí, jelikož jsme si neřekli, že pokuď nemáš stažený image a zadáš příkaz run tak Docker jako první zkontroluje localhost, potom Docker Hub a stáhne.

Po napsání horního příkazu vyčkej zhruba minutu, jelikož "jí" to trvá.. a poté zadej a najdi GENERATED ROOT PASSWORD:

docker container logs mysql

A to je vše! Nyní pokuď jsi došel až sem ovládáš základy Dockeru, jak fungují Images, kde se dají najít jak je spravovat s containery a jak samotný Docker prakticky funguje! Gratuluji!

Příště se podíváme na vytváření vlastních images a jejich nahrávání na Docker Hub.