Fa tres lliçons que construeixes. Cada docker build de les anteriors ha deixat capes al teu disc, i a hores d'ara la teva màquina acumula auroralibros/aurora-api en diverses versions, les bases node, postgres, redis, nginx i alpine, les imatges de laboratori dels exercicis i una memòria cau de BuildKit que no has mirat mai. Aquesta lliçó tracta d'administrar aquest magatzem: saber què tens, per què ocupa el que ocupa, com auditar de què està feta una imatge, com esborrar sense endur-te per davant el que necessites, d'on surten aquelles misterioses imatges <none>:<none> que apareixen build rere build, i com endur-te una imatge a una altra màquina quan no hi ha cap registre pel mig. És la lliçó menys vistosa del mòdul i la que més disgustos t'estalviarà: un docker system prune -a --volumes mal entès esborra en deu segons dades que van costar setmanes.

Contingut

  1. Llistar imatges: docker image ls i les seves opcions
  2. Inspeccionar: docker image inspect i --format
  3. Auditar com es va fer: docker image history
  4. Esborrar imatges: docker image rm
  5. Imatges dangling: les <none>:<none>
  6. Neteja amb la família prune
  7. Diagnòstic de l'espai: docker system df
  8. Portar imatges sense registre: save/load i export/import
  9. Rutina de manteniment recomanada

  1. Llistar imatges: docker image ls i les seves opcions

El punt de partida, amb la gramàtica docker <objecte> <acció> de la lliçó 01-04:

docker image ls
REPOSITORY                TAG          IMAGE ID       CREATED          SIZE
auroralibros/aurora-api   1.1.0        4e9c7d2a8f31   10 minutes ago   167MB
auroralibros/aurora-api   1.0.0        8c1e4a7f2b9d   35 minutes ago   167MB
auroralibros/aurora-api   0.1.0        6b4d2f8e1a3c   58 minutes ago   167MB
node                      22-alpine    9f2c1a5e7b04   6 days ago       142MB
postgres                  16-alpine    b71c3d8f4a29   9 days ago       278MB
redis                     7-alpine     3e5a9c1d7b82   9 days ago       41.4MB
nginx                     alpine       c8d4f2a91e37   11 days ago      52.5MB
alpine                    3.21         a1e7f9c34d02   3 weeks ago      8.17MB
registry                  2            7f1e2b8c5a43   2 months ago     25.4MB

docker images és l'àlies curt i fa exactament el mateix.

Un avís fonamental sobre la columna SIZE, que ja vas intuir a la lliçó 01-05: les mides no se sumen. Les tres versions d'aurora-api diuen 167 MB cadascuna, però no ocupen 501 MB al disc. Comparteixen la base node:22-alpine i bona part de les seves capes; l'espai real el dirà docker system df a l'apartat 7.

Opcions de llistat

# -a: inclou les capes intermèdies (amb el constructor clàssic)
docker image ls -a

# --digests: mostra el digest sha256 de cada imatge
docker image ls --digests node

# -q: només els ID, ideal per encadenar comandes
docker image ls -q

# --no-trunc: ID complets, sense abreujar
docker image ls --no-trunc
docker image ls --digests auroralibros/aurora-api
REPOSITORY                TAG     DIGEST                              IMAGE ID       SIZE
auroralibros/aurora-api   1.1.0   <none>                              4e9c7d2a8f31   167MB
auroralibros/aurora-api   1.0.0   <none>                              8c1e4a7f2b9d   167MB

El digest surt <none> perquè aquestes imatges es van construir en local i no s'han publicat mai: el digest del manifest l'assigna el registre en rebre el push. Així que les publiquis a la lliçó 02-06, aquella columna s'omplirà.

Filtrar amb --filter

# Imatges d'un repositori concret
docker image ls auroralibros/aurora-api

# Amb comodí al nom
docker image ls "auroralibros/*"

# Només les dangling (apartat 5)
docker image ls --filter "dangling=true"

# Anteriors a una imatge donada
docker image ls --filter "before=auroralibros/aurora-api:1.0.0"

# Posteriors a una imatge donada
docker image ls --filter "since=node:22-alpine"

# Per etiqueta OCI, les que vas afegir a 02-04
docker image ls --filter "label=org.opencontainers.image.vendor=Aurora Libros S.L."
REPOSITORY                TAG     IMAGE ID       CREATED          SIZE
auroralibros/aurora-api   1.1.0   4e9c7d2a8f31   12 minutes ago   167MB

Només apareix la 1.1.0, perquè és l'única que porta les etiquetes OCI. Aquí es veu el rendiment pràctic de la feina de la lliçó anterior: les metadades no eren decoració, són un índex consultable.

Format personalitzat amb plantilles Go

Recuperant --format de la lliçó 01-04:

docker image ls --format "table {{.Repository}}:{{.Tag}}\t{{.Size}}\t{{.CreatedSince}}"
REPOSITORY:TAG                        SIZE      CREATED
auroralibros/aurora-api:1.1.0         167MB     13 minutes ago
auroralibros/aurora-api:1.0.0         167MB     38 minutes ago
node:22-alpine                        142MB     6 days ago

Camps disponibles: .ID, .Repository, .Tag, .Digest, .CreatedSince, .CreatedAt, .Size.

Sense la paraula table, la sortida és text pla, perfecte per a scripts:

docker image ls --format "{{.Repository}}:{{.Tag}}" --filter "reference=auroralibros/*"
auroralibros/aurora-api:1.1.0
auroralibros/aurora-api:1.0.0
auroralibros/aurora-api:0.1.0

I en JSON, per processar amb jq:

docker image ls --format json | head -1
{"Containers":"N/A","CreatedAt":"2026-08-04 11:42:03 +0200 CEST","CreatedSince":"14 minutes ago","Digest":"<none>","ID":"4e9c7d2a8f31","Repository":"auroralibros/aurora-api","Size":"167MB","Tag":"1.1.0"}

  1. Inspeccionar: docker image inspect i --format

docker image inspect bolca totes les metadades d'una imatge en JSON. Sense filtre són centenars de línies:

docker image inspect auroralibros/aurora-api:1.1.0 | wc -l
187

La gràcia és extreure'n només el que necessites. La sintaxi de --format és la mateixa de la lliçó 01-04, i aquests són els camps que més faràs servir:

# El procés que arrenca el contenidor
docker image inspect auroralibros/aurora-api:1.1.0 --format '{{json .Config.Entrypoint}} {{json .Config.Cmd}}'
["node"] ["server.js"]
# Variables d'entorn, una per línia
docker image inspect auroralibros/aurora-api:1.1.0 --format '{{range .Config.Env}}{{println .}}{{end}}'
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NODE_VERSION=22.14.0
YARN_VERSION=1.22.22
NODE_ENV=production
PORT=3000
APP_VERSION=1.1.0

