ЁЯПл The SchoolтА║ЁЯН▒ DockerтА║ЁЯзКЁЯУЮ рдзрдбрд╛ 05 тАФ Volumes рдЖрдгрд┐ networks: рд╕рд╛рдорд╛рдпрд┐рдХ fridge рдЖрдгрд┐ intercom
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯзКЁЯУЮ рдзрдбрд╛ 05 тАФ Volumes рдЖрдгрд┐ networks: рд╕рд╛рдорд╛рдпрд┐рдХ fridge рдЖрдгрд┐ intercom

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 05 ┬╖ рдорд╛рдЧреЗ: lesson-04-run-containers ┬╖ рдкреБрдвреЗ: lesson-06-docker-compose


ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ

рдзрдбреЗ 01тАУ04, рдЖрдгрд┐ рддреНрдпрд╛рд╢рд┐рд╡рд╛рдп: рдлреЗрдХреВрди рджреЗрдгреНрдпрд╛рд╕рд╛рд░рдЦреНрдпрд╛ containers рдирдВрддрд░рд╣реА data рдХрд╕рд╛ рдЯрд┐рдХрддреЛ (volumes), рдЖрдгрд┐ containers рдПрдХрдореЗрдХрд╛рдВрдирд╛ рдХрд╕реЗ рд╢реЛрдзрддрд╛рдд (networks). рдЦрд░реА file:

ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ

рдЬреЗрд╡рдгрд╛рдЪреНрдпрд╛ рд╡реЗрд│реЗрддрд▓реЗ рджреЛрди рдкреНрд░рд╢реНрди:

рдкреНрд░рд╢реНрди 1: рдбрдмрд╛ рд╡рд┐рд╕рд░рддреЛ. ЁЯза рдзрдбрд╛ 04 "рдирд╡рд╛ рдбрдмрд╛, рддрд╛рдЬреА рд╕реНрдореГрддреА" рдиреЗ рд╕рдВрдкрд▓рд╛ тАФ visit counter рд╢реВрдиреНрдпрд╛рд╡рд░ рдЧреЗрд▓рд╛. ре▓рдкреНрд╕рд╕рд╛рдареА рдареАрдХ, databases рд╕рд╛рдареА рд╕рд░реНрд╡рдирд╛рд╢! рдЙрдкрд╛рдп: рд╕рд╛рдорд╛рдпрд┐рдХ fridge ЁЯзК (рдПрдХ volume). Fridge рдбрдмреНрдпрд╛рдВрдЪреНрдпрд╛ рдмрд╛рд╣реЗрд░ рдЙрднрд╛ рдЕрд╕рддреЛ. рдбрдмрд╛ рдЖрдкрд▓реЗ рдЙрд░рд▓реЗрд▓реЗ рдЕрдиреНрди fridge рдордзреНрдпреЗ рдареЗрд╡рддреЛ; рдбрдмрд╛ рдлреЗрдХреВрди рджрд┐рд▓рд╛ рдЬрд╛рддреЛ; рдкреБрдврдЪрд╛ рдбрдмрд╛ рддреЛрдЪ fridge рдЙрдШрдбрддреЛ тАФ рдЙрд░рд▓реЗрд▓реЗ рдЕрдиреНрди рдЕрдЬреВрди рддрд┐рдереЗрдЪ. Fridge рдбрдмреНрдпрд╛рдВрдирдВрддрд░рд╣реА рдЯрд┐рдХрддрд╛рдд. (рдУрд│рдЦреАрдЪреЗ рд╡рд╛рдЯрддреЗ? k8s рдХреЛрд░реНрд╕ рд╣реАрдЪ рдЧреЛрд╖реНрдЯ PVCs рд╕реЛрдмрдд рд╕рд╛рдВрдЧрддреЛ тАФ рджрдкреНрддрд░ рд╡рд┐рд░реБрджреНрдз рдЧреНрд░рдВрдерд╛рд▓рдпрд╛рдЪреА рдлрд│реА. рддреЗрдЪ рднреМрддрд┐рдХрд╢рд╛рд╕реНрддреНрд░.)

