---
# System prepended metadata

title: 'MMOS 2025/26: Vježba 06'
tags: [MMOS_2526]

---

---
author: Matija Burić
---

### Mrežni i mobilni operacijski sustavi 2025/26

# Docker: Networking i Volumes

Ova vježba fokusira se na mrežu točnije docker mrežu te volumene kojima se podaci mogu sačuvati i nakon što kontejner nestane.


## Docker mreže

1. **None** 
2. **Bridge** 
3. **Host** 
4. **Overlay** 
5. **Custom** 

Svaka od ovih Docker mreža ima svoje karakteristike i primjene. 

- None (bez mreže):
    - Ova mreža ne dodjeljuje kontejneru nikakvu mrežnu konfiguraciju. Kontejner nema pristup vanjskoj mreži niti drugim kontejnerima.
    - Ovo je korisno kada želite potpunu izolaciju kontejnera od ostalog svijeta, u svrhu testiranja ili sigurnosti.

- Bridge (Izolirana mreža):

    - Bridge mreža je zadana mreža za kontejnere u Dockeru. Svaki kontejner povezan s ovom mrežom ima svoju unikatnu IP adresu unutar iste podmreže.
    - Kontejneri koji su članovi Bridge mreže mogu komunicirati međusobno pomoću IP adresa unutar iste podmreže, ali nisu dostupni izvan hosta osim ako nije konfiguriran port forwarding.
    - Ova mreža je često korištena za postavljanje različitih aplikacija unutar kontejnera na istom hostu.

- Host (Djeljena mreža):

    - U Host mreži, kontejneri dijele mrežnu konfiguraciju s host operativnim sustavom. To znači da kontejneri koriste istu IP adresu kao i host.
    - Ova mreža omogućava brzu i jednostavnu komunikaciju između kontejnera i hosta, ali kontejneri nisu izolirani i dijele istu mrežu s hostom.

- Overlay (Napredna mreža):

    - Overlay mreža omogućava komunikaciju između kontejnera koji se nalaze na različitim Docker hostovima (na različitim fizičkim računalima ili virtualnim strojevima).
    - Ova mreža se koristi za stvaranje distribuiranih aplikacija koje se temelje na mikroservisima, gdje različiti dijelovi aplikacije mogu biti raspoređeni na različite hostove.

- Custom (Prilagođena mreža):

    - Custom mreža je mreža koju možete konfigurirati prema vašim potrebama. Možete odabrati podmrežu, postaviti IP adrese, VLAN-ove i druge mrežne parametre.
    - Ova mreža je korisna kada imate specifične zahtjeve za mrežnu konfiguraciju i želite stvoriti prilagođenu mrežu za svoje kontejnere.

u okviru ovih vježbi obraditi ćemo prve tri budući da vježbe radimo na jednome računalu.

```graphviz
digraph hierarchy {
    nodesep=1
    node [fontsize=30, style="bold" fontname=arial,shape=box, color=blue, margin=0.2]
    "Docker Mreže"->{None[color=red] "Single Host" "Multi Host" }
    "Single Host"->{Bridge[color=red] Host[color=red] }
    "Multi Host" -> {Overlay }
}
```

### Pregled mreža putem CLI

```shell
$ docker network ls

NETWORK ID     NAME      DRIVER    SCOPE
f78ab30afc13   bridge    bridge    local
bd53266ab167   host      host      local
f6c080d8bffd   none      null      local
```

- detaljan pregled bridge mreže

```shell!
$ docker network inspect bridge
...
    "Name": "bridge",
    "Id": "f78ab30afc13e0948d1636b8edd1682...c5a77161c5f",
    "Created": "2023-10-16T08:58:42.456342842Z",
    "Scope": "local",
    "Driver": "bridge",
    "EnableIPv6": false,
...
    "IPAM": {"Driver": "default", "Options": null, "Config": [
                {   "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }]},
...
```

## Primjer umrežavanja kontejnera

- U nastavku će se kroz primjer izvršiti umrežavanje 5 kontejnera:
 
    1. Denholm
    2. Jen
    3. Roy
    4. Moss
    5. Richmond

Pri čemu će se prvi postaviti u Host mrežu, drugi, treći i četvrti u zasebnu Bridge mrežu a zadnji kontejner u None mrežu.

