ЁЯОВ рдзрдбрд╛ 02 тАФ Images рдЖрдгрд┐ рдерд░: рдХреЗрдХ рдЖрдгрд┐ cache
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 02 ┬╖ рдорд╛рдЧреЗ: lesson-01-why-containers ┬╖ рдкреБрдвреЗ: lesson-03-dockerfile
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбрд╛ 01, рдЖрдгрд┐ рддреНрдпрд╛рд╢рд┐рд╡рд╛рдп: image рдЖрддреВрди рдирдХреНрдХреА рдХрд╛рдп рдЕрд╕рддреЗ тАФ рдПрдХрд╛рд╡рд░ рдПрдХ рд░рдЪрд▓реЗрд▓реЗ рдерд░ тАФ рдЖрдгрд┐ рд╣реЗ рд╕рдордЬрд▓реНрдпрд╛рд╡рд░ рддреБрдордЪреЗ builds 100├Ч рдЬрд▓рдж рдХрд╛ рд╣реЛрддрд╛рдд. рдЦрд░реА file:
- app/Dockerfile тАФ рдЦрд╛рд▓рдЪреА рдкреНрд░рддреНрдпреЗрдХ рдУрд│ рдПрдХ рдерд░ рдмрдирд╡рддреЗ
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
Image рд╣рд╛ рдПрдХ рднрд░реАрд╡ рдареЛрдХрд│рд╛ рдирд╛рд╣реА тАФ рддреЛ рдерд░рд╛рдВрдЪрд╛ рдХреЗрдХ ЁЯОВ рдЖрд╣реЗ, рдЦрд╛рд▓реВрди рд╡рд░ рднрд╛рдЬрд▓реЗрд▓рд╛, Dockerfile рдЪреНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ рдУрд│реАрдЪрд╛ рдПрдХ рдерд░:
- рд╕рд░реНрд╡рд╛рдд рдЦрд╛рд▓рдЪрд╛ рдерд░: рдЫреЛрдЯреЗ Linux + Node (
FROM node:20-alpine) тАФ рдмреЗрдХрд░реАрддреВрди рдЖрд▓реЗрд▓рд╛ рдЖрдзреАрдЪ рднрд╛рдЬрд▓реЗрд▓рд╛ рдерд░. рд╣рд╛ рддреБрдореНрд╣реА рд╕реНрд╡рддрдГ рдХрдзреАрдЪ рднрд╛рдЬрдд рдирд╛рд╣реА. - рдордзрд▓реЗ рдерд░: рддреБрдордЪреА settings (
WORKDIR,ENV,USER). - рд╡рд░рдЪрд╛ рдерд░: рддреБрдордЪрд╛ рдХреЛрдб (
COPY server.js).
рдЖрдгрд┐ рдмреЗрдХрд░реАрдЪрд╛ рдЬрд╛рджреБрдИ рдирд┐рдпрдо: рди рдмрджрд▓рд▓реЗрд▓рд╛ рдерд░ рдкреБрдиреНрд╣рд╛ рдХрдзреАрдЪ рднрд╛рдЬрд▓рд╛ рдЬрд╛рдд рдирд╛рд╣реА тАФ рддреЛ cache рдЪреНрдпрд╛ рдлрд│реАрд╡рд░реВрди рд▓рдЧреЗрдЪ рдШреЗрддрд▓рд╛ рдЬрд╛рддреЛ.
рдореНрд╣рдгреВрди рддреБрдореНрд╣реА server.js рдмрджрд▓реВрди рдкреБрдиреНрд╣рд╛ build рдХрд░рддрд╛ рддреЗрд╡реНрд╣рд╛:
- рдЦрд╛рд▓рдЪреЗ + рдордзрд▓реЗ рдерд░ тЖТ cache рдордзреВрди, 0 рд╕реЗрдХрдВрдж тЪб
- рдлрдХреНрдд
COPYрдерд░ рдЖрдгрд┐ рддреНрдпрд╛рд╡рд░рдЪреЗ тЖТ рдкреБрдиреНрд╣рд╛ рднрд╛рдЬрд▓реЗ рдЬрд╛рддрд╛рдд ЁЯФи
рдореНрд╣рдгреВрдирдЪ рдЕрдиреБрднрд╡реА рд▓реЛрдХ рдХреНрд╡рдЪрд┐рдд рдмрджрд▓рдгрд╛рд▒реНрдпрд╛ рдУрд│реА рддрд│рд╛рд╢реА рдЖрдгрд┐ рдХреЛрдб рд╡рд░ рдареЗрд╡рддрд╛рдд тАФ рдореНрд╣рдгрдЬреЗ рд░реЛрдЬрдЪреНрдпрд╛ rebuild рд▓рд╛ рдлрдХреНрдд рд╡рд░рдЪрд╛ рдкрд╛рддрд│ рдерд░ рд▓рд╛рдЧрддреЛ. рдХреЗрдХрдЪреА рд░рдЪрдирд╛ рдореНрд╣рдгрдЬреЗрдЪ build рдЪрд╛ рд╡реЗрдЧ. ЁЯОВтЪб
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
subgraph cake["ЁЯОВ image = layer cake, bottom-up"]
l4["CMD node server.js"]
l3["COPY server.js тЖР your code, changes often"]
l2["WORKDIR / ENV / USER"]
l1["FROM node:20-alpine тЖР pre-baked, huge, never changes"]
l4 --- l3 --- l2 --- l1
end
edit["тЬПя╕П edit server.js<br/>+ docker build"]
edit -->|"1 bottom layers: CACHE тЪб"| l1
edit -->|"2 only COPY + above rebaked ЁЯФи"| l3
тЭУ рдХрд╛рдп
- Image = read-only рдерд░рд╛рдВрдЪрд╛ рдХреНрд░рдорд╡рд╛рд░ рдвреАрдЧ + metadata (рдХрд╛рдп рдЪрд╛рд▓рд╡рд╛рдпрдЪреЗ, рдХреЛрдгрддреЗ ports, рдХреЛрдгрддрд╛ user). рдЧреЛрдард▓реЗрд▓реА; build рдирдВрддрд░ рдХрдзреАрдЪ рдмрджрд▓рдд рдирд╛рд╣реА.
- Layer (рдерд░) = рдПрдХрд╛ Dockerfile instruction рдиреЗ рддрдпрд╛рд░ рдЭрд╛рд▓реЗрд▓рд╛ filesystem рдордзрд▓рд╛ рдлрд░рдХ (diff).
рдерд░ content-addressed рдЕрд╕рддрд╛рдд рдЖрдгрд┐ images рдордзреНрдпреЗ рд╡рд╛рдЯрд▓реЗ рдЬрд╛рддрд╛рдд тАФ
node:20-alpineрд╡рд░рдЪреНрдпрд╛ рджрд╣рд╛ images рддреЛ base disk рд╡рд░ рдПрдХрджрд╛рдЪ рд╕рд╛рдард╡рддрд╛рдд. - Build cache: instruction рдЖрдгрд┐ рддреНрдпрд╛рдЪреЗ inputs рдмрджрд▓рд▓реЗ рдирд╕рддреАрд▓ рддрд░ Docker рддреЛ рдерд░ рдкреБрдиреНрд╣рд╛ рд╡рд╛рдкрд░рддреЛ. рдкрд╣рд┐рд▓реА рдмрджрд▓рд▓реЗрд▓реА рдУрд│ рддрд┐рдЪреНрдпрд╛рд╡рд░рдЪреЗ рд╕рдЧрд│реЗ рдЕрд╡реИрдз рдХрд░рддреЗ.
- Container = рдЧреЛрдард▓реЗрд▓реНрдпрд╛ рдврд┐рдЧрд╛рд╡рд░рдЪрд╛ рдПрдХ рдкрд╛рддрд│ writable рдерд░ тАФ рдореНрд╣рдгреВрдирдЪ рдПрдХрд╛ image рдордзреВрди 100 containers рд╕реНрд╡рд╕реНрдд рдкрдбрддрд╛рдд.
ЁЯза Image рд╡рд┐рд░реБрджреНрдз container тАФ рдЖрдгрд┐ image рдЪреА рддреАрди рдирд╛рд╡реЗ
IMAGE = read-only template (the layer cake, frozen)
тЖУ docker run
CONTAINER = a running instance of that image (+ a thin writable layer)
рдкреНрд░рддреНрдпреЗрдХ image рд▓рд╛ рддреАрди handles рдЕрд╕рддрд╛рдд:
| handle | рдЙрджрд╛рд╣рд░рдг | рдмрджрд▓рддреЗ рдХрд╛? |
|---|---|---|
| image ID | sha256:3f2aтАж (local, content рд╡рд░ рдЖрдзрд╛рд░рд┐рдд) |
рддреЛрдЪ content рдЕрд╕реЗрд▓ рддрд░ рдХрдзреАрдЪ рдирд╛рд╣реА |
| tag | hello-school:v1, :latest |
mutable тАФ рдХреЛрдгреАрд╣реА рд╣рд▓рд╡реВ рд╢рдХреЗрд▓ рдЕрд╕реЗ рд╕реНрдЯрд┐рдХрд░ |
| digest | sha256:9c1eтАж (registry, content рдЪреА рдУрд│рдЦ) |
immutable тАФ рдард╕рд╛ |
рд╣реАрдЪ рдЧреЛрд╖реНрдЯ рдЪрд┐рддреНрд░рд░реВрдкрд╛рдд тАФ рдПрдХ repository, рдЕрдиреЗрдХ handles:
Repository hello-school
тФЬтФАтФА tag: v1
тФЬтФАтФА tag: latest
тФФтФАтФА digest: sha256:abc123...
tag = human-friendly name
digest = immutable content identifier
latest = just another mutable tag
Image рдЪрд╛ content immutable рдЕрд╕рддреЛ: рдПрдХ byte рдмрджрд▓рд╛, рдирд╡рд╛ ID/digest рдорд┐рд│рддреЛ. latest
рд╣реЗ рдлрдХреНрдд default tag рдЪреЗ рдирд╛рд╡ рдЖрд╣реЗ тАФ рддреЗ "рд╕рд░реНрд╡рд╛рдд рдирд╡реЗ" рд╣реА рдирд╛рд╣реА рдЖрдгрд┐ рд╕реНрдерд┐рд░ рд╣реА рдирд╛рд╣реА. Tag рд╡рд┐рд░реБрджреНрдз
digest рд╣рд╛ рдореБрджреНрджрд╛ рдзрдбрд╛ 11 (ECR) рдордзреНрдпреЗ рдЖрдгрд┐ Kubernetes deployments рдордзреНрдпреЗ рдЬреЛрд░рд╛рдд рдкрд░рдд рдпреЗрддреЛ.
ЁЯдФ рдХрд╛
Cache рд▓рд╛ рдЕрдиреБрдХреВрд▓ Dockerfiles рдореНрд╣рдгрдЬреЗ 2 рд╕реЗрдХрдВрджрд╛рдВрдЪрд╛ рдЖрдгрд┐ 5 рдорд┐рдирд┐рдЯрд╛рдВрдЪрд╛ rebuild рдпрд╛рддрд▓рд╛ рдлрд░рдХ тАФ рдЖрдард╡рдбреНрдпрд╛рд▓рд╛ рд╢реЗрдХрдбреЛ рд╡реЗрд│рд╛. рдЖрдгрд┐ рд╡рд╛рдЯрд▓реЗрд▓реНрдпрд╛ рдерд░рд╛рдВрдореБрд│реЗрдЪ рддреБрдордЪреЗ рджрд╣рд╛рд╡реЗ Node ре▓рдк pull рдХрд░рдгреЗ рд▓рдЧреЗрдЪ рд╣реЛрддреЗ: рдЬрд╛рдб base рдерд░ рдЖрдзреАрдЪ рдорд╢реАрдирд╡рд░ рдЕрд╕рддреЛ. (рдзрдбрд╛ 11: push рдлрдХреНрдд registry рдХрдбреЗ рдирд╕рд▓реЗрд▓реЗ рдерд░ upload рдХрд░рддреЛ тАФ рддреАрдЪ рдХрд▓реНрдкрдирд╛.)
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
app/Dockerfile рдореБрджреНрджрд╛рдо cache рдЪреНрдпрд╛ рдХреНрд░рдорд╛рдиреЗ рд▓рд┐рд╣рд┐рд▓реЗ рдЖрд╣реЗ: FROM тЖТ
WORKDIR тЖТ COPY server.js тЖТ ENV/EXPOSE/USER/CMD. рдореЛрдареНрдпрд╛ ре▓рдкреНрд╕рдордзреНрдпреЗ
рдиреЗрд╣рдореАрдЪреА рдЪрд╛рд▓ рдЕрд╢реА: COPY . . рдЪреНрдпрд╛ рдЖрдзреА COPY package.json + RUN npm ci тАФ
рдореНрд╣рдгрдЬреЗ рдХреЛрдб рдмрджрд▓рд▓рд╛ рддрд░реА dependency install рдкреБрдиреНрд╣рд╛ рдЪрд╛рд▓рдд рдирд╛рд╣реА.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
docker build -t hello-school:v1 app/ # first build: every layer baked
docker build -t hello-school:v1 app/ # again: ALL "CACHED" тАФ ~1 second тЪб
echo "// tweak" >> app/server.js
docker build -t hello-school:v1 app/ # watch: FROM/WORKDIR cached, COPY rebuilt
git checkout app/server.js # undo the tweak
docker history hello-school:v1 # ЁЯОВ the actual layers + sizes
docker image ls | head -3 # images on your shelf
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
:latestрдореНрд╣рдгрдЬреЗ "рд╕рд░реНрд╡рд╛рдд рдирд╡рд╛ build" рдЕрд╕реЗ рдорд╛рдирдгреЗ тАФ рддреЛ рдЗрддрд░ tags рд╕рд╛рд░рдЦрд╛рдЪ рдПрдХ tag рдЖрд╣реЗ, рдЖрдгрд┐ рддреЛ рд╣рд▓рддреЛ- рдЪрд╛рд▓реВ container рдЪреНрдпрд╛ рдЖрдд files рдмрджрд▓реВрди image рдмрджрд▓реЗрд▓ рдЕрд╢реА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рдгреЗ (рддреА рдмрджрд▓рдд рдирд╛рд╣реА)
- cache рдЪреА рд╢рд┐рд╕реНрдд рди рдкрд╛рд│рддрд╛ rebuild рдХрд░рдгреЗ тАФ dependency рдЪреНрдпрд╛ рдУрд│реАрдВрдЪреНрдпрд╛ рд╡рд░ рдХреЛрдб copy рдЪреНрдпрд╛ рдУрд│реА = рд╣рд│реВ builds
тПня╕П рдкреБрдвреЗ
рдЖрддрд╛ recipe card рд╕реНрд╡рддрдГрдЪ рдУрд│-рдУрд│ рд╡рд╛рдЪреВрдпрд╛: Dockerfile.
git checkout lesson-03-dockerfile