рдкреНрд░рд╢реНрди 2: рдбрдмреНрдпрд╛рдВрдирд╛ рдПрдХрдореЗрдХрд╛рдВрдЪреЗ рдРрдХреВ рдпреЗрдд рдирд╛рд╣реА. рдкреНрд░рддреНрдпреЗрдХ рдбрдмрд╛ рдЖрдкрд▓реНрдпрд╛ рдЦрд╛рдЬрдЧреА рдЯреЗрдмрд▓рд╡рд░ рдЬреЗрд╡рддреЛ. proxy рдбрдмреНрдпрд╛рд▓рд╛ app рдбрдмреНрдпрд╛рд▓рд╛ рдмреЛрд▓рд╛рд╡рддрд╛ рдпрд╛рд╡реЗ рдореНрд╣рдгреВрди рджреЛрдШрд╛рдВрдиреА рдПрдХрд╛рдЪ intercom system ЁЯУЮ (рдПрдХрд╛ network) рдордзреНрдпреЗ рд╕рд╛рдореАрд▓ рд╡реНрд╣рд╛рдпрд▓рд╛ рд╣рд╡реЗ. рдЖрдгрд┐ рдЗрдереЗ рд╕реБрдВрджрд░ рднрд╛рдЧ: рд╕рд╛рдорд╛рдпрд┐рдХ network рд╡рд░ рдбрдмреЗ рдПрдХрдореЗрдХрд╛рдВрдирд╛ рдирд╛рд╡рд╛рдиреЗ рдмреЛрд▓рд╛рд╡рддрд╛рдд тАФ http://web:3000 тАФ IP рдиреЗ рдирд╛рд╣реА. рдирд╛рд╡реЗ рдЯрд┐рдХрддрд╛рдд; IPs рдорд╢реАрдирд╕рд╛рдареА рдЕрд╕рддрд╛рдд.

рдЖрдгрд┐ developers рд╕рд╛рдареА рддрд┐рд╕рд░реА рдпреБрдХреНрддреА: bind mount ЁЯУВ тАФ laptop рд╡рд░рдЪрд╛ folder рдбрдмреНрдпрд╛рд▓рд╛ рдЬреЛрдбрд╛ (-v $PWD/app:/app). File рддреБрдордЪреНрдпрд╛ laptop рд╡рд░ рдмрджрд▓рд╛; рдбрдмреНрдпрд╛рд▓рд╛ рддреА рд▓рдЧреЗрдЪ рджрд┐рд╕рддреЗ. рдзрдбрд╛ 01 рдЪреА рдЕрдЧрджреА рдкрд╣рд┐рд▓реА command рдЕрд╢реАрдЪ рдЪрд╛рд▓рд▓реА рд╣реЛрддреА!

ЁЯЧ║я╕П рдЖрдХреГрддреА

flowchart LR
    subgraph net["ЁЯУЮ network 'lunchnet' - the intercom"]
        w["ЁЯУж web<br/>the app"]
        p["ЁЯУж proxy<br/>calls http://web:3000"]
        p -->|"1 by NAME, not IP"| w
    end
    v["ЁЯзК volume - the fridge<br/>outside every box<br/>survives docker rm"]
    lap["ЁЯУВ bind mount<br/>laptop folder clipped in<br/>live-edit code"]
    w -.->|"2 leftovers persist"| v
    lap -.->|"3 for development"| w

тЭУ рдХрд╛рдп

ЁЯза Data рд░рд╛рд╣реВ рд╢рдХрддреЛ рдЕрд╢рд╛ рддреАрди рдЬрд╛рдЧрд╛

Container writable layer  тЖТ disposable; dies with docker rm
Named volume              тЖТ Docker-managed, persistent (survives rm)
Bind mount                тЖТ host directory тЖФ container (live editing)

Container рдХрд╛рдврд▓реНрдпрд╛рдиреЗ named volume рдХрд╛рдврд▓рд╛ рдЬрд╛рдд рдирд╛рд╣реА тАФ рдлрдХреНрдд docker volume rm (рдХрд┐рдВрд╡рд╛ docker compose down -v) рддреЛ рдХрд╛рдврддреЛ.

Networking, рдПрдХрд╛ рдЪрд┐рддреНрд░рд╛рдд:

web  тЖТ  db:5432
          тЖС
      Docker DNS  (the container NAME resolves to its current IP)