```graphviz
digraph hierarchy {
    nodesep=1
    node [fontsize=20, style="bold" fontname=arial,shape=box, margin=0.2];
    { rank=same HostMreza Internet }
    { rank=same  DefaultB ITcrowdBridge NoneMreza }
    
    HostMreza [ label=<
   <table border="0" cellborder="0" cellspacing="1">
     <tr><td align="left"><b>Host mreža</b></td></tr>
     <tr><td align="left"><br></br></td></tr>
     <tr><td align="left"><br></br></td></tr>
   </table>>];
   
   DefaultB [ label=<
   <table border="0" cellborder="0" cellspacing="1">
     <tr><td align="left"><b>Default Bridge  </b></td></tr>
     <tr><td align="left"><br></br></td></tr>
     <tr><td align="left"><br></br></td></tr>
     <tr><td align="left"><br></br></td></tr>
     <tr><td align="left"><br></br></td></tr>
     <tr><td align="left"><br></br></td></tr>
   </table>>];
   
   NoneMreza [ label=<
   <table border="0" cellborder="0" cellspacing="1">
     <tr><td align="left"><b>None mreža</b></td></tr>
     <tr><td align="left"><br></br></td></tr>
   </table>>];
   
   Internet [ shape=ellipse label=<
   <table border="0" cellborder="0" cellspacing="1">
     <tr><td align="left"><b>INTERNET</b></td></tr>
   </table>>];
   
   
   ITcrowdBridge [ style=dotted color=red line=none label=<
   <table border="0" cellborder="0" cellspacing="1">
     <tr><td align="left">* Denholm</td></tr>
     <tr><td align="left">* Jen</td></tr>
     <tr><td align="left">* Roy</td></tr>
     <tr><td align="left">* Moss</td></tr>
     <tr><td align="left">* Richmond</td></tr>
   </table>>];
    
    HostMreza -> Internet[arrowhead=none, penwidth=3]
    HostMreza -> DefaultB[arrowhead=none, penwidth=3]
    
    
}
```

### Prvi korak

- potrebno je izraditi kontejnere

```shell!
$ docker run --name Jen --network bridge -d nginx
```

ili

```shell!
$ docker run --name Jen -d nginx
```

- u oba slučaja će kontejner Jen biti spojen u Default Bridge mrežu. 
- kako bi provjerili je li kontejner spojen koristite slijedeću naredbu:

```shell
$ docker network inspect bridge
...
"Containers": {
            "6ce3a047982badd4d6265e2f4a5ef7ac8af5308a...406": {
                "Name": "Jen",
                "EndpointID": "2f42e806034fa474321628...9f1710f",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            },
...
```

- na isti način spojite i ostale kontejnere.

```shell!
$ docker run --name Roy -d nginx
$ docker run --name Denholm -d nginx
$ docker run --name Richmond -d nginx
$ docker run --name Moss -d nginx
```

- te provjerite jesu li spojeni u Default Bridge mrežu

```shell
$ docker network inspect bridge |grep 'Name\|IPv4'
                "Name": "Jen",
                "IPv4Address": "172.17.0.2/16",
                "Name": "Moss",
                "IPv4Address": "172.17.0.6/16",
                "Name": "Richmond",
                "IPv4Address": "172.17.0.5/16",
                "Name": "Denholm",
                "IPv4Address": "172.17.0.4/16",
                "Name": "Roy",
                "IPv4Address": "172.17.0.3/16",
```


```graphviz
digraph hierarchy {
    nodesep=1
    node [fontsize=20, style="bold" fontname=arial,shape=box, margin=0.2];
    { rank=same HostMreza Internet }
    { rank=same  DefaultB  NoneMreza }
    
    HostMreza [ label=<
   <table border="0" cellborder="0" cellspacing="1">
     <tr><td align="left"><b>Host mreža</b></td></tr>
     <tr><td align="left"><br></br></td></tr>
     <tr><td align="left"><br></br></td></tr>
   </table>>];
   
   DefaultB [ label=<
   <table border="0" cellborder="0" cellspacing="1">
     <tr><td align="left"><b>Default Bridge  </b></td></tr>
     <tr><td align="left">* Denholm</td></tr>
     <tr><td align="left">* Jen</td></tr>
     <tr><td align="left">* Roy</td></tr>
     <tr><td align="left">* Moss</td></tr>
     <tr><td align="left">* Richmond</td></tr>
   </table>>];
   
   NoneMreza [ label=<
   <table border="0" cellborder="0" cellspacing="1">
     <tr><td align="left"><b>None mreža</b></td></tr>
     <tr><td align="left"><br></br></td></tr>
   </table>>];
   
   Internet [ shape=ellipse label=<
   <table border="0" cellborder="0" cellspacing="1">
     <tr><td align="left"><b>INTERNET</b></td></tr>
   </table>>];
   

    HostMreza -> Internet[arrowhead=none, penwidth=3]
    HostMreza -> DefaultB[arrowhead=none, penwidth=3]
    
    
}
```