Aquesta és la comanda amb què audites que no hi ha cap secret dins d'una imatge abans de publicar-la. Converteix-la en un reflex.

# Usuari, directori de treball i ports declarats
docker image inspect auroralibros/aurora-api:1.1.0 \
  --format 'Usuari:   {{.Config.User}}
WorkDir:  {{.Config.WorkingDir}}
Ports:    {{range $p, $_ := .Config.ExposedPorts}}{{$p}} {{end}}'
Usuari:   node
WorkDir:  /app
Ports:    3000/tcp
# Arquitectura i sistema operatiu: crític en màquines ARM
docker image inspect node:22-alpine --format '{{.Os}}/{{.Architecture}} · Docker {{.DockerVersion}}'
linux/amd64 · Docker 27.4.1

Si això digués linux/amd64 i fossis en un Mac amb Apple Silicon, la imatge funcionaria per emulació, molt més lenta. És la primera comprovació davant d'un contenidor inexplicablement lent.

# Les capes: els digests del sistema de fitxers
docker image inspect auroralibros/aurora-api:1.1.0 --format '{{range .RootFS.Layers}}{{println .}}{{end}}'
sha256:4a1b8c2f9e3d7a5b1c8f2e6d4a9b3c7e1f5d8a2b6c4e9f3a7d1b5c8e2f6a4d9b
sha256:8f3e1d7c5b9a2f4e8d6c1b3a7f9e5d2c8b4a6f1e3d7c9b5a2f8e4d6c1b3a7f9e
...
# Recompte ràpid de capes: bon indicador de complexitat
docker image inspect auroralibros/aurora-api:1.1.0 --format '{{len .RootFS.Layers}} capes'
7 capes
# Les etiquetes OCI de la lliçó 02-04
docker image inspect auroralibros/aurora-api:1.1.0 \
  --format '{{index .Config.Labels "org.opencontainers.image.revision"}}'
7a3f912

Una comanda, i ja saps exactament quin commit porta dins aquella imatge.

Pots inspeccionar-ne diverses alhora i comparar-les:

docker image inspect --format '{{.RepoTags}} → {{.Size}} bytes, {{len .RootFS.Layers}} capes' \
  auroralibros/aurora-api:1.1.0 node:22-alpine alpine:3.21
[auroralibros/aurora-api:1.1.0] → 167142891 bytes, 7 capes
[node:22-alpine] → 142331904 bytes, 4 capes
[alpine:3.21] → 8172544 bytes, 1 capes

Aquí es veu la genealogia completa: Alpine aporta 1 capa, Node n'hi afegeix 3 més, i el teu Dockerfile les 3 restants (els dos COPY i el RUN).

  1. Auditar com es va fer: docker image history

docker image history reconstrueix la història de construcció d'una imatge capa a capa. És l'eina d'auditoria per excel·lència i ja la vas fer servir a la lliçó 02-01 per avaluar imatges alienes.

docker image history auroralibros/aurora-api:1.1.0
IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
4e9c7d2a8f31   18 minutes ago   CMD ["server.js"]                               0B        buildkit.dockerfile.v0
<missing>      18 minutes ago   ENTRYPOINT ["node"]                             0B        buildkit.dockerfile.v0
<missing>      18 minutes ago   HEALTHCHECK &{["CMD-SHELL" "wget --quiet --…    0B        buildkit.dockerfile.v0
<missing>      18 minutes ago   EXPOSE map[3000/tcp:{}]                         0B        buildkit.dockerfile.v0
<missing>      18 minutes ago   USER node                                       0B        buildkit.dockerfile.v0
<missing>      18 minutes ago   ENV NODE_ENV=production PORT=3000 APP_VERSI…    0B        buildkit.dockerfile.v0
<missing>      18 minutes ago   COPY . . # buildkit                             52.1kB    buildkit.dockerfile.v0
<missing>      18 minutes ago   RUN /bin/sh -c npm ci --omit=dev && npm cac…    24.7MB    buildkit.dockerfile.v0
<missing>      18 minutes ago   COPY package*.json ./ # buildkit                44.6kB    buildkit.dockerfile.v0
<missing>      18 minutes ago   WORKDIR /app                                    0B        buildkit.dockerfile.v0
<missing>      18 minutes ago   LABEL org.opencontainers.image.title=auror…     0B        buildkit.dockerfile.v0
<missing>      6 days ago       CMD ["node"]                                    0B        buildkit.dockerfile.v0
<missing>      6 days ago       ENTRYPOINT ["docker-entrypoint.sh"]             0B        buildkit.dockerfile.v0
<missing>      6 days ago       RUN /bin/sh -c apk add --no-cache --virtual…    7.82MB    buildkit.dockerfile.v0
<missing>      6 days ago       ENV NODE_VERSION=22.14.0                        0B        buildkit.dockerfile.v0
<missing>      6 days ago       /bin/sh -c #(nop) ADD file:1b8a2c9e4d7f… in /   8.17MB

Com llegir-ho:

  • Es llegeix de baix a dalt. L'última línia és la primera capa (el sistema de fitxers base d'Alpine); la primera línia és la instrucció més recent.
  • <missing> no és un error. Només la capa superior té un ID propi; les intermèdies d'una imatge construïda amb BuildKit no l'exposen. És normal.
  • La columna SIZE és la que importa. Allà es veu que el RUN npm ci aporta 24,7 MB i els dos COPY amb prou feines 52 kB i 44 kB junts. Totes les metadades —ENV, EXPOSE, USER, LABEL, HEALTHCHECK, ENTRYPOINT, CMD— pesen 0 B, exactament com es va anunciar a la lliçó anterior.
  • La història inclou la de la imatge base. Les línies de "6 dies" són de node:22-alpine: veus com la van construir els seus mantenidors.

Localitzar la capa que més pesa

És l'ús més rendible de la comanda:

docker image history auroralibros/aurora-api:1.1.0 --format "{{.Size}}\t{{.CreatedBy}}" --no-trunc | sort -rh | head -5
24.7MB   RUN /bin/sh -c npm ci --omit=dev && npm cache clean --force # buildkit
8.17MB   /bin/sh -c #(nop) ADD file:1b8a2c9e4d7f... in /
7.82MB   RUN /bin/sh -c apk add --no-cache --virtual .build-deps ...
52.1kB   COPY . . # buildkit
44.6kB   COPY package*.json ./ # buildkit

Quan una imatge pesa 900 MB i no saps per què, aquesta comanda et dona la resposta en un segon. Els sospitosos habituals: memòries cau de gestors de paquets sense netejar, eines de compilació que s'hi van quedar dins i fitxers temporals esborrats en una altra capa (amb l'efecte nul que vas demostrar a la lliçó 02-03).