Container рдЪрд╛ IP рдХрдзреАрд╣реА рд╕реНрдерд┐рд░ рдУрд│рдЦ рдореНрд╣рдгреВрди рд╡рд╛рдкрд░реВ рдирдХрд╛ тАФ рддреЛ рдкреНрд░рддреНрдпреЗрдХ restart рд▓рд╛ рдмрджрд▓рддреЛ; рдирд╛рд╡ рдмрджрд▓рдд рдирд╛рд╣реА. Compose service names (рдзрдбрд╛ 06) рд╣реА Kubernetes Services рдХрдбреЗ рдЬрд╛рдгрд╛рд░реА рдЙрддреНрддрдо рдкрд╛рдпрд░реА рдЖрд╣реЗ, рдЬреА рд╣рд▓рдгрд╛рд▒реНрдпрд╛ pods рд╕рдореЛрд░ рд╕реНрдерд┐рд░ IP рдЖрдгрд┐ DNS рдирд╛рд╡ рдареЗрд╡рдгрд╛рд░реА рддреАрдЪ рдХрд▓реНрдкрдирд╛ рдЖрд╣реЗ.

ЁЯдФ рдХрд╛

Volumes рдЬрдЧрд╛рд▓рд╛ рдлреЗрдХреВрди рджреЗрдгреНрдпрд╛рд╕рд╛рд░рдЦреЗ (containers) рдЖрдгрд┐ рдореМрд▓реНрдпрд╡рд╛рди (data) рдЕрд╢рд╛ рджреЛрди рднрд╛рдЧрд╛рдВрдд рд╡рд┐рднрд╛рдЧрддрд╛рдд тАФ рдкреБрдврдЪреЗ рдкреНрд░рддреНрдпреЗрдХ рддрдВрддреНрд░рдЬреНрдЮрд╛рди рд╣реА рд╡рд┐рднрд╛рдЧрдгреА рдкрд╛рд│рддреЗ (k8s рдзрдбрд╛ 12 рд╣реАрдЪ рдХрд▓реНрдкрдирд╛ cluster рдЪреНрдпрд╛ рдкрд╛рддрд│реАрд╡рд░ рдЖрд╣реЗ). рдирд╛рд╡рд╛рдВрд╕рд╣ networks рд╣реЗ service discovery рдЪреЗ рдмреАрдЬ рдЖрд╣реЗ: рдЗрдерд▓рд╛ http://web:3000 Kubernetes рдордзреНрдпреЗ http://school-api рд╣реЛрддреЛ тАФ рддреАрдЪ рдкрджреНрдзрдд, рдореЛрдареА рд╢рд╛рд│рд╛.

ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛

docker build -t hello-school:v1 app/

# --- the intercom ЁЯУЮ ---
docker network create lunchnet
docker run -d --name web --network lunchnet hello-school:v1     # note: no -p needed!
docker run --rm --network lunchnet curlimages/curl -s http://web:3000
# ЁЯН▒ hello from web тАФ found BY NAME across containers ЁЯОЙ

# --- the fridge ЁЯзК ---
docker volume create fridge
docker run --rm -v fridge:/data alpine sh -c 'echo leftovers > /data/note.txt'
docker run --rm -v fridge:/data alpine cat /data/note.txt        # different box, same fridge!

# --- cleanup ---
docker rm -f web && docker network rm lunchnet && docker volume rm fridge

тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛

тПня╕П рдкреБрдвреЗ

Network + рджреЛрди containers + config + portsтАж рд░реЛрдЬ рд╣реЗ рд╕рдЧрд│реЗ flags рдЯрд╛рдЗрдк рдХрд░рдгреЗ рд▓рд╡рдХрд░рдЪ рдХрдВрдЯрд╛рд│рд╡рд╛рдгреЗ рд╣реЛрддреЗ. рд╕рдВрдкреВрд░реНрдг рдЯреЗрдмрд▓ рдорд╛рдВрдбрдгрд╛рд░реА рдПрдХ YAML file: Docker Compose.

git checkout lesson-06-docker-compose

ЁЯзКЁЯУЮ Lesson 05 тАФ Volumes & networks: the shared fridge and the intercom