### Drugi korak

- iz prethodne naredbe mogu se očitati IP adrese pojedinog kontejnera. Kako bi se testirala mreža može se koristiti naredba ping s hosta prema kontejeneru Jen koji ima adresu 172.17.0.2.

```shell
$ ping 172.17.0.2

PING 172.17.0.2 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.178 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.082 ms
...
```

- radi li ping s kontejnera prema hostu?


```shell
$ docker exec -it Jen bash
> root@6ce3a047982b:/# ping 172.17.0.1
bash: ping: command not found
```
:::info
- budući da nginx image ne sadrži ping alat potrebno ga je instalirati.

```shell
> root@6ce3a047982b:/# apt-get update
...
> root@6ce3a047982b:/# apt-get install iputils-ping -y
...
```
:::

```shell
> root@6ce3a047982b:/# ping 172.17.0.1
PING 172.17.0.1 (172.17.0.1) 56(84) bytes of data.
64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=0.102 ms
...
```
- radi li konekcija prema ostalim kontejnerima? 
    - budući da u sebi imaju integrirani web server za testiranje koristimo naredbu curl koja vraća sadržaj stranice web servera.

:::info

- **curl** je naredba u Unix-like operativnim sustavima koja se koristi za preuzimanje sadržaja sa web servera putem HTTP, HTTPS, FTP i drugih protokola. Ova naredba omogućuje korisnicima da dobiju podatke s web stranica, web servisa ili drugih udaljenih izvora direktno iz terminala. Primjer upotrebe **curl** naredbe:

```shell
$ curl https://www.example.com
```

- Ovom naredbom, **curl** će preuzeti sadržaj web stranice "https://www.example.com" i ispisati ga u terminalu. **curl** podržava mnoge opcije i može se koristiti za slanje HTTP zahtjeva, preuzimanje datoteka, testiranje API-ja i još mnogo toga. To je koristan alat za administratore sustava, programere i sve koji trebaju interagirati s web servisima iz terminala.
:::

```shell!
> root@6ce3a047982b:/# curl 172.17.0.3

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
```

- radi li konekcija kada se koristi ime umjesto ip adrese?

```shell
$ docker network inspect bridge |grep
...
                "Name": "Roy",
                "IPv4Address": "172.17.0.3/16",
...
```
```shell!
> root@6ce3a047982b:/# curl Roy

curl: (6) Could not resolve host: Roy
```

:::info
- zašto ne radi konekcija imenom nego samo ip adresom?
    - kako se ne bi smanjila sigurnost kontejnera.
:::

- pogledajmo sadržaj hosts i resolv.conf datoteka

:::info
**/etc/hosts:**

- je lokalna tekstualna datoteka na Unix-sličnim operacijskim sustavima koja povezuje imena računala s IP adresama.
- Unosi u datoteci /etc/hosts imaju prednost nad DNS-om prilikom rješavanja imena računala, što znači da ako se ime računala nalazi u ovoj datoteci, sustav će koristiti odgovarajuću IP adresu bez traženja vanjskog DNS poslužitelja.

**/etc/resolv.conf:**

- je konfiguracijska datoteka na Unix-sličnim sustavima koja služi za specificiranje DNS (Domain Name System) informacija, kao što su IP adrese DNS poslužitelja i domene pretrage.
Obično je generirana i upravljana alatima za konfiguraciju mreže te može ukazivati na DNS poslužitelje koje pruža vaš Internet pružatelj usluga (ISP) ili druge konfigurirane DNS poslužitelje.

:::

```shell!
> root@6ce3a047982b:/# cat /etc/hosts

127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2      6ce3a047982b
```

- u hosts datoteci se nalazi putanja za localhost i ip6 adrese koje se ne koriste

```shell!
> root@6ce3a047982b:/# cat /etc/resolv.conf

search 51ur3jppi0eupdptvsj42kdvgc.bx.internal.cloudapp.net
options ndots:0
nameserver 8.8.8.8
nameserver 8.8.4.4
```

