ЁЯПл The SchoolтА║тШ╕я╕П KubernetesтА║ЁЯН▒ рдзрдбрд╛ 01 тАФ Containers рдЖрдгрд┐ Images: рднрд░рд▓реЗрд▓рд╛ рдЬреЗрд╡рдгрд╛рдЪрд╛ рдбрдмрд╛
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯН▒ рдзрдбрд╛ 01 тАФ Containers рдЖрдгрд┐ Images: рднрд░рд▓реЗрд▓рд╛ рдЬреЗрд╡рдгрд╛рдЪрд╛ рдбрдмрд╛

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 13 рдкреИрдХреА рдзрдбрд╛ 01 ┬╖ рдкреБрдврдЪреА branch: lesson-02-pods


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

рд╣реА branch рдЕрдЧрджреА рдкрд╣рд┐рд▓рд╛ рдзрдбрд╛ рдЬреЛрдбрддреЗ: container рдореНрд╣рдгрдЬреЗ рдХрд╛рдп, рдЖрдгрд┐ image рдореНрд╣рдгрдЬреЗ рдХрд╛рдп тАФ рдХрд╛рд░рдг Kubernetes рдЪреЗ рд╕рдВрдкреВрд░реНрдг рдХрд╛рдо containers рдЪрд╛рд▓рд╡рдгреЗ рд╣реЗрдЪ рдЖрд╣реЗ, рддреНрдпрд╛рдореБрд│реЗ рд╣реЗ рд╕рдордЬрд▓реНрдпрд╛рд╢рд┐рд╡рд╛рдп рдкреБрдврдЪреЗ рдХрд╛рд╣реАрдЪ рд╕рдордЬрдд рдирд╛рд╣реА. рдпрд╛ рдзрдбреНрдпрд╛рдд рд╡рд╛рдкрд░рд▓реЗрд▓реНрдпрд╛ рдЦрд▒реНрдпрд╛ files:

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

рдХрд▓реНрдкрдирд╛ рдХрд░рд╛, рддреБрдордЪреА рдЖрдИ рддреБрдореНрд╣рд╛рд▓рд╛ рдЬреЗрд╡рдгрд╛рдЪрд╛ рдбрдмрд╛ ЁЯН▒ рднрд░реВрди рджреЗрддреЗ. рддреНрдпрд╛рдд рддреБрдореНрд╣рд╛рд▓рд╛ рд▓рд╛рдЧрдгрд╛рд░реЗ рд╕рдЧрд│реЗ рдЖрд╣реЗ: рднрд╛рдд, рднрд╛рдЬреА, рдЪрдордЪрд╛, рд░реБрдорд╛рд▓. рддреБрдореНрд╣реА рддреЛ рдХреЛрдгрд╛рдЪреНрдпрд╛рд╣реА рдШрд░реА рдЙрдШрдбрд╛ тАФ рддреБрдордЪреЗ рдЬреЗрд╡рдг рдЕрдЧрджреА рддрд╕реЗрдЪ рдЕрд╕рддреЗ, рдХрд╛рд░рдг рд╕рдЧрд│реЗ рдбрдмреНрдпрд╛рдЪреНрдпрд╛ рдЖрддрдЪ рдЖрд▓реЗ рд╣реЛрддреЗ.

Container рдореНрд╣рдгрдЬреЗ program рд╕рд╛рдареАрдЪрд╛ рдЬреЗрд╡рдгрд╛рдЪрд╛ рдбрдмрд╛. рддреНрдпрд╛рдд app рдЖрдгрд┐ рддреНрдпрд╛рд▓рд╛ рд▓рд╛рдЧрдгрд╛рд░реЗ рд╕рдЧрд│реЗ рдЕрд╕рддреЗ тАФ Node.js, libraries, config. рддреНрдпрд╛рдореБрд│реЗ рддреЗ рддреБрдордЪреНрдпрд╛ laptop рд╡рд░, рдореИрддреНрд░рд┐рдгреАрдЪреНрдпрд╛ laptop рд╡рд░ рдЖрдгрд┐ рдПрдЦрд╛рджреНрдпрд╛ рдореЛрдареНрдпрд╛ AWS server рд╡рд░ рдЕрдЧрджреА рд╕рд╛рд░рдЦреЗрдЪ рдЪрд╛рд▓рддреЗ. рдЖрддрд╛ "рдкрдг рдорд╛рдЭреНрдпрд╛ machine рд╡рд░ рддрд░ рдЪрд╛рд▓рддреЗ!" рдЕрд╕реЗ рдореНрд╣рдгрд╛рдпрдЪреА рд╡реЗрд│ рдпреЗрдд рдирд╛рд╣реА ЁЯШд

