Docker
Opis dockera
- Šta je Docker?
- Kako setovati Docker radno okruženje?
- Docker Cheat Sheet – sve bitne komande na jednom mestu
- Docker run – moj prvi kontejner
- Dockerfile – Moj prvi image
- docker-compose.yml – set instrukcija za stvaraje kontejnera
Šta je Docker?

NAPOMENA: Ovo i sva uputstva koja slede nisu oficijalna i moja su interpretacija originalne dokumentacije i uslova pod kojim se izvode. Tako da mogu i ne moraju da budu ispravna.
Pa da krenemo.
Docker je ako ste developer ili devops vaš najbolji prijatelj. Dosta ljudi ga izbegava zato što im izgleda teško i previše komplikovano za rad, ali istina je potpuno suprotna.
Koliko puta ste se setovali na isti projekat na različitim računarima? I uvek je milion stvari krenulo naopako. Nije bila dobra verzija baze, ili nije bio dobra verzija php-a, ili nešto u operativnom sistemu nije radilo kako treba a vi zato što ste developer možda niste znali šta je, ili ako ste devops niste znali šta je to developer stavio od dependencya. I tako prebacujete se sa računara na računar (sa čoveka na čoveka) i trošite svoje i firmino vreme na setovanje.
Tu docker uskače da vam pomogne. Docker je prostim rečima mikro operativni sistem (ali je u stvari servis). On koristi kernel i neke biblioteke host operativnog sistema, ali je u suštini potpuno nezavistan i osećaj kada radite unutar kontejnera je kao da ste na nekom remote serveru. Možete instalirati sve što vam treba, možete setovati sve što vam treba. I možete bez ikakve griže savesti sve unutra pokvariti i to neće imati nikakve posledice na host operativni sistem.
Docker image
Kako bi podigli kontejner, morate imati njegov image. On se sastoji od više slojeva koji su u suštini fajlovi koji su generisani ispaljivanjem neke od komandi tokom build procesa. U toku buildanja image-a, svaka komanda koja se unese npr. ” apt update” generiše novi sloj, tj novi fajl. Docker image slojevi koji su identični, koriste se između različitih imidža, npr. Imate image “ubuntu-git” i image “ubuntu-jenkins” oni imaju zajedničku stvar, a to je njihov operativni sistem. Tako da će uštedeti prostor i koristiti isti “sloj” -(eng. layer) . Ovo je primer slojeva za image alpine:latest.

Generalno, vi ovo ne morate znati, ali mislio sam da će vredeti da se pomene kako to izgleda.
Docker container
Sada kada znate šta su imidži, da vam malkice približim i kontejnere. Kada bilo koji image želite da pokrenete, i od njega kreirate servis, stvorićete kontejner. To je nešto poput virtualne mašine koja će pokrenuti vaš image. Bitno je da kontejner posmatrate kao PRIVREMENU stvar. Nakon što prestane da bude potreban on će se zaustaviti. A u jednom zaustavljen kontejner više ne možete ući. Primer. Pokrenuo sam image redisa.

Vidite da je dobio ID 76ad5369f68d. Nakon zaustavljanja, proverio sam da li je neki kontejner aktivan. Video da nije, i opet ga pokrenuo.