- resolv.conf datoteka sadrži DNS za internet adrese ali ne i lokalni DNS.

:::info
znate li čiji su DNS 8.8.8.8 i 8.8.4.4?
:::

### Treći korak

- u ovom koraku će se izgraditi nova Bridge mreža s imenom ITcrowd te će se Jen, Roy i Moss prebaciti u novu mrežu.

```graphviz
digraph hierarchy {
    nodesep=1
    node [fontsize=20, style="bold" fontname=arial,shape=box, margin=0.2];
    { rank=same HostMreza Internet }
    { rank=same NoneMreza DefaultB ITcrowdBridge }
    
    HostMreza [ label=<
   <table border="0" cellborder="0" cellspacing="1">
     <tr><td align="left"><b>Host mreža</b></td></tr>
     <tr><td align="left"><br></br></td></tr>
     <tr><td align="left"><br></br></td></tr>
   </table>>];
   
   DefaultB [ label=<
   <table border="0" cellborder="0" cellspacing="1">
     <tr><td align="left"><b>Default Bridge  </b></td></tr>
     <tr><td align="left">* Denholm</td></tr>
     <tr><td align="left">* Richmond</td></tr>
     <tr><td align="left"><br></br></td></tr>
     <tr><td align="left"><br></br></td></tr>
     <tr><td align="left"><br></br></td></tr>
   </table>>];
   
   NoneMreza [ label=<
   <table border="0" cellborder="0" cellspacing="1">
     <tr><td align="left"><b>None mreža</b></td></tr>
     <tr><td align="left"><br></br></td></tr>
   </table>>];
   
   Internet [ shape=ellipse label=<
   <table border="0" cellborder="0" cellspacing="1">
     <tr><td align="left"><b>INTERNET</b></td></tr>
   </table>>];
   
   
   ITcrowdBridge [ label=<
   <table border="0" cellborder="0" cellspacing="1">
     <tr><td align="left"><b>ITcrowd mreža  </b></td></tr>
     <tr><td align="left">* Jen</td></tr>
     <tr><td align="left">* Roy</td></tr>
     <tr><td align="left">* Moss</td></tr>
     <tr><td align="left"><br></br></td></tr>
     <tr><td align="left"><br></br></td></tr>
   </table>>];
    
    HostMreza -> Internet[arrowhead=none, penwidth=3]
    HostMreza -> DefaultB[arrowhead=none, penwidth=3]
    HostMreza -> ITcrowdBridge[arrowhead=none, penwidth=3]
    
}
```

- Prvo je potrebno kreirati mrežu


```shell!
$ docker network create ITcrowd
```

- provjerite je li kreirana nova mreža te njen tip

```shell!
$ docker network ls

NETWORK ID     NAME      DRIVER    SCOPE
1164a74a2db0   ITcrowd   bridge    local
f78ab30afc13   bridge    bridge    local
bd53266ab167   host      host      local
f6c080d8bffd   none      null      local
```

#### kako se spojiti na novu mrežu?

- odspojiti se od postojeće mreže pa se spojiti na novu

```shell!
$ docker network disconnect bridge Jen
$ docker network connect ITcrowd Jen
```

- ili izbrisati kontejner i napraviti novi koji se odmah spaja na mrežu
    
```shell!
$ docker stop Jen
$ docker rm Jen
$ docker run --name Jen --network ITcrowd -d nginx
```

- provjerimo radi li i dalje veza ip adresom

```shell!
> root@dd617949079d:/# curl http://172.17.0.3
```

Zašto ne radi? Što se promjenilo?

```shell
$ docker network inspect ITcrowd |grep 'Name\|IPv4'

        "Name": "ITcrowd",
                "Name": "Moss",
                "IPv4Address": "172.19.0.4/16",
                "Name": "Jen",
                "IPv4Address": "172.19.0.2/16",
                "Name": "Roy",
                "IPv4Address": "172.19.0.3/16",
```

- primjetite da se podmreža promijenila. pokušajte sa novom ip adresom.


```shell
> root@dd617949079d:/# curl 172.19.0.3
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
...
```

- radi li sada korištenjem imena umjesto ip adrese?

```shell
$ docker exec -it Jen bash
> root@dd617949079d:/# curl Roy
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
...
```

- pogledajmo je li se promijenio DNS u kontejneru.