рдПрдХрд╛ рдкрд╛рдХрдХреГрддреАрддреВрди рддреБрдореНрд╣реА 100 рдПрдХрд╕рд╛рд░рдЦреЗ рдбрдмреЗ рдмрдирд╡реВ рд╢рдХрддрд╛. рдореНрд╣рдгреВрдирдЪ рдПрдХ image 100 рдПрдХрд╕рд╛рд░рдЦреНрдпрд╛ containers рдореНрд╣рдгреВрди рдЪрд╛рд▓реВ рд╢рдХрддреЗ.

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

flowchart LR
    subgraph recipe["ЁЯУЭ Recipe - Dockerfile"]
        D["FROM node:20<br/>COPY src<br/>RUN npm install"]
    end
    subgraph shelf["ЁЯзК Image - frozen lunchbox"]
        I["school-api:latest<br/>app + Node.js + libs"]
    end
    subgraph running["ЁЯПГ Containers - lunch time"]
        C1["container 1"]
        C2["container 2"]
        C3["container 3"]
    end
    D -- "docker build" --> I
    I -- "docker run" --> C1
    I -- "docker run" --> C2
    I -- "docker run" --> C3

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

ЁЯдФ рдХрд╛

Containers рдирд╕рддреАрд▓ рддрд░: "Node 20, Postgres 16 install рдХрд░рд╛, рд╣реЗ 12 env vars set рдХрд░рд╛тАж" рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ machine рд╣рд│реВрд╣рд│реВ рд╡реЗрдЧрд│реА рд╣реЛрдд рдЬрд╛рддреЗ. Containers рдЕрд╕рддреАрд▓ рддрд░: рдПрдХрджрд╛ build рдХрд░рд╛, рдХреБрдареЗрд╣реА, рдЕрдЧрджреА рд╕рд╛рд░рдЦреЗрдЪ рдЪрд╛рд▓рд╡рд╛. Kubernetes рдЕрд╕реНрддрд┐рддреНрд╡рд╛рдд рдЖрд╣реЗ рддреЗ рдЕрдиреЗрдХ machines рд╡рд░ рдЕрдиреЗрдХ containers рдЪрд╛рд▓рд╡рдгреНрдпрд╛рд╕рд╛рдареА тАФ рдореНрд╣рдгреВрди рдкреБрдвреЗ рдпреЗрдгрд╛рд▒реНрдпрд╛ рд╕рдЧрд│реНрдпрд╛рдЪреЗ рдЕрдгреВ рдореНрд╣рдгрдЬреЗ containers.

ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)

apps/school-api/Dockerfile рдЙрдШрдбрд╛:

  1. FROM node:20-alpine тАФ рдЬреНрдпрд╛рдд рдЖрдзреАрдЪ Node рдЖрд╣реЗ рдЕрд╢рд╛ рд▓рд╣рд╛рди рдореВрд│ рдбрдмреНрдпрд╛рдкрд╛рд╕реВрди рд╕реБрд░реБрд╡рд╛рдд рдХрд░рд╛.
  2. COPY + RUN npm ci тАФ app рдЖрдгрд┐ рддреНрдпрд╛рдЪреНрдпрд╛ libraries рдЖрдд рдареЗрд╡рд╛.
  3. Multi-stage build тАФ рдЕрдВрддрд┐рдо image рдордзреНрдпреЗ рдлрдХреНрдд рдЪрд╛рд▓рд╡рдгреНрдпрд╛рд╕рд╛рдареА рд▓рд╛рдЧрдгрд╛рд░реЗрдЪ рд░рд╛рд╣рддреЗ (рд▓рд╣рд╛рди = рдкрд╛рдард╡рд╛рдпрд▓рд╛ рдЬрд▓рдж).
  4. CMD тАФ рдбрдмрд╛ рдЙрдШрдбрд▓реНрдпрд╛рд╡рд░ рдХрд╛рдп рдХрд░рд╛рдпрдЪреЗ ("server рд╕реБрд░реВ рдХрд░рд╛").

рддреНрдпрд╛рдирдВрддрд░ docker-compose.yml рддреБрдордЪреНрдпрд╛ laptop рд╡рд░ рддреАрди containers рдПрдХрддреНрд░ рдЪрд╛рд▓рд╡рддреЗ: school-api, school-analytics, рдЖрдгрд┐ postgres.

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

# Build the image (bake the lunchbox) тАФ needs Docker Desktop running
docker build -t school-api:v1 apps/school-api

# Run one container from it (open the box)
docker run --rm -p 3000:3000 school-api:v1

# In another terminal тАФ it's alive:
curl http://localhost:3000/healthz

# Or run the WHOLE lunch table (both APIs + Postgres):
docker compose up

ЁЯФз рдпрд╛ рдзрдбреНрдпрд╛рд╕рд╛рдареА kubectl