Vidite novi ID: 41a531650ed8. Isti image. Ista komanda za pokretanje. Dva različita kontejnera. U tome je prava lepota dockera. Ne možete vi dovoljno nešto zeznuti koliko sve možete za 5 sekundi vratiti na početno stanje 🙂
Trebate znati i da svaki kontejner ima svoj networking, potpuno je izolovan od ostalih kontejnera, i sem ako mu se to ne naznači, on neće ni znati da nešto tu postoji osim njega.
Docker Registry
Sve imidže koje napravite negde morate čuvati. Za to se koriste registri. Većina koriste onaj glavni docker hub. Besplatan je. Kreirate tamo nalog. Ulogujete se na računaru koristeći komandu “docker login” . Ulogujete se na serveru. I isto kao na gitu, koristite komande push i pull 🙂 . Prelepo i jednostavno.
Sve početne imidže koje ćete ikada koristiti preuzećete sa docker huba. Pa vredelo bi da se upoznate sa sadržajem.
Znate koliko je teško nekada setovati neko parče softvera i koliko biblioteka može nedostajati da to nešto proradi. Znate ono, radi samo na tom operativnom sistemu, sa tim zastarelim bibliotekama kojih više nema nigde. Ali vi ste nakako uspeli sve to da pronađete, podignete i naterali da radi, ako ste to uradili unutar kontejnera možete sačuvati taj kontejner u image. I možda nekom olakšati život tako što ćete taj image deponovati na neki javni registar. Ujedno će i vama biti dostupno za sledeći put.
Možda vama treba nešto, pregledajte docker registar, možda se neko već sreo sa tim problemom i rešio ga za vas.
Za sada, od mene toliko. U sledećim tekstovima možete očekivati detaljnija objašnjenja i praktičnu primenu dockera.
Hvala na čitanju.
Kako setovati Docker radno okruženje?

NAPOMENA: Ovo i sva uputstva koja slede nisu oficijalna i moja su interpretacija originalne dokumentacije i uslova pod kojim se izvode. Tako da mogu i ne moraju da budu ispravna.
Za testne potrebe rada pod dockerom podigao sam mint 19.2 cinamon na virtualboxu. Tako da ako želite da vam sve izgleda identično thats the way to go.
Instalacija
Postoje nekoliko načina instalacije, biranje verzija blah blah. Mislim da je to previše za početnika. Idemo straight forward.
sudo apt update
apt install docker.io
apt install docker-compose
Posle uspešne instalacije oba paketa, ispalite
docker -v
Prva komanda instalirala vam je Docker engine. Druga jedan jako koristan tool, koji će vam olakšati deployment kontejnera. Ali nećemo o tome sada.
Registracija na docker hub
Sećate se onog cool mesta sa imidžima već spakovanih softvera, eee to je ovde. https://hub.docker.com/signup
Za potrebe ovog tutorijala, napravih novi profil.

Na sledećoj stranici popunite kako god vam je volja. Nije za produkciju,

Nakon toga, stigao vam je verifikacioni mail sa linkom na koji trebate kliknuti.
E sada se vraćamo nazad terminalu. I logujemo se na docker hub.
sudo docker login
Ulogujte sa sa kreiranim korisničkim imenom i lozinkom.

Potencijalni problem: – Error saving credentials

Rešenje;
sudo apt install gnupg2 pass
Kako bi testirali da li smo sve lepo setovali, hajde da svučemo jedan image.
sudo docker pull redis
Ako je sve prošlo kako treba, pokrenuće se download.

Sada na vašem računaru imate image iz repozitorijuma REDIS koji je tagovan kao latest tj poslednji.
Znači repozitorijum:tag je redis:latest .
Na isti način možete pullovati neku stariju verziju redisa.
Probajte:
sudo docker pull redis:4.0
Da bi potvrdili koje image imamo u lokalu dovoljno je da ispalite:
sudo docker images

Ovo je moj listing. Ovde se vidi da imam 3 imidža. Ali pošto zadnje dve slike dele image ID. Možemo zaključiti da je verzija 5.0 poslednja.
Toliko u ovom tutorijalu. U sledećem ću se malo skoncentrisati na komande. I šta se i kada koristi.
Docker Cheat Sheet – sve bitne komande na jednom mestu