```shell
> root@dd617949079d:/# cat /etc/resolv.conf
search 51ur3jppi0eupdptvsj42kdvgc.bx.internal.cloudapp.net
nameserver 127.0.0.11
options ndots:0
```
:::info
## kako se spojiti u kontejner koristeći adresu hosta?

- `-p` flag u docker `run naredbi` koristi se za mapiranje portova između host operativnog sustava i kontejnera. To omogućava komunikaciju između hosta i kontejnera preko određenih mrežnih portova. Flag `-p` ima dva argumenta: **<host-port>:<container-port>**.

    - **<host-port>** predstavlja port na hostu (tj. vašem računalu), dok
    - **<container-port>** predstavlja port unutar kontejnera. Na taj način možete usmjeriti promet sa specifičnog porta na hostu prema odgovarajućem portu unutar kontejnera.

Primjer:

```shell
docker run -p 8080:80 my-web-app
```
- U ovom primjeru, my-web-app kontejner će biti pokrenut, a port 80 unutar kontejnera bit će mapiran na port 8080 na hostu. To znači da ako pristupite hostu putem web preglednika na adresi http://localhost:8080, zahtjevi će biti preusmjereni na kontejner na portu 80, gdje se može nalaziti web aplikacija.

- Ovaj flag je posebno koristan kada želite hostirati više kontejnera na istom hostu, svaki s različitim web aplikacijama, a da se ne bi sukobljali na istom portu. Mapiranjem portova možete imati više kontejnera koji koriste port 80, svaki sa svojim vlastitim host portom.
:::

- pokušajmo sada rekreirati kontejnere koristeći `-p` flag

```shell!
$ docker run --name Jen --network ITcrowd -d -p 8080:80 nginx
```
```shell!
$ docker run --name Roy --network ITcrowd -d -p 8081:80 nginx
```
```shell!
$ docker run --name Moss --network ITcrowd -d -p 8082:80 nginx
```

- Kako sada izgledaju kontejneri. obratite pažnju na **<host-port>**

```shell!
$ docker ps
CONTAINER ID  IMAGE  ...   PORTS                  NAMES
b12e6b635935  nginx  ...   80/tcp                 Richmond
2acfacc0a904  nginx  ...   80/tcp                 Denholm
93a01e571495  nginx  ...   0.0.0.0:8082->80/tcp   Moss
254b953296af  nginx  ...   0.0.0.0:8081->80/tcp   Roy
820953e87ede  nginx  ...   0.0.0.0:8080->80/tcp   Jen
```

- provjerimo radi li konekcija adrsom hosta i dodjeljnim portom


```shell
$ curl 0.0.0.0:8080
<!DOCTYPE html>
<html>
<head>
...
```

```shell
$ curl 127.0.0.1:8080
<!DOCTYPE html>
<html>
<head>
...
```

```shell
$ curl localhost:8080
<!DOCTYPE html>
<html>
<head>
...
```

### Četvrti korak
    
- na isti način kao i prije možemo odspojiti se s mreže i spojit se na drugu ili rekreirati novi kontejner dirketno u mrežu.

```shell
$ docker network disconnect bridge Richmond
$ docker network connect none Richmond
```
```shell!
$ docker stop Denholm
$ docker rm Denholm
$ docker run --name Denholm --network host -d nginx
```