--no-trunc: veure la comanda completa

Per defecte la columna CREATED BY es talla. Per auditar de debò, cal el text sencer:

docker image history node:22-alpine --no-trunc --format "{{.CreatedBy}}" | head -3

Aquesta és la comanda amb què detectes en una imatge aliena un curl … | sh sospitós, la instal·lació d'una eina que no esperaves o, a la teva pròpia imatge abans de publicar-la, un --build-arg amb una contrasenya com el de la lliçó 02-04.

Una limitació honesta: history mostra les instruccions, no el contingut. Un fitxer copiat amb COPY no es veu aquí. Per a això, arrencar la imatge i mirar (docker run --rm imatge ls -la /app) o eines de tercers com dive (lliçó 07-04).

  1. Esborrar imatges: docker image rm

docker image rm auroralibros/aurora-api:0.1.0
Untagged: auroralibros/aurora-api:0.1.0
Deleted: sha256:6b4d2f8e1a3c...
Deleted: sha256:9a2f7c1e5b8d...

docker rmi és l'àlies curt. Fixa't en la sortida: Untagged i Deleted són dues coses diferents, i entendre'n la diferència és la clau de tot aquest apartat.

Esborrar una de diverses etiquetes

Quan dues etiquetes apunten a la mateixa imatge (el mateix IMAGE ID), esborrar-ne una no esborra la imatge:

docker image tag auroralibros/aurora-api:1.1.0 auroralibros/aurora-api:estable
docker image ls auroralibros/aurora-api
REPOSITORY                TAG       IMAGE ID       SIZE
auroralibros/aurora-api   1.1.0     4e9c7d2a8f31   167MB
auroralibros/aurora-api   estable   4e9c7d2a8f31   167MB

Mateix IMAGE ID: és una imatge amb dos noms, no dues imatges de 167 MB. Ara esborra'n una:

docker image rm auroralibros/aurora-api:estable
Untagged: auroralibros/aurora-api:estable

Només Untagged, sense cap Deleted. S'ha tret el nom; les dades continuen sent-hi perquè 1.1.0 les continua referenciant. El Deleted només apareix quan desapareix l'última referència. Aquesta és la raó que de vegades esborris una imatge i no recuperis ni un byte de disc.

Esborrar per ID i per digest

# Per ID (n'hi ha prou amb un prefix inequívoc)
docker image rm 4e9c7d2a

# Per digest, després d'haver publicat la imatge
docker image rm node@sha256:9f2c1a5e7b04...

Esborrar per ID quan hi ha diverses etiquetes apuntant a aquella imatge falla:

Error response from daemon: conflict: unable to delete 4e9c7d2a8f31 (must be forced)
- image is referenced in multiple repositories

Docker s'hi nega perquè no sap quin nom vols eliminar. O esborres cada etiqueta pel seu nom, o fas servir -f per eliminar-les totes de cop.

L'error de la imatge en ús

El més freqüent de tots:

docker run -d --name aurora-demo auroralibros/aurora-api:1.1.0
docker stop aurora-demo
docker image rm auroralibros/aurora-api:1.1.0
Error response from daemon: conflict: unable to remove repository reference
"auroralibros/aurora-api:1.1.0" (must force) - container 3f8a1c9b7e2d is using its
referenced image 4e9c7d2a8f31

El contenidor està aturat, no en execució, i tot i així bloqueja l'esborrat. Té tota la lògica: com vas aprendre a la lliçó 01-05, un contenidor aturat conserva la seva capa d'escriptura, que s'apila a sobre de les capes de la imatge. Esborrar la imatge deixaria aquella capa flotant sobre el no-res, i el contenidor no podria tornar a arrencar.

Les tres sortides possibles:

# a) Localitzar els contenidors que la fan servir
docker ps -a --filter ancestor=auroralibros/aurora-api:1.1.0

# b) Esborrar el contenidor i després la imatge — LA FORMA CORRECTA
docker rm aurora-demo
docker image rm auroralibros/aurora-api:1.1.0

# c) Forçar
docker image rm -f auroralibros/aurora-api:1.1.0

Quan és acceptable -f? Menys vegades de les que es fa servir:

Situació -f? Alternativa
Contenidor aturat que ja no necessites Acceptable Millor docker rm primer: més explícit
Diverses etiquetes apuntant a la mateixa imatge i les vols esborrar totes És l'ús legítim
Contenidor en execució No Atura'l abans, amb el seu cicle de vida ordenat
No saps per què falla No Investiga amb docker ps -a --filter ancestor=…

El perill de -f sobre un contenidor en execució: la imatge queda "esborrada" del llistat però les seves capes continuen ocupant disc mentre el contenidor visqui, i el contenidor no podrà reiniciar-se quan s'aturi. Acabes amb un servei que funciona fins al primer reinici i després és irrecuperable, sense cap manera de reconstruir-lo llevat del registre. És un incident de producció clàssic.

Esborrat massiu

# Totes les imatges d'un repositori
docker image rm $(docker image ls -q auroralibros/aurora-api)

# TOTES les imatges (compte!)
docker image rm -f $(docker image ls -aq)

El patró $(docker image ls -q …) combina -q (només ID) amb la substitució de comandes de l'intèrpret d'ordres. Abans d'executar un esborrat massiu, executa primer només la part interna per veure què destruiràs:

docker image ls auroralibros/aurora-api    # Mira què hi ha
docker image rm $(docker image ls -q auroralibros/aurora-api)   # I aleshores esborra

  1. Imatges dangling: les <none>:<none>

Tard o d'hora veuràs això:

REPOSITORY                TAG       IMAGE ID       CREATED          SIZE
<none>                    <none>    2f8e1a9c4b73   5 minutes ago    167MB
<none>                    <none>    7d3c9f2e8a51   22 minutes ago   167MB
auroralibros/aurora-api   1.1.0     4e9c7d2a8f31   30 minutes ago   167MB

Aquestes <none>:<none> són imatges dangling (penjants): imatges reals, completes i perfectament funcionals, que han perdut el nom.

D'on surten

La causa principal, amb diferència, és reconstruir amb la mateixa etiqueta:

cd ~/aurora-libros/api
docker build -t auroralibros/aurora-api:1.1.0 .    # Imatge A ← 1.1.0
echo "// un canvi" >> server.js
docker build -t auroralibros/aurora-api:1.1.0 .    # Imatge B ← 1.1.0

A la segona build neix una imatge nova (contingut diferent, ID diferent) i l'etiqueta 1.1.0 es mou cap a ella. La imatge A no s'esborra: es queda sense nom. És exactament el model de la lliçó 02-01 —les etiquetes són punters mòbils a digests immutables—, vist des del costat local.

Comprova-ho:

docker image ls --filter "dangling=true"
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
<none>       <none>    2f8e1a9c4b73   2 minutes ago   167MB

Les altres dues fonts:

  • Builds sense -t. docker build . produeix una imatge sense nom des del primer segon. És el motiu del consell de la lliçó 02-02: etiqueta sempre.
  • Builds fallides que van deixar capes intermèdies.

Per què importen

Perquè s'acumulen en silenci. Un desenvolupador que reconstrueix vint vegades al dia amb la mateixa etiqueta genera vint imatges dangling diàries. La majoria comparteixen capes i no ocupen 167 MB cadascuna, però les capes pròpies (el COPY . . i de vegades el RUN npm ci) sí que són exclusives. En unes setmanes són uns quants gigabytes, i el missatge no space left on device arriba en el pitjor moment.

No són brossa absoluta: si en saps l'ID, les pots executar i fins i tot reetiquetar.

docker image tag 2f8e1a9c4b73 recuperada:1.0

Això et treu del pas quan esborres per error l'etiqueta d'una imatge que encara no havies publicat. Però com a pràctica habitual, es netegen.

  1. Neteja amb la família prune

Quatre comandes, amb quatre radis de destrucció molt diferents. Aquesta taula és la que cal memoritzar:

Comanda Què esborra Risc
docker image prune Només imatges dangling Baix: és segur gairebé sempre
docker image prune -a Totes les imatges sense cap contenidor que les faci servir Mitjà: t'obliga a tornar a descarregar bases
docker builder prune La memòria cau de BuildKit Mitjà: les builds següents seran lentes
docker system prune Contenidors aturats + xarxes sense fer servir + dangling + memòria cau de build Mitjà-alt
docker system prune -a --volumes Tot l'anterior + totes les imatges sense contenidor + volums MOLT ALT: destrueix dades

docker image prune

docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Deleted Images:
deleted: sha256:2f8e1a9c4b73...
deleted: sha256:7d3c9f2e8a51...

Total reclaimed space: 51.3MB

Aquest és el que pots executar amb confiança: només s'endú imatges sense nom. Amb -f se salta la confirmació (útil en scripts) i amb --filter "until=168h" limita l'esborrat a les de més d'una setmana:

docker image prune -f --filter "until=168h"

docker image prune -a

docker image prune -a
WARNING! This will remove all images without at least one container associated to them.
Are you sure you want to continue? [y/N]

Llegeix bé l'avís: esborra totes les imatges que no tinguin un contenidor associat, no només les dangling. Si no tens contenidors creats —el normal després de netejar—, això s'endú node:22-alpine, postgres:16-alpine, redis:7-alpine, les teves aurora-api locals i tota la resta. No és catastròfic (es pot reconstruir i tornar a descarregar), però significa gigabytes de descàrrega i, si estàs sense connexió o a prop del límit de descàrregues de la lliçó 02-01, una mala estona.

docker builder prune

La memòria cau de BuildKit és invisible a docker image ls i sol ser el més voluminós de la màquina:

docker builder prune
WARNING! This will remove all dangling build cache. Are you sure you want to continue? [y/N] y
Total:  2.847GB

Gairebé tres gigues que no apareixien en cap llistat d'imatges. Variants:

docker builder prune -a                      # També la memòria cau en ús
docker builder prune --filter "until=72h"    # Només l'anterior a 3 dies
docker builder prune --keep-storage=10GB     # Deixa fins a 10 GB de memòria cau

La contrapartida: la build següent de cada projecte anirà en fred. Recorda de la lliçó 02-02 que és allà on la memòria cau no ajuda.

docker system prune

docker system prune
WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all dangling images
  - unused build cache

Are you sure you want to continue? [y/N] y

Deleted Containers:
3f8a1c9b7e2d...
Deleted Networks:
aurora-xarxa-proves
Deleted Images:
deleted: sha256:2f8e1a9c4b73...
Total reclaimed space: 3.12GB

L'avís llista exactament el que esborrarà. Llegeix-lo sempre: és la diferència entre netejar i perdre feina. El que s'endú per sorpresa sol ser un contenidor aturat que contenia dades a la seva capa d'escriptura, o una xarxa que havies creat a mà per a unes proves.

docker system prune -a --volumes: la comanda perillosa

docker system prune -a --volumes
WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all volumes not used by at least one container
  - all images without at least one container associated to them
  - all build cache

Aquesta és la línia que t'arruïna el dia: all volumes not used by at least one container.

Traduït a Aurora Libros: quan al mòdul 3 tinguis un volum amb el catàleg de PostgreSQL i hagis aturat i esborrat el contenidor d'aurora-db per recrear-lo, aquell volum queda temporalment sense contenidor associat. Un docker system prune -a --volumes en aquell moment esborra la base de dades sencera. Sense paperera, sense desfer, sense recuperació.

Regles d'ús:

  • Mai en un servidor. Mai.
  • En desenvolupament, només quan tinguis clar que no hi ha cap volum que t'importi.
  • Abans d'executar-lo, mira quins volums hi ha:
docker volume ls
docker system df -v | head -20
  • Si només vols espai, l'escala segura és: docker image prunedocker builder prunedocker system prune. Poques vegades cal arribar a l'últim esglaó.

  1. Diagnòstic de l'espai: docker system df

Abans d'esborrar res, mesura.

docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          9         2         842.3MB   601.7MB (71%)
Containers      4         1         12.4MB    9.1MB (73%)
Local Volumes   3         1         248.9MB   187.2MB (75%)
Build Cache     47        0         2.847GB   2.847GB (100%)

Com llegir-ho:

Columna Significat
TOTAL Nombre d'objectes d'aquell tipus
ACTIVE Els que estan en ús (imatges amb contenidor, volums muntats…)
SIZE Espai real al disc, ja descomptades les capes compartides
RECLAIMABLE Quant alliberaries en netejar, i quin percentatge del total és