docker build ┬╖ docker run ┬╖ docker logs

ЁЯФЧ рдпрд╛рд╡рд░ рдЖрдзрд╛рд░рд┐рдд: ЁЯН▒ Docker рд╢рд╛рд│рд╛ L01тАУL04 (images, run, ports)

тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ

docker run -p 3000:3000 school-api:v1 рд╣реЗ curl localhost:3000/health рд▓рд╛ рдЙрддреНрддрд░ рджреЗрддреЗ.

ЁЯз╣ рд╕рд╛рдлрд╕рдлрд╛рдИ

Container рд▓рд╛ docker rm -f рдХрд░рд╛ тАФ images рдлрдХреНрдд disk рдЪреА рдЬрд╛рдЧрд╛ рдШреЗрддрд╛рдд

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

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

Kubernetes рдордзреНрдпреЗ container рдХрдзреАрдЪ рдПрдХрдЯрд╛, рдЙрдШрдбреНрдпрд╛рд╡рд░ рдЪрд╛рд▓рдд рдирд╛рд╣реА тАФ рддреЛ рдиреЗрд╣рдореА Pod рдЪреНрдпрд╛ рдЖрдд рдмрд╕реВрди рдЪрд╛рд▓рддреЛ.

git checkout lesson-02-pods

ЁЯН▒ Lesson 01 тАФ Containers & Images: the packed lunchbox

ЁЯУН You are here: Lesson 01 of 13 ┬╖ Next branch: lesson-02-pods


ЁЯУж What's in this branch

This branch adds the very first lesson: what a container is, and what an image is тАФ because Kubernetes' whole job is running containers, so nothing else makes sense until this does. Real files this lesson uses:

ЁЯзТ Explain like I'm 5

Imagine your mom packs you a lunchbox ЁЯН▒. Inside is everything you need: rice, curry, a spoon, a napkin. It doesn't matter whose house you open it in тАФ your lunch is exactly the same, because everything came inside the box.

A container is a lunchbox for a program. Inside is the app plus everything it needs тАФ Node.js, libraries, config. So it runs exactly the same on your laptop, your friend's laptop, and a giant AWS server. No more "but it works on my machine!" ЁЯШд

You can make 100 identical lunchboxes from one recipe. That's why one image can run as 100 identical containers.

ЁЯЧ║я╕П Diagram

flowchart LR
    subgraph recipe["ЁЯУЭ Recipe - Dockerfile"]
        D["FROM node:20<br/>COPY src<br/>RUN npm install"]
    end
    subgraph shelf["ЁЯзК Image - frozen lunchbox"]
        I["school-api:latest<br/>app + Node.js + libs"]
    end
    subgraph running["ЁЯПГ Containers - lunch time"]
        C1["container 1"]
        C2["container 2"]
        C3["container 3"]
    end
    D -- "docker build" --> I
    I -- "docker run" --> C1
    I -- "docker run" --> C2
    I -- "docker run" --> C3

тЭУ What

ЁЯдФ Why

Without containers: "install Node 20, Postgres 16, set these 12 env varsтАж" and every machine drifts apart. With containers: build once, run anywhere, identically. Kubernetes exists to run lots of containers across lots of machines тАФ so containers are the atoms of everything that follows.

ЁЯФз How (in this repo)

Open apps/school-api/Dockerfile:

  1. FROM node:20-alpine тАФ start from a small base lunchbox that already has Node.
  2. COPY + RUN npm ci тАФ put the app and its libraries inside.
  3. Multi-stage build тАФ the final image keeps only what's needed to run (small = fast to ship).
  4. CMD тАФ what to do when the box is opened ("start the server").

docker-compose.yml then runs three containers together on your laptop: school-api, school-analytics, and postgres.

ЁЯзк Try it

# Build the image (bake the lunchbox) тАФ needs Docker Desktop running
docker build -t school-api:v1 apps/school-api

# Run one container from it (open the box)
docker run --rm -p 3000:3000 school-api:v1

# In another terminal тАФ it's alive:
curl http://localhost:3000/healthz

# Or run the WHOLE lunch table (both APIs + Postgres):
docker compose up

ЁЯФз kubectl for this lesson

docker build ┬╖ docker run ┬╖ docker logs

ЁЯФЧ Builds on: ЁЯН▒ Docker school L01тАУL04 (images, run, ports)

тЬЕ Verify тАФ what you should see

docker run -p 3000:3000 school-api:v1 answers on curl localhost:3000/health.

ЁЯз╣ Clean up

docker rm -f the container тАФ images cost disk only

тЪая╕П Common mistakes

тПня╕П Next

A container never runs "naked" in Kubernetes тАФ it always rides inside a Pod.

git checkout lesson-02-pods
тЖР Course homeall lessonsNext тЖТpods

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