```graphviz
digraph hierarchy {
    nodesep=1
    node [fontsize=20, style="bold" fontname=arial,shape=box, margin=0.2];
    { rank=same HostMreza Internet }
    { rank=same NoneMreza DefaultB ITcrowdBridge }
    
    HostMreza [ label=<
   <table border="0" cellborder="0" cellspacing="1">
     <tr><td align="left"><b>Host mreža</b></td></tr>
     <tr><td align="left">* Denholm</td></tr>
     <tr><td align="left"><br></br></td></tr>
   </table>>];
   
   DefaultB [ label=<
   <table border="0" cellborder="0" cellspacing="1">
     <tr><td align="left"><b>Default Bridge  </b></td></tr>
     <tr><td align="left"><br></br></td></tr>
     <tr><td align="left"><br></br></td></tr>
     <tr><td align="left"><br></br></td></tr>
     <tr><td align="left"><br></br></td></tr>
     <tr><td align="left"><br></br></td></tr>
   </table>>];
   
   NoneMreza [ label=<
   <table border="0" cellborder="0" cellspacing="1">
     <tr><td align="left"><b>None mreža</b></td></tr>
     <tr><td align="left">* Richmond</td></tr>
   </table>>];
   
   Internet [ shape=ellipse label=<
   <table border="0" cellborder="0" cellspacing="1">
     <tr><td align="left"><b>INTERNET</b></td></tr>
   </table>>];
   
   
   ITcrowdBridge [ label=<
   <table border="0" cellborder="0" cellspacing="1">
     <tr><td align="left"><b>ITcrowd mreža  </b></td></tr>
     <tr><td align="left">* Jen</td></tr>
     <tr><td align="left">* Roy</td></tr>
     <tr><td align="left">* Moss</td></tr>
     <tr><td align="left"><br></br></td></tr>
     <tr><td align="left"><br></br></td></tr>
   </table>>];
    
    HostMreza -> Internet[arrowhead=none, penwidth=3]
    HostMreza -> DefaultB[arrowhead=none, penwidth=3]
    HostMreza -> ITcrowdBridge[arrowhead=none, penwidth=3]
    
}
```

- provjerimo radi li konekcija korištenjem host mreže
- promijenimo sadržaj index.html dokumneta da vrati sadržaj koji nam odgovara

```shell!
$ docker exec -it Denholm bash
> cd /usr/share/nginx/html
> echo "ovo je Denholm kojeg zovem sa hosta" > index.html
> exit

$ curl localhost
ovo je Denholm kojeg zovem sa hosta
```

:::info

- navedena linija `> echo "ovo je Denholm kojeg zovem sa hosta" > index.html` ispisuje poruku korištenjem echo naredbe i preusmjerava ju u dokumnet index.html pri čemu prepisuje sadržaj datoteke.

:::

- koju ip adresu imaju kontejeneri


```shell!
$ docker inspect Jen |grep "IPAddress"
            "IPAddress": "",
                    "IPAddress": "172.19.0.2",
                    
$ docker inspect Denholm |grep "IPAddress"
            "IPAddress": "",
                    "IPAddress": "",
                    
$ docker inspect Richmond |grep "IPAddress"
            "IPAddress": "",
                    "IPAddress": "",
```

- pogledajmo kojoj mreži pripadaju kontejneri

```shell!
$ docker inspect Jen |grep -A 1 "Networks"
            "Networks": {
                "ITcrowd": {
                
$ docker inspect Denholm |grep -A 1 "Networks"
            "Networks": {
                "host": {
                
$ docker inspect Richmond |grep -A 1 "Networks"
            "Networks": {
                "none": {
```

#### Peti korak


- pogledajmo `ip addr` i `ifconfig` hosta

- prije

```shell
$ ip addr |grep inet
 inet 127.0.0.1/8 scope host lo
 inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
 inet 192.168.0.28/23 scope global eth0
 inet 172.18.0.57/16 scope global eth1
```
```shell!
$ ifconfig |grep Link
docker0   Link encap:Ethernet  HWaddr 02:42:7D:41:BE:C8
eth0      Link encap:Ethernet  HWaddr A6:A4:92:00:88:95
eth1      Link encap:Ethernet  HWaddr 02:42:AC:12:00:39
lo        Link encap:Local Loopback
```

- sada

```shell!
$ ip addr |grep inet
 inet 127.0.0.1/8 scope host lo
 inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
 inet 172.19.0.1/16 brd 172.19.255.255 scope global br-41b87dedcddf
 inet 192.168.0.28/23 scope global eth0
 inet 172.18.0.57/16 scope global eth1
```

```shell!
$ ifconfig |grep Link
br-41b87dedcddf Link encap:Ethernet  HWaddr 02:42:4E:4C:33:62
docker0   Link encap:Ethernet  HWaddr 02:42:7D:41:BE:C8
eth0      Link encap:Ethernet  HWaddr A6:A4:92:00:88:95
eth1      Link encap:Ethernet  HWaddr 02:42:AC:12:00:39
lo        Link encap:Local Loopback
veth984bbb6 Link encap:Ethernet  HWaddr 62:DD:61:BE:25:B4
vethcd178c6 Link encap:Ethernet  HWaddr 22:F0:17:79:FA:89
vetheed5061 Link encap:Ethernet  HWaddr 6A:9D:85:3B:84:B7
```

- možete li zaključiti koji su novi mrežni interface-i i na što su povezani.