NAPOMENA: Ovo i sva uputstva koja slede nisu oficijalna i moja su interpretacija originalne dokumentacije i uslova pod kojim se izvode. Tako da mogu i ne moraju da budu ispravna.
Moj iskreni predlog je da bookmarkujete ovu stranicu. Ažuriraću je redovno i dodavati nove komande i objašnjenja.
Svlačenje imidža sa repozitorijuma
primer:
docker pull redis:latest
Dizanje imidža na repozitorijum
primer:
docker push redis:mojbuild
Koristi se za guranje imidža koje ste vi pravili na lokalu na neki od registra.
Listanje imidža
primer:
docker images
Izlistaće sve lokalne imidže koje ste preuzeli ili buildali.
Listanje kontejnera
docker ps
Gornja komanda izlistaće vam sve AKTIVNE kontejnere
docker ps -a
Izlistaće vam sve kontejnere, uključujući i exitovane. Ovo je korisno ako tražite id kontejnera koji se nije uspešno digao zbog daljeg debugovanja.
Buildanje image-a
docker build -t mojnoviimage .
Komanda traži Dockerfile u direktorijumu iz kog se izvršava (primećujete tačku na kraju) . Komandom -t definište tag image-a.
Logovi
docker logs idkontejnera
Nakon što vam ne uspe dizanje kontejnera iz bilo kog razloga prvo mesto gde tražite problem su docker logovi. Prethodno komandom docker ps -a pokupite id exitovanog kontejnera i zatim ovom komandom iščitate šta nije u redu.
Čišćenje exitovanih kontejnera
docker container prune
Ovom komandom brišete sve exitovane kontejnere. Nakon nekog vremena nakupi se njih da zauzme pozamašni prostor. Sećate se da se svaki kontejner izvršava samo jednom.
Čišćenje neupotrebljenih imidža
docker image prune
Iako imidži native dele dosta prostora u lajerima, vremenom se nakupe razni updejti, pa neki mogu narasti i preko 1 gb. Puta broj raznih varijacija. Ode disk. Komanda će obrisati sve image koje u datom trenutku ne koristi najmanje jedan kontejner.
Čišćenje celog docker sistema
docker system prune
Ova iako na izgled bezopasna komanda bi trebalo bez nekih većih opasnosti ukloniti sve kontejnere, volume, imidže i ostatak crapa koji se nakupi radom dockera. Meni je slupao testno docker swarm okruženje. Tako da ga ne preporučujem. Nisam siguran da li je bio neki bug. Ali eto. Probajte pa vidite.
Docker compose
docker-compose up
izvršava se iz direktorijuma gde vam se nalazi docker-compose.yml fajl. Podiže ceo set zadatih kontejnera sa promenljivama koje ste uneli. (za ovo će trebati poseban post)
docker-compose up -d
Radi isto što i prethodna komanda ali vam se ne vezuje sa sesijom nego radi to detached, a vaš terminal ostaje slobodan za druge poslove
docker-compose -f moj-compose.yml up
Isto radi što i ove gore komande, ali ako imate par compose fajlova u istom direktorijumu, ovako možete izabrati onaj koji vam treba. Takođe radi sa -d
docker-compose down
Zaustavlja sve servise koji se pominju u compose fajlu direktorijuma iz kog se ispaljuje.
Docker swarm
docker stack deploy -c compose.yml --with-registry-auth imestaka
Komanda se ispaljuje na menadžeru iz direktorijuma gde je smešten compose fajl. --with-registry-auth kaže da za svlačenje imidža koji su naslovljeni u compose fajlu koristi kredencijale za registar kao i registar na koji je node na kome se deploy izvršava ulogovani. imestaka predstavalja ime kojim će se označavaju svi servisi (kontejneri) koje će ovaj compose fajl kreirati.
docker stack rm imestacka
Ovim uklanjate sve kontejnere koje ste podigli prethodnim compose fajlom.
docker stack ls
Ovim listate sve stackove. Pored imena svakog od njih, pisaće koliko servisa imaju podignutih (kontejnera)
docker service ls
Ovim listate sve servise na svim nodovima. Ova kao i sve prethodne komande mogu se izvršiti samo sa DOCKER MENADŽERA
Docker run – moj prvi kontejner

NAPOMENA: Ovo i sva uputstva koja slede nisu oficijalna i moja su interpretacija originalne dokumentacije i uslova pod kojim se izvode. Tako da mogu i ne moraju da budu ispravna.
docker run je komanda kojom ćete od imaga konačno napraviti kontejner. Što bi se reklo vaš image je porastao i vreme mu je da se uozbilji 🙂
Dakle. Prvo sa docker huba, preuzimamo neki image koji nam u ovom trenutku treba. Nekad to bude redis repozitorijum, poslednji image.
sudo docker pull redis:latest

