La imatge auroralibros/aurora-api:1.2.0 pesa 142 MB. No és cap desastre, però tampoc no està optimitzada: a dins hi viatja un compilador de C, les dependències de desenvolupament i fitxers que ningú no executa. En aquesta lliçó la poses a règim mesurant a cada pas, fins a una xifra concreta, sense perdre res de l'enduriment de la lliçó 05-03.
Contingut
- Per què importa la mida i què no s'ha de sacrificar
- Mesurar primer:
image lsihistory dive: explorar capa a capa- Elecció de la base, amb xifres
- Construccions multietapa: el concepte
- Multietapa aplicada a
aurora-api - Etapes amb nom i
--target - Imatge base comuna per a diverses imatges
- Reduir capes i contingut
- Esborrar un fitxer no redueix la mida (demostrat)
- Ordenar per a la memòria cau
- Verificació final i taula resum
- Per què importa la mida i què no s'ha de sacrificar
| Motiu | Impacte concret |
|---|---|
| Temps de descàrrega | Cada node nou descarrega la imatge sencera la primera vegada |
| Cost d'emmagatzematge | Registre d'imatges, memòria cau de cada node i cada versió conservada |
| Superfície d'atac | Menys paquets, menys CVE (lliçó 05-03) |
| Velocitat de desplegament | Un rollback urgent és tan ràpid com la descàrrega |
| Escalat automàtic | Un pic de trànsit exigeix arrencar rèpliques ara |
En una plataforma amb cinc nodes i quinze desplegaments al mes, abaixar 40 MB per imatge són uns 3 GB menys de transferència mensual i desenes de segons menys a cada arrencada en fred.
I el que no se sacrifica per aprimar: el HEALTHCHECK, l'usuari sense privilegis, les etiquetes OCI de traçabilitat, la capacitat de diagnosticar un problema en producció i la reproductibilitat de la construcció. Una imatge de 40 MB que ningú no sap depurar a les tres de la matinada és un mal negoci.
- Mesurar primer:
image ls i history
image ls i historydocker image ls auroralibros/aurora-api --format "{{.Tag}}\t{{.Size}}"
docker image history auroralibros/aurora-api:1.2.0 --format "{{.Size}}\t{{.CreatedBy}}" | head -81.2.0 142MB
21.4MB RUN npm ci --omit=dev
3.1MB COPY src/ ./src/
1.8MB RUN apk add --no-cache tini
0B ENV NODE_ENV=production
0B USER node
0B HEALTHCHECK &{["CMD-SHELL" "wget -qO- ..."]}
115MB /bin/sh -c #(nop) ADD file:... in /El diagnòstic és immediat i sorprèn gairebé tothom la primera vegada: dels 142 MB, 115 MB són la imatge base. Les dependències són 21 MB i el codi propi, 3 MB. La palanca principal no és al teu codi: és en quina base tries i en què hi afegeixes a sobre.
Per comparar amb precisió fes servir la mida real (docker image inspect --format '{{.Size}}' | numfmt --to=iec) i no la que mostra el registre d'imatges, que està comprimida i sempre sembla menor.
dive: explorar capa a capa
dive: explorar capa a capadocker history diu quant pesa cada capa; dive diu què hi ha a dins i quant se'n malbarata.
docker run --rm -it \
-v /var/run/docker.sock:/var/run/docker.sock \
wagoodman/dive:latest auroralibros/aurora-api:1.2.0│ Image Details │
Total Image size: 142 MB
Potential wasted space: 9.7 MB
Image efficiency score: 93 %
Count Total Space Path
2 6.1 MB /app/node_modules/.cache
2 2.4 MB /root/.npm/_cacache
3 1.2 MB /app/.gitTres troballes i tres decisions: la memòria cau d'npm no hauria de ser a la imatge final, node_modules/.cache és brossa de compilació, i .git no hauria d'haver entrat mai al context de construcció (falta una línia al .dockerignore).
L'efficiency score mesura quant contingut s'escriu en una capa i se sobreescriu o s'esborra en una altra; per sota del 95 % hi ha feina a fer. Per automatitzar-ho a CI, afegeix -e CI=true i --lowestEfficiency=0.95: dive acaba amb codi diferent de zero si no s'assoleix el llindar.
- Elecció de la base, amb xifres
| Base | Mida | libc | Eines | Quan triar-la |
|---|---|---|---|---|
node:22 |
~1,1 GB | glibc | Totes: git, compiladors, curl |
Només com a etapa de compilació |
node:22-slim |
~230 MB | glibc | Mínimes de Debian | Dependències natives exigents amb glibc |
node:22-alpine |
~135 MB | musl | BusyBox, apk |
Cas general: l'equilibri |
distroless/nodejs22 |
~110 MB | glibc | Cap | Producció endurida |
scratch |
0 MB | — | Cap | Només binaris estàtics (Go, Rust) |
La contrapartida d'Alpine té nom: musl en lloc de glibc. Conseqüències reals:
- Els paquets npm amb binaris precompilats per a glibc poden no funcionar i haver-se de compilar en instal·lar-los (més lent, i exigeix
build-base). - Algunes càrregues intensives en DNS o en resolució de noms es comporten de manera diferent amb musl.
- Certes biblioteques científiques i d'aprenentatge automàtic no suporten musl.
aurora-api fa servir Express, pg i redis, cap amb dependències natives problemàtiques: Alpine és l'elecció correcta. Si un dia una dependència donés problemes, node:22-slim costa 95 MB més i els resol.
- Construccions multietapa: el concepte
Una construcció multietapa fa servir diverses imatges base al mateix Dockerfile. Les etapes intermèdies compilen i preparen; l'etapa final copia només el resultat. Tota la resta —compiladors, memòries cau, dependències de desenvolupament, codi font— es queda fora de la imatge publicada.
flowchart LR
subgraph E1["Etapa: dependencies (node:22-alpine)"]
A["package*.json"] --> B["npm ci --omit=dev<br/>+ build-base per compilar"]
end
subgraph E2["Etapa: desenvolupament"]
C["npm ci complet<br/>devDependencies, proves"]
end
subgraph E3["Etapa final (node:22-alpine)"]
D["COPY --from=dependencies node_modules"]
E["COPY src/"]
end
B -.->|"COPY --from"| D
E3 --> F["Imatge publicada:<br/>sense compiladors ni memòries cau"]
E2 -.->|"només amb --target"| G["Imatge de desenvolupament"]
Dues regles que resumeixen el mecanisme:
- Només l'última etapa (o la indicada amb
--target) acaba a la imatge; les altres es descarten. COPY --from=<etapa>porta fitxers concrets d'una etapa anterior, i res més no hi viatja: ni les seves capes, ni el seu historial, ni els seus secrets.
- Multietapa aplicada a
aurora-api
aurora-apiPunt de partida (una sola etapa, 142 MB) i destinació:
# syntax=docker/dockerfile:1
ARG NODE_VERSION=22
# ---------- Etapa 1: dependències de producció ----------
FROM node:${NODE_VERSION}-alpine AS dependencies
WORKDIR /app
# build-base només viu aquí: compila el que calgui i NO viatja a la final
RUN apk add --no-cache --virtual .build python3 make g++
COPY package.json package-lock.json ./
RUN npm ci --omit=dev && npm cache clean --force
# ---------- Etapa 2: desenvolupament i proves (no es publica) ----------
FROM node:${NODE_VERSION}-alpine AS desenvolupament
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
CMD ["node", "--watch", "src/server.js"]
# ---------- Etapa 3: imatge final, mínima ----------
FROM node:${NODE_VERSION}-alpine AS produccio
ARG VERSION=1.3.0
ARG REVISION=desconeguda
LABEL org.opencontainers.image.title="aurora-api" \
org.opencontainers.image.version="${VERSION}" \
org.opencontainers.image.revision="${REVISION}" \
org.opencontainers.image.source="https://github.com/aurora-libros/aurora-api"
WORKDIR /app
ENV NODE_ENV=production PORT=3000
COPY --from=dependencies --chown=node:node /app/node_modules ./node_modules
COPY --chown=node:node package.json ./
COPY --chown=node:node src/ ./src/
USER node
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD wget -qO- http://127.0.0.1:3000/salut || exit 1
ENTRYPOINT ["node"]
CMD ["src/server.js"]docker build -t auroralibros/aurora-api:1.3.0 --build-arg VERSION=1.3.0 ./api
docker image ls auroralibros/aurora-api --format "{{.Tag}}\t{{.Size}}"142 MB → 121 MB: un 15 % menys amb un sol canvi estructural. D'on surten els 21 MB? De build-base (python3, make, g++), que s'instal·lava a la imatge final i ara viu i mor a l'etapa dependencies, i de la memòria cau d'npm.
Fixa't que no s'ha perdut res del que estava endurit: USER node, el HEALTHCHECK, les etiquetes OCI i l'ENTRYPOINT/CMD en forma exec continuen allà. Optimitzar no és retallar seguretat.
- Etapes amb nom i
--target
--targetLes etapes amb nom no són només organització: són artefactes construïbles per separat.
docker build --target desenvolupament -t aurora-api:dev ./api
docker build --target dependencies -t aurora-api:deps ./api
docker build -t auroralibros/aurora-api:1.3.0 ./api # última etapa
docker image ls aurora-api --format "{{.Tag}}\t{{.Size}}"La imatge de desenvolupament pesa 318 MB i està bé que sigui així: porta les devDependencies, el marc de proves i les eines de depuració. És exactament el target: desenvolupament que compose.override.yaml fa servir des de la lliçó 04-07, i ara veus d'on surt.
Un patró molt útil és una etapa de proves que fa fallar la construcció si les proves fallen:
BuildKit no executa aquella etapa en construir la de producció, perquè no forma part del seu graf de dependències (lliçó 05-05). Només s'executa si la demanes amb --target.
- Imatge base comuna per a diverses imatges
Quan publiques diversos serveis en Node, convé una base pròpia amb el que és compartit:
# aurora-base/Dockerfile -> auroralibros/aurora-base-node:22
FROM node:22-alpine
RUN apk add --no-cache tini tzdata && \
addgroup -g 1001 aurora && adduser -u 1001 -G aurora -s /bin/sh -D aurora
ENV TZ=Europe/Madrid NODE_ENV=production
ENTRYPOINT ["/sbin/tini", "--"]Avantatges: una sola actualització de seguretat es propaga a tots els serveis, la capa base es comparteix al disc i a la descàrrega entre ells, i les decisions comunes són en un sol lloc. Inconvenient: crees una dependència interna que cal mantenir i versionar. Compensa a partir de tres o quatre serveis.
- Reduir capes i contingut
# ❌ Tres capes, i la memòria cau d'apk queda a dins per sempre
RUN apk update
RUN apk add curl
RUN rm -rf /var/cache/apk/*
# ✅ Una capa, sense memòria cau: el que no s'escriu no ocupa
RUN apk add --no-cache curl| Tècnica | Què fa | Estalvi típic |
|---|---|---|
apk add --no-cache |
Evita escriure l'índex de paquets | 5-10 MB |
apt-get ... && rm -rf /var/lib/apt/lists/* al mateix RUN |
Igual a Debian | 30-50 MB |
--no-install-recommends |
No instal·la paquets "suggerits" | 20-100 MB |
npm ci --omit=dev |
Sense dependències de desenvolupament | 40-70 % de node_modules |
npm cache clean --force |
Elimina ~/.npm/_cacache |
10-30 MB |
--virtual .build + apk del .build |
Compiladors temporals a la mateixa capa | 100-200 MB |
.dockerignore afinat |
Impedeix que hi entri el que no toca | Variable, de vegades enorme |
El .dockerignore d'aurora-api després del que va revelar dive:
.git
.gitignore
node_modules
npm-debug.log
Dockerfile*
compose*.yaml
.env
.env.*
!.env.example
coverage/
.nyc_output/
*.md
!README.md
.vscode/
.idea/
proves/
**/*.test.jsDe 94 MB de directori a 812 kB de context. Això no només fa la construcció més ràpida: garanteix que .git i .env no es puguin colar en cap capa, cosa que és un assumpte de seguretat a més de mida.
- Esborrar un fitxer no redueix la mida (demostrat)
FROM alpine:3
RUN dd if=/dev/zero of=/temporal.bin bs=1M count=100 # capa A: +100 MB
RUN rm /temporal.bin # capa B: whiteoutdocker build -q -t esborrat:mal /tmp/esborrat
docker image ls esborrat:mal --format "{{.Size}}"
docker run --rm esborrat:mal ls -la /temporal.bin 2>&1
docker image history esborrat:mal --format "{{.Size}}\t{{.CreatedBy}}" | head -3113MB
ls: /temporal.bin: No such file or directory
0B RUN rm /temporal.bin
105MB RUN dd if=/dev/zero of=/temporal.bin bs=1M count=100
8MB /bin/sh -c #(nop) ADD file:... in /El fitxer no existeix i la imatge continua pesant 113 MB. L'explicació és la de la lliçó 05-02: les capes són immutables i rm en una capa posterior només crea un whiteout que amaga el fitxer; els 105 MB continuen allà baix, es descarreguen a cada pull i s'emmagatzemen a cada node.
La correcció és unir creació i esborrat a la mateixa instrucció:
FROM alpine:3
RUN dd if=/dev/zero of=/temporal.bin bs=1M count=100 && \
echo "fer servir el fitxer..." && \
rm /temporal.binDe 113 MB a 8,15 MB. La mateixa lògica, el mateix resultat funcional, un && de diferència. I és exactament el motiu de --virtual .build al Dockerfile de l'apartat 6: instal·lar, compilar i desinstal·lar dins d'un sol RUN.
- Ordenar per a la memòria cau
Recordatori de la lliçó 02-02, ara combinat amb multietapa: les instruccions s'ordenen de menys a més canviant.
COPY package.json package-lock.json ./ # canvia poc
RUN npm ci --omit=dev # capa cara, reutilitzable
COPY src/ ./src/ # canvia a cada commitAmb multietapa l'efecte es multiplica: en tocar src/server.js, BuildKit reutilitza tota l'etapa dependencies —inclosa la instal·lació d'npm— i només refà les dues últimes capes de l'etapa final.
=> CACHED [dependencies 4/4] RUN npm ci --omit=dev
=> [produccio 5/5] COPY --chown=node:node src/ ./src/ 0.2s
real 0m3.184sTres segons davant dels quaranta i escaig d'una construcció neta. Optimitzar la mida i optimitzar la velocitat de construcció són, gairebé sempre, la mateixa feina.
- Verificació final i taula resum
Una imatge optimitzada que no funciona no val res. La comprovació és obligatòria:
docker compose up -d --wait
docker compose exec aurora-api node --version
curl -s http://localhost:8080/api/salut | jq -c
curl -s http://localhost:8080/api/llibres | jq -c '{origen, total}'
curl -s http://localhost:8080/api/llibres/3 | jq -c '{titol, autor}'
docker inspect aurora-libros-aurora-api-1 --format 'user={{.Config.User}} salut={{.State.Health.Status}}'v22.11.0
{"estat":"ok","bd":"connectada","cache":"connectada","version":"1.3.0"}
{"origen":"db","total":9}
{"titol":"Cien años de soledad","autor":"Gabriel García Márquez"}
user=node salut=healthyI l'últim esglaó, si el teu context ho permet: canviar la base final a distroless.
FROM gcr.io/distroless/nodejs22-debian12 AS produccio
COPY --from=dependencies --chown=1000:1000 /app/node_modules /app/node_modules
COPY --chown=1000:1000 src/ /app/src/
WORKDIR /app
USER 1000
CMD ["src/server.js"] # distroless ja té node com a ENTRYPOINTdocker build -t auroralibros/aurora-api:1.3.0-distroless ./api
docker image ls auroralibros/aurora-api --format "{{.Tag}}\t{{.Size}}"142 MB → 102 MB: un 28 % menys. El preu, ja conegut de la lliçó 05-03: sense sh no hi ha docker exec ... sh i el HEALTHCHECK amb wget deixa de funcionar, així que la sonda passa a fer-se des de Compose o des de l'orquestrador.
| Tècnica | Estalvi típic | Cost |
|---|---|---|
Base -alpine en comptes de completa |
800-900 MB | musl en lloc de glibc |
| Multietapa (fora compiladors i devDependencies) | 20-40 % | Dockerfile una mica més llarg |
--virtual + apk del al mateix RUN |
100-200 MB | Cap |
npm ci --omit=dev + cache clean |
40-70 % de node_modules |
Cap |
.dockerignore afinat |
Variable (aquí, 93 MB de context) | Cal mantenir-lo |
Agrupar RUN amb && |
El que ocupi el que és temporal | Menys granularitat de memòria cau |
| Base distroless | 15-25 MB més | Sense shell: depuració difícil |
| Fusionar totes les capes | Poc | Trenca la memòria cau: gairebé mai no compensa |
Errors Habituals i Consells
Optimitzar sense mesurar. Sense docker history i dive, es retalla on no fa mal i es deixa intacta la capa de 100 MB.
Esborrar fitxers en un RUN posterior. El fitxer desapareix i l'espai no. Creació i esborrat, a la mateixa instrucció.
Copiar tot el projecte amb COPY . . sense .dockerignore. Hi entren .git, node_modules i, amb sort, algun .env.
Instal·lar eines de compilació a la imatge final. Compiladors en producció són pes i superfície d'atac. Van a l'etapa de dependències.
Sacrificar el HEALTHCHECK o l'USER per estalviar uns megues. L'intercanvi és pèssim: la seguretat i l'operabilitat valen més que 3 MB.
Perseguir el mínim absolut. Un binari a scratch que no pots depurar costa més car a la primera incidència del que va estalviar en un any de descàrregues.
Consell: integra el mesurament al flux de treball. Un pas de CI que compari la mida de la imatge amb la de la versió anterior i avisi si creix més d'un 10 % detecta la dependència inflada el dia que entra, no sis mesos després.
Exercicis
Exercici 1. Analitza auroralibros/aurora-api:1.2.0 amb history i amb dive: identifica la capa més gran, calcula quin percentatge del total representa la base, i troba com a mínim un malbaratament real que puguis eliminar amb .dockerignore.
Exercici 2. Converteix el Dockerfile d'aurora-api a multietapa amb tres etapes (dependencies, desenvolupament, produccio), mesura l'abans i el després, i demostra que la imatge final no conté el compilador que sí que és a l'etapa de dependències.
Exercici 3. Demostra que esborrar un fitxer en una capa posterior no redueix la mida i arregla-ho. Calcula l'estalvi exacte i explica què hauria passat si aquell fitxer hagués estat un fitxer de credencials.
Solucions
Solució 1.
docker image history auroralibros/aurora-api:1.2.0 --format "{{.Size}}\t{{.CreatedBy}}" \
| sort -h -r | head -3
total=$(docker image inspect auroralibros/aurora-api:1.2.0 --format '{{.Size}}')
base=$(docker image inspect node:22-alpine --format '{{.Size}}')
echo "base: $((base * 100 / total)) % del total"115MB /bin/sh -c #(nop) ADD file:... in /
21.4MB RUN npm ci --omit=dev
3.1MB COPY src/ ./src/
base: 81 % del totalEl 81 % de la imatge és la base. És la dada que reordena les prioritats: barallar-se pels 3 MB del codi propi és irrellevant mentre no es decideixi conscientment quina base es fa servir. Amb dive apareix el malbaratament concret:
Potential wasted space: 9.7 MB
2 6.1 MB /app/node_modules/.cache
2 2.4 MB /root/.npm/_cacache
3 1.2 MB /app/.git.git dins d'una imatge de producció no és només 1,2 MB de pes: és l'historial complet del repositori viatjant al registre d'imatges, amb qualsevol secret que algú hagués fet servir en un commit i després esborrat. Es corregeix amb una línia al .dockerignore, i la comprovació és directa:
Solució 2.
docker build -t aurora-api:abans -f api/Dockerfile.mono ./api
docker build -t aurora-api:despres ./api
docker image ls aurora-api --format "{{.Tag}}\t{{.Size}}"# Hi és, el compilador, a cada etapa?
docker build -q --target dependencies -t aurora-api:deps ./api >/dev/null
docker run --rm aurora-api:deps sh -c 'which g++ make python3 | wc -l'
docker run --rm aurora-api:despres sh -c 'which g++ make python3 2>/dev/null | wc -l'
docker run --rm aurora-api:despres sh -c 'ls node_modules | wc -l'
docker run --rm aurora-api:deps sh -c 'ls node_modules | wc -l'L'etapa dependencies té els tres binaris de compilació; la final, cap. I tanmateix totes dues tenen els mateixos 64 paquets a node_modules: COPY --from=dependencies ha portat exactament el resultat de la feina i res de l'utillatge que la va produir.
Aquesta és la idea central de multietapa expressada de la manera més clara possible: el que necessites per construir no és el que necessites per executar. I el benefici no és només de mida; també és de seguretat, perquè un atacant amb execució de comandes a la imatge final no hi troba cap compilador amb què preparar la fase següent del seu atac.
Solució 3.
mkdir -p /tmp/b1 /tmp/b2
printf 'FROM alpine:3\nRUN dd if=/dev/zero of=/t.bin bs=1M count=100\nRUN rm /t.bin\n' > /tmp/b1/Dockerfile
printf 'FROM alpine:3\nRUN dd if=/dev/zero of=/t.bin bs=1M count=100 && rm /t.bin\n' > /tmp/b2/Dockerfile
docker build -q -t mal /tmp/b1 >/dev/null && docker build -q -t be /tmp/b2 >/dev/null
docker image ls mal be --format "{{.Repository}}\t{{.Size}}"
docker run --rm mal ls /t.bin 2>&1L'estalvi exacte són 104,85 MB, un 92,8 % del total, i el resultat funcional és idèntic: en totes dues imatges el fitxer no existeix. La diferència és si els 100 MB van arribar a formar part d'una capa consolidada. A mal, la capa A els va escriure i van quedar immutables; la capa B només hi va afegir un whiteout que els amaga. A be, el fitxer va néixer i va morir dins de la mateixa instrucció, així que quan BuildKit va consolidar la capa ja no hi era.
La pregunta sobre les credencials porta la demostració a la seva conclusió més incòmoda:
printf 'FROM alpine:3\nRUN echo "aurora:S3cr3t0_2026" > /cred.txt && cat /cred.txt >/dev/null\nRUN rm /cred.txt\n' > /tmp/b1/Dockerfile
docker build -q -t cred /tmp/b1 >/dev/null
docker run --rm cred ls /cred.txt 2>&1
docker save cred | tar -xO --wildcards '*/layer.tar' 2>/dev/null | strings | grep -o 'S3cr3t0_[0-9]*'El fitxer no existeix i la contrasenya es recupera de la capa exportada amb una sola comanda. Si aquella imatge s'hagués publicat a Docker Hub, qualsevol podria extreure-la amb docker pull i docker save, sense necessitat d'executar el contenidor. Per això el mateix && que estalvia 105 MB és també un control de seguretat, i per això la solució correcta per als secrets de construcció no és un && sinó RUN --mount=type=secret, que veuràs a la lliçó següent.
Conclusió
aurora-api ha passat de 142 MB a 102 MB, un 28 % menys, sense perdre l'usuari sense privilegis, el HEALTHCHECK, les etiquetes OCI ni un sol endpoint: /salut, /llibres i /llibres/:id responen igual i el contenidor continua arribant a healthy. I, més important que la xifra, tens el mètode: mesurar primer. docker image ls per al total, docker image history per trobar la capa grassa —que va resultar ser la base, amb el 81 % del pes— i dive per veure el malbaratament real, que va destapar la memòria cau d'npm i un .git que mai no hauria d'haver entrat al context.
Saps triar la base amb criteri i no per costum, coneixent la contrapartida de musl davant de glibc i què costa cada esglaó entre node:22, -slim, -alpine, distroless i scratch. Domines les construccions multietapa: una etapa que instal·la i compila amb build-base, una de desenvolupament amb les devDependencies que alimenta el target: desenvolupament del teu compose.override.yaml, una etapa de proves que trenca la construcció si alguna cosa falla, i una de final que només rep node_modules i src/ mitjançant COPY --from —demostrat: tres compiladors a l'etapa intermèdia, zero a la publicada—. I saps construir cadascuna per separat amb --target, a més de compartir una imatge base pròpia entre diversos serveis.
Del costat del contingut: --no-cache, --no-install-recommends, --virtual amb el seu apk del, npm ci --omit=dev, npm cache clean i un .dockerignore que va reduir el context de 94 MB a 812 kB. I la demostració que més val la pena recordar: esborrar un fitxer en una capa posterior no redueix la mida —113 MB davant de 8,15 MB per un &&—, i aquest mateix mecanisme fa que una credencial escrita i esborrada continuï sent extraïble de la imatge publicada.
A la lliçó 05-05 entra en escena el constructor que ha estat fent tot això per sota: BuildKit, amb el seu graf de dependències i el seu paral·lelisme entre etapes, i Buildx amb els seus builders. Veuràs els muntatges a RUN —type=cache per no reinstal·lar npm a cada build, type=bind, type=tmpfs i sobretot type=secret, la resposta correcta al problema de credencials que acabes de demostrar—, la memòria cau remota compartida amb --cache-from i --cache-to, la compilació multiarquitectura per a amd64 i arm64 amb les seves manifest lists, i docker buildx bake per construir totes les imatges d'Aurora Libros d'una sola vegada.
Docker: De Principiant a Avançat
Mòdul 1: Introducció a Docker
- Què és Docker?
- Instal·lant Docker
- Arquitectura de Docker
- Comandes Bàsiques de Docker
- Entenent les Imatges de Docker
- Creant el teu Primer Contenidor Docker
- El Projecte del Curs: la Plataforma Aurora Libros
Mòdul 2: Treballant amb Imatges Docker
- Docker Hub i Repositoris
- Construint Imatges Docker
- Conceptes Bàsics de Dockerfile
- Instruccions Avançades del Dockerfile
- Gestionant Imatges Docker
- Etiquetatge i Publicació d'Imatges
Mòdul 3: Contenidors Docker
- Executant Contenidors
- Cicle de Vida del Contenidor
- Gestionant Contenidors
- Inspecció i Depuració de Contenidors
- Xarxes a Docker
- Persistència de Dades amb Volums
- Límits de Recursos i Polítiques de Reinici
Mòdul 4: Docker Compose
- Introducció a Docker Compose
- Definint Serveis a Docker Compose
- Comandes de Docker Compose
- Aplicacions Multi-Contenidor
- Variables d'Entorn a Docker Compose
- Perfils, Overrides i Múltiples Entorns
- Desenvolupament Local amb Docker Compose
Mòdul 5: Conceptes Avançats de Docker
- Aprofundiment en Xarxes Docker
- Opcions d'Emmagatzematge Docker
- Millors Pràctiques de Seguretat a Docker
- Optimitzant Imatges Docker
- Builds Avançades amb BuildKit i Buildx
- Registre i Monitoratge a Docker
- El Runtime per Dins: Namespaces, Cgroups i Capes
Mòdul 6: Docker en Producció
- Preparar una Imatge per a Producció
- CI/CD amb Docker
- Orquestrant Contenidors amb Docker Swarm
- Introducció a Kubernetes
- Desplegant Contenidors Docker a Kubernetes
- Escalat i Balanceig de Càrrega
- Estratègies de Desplegament i Rollback