Dues conclusions immediates d'aquest exemple:

  1. Nou imatges ocupen 842 MB, no la suma de les seves columnes SIZE a docker image ls (que donaria més d'1,2 GB). La diferència són les capes compartides de la lliçó 01-05, comptades una sola vegada.
  2. La memòria cau de build és de 2,85 GB, el 100 % recuperable, i és amb diferència el més gran. És el primer que cal netejar, i no apareixia en cap llistat d'imatges.

El detall amb -v

docker system df -v
Images space usage:

REPOSITORY                TAG         IMAGE ID       SIZE      SHARED SIZE   UNIQUE SIZE   CONTAINERS
auroralibros/aurora-api   1.1.0       4e9c7d2a8f31   167MB     142MB         24.8MB        1
auroralibros/aurora-api   1.0.0       8c1e4a7f2b9d   167MB     142MB         24.7MB        0
node                      22-alpine   9f2c1a5e7b04   142MB     142MB         0B            0
postgres                  16-alpine   b71c3d8f4a29   278MB     8.17MB        270MB         0

Containers space usage:

CONTAINER ID   IMAGE                           SIZE      STATUS
3f8a1c9b7e2d   auroralibros/aurora-api:1.1.0   4.2MB     Up 12 minutes

Local Volumes space usage:

VOLUME NAME                                   LINKS     SIZE
aurora-dades-db                               1         187.2MB
f3a9c2e1b8d7460a2c5f8e1d4b7a3c9e2f6d8a1b     0         61.7MB

Les columnes SHARED SIZE i UNIQUE SIZE són les que ho aclareixen tot:

  • node:22-alpine: 142 MB de mida, 142 MB compartits, 0 B únics. Esborrar-la no alliberaria res, perquè totes les seves capes les fan servir les teves imatges d'aurora-api.
  • aurora-api:1.0.0: 167 MB, dels quals només 24,7 MB són exclusius. Això és el que guanyaries en esborrar-la.
  • postgres:16-alpine: 278 MB amb 270 MB únics. Aquesta sí que és una bona candidata si no l'has de fer servir.

I mira l'última línia de volums: f3a9c2e1b8d7… amb 0 links és un volum anònim orfe, exactament el que anticipava la lliçó 02-04 en desaconsellar VOLUME al Dockerfile. Ocupa 61,7 MB i ningú no sap què conté.

  1. Portar imatges sense registre: save/load i export/import

De vegades cal portar una imatge a una altra màquina sense cap registre pel mig: un client amb la xarxa aïllada, un entorn sense sortida a Internet, una demostració en un portàtil sense connexió. Docker ofereix dues parelles de comandes que es confonen constantment i que no són intercanviables.

Aspecte save / load export / import
Opera sobre Una imatge Un contenidor
Què desa Totes les capes + manifest + metadades El sistema de fitxers aplanat, sense capes
Conserva l'historial No
Conserva CMD, ENTRYPOINT, ENV, USER, EXPOSE No
Conserva etiquetes d'imatge No (cal reetiquetar)
Diverses imatges en un fitxer No
Mida del .tar Més gran (totes les capes) Més petita (un sol nivell)
Ús correcte Portar imatges Extreure un sistema de fitxers, aplanar

La regla: per moure una imatge, sempre save/load. export/import serveix per a una altra cosa.

docker save / docker load amb Aurora Libros

# 1. Exportar la imatge a un fitxer tar
docker save -o aurora-api-1.1.0.tar auroralibros/aurora-api:1.1.0
ls -lh aurora-api-1.1.0.tar
-rw------- 1 joan joan 168M ago  4 12:14 aurora-api-1.1.0.tar
# 2. Comprimir: les capes són sobretot text i binaris, comprimeixen bé
gzip -9 aurora-api-1.1.0.tar
ls -lh aurora-api-1.1.0.tar.gz
-rw------- 1 joan joan 62M ago  4 12:15 aurora-api-1.1.0.tar.gz

De 168 MB a 62 MB: un 63 % menys, i això és el que viatja pel llapis de memòria o l'SCP. També es pot fer en un sol pas amb una canonada:

docker save auroralibros/aurora-api:1.1.0 | gzip -9 > aurora-api-1.1.0.tar.gz
# 3. Transferir a l'altra màquina
scp aurora-api-1.1.0.tar.gz operador@servidor-aurora:/tmp/

# 4. Carregar-la allà
ssh operador@servidor-aurora
gunzip -c /tmp/aurora-api-1.1.0.tar.gz | docker load
Loaded image: auroralibros/aurora-api:1.1.0
# 5. Verificar que ha arribat completa
docker image ls auroralibros/aurora-api
docker image inspect auroralibros/aurora-api:1.1.0 --format '{{json .Config.Entrypoint}} · {{.Config.User}}'
docker run -d --name aurora-portada -p 3000:3000 auroralibros/aurora-api:1.1.0
curl -s http://localhost:3000/salut
REPOSITORY                TAG     IMAGE ID       CREATED          SIZE
auroralibros/aurora-api   1.1.0   4e9c7d2a8f31   45 minutes ago   167MB

["node"] · node

{"servei":"aurora-api","version":"1.0.0","db":"ko","cache":"ko",...}

Mateix IMAGE ID, mateix ENTRYPOINT, mateix USER. La imatge ha arribat íntegra, amb totes les metadades que vas definir a la lliçó 02-04.

Desar diverses imatges en un sol fitxer, útil per endur-te la pila sencera d'Aurora Libros:

docker save -o aurora-pila.tar \
  auroralibros/aurora-api:1.1.0 \
  postgres:16-alpine \
  redis:7-alpine \
  nginx:alpine
ls -lh aurora-pila.tar
-rw------- 1 joan joan 512M ago  4 12:22 aurora-pila.tar

Un únic fitxer amb tot el necessari per aixecar la plataforma en una màquina sense Internet.

docker export / docker import

Treballa sobre contenidors, no imatges, i aplana el resultat:

docker run -d --name per-exportar auroralibros/aurora-api:1.1.0
docker export -o aurora-pla.tar per-exportar
ls -lh aurora-pla.tar
-rw------- 1 joan joan 158M ago  4 12:25 aurora-pla.tar
docker import aurora-pla.tar aurora-plana:1.0
docker image history aurora-plana:1.0
IMAGE          CREATED         CREATED BY   SIZE      COMMENT
5c9e2f7a1b83   4 seconds ago                158MB     Imported from -

Una sola capa i cap historial. Tota la genealogia ha desaparegut. I el més greu:

docker run --rm aurora-plana:1.0
docker: Error response from daemon: no command specified.

S'han perdut l'ENTRYPOINT, el CMD, l'ENV, l'USER i l'EXPOSE. La imatge importada és un sistema de fitxers sense instruccions. Caldria reposar-los a mà en executar:

docker run --rm -u node -e NODE_ENV=production -w /app aurora-plana:1.0 node server.js

Aleshores, per a què serveix? Per a dues coses legítimes:

  1. Aplanar una imatge amb massa capes o amb un secret enterrat en una capa intermèdia que vols eliminar de debò. En aplanar, aquella capa desapareix. (La manera moderna i millor d'aconseguir-ho són les builds multietapa, lliçó 05-04.)
  2. Extreure el sistema de fitxers d'un contenidor per analitzar-lo forensement o per construir una imatge base a partir d'un sistema existent.

Es poden reposar les metadades en importar, amb -c:

docker import \
  -c 'ENTRYPOINT ["node"]' \
  -c 'CMD ["server.js"]' \
  -c 'WORKDIR /app' \
  -c 'USER node' \
  -c 'ENV NODE_ENV=production PORT=3000' \
  -c 'EXPOSE 3000' \
  aurora-pla.tar aurora-plana:1.1
docker run -d --name plana-ok -p 3001:3000 aurora-plana:1.1
curl -s http://localhost:3001/salut | head -c 60
{"servei":"aurora-api","version":"1.0.0","db":"ko","cache":"ko"

Funciona, però has hagut de reconstruir a mà el que save conservava tot sol. Queda clar quina és l'eina adequada per portar imatges.

Neteja:

docker rm -f per-exportar plana-ok aurora-portada 2>/dev/null
docker image rm aurora-plana:1.0 aurora-plana:1.1 2>/dev/null
rm -f aurora-pla.tar

  1. Rutina de manteniment recomanada

Amb tot això, aquesta és una rutina raonable per a una màquina de desenvolupament.

Setmanal (segura, es pot automatitzar):

docker image prune -f
docker builder prune -f --filter "until=168h"
docker system df

Esborra les dangling i la memòria cau de build de més d'una setmana, i mostra com queda l'espai. No toca res amb nom, ni contenidors, ni volums.

Mensual (revisió manual):

docker system df -v | head -40                    # Què ocupa i què és únic?
docker image ls --filter "before=$(date -d '30 days ago' +%Y-%m-%d)" 2>/dev/null
docker volume ls -f dangling=true                 # Volums orfes: MIRA què són
docker ps -a --filter status=exited               # Contenidors aturats oblidats

Aquí no s'automatitza res: es mira i es decideix. Els volums orfes s'han d'inspeccionar abans d'esborrar-los, perquè poden contenir dades.

Abans d'una build important:

docker builder prune -f
docker build --no-cache --pull -t auroralibros/aurora-api:1.1.0 .

Memòria cau neta i base actualitzada, com es va explicar a la lliçó 02-02.

Quan falta espai, l'escala segura:

docker system df                                  # 1. Mesura abans de tocar res
docker builder prune -f                           # 2. El més gran i el menys arriscat
docker image prune -f                             # 3. Les dangling
docker container prune -f                         # 4. Contenidors aturats (revisa'ls)
docker image prune -a --filter "until=720h"       # 5. Imatges sense fer servir de +30 dies

En cinc passos ordenats de menor a major risc es recuperen gairebé sempre uns quants gigabytes sense arribar mai a docker system prune -a --volumes.

Un script de manteniment amb informe:

#!/bin/bash
# manteniment-docker.sh — neteja setmanal segura
set -e

echo "=== Espai ABANS ==="
docker system df

echo "=== Netejant imatges dangling ==="
docker image prune -f

echo "=== Netejant memòria cau de build de més de 7 dies ==="
docker builder prune -f --filter "until=168h"

echo "=== Espai DESPRÉS ==="
docker system df

echo "=== Volums orfes (REVISAR A MÀ, no s'esborren) ==="
docker volume ls -f dangling=true

Fixa't en l'última secció: llista els volums orfes però no els esborra. Aquesta és la línia que separa un script de manteniment d'un script de destrucció de dades.

Errors Habituals i Consells

  • Sumar la columna SIZE de docker image ls. No és espai al disc: les capes compartides es compten a cada fila. La dada real és a docker system df, i el desglossament a docker system df -v.
  • Esborrar una etiqueta i esperar recuperar espai. Si la sortida només diu Untagged i no Deleted, no has alliberat res: la imatge té una altra referència.
  • docker image rm -f sobre un contenidor en execució. La imatge "desapareix" però les seves capes continuen al disc i el contenidor no podrà reiniciar-se mai més. Atura el contenidor primer.
  • docker system prune -a --volumes sense llegir l'avís. Esborra volums sense contenidor associat, i un volum de base de dades entre recreacions de contenidor està exactament en aquell estat. Mai en un servidor.
  • Ignorar la memòria cau de BuildKit. No apareix a docker image ls i sol ser el més voluminós de la màquina. docker system df la delata.
  • Confondre save/load amb export/import. export perd ENTRYPOINT, CMD, ENV, USER i l'historial, i la imatge importada dona no command specified. Per portar imatges, sempre save/load.
  • Oblidar comprimir el .tar. Un gzip -9 retalla habitualment entre un 50 % i un 65 %.
  • Consell: audita les variables abans de publicar. docker image inspect --format '{{range .Config.Env}}{{println .}}{{end}}' ha de ser un reflex abans de qualsevol docker push.
  • Consell: fes servir docker image history … | sort -rh per caçar capes grosses. És el diagnòstic de "per què pesa tant aquesta imatge" en una sola comanda.
  • Consell: etiqueta sempre amb -t. Cada build sense etiqueta és una imatge dangling des del primer segon.
  • Consell: abans d'un esborrat massiu, executa només la part interna del $( … ) per veure què destruiràs.

Exercicis

Exercici 1: audita l'espai real de la teva màquina

  1. Executa docker system df i anota el total i el percentatge recuperable de cada categoria.
  2. Amb docker system df -v, identifica la imatge amb més UNIQUE SIZE i la que tingui UNIQUE SIZE de 0 B. Explica què significa cada cas i quant alliberaria esborrar cadascuna.
  3. Localitza amb docker image history la capa més pesada d'auroralibros/aurora-api:1.1.0 i de postgres:16-alpine.
  4. Comprova si tens volums orfes i esbrina, sense esborrar-los, de quina imatge van sortir.

Exercici 2: demostra el cicle de vida de les etiquetes i les dangling

  1. Construeix auroralibros/aurora-api:experiment des del teu Dockerfile i anota l'IMAGE ID.
  2. Crea una segona etiqueta auroralibros/aurora-api:copia apuntant a la mateixa imatge. Comprova que l'ID coincideix i que docker system df no ha crescut.
  3. Esborra l'etiqueta copia. Surt Untagged, Deleted o tots dos? Per què?
  4. Modifica server.js, reconstrueix amb la mateixa etiqueta experiment i comprova que apareix una imatge <none>:<none>. Explica d'on va sortir.
  5. Recupera aquella imatge dangling reetiquetant-la com a auroralibros/aurora-api:rescatada i verifica que funciona.
  6. Neteja tot el que has creat a l'exercici.

Exercici 3: porta la pila d'Aurora Libros a una màquina sense Internet

Simula un desplegament en un entorn aïllat:

  1. Exporta en un únic fitxer auroralibros/aurora-api:1.1.0, postgres:16-alpine i redis:7-alpine.
  2. Comprimeix-lo i anota la mida abans i després.
  3. Esborra les tres imatges de la teva màquina (simulant la màquina de destinació en blanc).
  4. Carrega-les des del fitxer i verifica que aurora-api conserva ENTRYPOINT, USER, ENV i l'HEALTHCHECK.
  5. Repeteix el cicle amb export/import sobre un contenidor d'aurora-api i compara: mida del tar, nombre de capes de l'history i comportament en executar docker run sense arguments. Conclou quina parella faries servir i per què.

Solucions

Solució a l'exercici 1

docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          9         2         842.3MB   601.7MB (71%)
Containers      4         1         12.4MB    9.1MB (73%)
Local Volumes   3         1         248.9MB   187.2MB (75%)
Build Cache     47        0         2.847GB   2.847GB (100%)

1. Total aproximat: 3,95 GB, dels quals 3,65 GB són recuperables. La memòria cau de build és el 72 % de tot i és 100 % recuperable: és l'objectiu prioritari.

2.

docker system df -v | head -15
  • Més UNIQUE SIZE: postgres:16-alpine, amb 270 MB únics dels seus 278 MB. Només comparteix amb les altres la capa base d'Alpine (8,17 MB). Esborrar-la alliberaria 270 MB reals.
  • UNIQUE SIZE de 0 B: node:22-alpine. Els seus 142 MB estan íntegrament compartits amb les teves imatges d'aurora-api, que es van construir sobre ella. Esborrar-la no alliberaria ni un byte mentre existeixi alguna imatge derivada; només desapareixeria del llistat. És la demostració pràctica de les capes compartides de la lliçó 01-05.

3.

docker image history auroralibros/aurora-api:1.1.0 --format "{{.Size}}\t{{.CreatedBy}}" | sort -rh | head -3
docker image history postgres:16-alpine --format "{{.Size}}\t{{.CreatedBy}}" --no-trunc | sort -rh | head -3
24.7MB   RUN /bin/sh -c npm ci --omit=dev && npm cache clean --force # buildkit
8.17MB   /bin/sh -c #(nop) ADD file:1b8a2c9e... in /
7.82MB   RUN /bin/sh -c apk add --no-cache --virtual .build-deps ...

248MB    RUN /bin/sh -c set -eux; apk add --no-cache --virtual .build-deps ... ; make -C /usr/src/postgresql ...
21.4MB   RUN /bin/sh -c apk add --no-cache bash su-exec tzdata zstd
8.17MB   /bin/sh -c #(nop) ADD file:1b8a2c9e... in /

A aurora-api, el npm ci amb 24,7 MB és el contribuent propi més gran: són les dependències de producció. A postgres, els 248 MB de la compilació de PostgreSQL n'expliquen la mida per si sols.

4.

docker volume ls -f dangling=true
docker volume inspect f3a9c2e1b8d7460a2c5f8e1d4b7a3c9e2f6d8a1b --format '{{.Mountpoint}} · creat {{.CreatedAt}}'
sudo ls /var/lib/docker/volumes/f3a9c2e1b8d7460a2c5f8e1d4b7a3c9e2f6d8a1b/_data
PG_VERSION  base  global  pg_wal  postgresql.conf  ...

El contingut en delata l'origen: és un volum anònim creat per la imatge de PostgreSQL, que declara VOLUME /var/lib/postgresql/data al seu Dockerfile. És exactament l'escenari que la lliçó 02-04 donava com a raó per no fer servir VOLUME. No l'esborris sense comprovar-ne el contingut: podria ser una base de dades amb feina a dins.

Solució a l'exercici 2

cd ~/aurora-libros/api

# 1
docker build -q -t auroralibros/aurora-api:experiment .
docker image ls auroralibros/aurora-api:experiment --format "{{.ID}}"
4e9c7d2a8f31
# 2
docker system df --format "{{.Type}}: {{.Size}}" | head -1
docker image tag auroralibros/aurora-api:experiment auroralibros/aurora-api:copia
docker image ls auroralibros/aurora-api --format "table {{.Tag}}\t{{.ID}}\t{{.Size}}"
docker system df --format "{{.Type}}: {{.Size}}" | head -1
Images: 842.3MB
TAG            ID             SIZE
experiment     4e9c7d2a8f31   167MB
copia          4e9c7d2a8f31   167MB
Images: 842.3MB

Mateix ID i el mateix espai total. docker image tag només crea una referència; no copia ni un sol byte. És la demostració local del que veuràs al registre a la lliçó 02-06.

# 3
docker image rm auroralibros/aurora-api:copia
Untagged: auroralibros/aurora-api:copia

Només Untagged. No hi ha Deleted perquè l'etiqueta experiment continua apuntant a aquella imatge: les dades continuen referenciades i l'esborrat es limita a eliminar el nom.

# 4
echo "// canvi per generar una dangling" >> server.js
docker build -q -t auroralibros/aurora-api:experiment .
docker image ls --filter "dangling=true"
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
<none>       <none>    4e9c7d2a8f31   8 minutes ago    167MB

L'ID 4e9c7d2a8f31 és el mateix del pas 1: la imatge original no s'ha esborrat, ha perdut el nom. La build nova va produir una imatge diferent i l'etiqueta experiment s'hi va moure. Les etiquetes són punters, no propietàries.

# 5
docker image tag 4e9c7d2a8f31 auroralibros/aurora-api:rescatada
docker run --rm auroralibros/aurora-api:rescatada --version
docker image ls --filter "dangling=true"
v22.14.0
(sense resultats)

Recuperada i funcional, i ja no figura com a dangling perquè torna a tenir nom. Fixa't que --version va funcionar gràcies a l'ENTRYPOINT ["node"] de la lliçó 02-04.

# 6
docker image rm auroralibros/aurora-api:experiment auroralibros/aurora-api:rescatada
docker image prune -f

Solució a l'exercici 3

# 1 i 2
cd /tmp
docker save -o aurora-pila.tar \
  auroralibros/aurora-api:1.1.0 postgres:16-alpine redis:7-alpine
ls -lh aurora-pila.tar
gzip -9 aurora-pila.tar
ls -lh aurora-pila.tar.gz
-rw------- 1 joan joan 481M ago  4 12:40 aurora-pila.tar
-rw------- 1 joan joan 173M ago  4 12:41 aurora-pila.tar.gz

De 481 MB a 173 MB: un 64 % menys. La compressió val la pena sempre, sobretot si el fitxer viatja per SCP o per un llapis de memòria.

# 3
docker image rm auroralibros/aurora-api:1.1.0 postgres:16-alpine redis:7-alpine
docker image ls | grep -E "aurora-api|postgres|redis"   # sense resultats

# 4
gunzip -c aurora-pila.tar.gz | docker load
Loaded image: auroralibros/aurora-api:1.1.0
Loaded image: postgres:16-alpine
Loaded image: redis:7-alpine
docker image inspect auroralibros/aurora-api:1.1.0 --format \
'Entrypoint: {{json .Config.Entrypoint}}
Cmd:        {{json .Config.Cmd}}
User:       {{.Config.User}}
Env:        {{index .Config.Env 3}} {{index .Config.Env 4}}
Health:     {{json .Config.Healthcheck.Test}}
Revision:   {{index .Config.Labels "org.opencontainers.image.revision"}}'
Entrypoint: ["node"]
Cmd:        ["server.js"]
User:       node
Env:        NODE_ENV=production PORT=3000
Health:     ["CMD-SHELL","wget --quiet --tries=1 --spider http://localhost:3000/salut || exit 1"]
Revision:   7a3f912

Absolutament tot intacte: entrypoint, cmd, usuari, variables, healthcheck i fins i tot les etiquetes OCI amb el hash del commit.

# 5. Comparació amb export/import
docker run -d --name comparar auroralibros/aurora-api:1.1.0
docker export comparar | gzip -9 > aurora-pla.tar.gz
ls -lh aurora-pla.tar.gz
gunzip -c aurora-pla.tar.gz | docker import - aurora-plana:test
docker image history aurora-plana:test
docker run --rm aurora-plana:test
-rw------- 1 joan joan 58M ago  4 12:48 aurora-pla.tar.gz

IMAGE          CREATED         CREATED BY   SIZE      COMMENT
9d2e4f8a1c73   3 seconds ago                158MB     Imported from -

docker: Error response from daemon: no command specified.

Taula comparativa final:

Aspecte save/load export/import
Mida comprimida (només aurora-api) ~62 MB ~58 MB
Capes conservades 7 1
Historial Complet Cap
ENTRYPOINT, CMD, USER, ENV Conservats Perduts
HEALTHCHECK i etiquetes OCI Conservats Perduts
docker run sense arguments Arrenca l'API no command specified
Diverses imatges per fitxer No

Conclusió: per portar imatges, save/load, sense discussió. El petit estalvi de mida d'export no compensa perdre tota la configuració d'execució, el healthcheck i la traçabilitat que va costar una lliçó sencera construir. export/import és una eina per aplanar sistemes de fitxers, no per moure imatges.

Neteja:

docker rm -f comparar
docker image rm aurora-plana:test
rm -f /tmp/aurora-pila.tar.gz /tmp/aurora-pla.tar.gz

Conclusió

Ja saps administrar el teu magatzem d'imatges. Llistes i filtres amb docker image ls, els seus --filter (inclòs el filtratge per les etiquetes OCI que vas afegir a 02-04) i les seves plantilles Go. Extreus qualsevol metadada concreta amb docker image inspect --format, i tens un reflex nou que convé conservar: auditar les variables d'entorn abans de publicar qualsevol imatge. Amb docker image history reconstrueixes com es va fer una imatge, capa a capa, i localitzes en una sola comanda la que es va menjar els megues —a aurora-api, el npm ci amb 24,7 MB; a postgres, els 248 MB de la seva compilació—.

Saps esborrar entenent el que passa: Untagged treu un nom i Deleted destrueix dades, i només apareix quan cau l'última referència. Saps per què un contenidor aturat bloqueja l'esborrat de la seva imatge (conserva la capa d'escriptura apilada a sobre) i quan -f és acceptable i quan és una manera elegant de trencar un servei al pròxim reinici. Entens d'on surten les <none>:<none>: reconstruir amb la mateixa etiqueta mou el punter i deixa òrfena la imatge anterior, que continua al disc i fins i tot es pot rescatar reetiquetant-la.

Domines l'escala de neteja, de menor a major risc —image prune, builder prune, system prune— amb una advertència gravada a foc sobre l'últim esglaó: docker system prune -a --volumes esborra volums sense contenidor associat, i un volum de base de dades entre recreacions està exactament en aquell estat. Mesures abans de tocar res amb docker system df i la seva versió -v, que revela el que cap llistat d'imatges mostra: la memòria cau de BuildKit ocupant gigabytes, les capes compartides comptades una sola vegada i les columnes SHARED/UNIQUE que diuen quant alliberaries de debò en esborrar cada imatge. I saps endur-te una imatge a una màquina aïllada amb docker save/load, conservant entrypoint, usuari, healthcheck i etiquetes OCI, davant d'export/import, que aplana el sistema de fitxers i ho perd tot.

La teva imatge està construïda, és professional i saps mantenir-la. Li falta l'única cosa que justificava tot el mòdul: sortir de la teva màquina. A l'última lliçó, Etiquetatge i Publicació d'Imatges, tancaràs el cicle. Veuràs que docker image tag no copia res sinó que crea referències, decidiràs una estratègia d'etiquetatge seriosa —versionatge semàntic amb etiquetes mòbils i fixes, per SHA de commit, per branca, per entorn— i publicaràs auroralibros/aurora-api a Docker Hub i a GitHub Container Registry, llegint la sortida del push, verificant el resultat amb docker manifest inspect i entenent per què en producció es desplega per digest i mai per latest.

Docker: De Principiant a Avançat

Mòdul 1: Introducció a Docker

Mòdul 2: Treballant amb Imatges Docker

Mòdul 3: Contenidors Docker

Mòdul 4: Docker Compose

Mòdul 5: Conceptes Avançats de Docker

Mòdul 6: Docker en Producció

Mòdul 7: Ecosistema i Eines de Docker

© Copyright 2026. Tots els drets reservats