Kao što vidite u primeru, ako ne naznačite image, pullovaće se po defaultu latest iz tog repoa.
Hajde da pokrenemo direktno redis, bez ikakve pripreme. Čisto da vidimo šta će se desiti.
sudo docker run reds

Kao što vidite, redisov proces se pokrenuo. Da se podsetimo priča od ranije, u docker svetu proces=kontejner. Tako da nije pogrešno reći da smo pokrenuli docker kontejner redisa. Dobili smo log startupa. I on sada živi u ovoj sesiji koju sam inicijalizovao. Ako iz bilo kog razloga zatvorim ovaj terminal(ukinem sesiju). Redis će prestati da postoji.
Pošto je cilj eksperimenta postignut. Hajde da ukinemo sesiju kao bilo šta drugo ctl+c. I time ubijamo ovaj kontejner.

Hajde sada da pokrenemo redis u detached modu, tj da naša aktivna sesija više nema veze sa pokrenutim kontejnerima.
sudo docker run -d redis:latest

Komandom sudo docker ps možemo izlistati startovane kontejnere.

Ovo jeste zanimljivo, ali za bilo kakvo ozbiljnije korišćenje, predlažem rad sa compose fajlovima. O tome ću pisati u nekom drugom postu.
Za više informacija kako radi docker run, posetite ovaj link https://docs.docker.com/engine/reference/run/
Dockerfile – Moj prvi image

Konačno smo dogurali do onog zanimljivog dela. Do pravljenja naše verzije nekog imidža. Ako vam je kojim slučajem izvetro šta je imidž, ne krivim vas, mnogo sam veliki razmak napravio između tekstova. Podsetite se klikom na OVAJ link
Pa da zaronimo. Dockerfile je srce svakog imidža. Svi do poslednjeg image koji ste preuzeli sa nekog registra napravljeni su na ovaj način.
Napomena: Dockerfile, mora baš tako i da se imenuje veliko D je obavezno. Bez ekstenzije je.
Udjite u test direktorijum, otvorite terminal. I kreirajte Dockerfile
touch Dockerfile
Editujte ga editorom koji vam odgovara. Ja ću koristiti nano.
nano Dockerfile
Hajde da napravimo imidž koji će biti zasnovan na php 7.2 fpm. I da mu ubacimo samo naj potrebnije stvari. Naravno i da ga ažuriramo.
FROM php:7.2-fpm
RUN apt-get update && apt-get install -y
CMD ["php-fpm"]
EXPOSE 9000
Da raščlanimo:
FROM php:7.2-fpm – Ovim dockeru kažemo da preuzme imidž iz repozitorijuma php sa tagom 7.2-fpm. Ovako možete modifikovati bilo koji image koji imate u lokalnim repozitorijumima ili ste od negde preuzeli. Time će biti kreiran prvi sloj(layer) našeg imidža. A Dockerfile php:7.2-fpm možete pogledati ovde.
RUN apt-get update && apt-get install -y – Ovom komandom stvaramo novi sloj. Operativni sistem na kome je zasnovan php 7.2 fpm( debian:buster-slim) ažuriraće se i postaviti sloj broj 2 unutar ovog imidža.
RUN komandu, koristite isključivo za proces izvršavanja instalacija i modfikacija koji će se upisati u vašu verziju imidža.
CMD ["php-fpm"] – Po stvaranju kontejnera od ovog imidža, izvršiće se ova komanda. I tako će docker kontejner ostati da radi, neće pasti. U stvari mi samo pokrećemo php-fpm.
CMD – Ako imate više CMD direktiva u okviru jednog dockerfajla, izvršiće se sve u build procesu, sem poslednje. Ona će ostati da se izvrši pri podizanju kontejnera. Ovo je bitno znati, da se ne oslanjate na njih za više stvari koje treba uraditi na inicijalizaciji kontejnera. Za te stvari, koristimo ENTRYPOINT.
EXPOSE 9000 – To znači da vam port 9000 neće biti otvoren kada pokrenete ovaj kontejner ka host mašini, već samo ka dockerovoj mreži.
Konačno buildanje
sudo docker build -t ime_imidza .
Komanda se pokreće iz direktorijuma gde je smešten Dockerfile. -t označava tag i obavezna je taćka na kraju, kako bi dockeru rekli da smo unutar direktorijuma gde nam je Dockerfile.