:::info
- novonastala ITcrowd mreža je br-41b87dedcddf, a veth* sučelja su sučelja Jen, Roy i Moss kontejenra koji imaju svoje adrese.

:::



## Što su Docker volumes?

- Svrha korištenja Docker volumes je pohraniti podatke izvan kontejnera kako bi se mogli sigurnosno kopirati ili dijeliti.

- Docker volumes su ovisni o Docker file sustavu i predstavljaju poželjni način pohrane podataka za Docker kontejnere i servise. Kada se kontejner pokrene, Docker učitava sloj samo za čitanje slike, dodaje sloj za čitanje i pisanje na vrh slike i montira volumes na file sustav kontejnera.


## Zašto koristiti Docker Volumene?

- Ako koristite Docker za razvoj, morate biti upoznati s opcijom `-v` ili `--volume` koja omogućuje da montirate svoje lokalne datoteke u kontejner. Na primjer, možete montirati svoj lokalni direktorij `
./target` na direktorij `/usr/share/nginx/html` u kontejneru ili u kontejneru s nginxom kako biste vizualizirali svoje HTML datoteke.

```shell!
$ echo "<h1>Hello from Host</h1>" > ./target/index.html
$ docker run -it --rm --name nginx -p 8080:80 -v "$(pwd)"/target:/usr/share/nginx/html nginx
```

- sada otvorite poveznicu `http://localhost:8080/` i trebali bi vidjeti sadržaj vašeg prvog volume-a.

- Ovo se naziva bind mount i često se koristi od strane programera. Međutim, ako koristite Docker Desktop na sustavima Windows ili MacOS, bind mountovi imaju značajne probleme s performansama. Kao rezultat toga, upotreba volumena može biti najbolja alternativa za očuvanje stanja između pokretanja kontejnera.

- Za razliku od bind mountova, gdje možete montirati bilo koji direktorij s vašeg domaćina, volumeni se pohranjuju na jednom mjestu (vjerojatno /var/lib/docker/volumes/ na Unix sustavima) i značajno olakšavaju upravljanje podacima (sigurnosno kopiranje, vraćanje i migracija). Docker volumeni se mogu sigurno dijeliti između nekoliko pokrenutih kontejnera.

## Stvaranje i Upravljanje Docker Volumenima

- U ovoj dijelu vježbi, naučit ćete kako implicitno i eksplicitno stvoriti Docker volumen te ga zatim deklarirati iz Docker datoteke. Zatim ćete naučiti kako pregledati data volumen i montirati ga na kontejner.

### Implicitno Stvaranje Docker Volumena

- Najjednostavniji način za stvaranje i upotrebu volumena je korištenje docker run naredbe i zastavice `-v` ili `--volume`. Ova zastava prima tri argumenta odvojena znakom `:`.

```shell!
-v <source>:<destination>:<options>
```
- Ako je "source" putanja koja je korištena u prethodnom primjeru, Docker će koristiti volume binding. Ako je "source" ime, tada Docker pokušava pronaći taj volumen ili ga stvara ako nije pronađen. Niže je prikazan ažurirani prethodni primjer koji koristi volumen umjesto vezivanja za montiranje:

```shell!
$ docker run -it --rm --name nginx -p 8080:80 -v moj-volume:/usr/share/nginx/html nginx
```

- Možete provjeriti je li spremnik pravilno stvoren koristeći `$docker volume ls`
koji će izlistati sve postojeće volumene.

```shell
$ docker volume ls
DRIVER    VOLUME NAME
local     moj-volume
```

- Možete provjeriti status vaših volumena na Linuxu. To vam omogućava da vidite gdje se volumeni nalaze:

```shell
$ ls /var/lib/docker/volumes/moj-volume/_data
50x.html    index.html
```

- Na Mac i Windows OS-ima je malo složenije. Kako biste stvari pojednostavili, možete montirati volumen na kontejner s Ubuntu i koristiti naredbu "ls" kako biste vidjeli sadržaj svog volumena:

```shell
$ docker run -it --rm -v moj-volume:/opt/moj-volume ubuntu ls /opt/moj-volume
50x.html  index.html
```

### Stvorite Docker volumen eksplicitno

- Alternativno, možete koristiti naredbu "docker volume create" kako biste eksplicitno stvorili podatkovni volumen. Ova naredba omogućava vam da odaberete i konfigurirate vozača za volumen. Implicitno stvaranje volumena uvijek koristi lokalnog vozača s zadanim postavkama. 