ЁЯУН You are here: Lesson 05 of 12 ┬╖ Previous: lesson-04-run-containers ┬╖ Next: lesson-06-docker-compose


ЁЯУж What's in this branch

Lessons 01тАУ04, plus: how data survives disposable containers (volumes), and how containers find each other (networks). Real file:

ЁЯзТ Explain like I'm 5

Two problems from lunch time:

Problem 1: the box forgets. ЁЯза Lesson 04 ended with "new box, fresh memory" тАФ the visit counter reset. Fine for apps, catastrophic for databases! Solution: the shared fridge ЁЯзК (a volume). The fridge stands OUTSIDE the boxes. A box stores its leftovers in the fridge; the box gets thrown away; the NEXT box opens the same fridge тАФ leftovers still there. Fridges survive boxes. (Sound familiar? The k8s course tells this exact story with PVCs тАФ backpack vs library shelf. Same physics.)

Problem 2: boxes can't hear each other. Each box eats at its own private table. For the proxy box to call the app box, they must join the same intercom system ЁЯУЮ (a network). And here's the beautiful part: on a shared network, boxes call each other by NAME тАФ http://web:3000 тАФ not by IP. Names stay; IPs are for machines.

Plus a third trick for developers: the bind mount ЁЯУВ тАФ clip a laptop folder into the box (-v $PWD/app:/app). Edit the file on your laptop; the box sees it instantly. That's how lesson 01's very first command worked!

ЁЯЧ║я╕П Diagram

flowchart LR
    subgraph net["ЁЯУЮ network 'lunchnet' - the intercom"]
        w["ЁЯУж web<br/>the app"]
        p["ЁЯУж proxy<br/>calls http://web:3000"]
        p -->|"1 by NAME, not IP"| w
    end
    v["ЁЯзК volume - the fridge<br/>outside every box<br/>survives docker rm"]
    lap["ЁЯУВ bind mount<br/>laptop folder clipped in<br/>live-edit code"]
    w -.->|"2 leftovers persist"| v
    lap -.->|"3 for development"| w

тЭУ What

ЁЯза Three places data can live

Container writable layer  тЖТ disposable; dies with docker rm
Named volume              тЖТ Docker-managed, persistent (survives rm)
Bind mount                тЖТ host directory тЖФ container (live editing)

Removing a container does not remove a named volume тАФ only docker volume rm (or docker compose down -v) does.

Networking, in one picture:

web  тЖТ  db:5432
          тЖС
      Docker DNS  (the container NAME resolves to its current IP)

Never use a container's IP as a stable identity тАФ it changes on every restart; the name doesn't. Compose service names (lesson 06) are an excellent stepping stone toward Kubernetes Services, which are the same idea with a stable IP and DNS name in front of moving pods.

ЁЯдФ Why

Volumes split the world into disposable (containers) and precious (data) тАФ the split every later technology respects (k8s lesson 12 is this exact idea at cluster scale). Networks-with-names is the seed of service discovery: http://web:3000 here becomes http://school-api in Kubernetes тАФ same pattern, bigger school.

ЁЯзк Try it

docker build -t hello-school:v1 app/

# --- the intercom ЁЯУЮ ---
docker network create lunchnet
docker run -d --name web --network lunchnet hello-school:v1     # note: no -p needed!
docker run --rm --network lunchnet curlimages/curl -s http://web:3000
# ЁЯН▒ hello from web тАФ found BY NAME across containers ЁЯОЙ

# --- the fridge ЁЯзК ---
docker volume create fridge
docker run --rm -v fridge:/data alpine sh -c 'echo leftovers > /data/note.txt'
docker run --rm -v fridge:/data alpine cat /data/note.txt        # different box, same fridge!

# --- cleanup ---
docker rm -f web && docker network rm lunchnet && docker volume rm fridge

тЪая╕П Common mistakes

тПня╕П Next

Network + two containers + config + portsтАж typing all those flags daily gets old fast. One YAML file to set the whole table: Docker Compose.

git checkout lesson-06-docker-compose
тЖР Previousrun containersNext тЖТdocker compose

This page is the lesson's README from the lesson-05-volumes-networks branch, shown here so the whole School stays on one site. Code files open on GitHub at the same branch.