Uvod u Docker svet
Šta je Docker?
Docker je platforma koja omogućava programerima da jednostavno kreiraju, implementiraju i pokreću aplikacije unutar kontejnera.
Šta su to kontejneri?
Kontejneri se mogu shvatiti kao lagane virtuelne mašine, ali su dosta brži i manje zahtevni od njih, oni sadrže sve što je potrebno za pokretanje aplikacije: kod, biblioteke i podešavanja operativnog sisteme.
Zašto koristiti Docker?
-
Rad aplikacije na različitim sistemima
Kada aplikacija radi u kontejneru, onda ona može raditi bilo gde, i lokalno ili u nekom udaljenom serveru. Kontejneri omogućavaju aplikacijama da rade konzistentno u različitim okruženjima a to se naručito “oseti” kod timova koji razvijaju aplikaciju na različitim računarima koristeći različite operativne sisteme, kao npr.:
- Programer A (Windows): Razvija aplikaciju u Docker kontejneru.
- Programer B (Mac): Testira aplikaciju u Docker kontejneru.
- Server za produkciju (Linux): Pokreće aplikaciju u istom Docker kontejneru.
Bez Docker-a, svaki programer bi morao instalirati sve potrebne alate i biblioteke na svom računaru, što može dovesti do problema sa kompatibilnošću i reproduktivnošću. A ako se koristi Docker onda svi programeri koriste jednu istu Docker sliku, što im omogućava da razvijaju i testiraju aplikaciju u identičnom okruženju. Na kraju, aplikacija se prenosi na produkciju bez brige o različitim verzijama biblioteka ili softvera na produkciskom serveru.
-
Izolacija aplikacije
Kontejneri omogućavaju svakoj aplikaciji da radi u svom odvojenom okruženju, bez međusobnog ometanja. Ovo može biti veoma bitno kod kompanija koja razvijaju ili hostuje dve različite aplikacije a koje zahtevaju različite verzije MySQL baze podataka. U tom slučaju je idealno da se koristi Docker jer se tada svaka aplikacija može smestiti u svoj Docker kontejner sa odgovarajućom verzijom MySQL-a, kao u sledećem primeru:
- Aplikacija 1 (MySQL 5.7): Pokreće se u Docker kontejneru sa MySQL 5.7
- Aplikacija 2 (MySQL 8.0): Pokreće se u Docker kontejneru sa MySQL 8.0
Ili kada tim radi na aplikaciji koja zavisi od specifičnih verzija Node.js-a, NPM-a ili nekih drugih biblioteka. U tom slučaju kada se koristi Docker onda tim kreira Docker sliku koja sadrži sve potrebne zavisnosti, pa se na taj način pokreće aplikacija u potpuno istom okruženju, bez brige o verzijama biblioteka.
-
Skalabilnost aplikacije
Docker omogućava lako skaliranje aplikacija horizontalno (dodavanje novih instanci), pa ako kompanija doživljava nagli porast saobraćaja na svojoj e-commerce platformi onda se sistem lako skalira dodavanjem dodatnih kontejnera za rukovanje većim opterećenjem, kao npr.:
- Web serveri: 10 Docker kontejnera sa Nginx-om
- API serveri: 15 Docker kontejnera sa aplikacijom
- Web serveri: 15 Docker kontejnera sa MySQL-om
Osnovni Docker koncepti:
- Docker Image (Slika): Template za stvaranje kontejnera. Definiše kako će izgledati kontejner.
- Docker Container (Kontejner): Pokrenut primerak Docker slike.
- Dockerfile: Datoteka s uputstvima kako kreirati Docker sliku.
- Docker Hub: Repozitorijum za deljenje i preuzimanje Docker slika.
Instalacija Docker-a
Evo kratkog uputstva za instalaciju:
-
Provera sistemskih zahteva:
- Docker Desktop zahteva 64-bitni Windows 10 ili noviji sa verzijom 21H2 ili novijom, ili Windows 11.
- Virtualizacija mora biti omogućena u BIOS-u (Hyper-V i Windows Container funkcije).
- Instalacija zahteva najmanje 4GB RAM-a.
- Preuzmi Docker Desktop instalacioni program: na ovom linku ili poseti stranicu za instalaciju i klikni na dugme “Download Docker Desktop for Windows”.
- Pokreni instalacioni program (npr. “Docker Desktop Installer.exe”) i prati uputstva na ekranu.
- Restartuj računar
-
Proveri Docker instalaciju:
- Otvori terminal (PowerShell ili Command Prompt) i pokreni komandu:
1docker --version - Ako vidiš verziju Dockera, to znači da je instalacija uspela.
- Otvori terminal (PowerShell ili Command Prompt) i pokreni komandu:
NAPOMENA:
Postupak instalacije se može menjati od verzije do verzije, te je najbolje pogledati aktuelno stanje na oficijalnoj stranici.
Korišćenje Docker-a
Docker može da se koristi preko preuzete aplikacije Doker Desktop ili preko terminala, evo par najčešćih komandi za terminal:
-
Preuzimanje Docker slike sa Docker Huba
1docker pull <repository>:<tag>Kao npr:
1docker pull nginx:latestili
1docker pull nginx:1.21.0 -
Kreiranje slike prema uputstvu iz Dokerfile-a
1docker build [OPTIONS] PATHU trenutom direktorijumu:
1docker build -t naziv_slike .Ako se DockerFile nalazi na nekoj drugoj lokaciji:
1docker build -f /path/to/Dockerfile -t naziv_slike .Gde je:
- -t: Označava (tag) sliku imenom.
- -f: Navodi put do Dockerfilea.
-
Prikazivanje dostupnih Docker slika
Naredba docker images se koristi za prikazivanje liste svih Docker slika koje su trenutno sačuvane na vašem lokalnom računaru.
1docker imagesKada koristite samo docker images bez dodatnih opcija, Docker prikazuje samo najnovije označene slike za svaki repozitorijum. Ovo znači da, ako imate više verzija slike sa različitim oznakama (tagovima), prikazuje se samo poslednja verzija. Kada dodate opciju “-a” ili “–all”, Docker prikazuje sve slike, uključujući sve verzije iste slike kao i tzv. “dangling images” tj. slike koje nemaju oznake i često su rezultat međukoraka tokom procesa građenja slike.
1docker images -aPrimer
1234REPOSITORY TAG IMAGE ID CREATED SIZEmy-app latest 12345 1 week ago 500MBmy-app v1.0 67890 2 weeks ago 500MBnone none abcde 3 weeks ago 500MBOva opcija omogućava da vidimo sve slike koje su sačuvane na vašem sistemu, što vam pomaže da upravljate prostorom na disku i odlučite koje slike možete obrisati.
-
Pokretanje kontejnera
1docker run [OPTIONS] IMAGE [COMMAND] [ARG...]Kao npr.:
1docker run nginx:latestili sa dodatnim opcijama:
1docker run -d -p 8080:80 --name moj-nginx nginx:latestZnačenje opcija:
- -d: Pokreće kontejner u pozadini (detached mode)
- -p: Mapira portove host:container (npr. 8080:80)
- –name: Dodjeljuje ime “moj-nginx” kontejneru
-
Spisak pokrenutih kontejnera
1docker ps [OPTIONS]Npr.
1docker psili sa dodatnim opcijama:
1docker ps -aOpcija -a prikazuje sve kontejnere, uključujući i zaustavljene.
-
Zaustavljanje pokrenutog kontejnera
1docker stop <container_id_or_name>Zaustavljanje po nazivu:
1docker stop moj-nginxili prema id-u:
1docker stop df61c3a9e43b -
Brisanje kontejnera
1docker rm <container_id_or_name>Brisanje po nazivu:
1docker rm moj-nginxNAPOMENA:
Naredba "docker container prune" sza uklanjanje svih zaustavljenih kontejnera sa vašeg sistema. Ova naredba pomaže u oslobađanju prostora i održavanju urednog Docker okruženja uklanjanjem kontejnera koji više nisu aktivni. -
Brisanje Docker slike
1docker rmi <image_id_or_repository:tag>Npr:
1docker rmi nginx:latestNAPOMENA:
“Dangling” slike su one koje nisu povezane ni sa jednim repozitorijumom ili oznakom (tagom). Obično imaju “none” kao naziv repozitorijuma i oznake. Naredba "docker image prune" se koristi za uklanjanje neupotrebljenih (dangling) Docker slika sa vašeg lokalnog sistema. -
Izvršavanje naredbe unutar pokrenutog kontejnera:
1docker exec [OPTIONS] <container_id_or_name> <command>Npr.:
1docker exec -it neki_kontejner ls -
Prikazivanje logova kontejnera:
1docker logs [OPTIONS] <container_id_or_name>Npr. prikazivanje svih logova
1docker logs moj-nginxPrikazivanje zadnjih 10 linija loga:
1docker logs -f --tail 10 moj-nginx
Docker Volume
Docker volume je mehanizam za trajno skladištenje podataka generisanih i korišćenih od strane Docker kontejnera. Volumeni omogućavaju da podaci prežive ponovna pokretanja kontejnera, a mogu se deliti između različitih kontejnera. Koriste se za upravljanje podacima na način koji je nezavistan od životnog ciklusa kontejnera.
Ključne karakteristike Docker volumena:
- Trajnost podataka: Podaci smešteni u Docker volumene opstaju čak i kada kontejneri koji ih koriste budu obrisani.
- Deljenje podataka: Više kontejnera može istovremeno koristiti isti volumen, što omogućava deljenje podataka između kontejnera.
- Izolacija podataka: Docker volumeni su izolovani od sistema domaćina (host) i ostalih kontejnera, što doprinosi boljoj sigurnosti i organizaciji podataka.
- Performanse: Docker volumeni obično nude bolje performanse u odnosu na skladištenje podataka direktno na fajl sistemu kontejnera.
Kreiranje i korišćenje Docker volumena:
Kreiranje volumena:
1 |
docker volume create my_volume |
Pregled postojećih volumena:
1 |
docker volume ls |
Korišćenje volumena u kontejneru:
Kada kreirate ili pokrećete kontejner, možete montirati volumen koristeći opciju -v ili --mount.
Korišćenje opcije -v:
1 |
docker run -d -v my_volume:/app/data my_image |
U ovom primeru:
- my_volume je naziv volumena koji montirate.
- /app/data je direktorijum unutar kontejnera gde će volumen biti montiran.
- my_image je Docker slika koju koristite za kreiranje kontejnera.
Korišćenje opcije --mount:
1 |
docker run -d --mount source=my_volume,target=/app/data my_image |
Ova sintaksa je slična, ali pruža više fleksibilnosti i čitljivosti.
Upravljanje Docker volumenima:
Brisanje volumena:
1 |
docker volume rm my_volume
Automatsko brisanje volumena:
Kada želite da uklonite sve nepovezane (dangling) volumene, koristite naredbu:
1 |
docker volume prune |
Primer upotrebe:
Pretpostavimo da imate aplikaciju koja skladišti podatke u direktorijumu /app/data unutar kontejnera. Želite da osigurate da ti podaci budu trajni i dostupni čak i ako ponovo pokrenete kontejner.
1. Kreirajte Docker volumen:
1 |
docker volume create app_data |
2. Pokrenite kontejner i montirajte volumen:
1 |
docker run -d --name my_app_container -v app_data:/app/data my_app_image |
Podaci kreirani u /app/data unutar kontejnera my_app_container biće sačuvani u volumenu app_data, koji možete koristiti sa drugim kontejnerima ili pristupiti direktno ako je potrebno.
Docker Compose
Docker Compose je alat koji olakšava upravljanje višekontejnerskim Docker aplikacijama. Koristeći jednostavni YAML fajl (docker-compose.yml), možemo da definišemo konfiguraciju svih servisa, mreža i volumena koji čine našu aplikaciju, a zatim ih pokrenete i upravljate njima pomoću jedne komande. Docker Compose je uključen u sklopu Docker Dektop instalacije.
YAML je format za serializaciju podataka koji je dizajniran da bude jednostavan za čitanje i pisanje. Podaci su organizovani u parove ključeva i vrednosti. Ključ i vrednost se odvajaju dvotačkom i jednim razmakom. Struktura podataka u YAML-u definiše se pomoću uvlačenja razmacima, što omogućava jasnu hijerarhiju podataka.
1 |
ime: John Doe |
Rečnici se definišu pomoću ključeva i vrednosti, sa uvlačenjem koje pokazuje koji ključevi pripadaju kojem rečniku.
1 2 3 |
osoba: ime: Jane Doe godine: 25 |
Liste se predstavljaju pomoću crtica sa jednim razmakom ispred svakog elementa liste.
1 2 3 4 |
voće: - Jabuka - Pomorandža - Banana |
Komentari u YAML-u počinju sa # i mogu biti postavljeni bilo gde u liniji.
1 2 |
# Ovo je komentar ključ: vrednost |
Primer
U ovome primeru je prikazan doker-compose.yml fajl sa uputstvima za aplikaciju sa dva servisa: frontend (Vue.js aplikacija) i backend (NestJS API):
1 2 3 4 5 6 7 8 9 10 11 12 |
version: '3' services: backend: build: ./backend ports: - "3000:3000" frontend: build: ./frontend ports: - "8080:8080" depends_on: - backend |
Gde je backend servis (NestJS API) opisan u DockerFile:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# Dockerfile za backend #Koristimo zvaničnu Node.js sliku verzije 18 kao osnovu za kreiranje novog kontejnera FROM node:18 # Postavljamo radni direktorijum unutar kontejnera na /app WORKDIR /app # Kopiramo package.json i package-lock.json u /app direktorijum COPY package*.json ./ # Instaliramo zavisnosti iz package.json RUN npm install # Kopiramo ostatak koda u /app COPY . . # Gradimo aplikaciju RUN npm run build # Pokrećemo aplikaciju koristeći npm run start:prod CMD ["npm", "run", "start:prod"] |
I frontend servis (Vue.js aplikacija) opisan u DockerFile:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# Dockerfile za frontend #Koristimo zvaničnu Node.js sliku verzije 18 kao osnovu za kreiranje novog kontejnera FROM node:18 # Postavljamo radni direktorijum unutar kontejnera na /app WORKDIR /app # Kopiramo package.json i package-lock.json u /app direktorijum COPY package*.json ./ # Instaliramo zavisnosti iz package.json RUN npm install # Kopiramo ostatak koda u /app COPY . . # Pokrećemo aplikaciju koristeći npm run serve CMD ["npm", "run", "serve"] |
Objašnjenje koraka
-
FROM node:18:
Koristi zvaničnu Node.js sliku verzije 18 kao osnovu za kreiranje novog kontejnera.
-
WORKDIR /app:
Postavlja radni direktorijum na /app. Ako direktorijum postavljen sa WORKDIR ne postoji, Docker ga automatski kreira.
- Sledeće naredbe u Dockerfile-u će se izvršavati relativno prema ovom direktorijumu.
- Na primer, ako naredba COPY . . sledi nakon WORKDIR /app, sve datoteke će biti kopirane u /app. COPY, ADD i druge naredbe koje koriste fajl ili direktorijum kao argument oslanjaju se na relativne puteve prema trenutnom radnom direktorijumu.
-
COPY package*.json ./:
Kopira package.json i package-lock.json iz trenutnog direktorijuma na hostu u trenutni radni direktorijum unutar kontejnera (/app).
- ./ ukazuje na radni direktorijum (postavljen sa WORKDIR).
-
RUN npm install:
Izvršava npm install unutar trenutnog radnog direktorijuma (/app).
- Instalira sve Node.js zavisnosti prema package.json.
-
COPY . .:
Kopira sav preostali kod iz trenutnog direktorijuma na hostu u trenutni radni direktorijum unutar kontejnera (/app).
-
CMD [“npm”, “start”]:
Postavlja komandnu liniju za pokretanje aplikacije koristeći npm start.
Struktura projekta:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
project │ ├── docker-compose.yml ├── backend │ ├── Dockerfile │ └── src │ └── main.ts │ └── package.json └── frontend ├── Dockerfile └── src └── main.js └── package.json |
Za pokretanje apilikacije je potrebno da se u terminalu “prebacimo” do lokacije projekta:
1 |
cd project |
A zatim pokrenemo Docker Compose na sledeći način:
1 |
docker-compose up -d |
Nakon čega možemo da pogledamo aplikaciju u pretraživaču:
1 |
http://localhost:8080 |