```shell
$ docker volume create --name moj-2volume
```

### Deklarirajte Docker volumen iz Dockerfile-a

- Volumeni se mogu deklarirati u vašem Dockerfile-u koristeći `VOLUME` naredbu. Ova naredba deklarira da određeni put kontejnera mora biti montiran na Docker volumen. Kada pokrenete kontejner, Docker će stvoriti anonimni volumen (volumen s jedinstvenim ID-em kao imenom) i montirati ga na određeni put.

```dockerfile
FROM nginx:latest
RUN echo "<h1>Pozdrav od tvog volume-a</h1>" > /usr/share/nginx/html/index.html
VOLUME /usr/share/nginx/html
```

- Izgradimo i pokrenimo vašu novu sliku:

```shell
$ docker build -t moj-volume-image .
$ docker run -p 8081:80 moj-volume-image
```

- Sada možete provjeriti da nginx prikazuje vašu poruku na [http://localhost:8081/](http://localhost:8081/).

- Važnije, stvoren je anonimni Docker volumen, i svaki put kad pokrenete novi kontejner, stvori se još jedan volumen s sadržajem `/usr/share/nginx/html`.


### pregled Volume-a

- Da biste upravljali svojim podacima, ponekad trebate izlistati podatkovne volume s naredbenog retka kao referencu, što je brže od ponovnog provjeravanja konfiguracijskih datoteka. Možete koristiti naredbu `docker volume ls` za pregled popisa podatkovnih volumena.

```shell
$ docker volume ls
DRIVER    VOLUME NAME
local     fb77b01385aa706f1764bd9f4cc3317815b6de5ac942f7cb49d4ca5666459401
local     moj-volume
```

- detaljnini pregled:

```shell
$ docker volume inspect moj-volume
[
    {
        "CreatedAt": "2023-10-30T19:37:03Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/moj-volume/_data",
        "Name": "moj-volume",
        "Options": null,
        "Scope": "local"
    }
]

```

### Dodjeljivanje Volume kontejneru

- Kao što ste vidjeli kroz različite primjere, `-v` i `--volume` su najčešći način za montiranje volumena na kontejner koristeći sintaksu:

```shell
-v <name>:<destination>:<options>
```
- Jedna značajna opcija je `ro`, što znači da će volumen biti montiran samo za čitanje:

```shell
$ docker run -it -v moj-3volume:/data:ro ubuntu
```
- Pokušajte zapisati u folder/data kako biste provjerili je li volumen u načinu samo za čitanje:

```shell
echo "test" > /data/test
```

- Alternativa za `-v` je dodati opciju `--mount` naredbi docker run. `--mount` je detaljnija verzija `-v`.

- Za pokretanje kontejnera i montiranje podatkovnog volumena, slijedite ovu sintaksu:

```shell
docker run --mount source=[volume_name],destination=[path_in_container] [docker_image]
```

- npr.

```shell
$ docker run --rm -it --mount source=moj-4volume,destination=/tu-je-volume ubuntu
```

- Sjetite se, ako volumen ne postoji, Docker će ga automatski stvoriti za vas.

- Ispisujte sadržaj kontejnera kako biste provjerili je li volumen uspješno pričvršćen. Trebali biste pronaći naziv Docker volumena definiran u prethodnom sintaksnom podacima.

```shell
$ docker run --rm -it --mount source=moj-4volume,destination=/tu-je-volume ubuntu
root@f29ed57bc271:/# ls
bin   dev  home  lib32  libx32  mnt  proc  run   srv  tmp           usr
boot  etc  lib   lib64  media   opt  root  sbin  sys  tu-je-volume  var
```

### Kopiranje podatake između kontejnera

- Pogledajmo kako Docker volumeni omogućavaju dijeljenje datoteka između kontejnera.

- U ovom primjeru koristit ćemo prethodno definirani volumen i kontejner te izvršiti sljedeće naredbe:

```shell
$ docker run -it --name=v_kon_1 --mount source=moj-5volume,destination=/data ubuntu
root@f30f5b8dedef:/# touch /data/ovo_je_dokument_u_volume
root@f30f5b8dedef:/# exit

$ docker run -it --name=v_kon_2 --mount source=moj-5volume,destination=/data ubuntu
root@8bbf9c809e41:/# ls /data
ovo_je_dokument_u_volume
```