Kao što vidite, imali smo 4 komande u našem Dockerfajlu. Sve 4 su kreirale svoje kontejnere u okviru kojih su se izvršile i postale lajeri tj slojevi. I na kraju smo stvorili novi image. Sada pustite mašti na volju, vidite koliko se lako prave imidži. A jednom napravljeni imidž, možete na milion mesta koristiti.
I na kraju da vam napomenem. Prijavite se na moju mailing listu, ili na telegram kanal. https://t.me/LudiSistemas . U slučaju da se desi neki problem sa fejsbuk stranicom, da ostanemo u kontaktu.
NAPOMENA: Ovo i sva uputstva koja slede nisu oficijalna i moja su interpretacija originalne dokumentacije i uslova pod kojim se izvode. Tako da mogu i ne moraju da budu ispravna.
docker-compose.yml – set instrukcija za stvaraje kontejnera

Docker compose možete posmatrati kao set instrukcija koji će dati vašem imidžuu neki dodatni set funkcionalnosti a koji ne mogu da se definišu unutar Dockerfajla. Uz njega možete izbeći sve one komplikacije gde morate u dugaćkim kobasicama navoditi šta želite da vaš kontejner ima otvoreno od portova, koje mount pointe da koristi, kako da mu bude ime definisano.
Neki od vas su sigurno bar jednom otkuali docker-compose up , možda baš u laradocku, i naveli šta sve žele da se startuje od usluga. E ovde ću pokušati da vam prikažem kroz objašnjenje jednog nasumičnog yaml fajla sa interneta, šta sve docker-compose može.
Podizanje wordpressa
Version: '3.3'
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
db_data: {}
NAPOMENA: Kod yaml kodiranja, jako su bitni indenti. Ako tu omašite za jedan razmak, yaml fajl neće raditi.
Komentar je isti kao u većini programskih jezika, počinje sa znakom # . Sada ću kopirati kod od iznad, i iskomentarisati vam u kodu i inline šta znači šta.
Version: '3.3' #Verzija zavisi od toga koji docker engine koristite. Može se desiti da sintaksa koju koristite ne bude podržana na starijim enginima.
services: #Ovde navodimo koje servise želimo da podignemo i definišemo imena
db: #Definišemo ime servisa koji će gurati bazu podataka
image: mysql:5.7 #Ovde navodimo od kog imidža sa docker huba se ovaj kontejner/servis spawnuje
volumes: #ovde definišemo persistentnu memoriju kontejnera.
- db_data:/var/lib/mysql # lokalni_dir:/lokacija/u/kontejneru
restart: always # U slučaju da nešto krene naopako pokrećemo ga opet
environment: #Definišemo globalne promenljive ovog kontejnera
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress: #Ime jednog od servisa, obratite pažnju da je u istom indentu kao i db gore
depends_on: #Ovde možemo da kažemo ovom kontejneru da čeka dok se ne podigne neki kontejner
- db #U stvari čekamo bazu, ili php ima da kaže da ne vidi bazu, i srušiće se kontejner
image: wordpress:latest #Opet navodimo koji image želimo da podginemo
ports: #Definišemo koje portove želimo da prosledimo lokalnoj mašini sa dockera
- "8000:80"
restart: always #Isti uslov kao i za bazu
environment:
WORDPRESS_DB_HOST: db:3306 #Obratite pažnju, ovde gađamo ime servisa:kroz port u docker networku
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
db_data: {} #Ovde mountujemo db_data iz meni nepoznatog razloga u okviru wordpressa :)
Ovaj fajl sačuvajte kao docker-compose.yml i napravie direktoriju db_data. Nakon što ispalite dokcer-compose up. DIžu se se DVA kontejnera/servisa. Kontejner koji se zove db i kontejner koji se zoba wordpress. I oni komuniciraju bezbedno kroz docker mrežu. Ali to je već priča za sebe. O tome drugi put.
Ako budete imali pitanja, postavite ih u komentaru na fejsbuk stranici. A ja ću dopisati odgovore u okviru ovog članka.