Quan vas executar docker run hello-world a la lliçó anterior, el mateix missatge del contenidor et va resumir el que havia passat: el client va contactar amb el daemon, el daemon va descarregar una imatge del registre, va crear un contenidor a partir d'ella i et va retornar la seva sortida. Aquesta frase amaga una arquitectura completa, i entendre-la és el que separa qui memoritza comandes de qui sap diagnosticar problemes. En aquesta lliçó obriràs la caixa: descobriràs que docker no executa contenidors (només els demana), qui els executa realment, quin paper hi juguen containerd i runc, què és aquest socket del qual tant parlem i per què el daemon és el veritable amo de totes les teves imatges, contenidors, volums i xarxes. Acabaràs interpretant la sortida real de docker info i docker system df amb ulls nous.
Contingut
- Docker és client-servidor, no un programa
- El client
docker - El daemon
dockerd - L'API REST i el socket
/var/run/docker.sock - El flux complet d'un
docker run - containerd i runc: per què hi ha tres capes
- Els objectes que gestiona el daemon
- Els registres i el seu paper
- Demostració pràctica:
docker infoidocker system df
- Docker és client-servidor, no un programa
El primer malentès que cal desfer: quan escrius docker run, aquesta comanda no crea cap contenidor. L'única cosa que fa és traduir la teva ordre a una petició HTTP i enviar-la a un altre procés, que és el que fa la feina de debò.
Docker segueix una arquitectura client-servidor amb tres actors:
| Actor | Què és | On viu |
|---|---|---|
Client (docker) |
Un programa de línia de comandes que tradueix les teves ordres a crides d'API | El teu terminal |
Daemon (dockerd) |
Un servei de llarga durada que construeix, executa i gestiona tot | Normalment la mateixa màquina; pot ser remota |
| Registre | Un servei que emmagatzema i distribueix imatges | Internet (Docker Hub) o la teva xarxa |
Les conseqüències d'aquest disseny són molt pràctiques:
- El client pot estar en una màquina diferent del daemon. Pots gestionar un servidor remot des del teu portàtil amb la mateixa comanda
docker. - Hi pot haver molts clients contra un mateix daemon. El teu terminal, el teu IDE i una eina de CI poden parlar amb el mateix motor alhora.
- Si el daemon està aturat, el client no pot fer res. D'aquí el famós
Cannot connect to the Docker daemon. - L'estat viu al daemon, no al teu terminal. Tancar el terminal no atura els teus contenidors.
- El client
docker
dockerEl client és sorprenentment ximple, i això és bo. Les seves responsabilitats són:
- Analitzar el que escrius (
docker run -d --name web nginx). - Convertir-ho en una o diverses crides a l'API REST del daemon.
- Mostrar-te la resposta amb format llegible.
Res més. No sap crear contenidors, ni descomprimir imatges, ni parlar amb el nucli.
El client decideix amb quin daemon parla mitjançant els anomenats contextos. Els pots veure així:
NAME DESCRIPTION DOCKER ENDPOINT ERROR
default * Current DOCKER_HOST based configuration unix:///var/run/docker.sockLectura: hi ha un únic context, default, marcat com a actiu amb l'asterisc, i apunta al socket Unix local. Si tinguessis un servidor remot configurat, hi veuries una altra fila amb un DOCKER ENDPOINT del tipus ssh://usuari@servidor.
També pots forçar el destí amb la variable d'entorn DOCKER_HOST:
Aquesta comanda llista els contenidors del servidor remot, no els teus. El client és exactament el mateix binari; només canvia amb qui parla. És una demostració perfecta que el client no executa res.
- El daemon
dockerd
dockerddockerd és el procés que fa la feina. Corre com a servei del sistema (a Linux, gestionat per systemd) amb privilegis de root, perquè necessita manipular el nucli: crear espais de noms, configurar interfícies de xarxa virtuals, muntar sistemes de fitxers.
El pots veure amb les eines normals del sistema:
La primera línia et mostra l'estat del servei (active (running)); la segona, el procés real i els seus arguments. Hi veuràs alguna cosa com /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock, on -H fd:// indica que escolta al socket que li passa systemd i --containerd= assenyala amb quin containerd parla (ho veurem a l'apartat 6).
Les seves responsabilitats:
- Exposar l'API REST i atendre els clients.
- Gestionar el cicle de vida d'imatges, contenidors, volums i xarxes.
- Descarregar i pujar imatges des dels registres i cap a ells.
- Construir imatges (delegant en BuildKit, tema del mòdul 2 i de la lliçó 05-05).
- Configurar la xarxa virtual dels contenidors.
- Delegar l'execució real en containerd.
Un detall important: si dockerd es reinicia, els teus contenidors no han de morir necessàriament. Gràcies a la separació amb containerd que veuràs de seguida, els contenidors en execució poden sobreviure a un reinici del daemon.
- L'API REST i el socket
/var/run/docker.sock
/var/run/docker.sockTota la comunicació entre el client i el daemon és una API REST sobre HTTP. El que crida l'atenció és que, per defecte, aquest HTTP no viatja per la xarxa: viatja per un socket Unix, un fitxer especial del sistema de fitxers:
Llegeix-ho amb atenció, perquè explica coses de la lliçó anterior:
- La
sinicial indica que és un socket, no un fitxer normal. - El propietari és
rooti el grup ésdocker. - Els permisos
rw-rw----signifiquen: root pot llegir i escriure, el grupdockertambé, i ningú més.
Aquí ho tens, en una línia, per què necessitaves sudo o pertànyer al grup docker. I també per què pertànyer al grup docker equival a ser root: qui pot escriure en aquest socket pot demanar al daemon (que és root) el que vulgui.
Que l'API sigui HTTP té una conseqüència divertida: pots parlar amb Docker sense fer servir el client. Amb curl:
{"Platform":{"Name":"Docker Engine - Community"},"Version":"28.1.1","ApiVersion":"1.49","Os":"linux","Arch":"amd64"}Què acabes de fer: --unix-socket diu a curl que en lloc d'obrir una connexió TCP faci servir aquest fitxer socket; http://localhost/version és la ruta de l'endpoint (l'amfitrió és irrellevant, només cal per formar una URL vàlida). La resposta és JSON cru: exactament el mateix que docker version et mostra bonic.
Un altre exemple, llistant contenidors:
Retorna un array JSON amb els contenidors en execució: l'equivalent exacte de docker ps. Això no és cap truc de festa: és com funcionen per dins les eines gràfiques, els plugins d'IDE i els sistemes de monitoratge.
Advertiment de seguretat. Muntar
/var/run/docker.sockdins d'un contenidor és una pràctica que veuràs en tutorials (eines de CI, taulers). Equival a donar-li root sobre l'amfitrió a aquest contenidor. Es tracta amb detall a la lliçó 05-03.
El daemon pot a més escoltar en TCP (-H tcp://0.0.0.0:2376), imprescindible per a l'accés remot, però mai sense TLS i autenticació: un daemon exposat sense protegir a Internet es compromet en minuts.
- El flux complet d'un
docker run
docker runAra sí, el recorregut complet de l'ordre més habitual del curs:
sequenceDiagram
participant U as Tu (terminal)
participant C as Client docker
participant D as Daemon dockerd
participant R as Registre (Docker Hub)
participant CD as containerd
participant RC as runc
participant K as Nucli Linux
U->>C: docker run -d -p 8080:80 nginx:alpine
C->>D: POST /images/create (si falta la imatge)
D->>D: Hi ha nginx:alpine en local?
alt No hi és
D->>R: GET manifest + capes
R-->>D: Manifest i capes (blobs)
D->>D: Descomprimeix i desa les capes
end
C->>D: POST /containers/create
D->>D: Prepara sistema de fitxers i config de xarxa
C->>D: POST /containers/{id}/start
D->>CD: Crear i arrencar contenidor
CD->>RC: Crear procés aïllat segons spec OCI
RC->>K: namespaces + cgroups + muntatges
K-->>RC: Procés en execució
RC-->>CD: Llest (runc acaba)
CD-->>D: ID del contenidor i estat
D-->>C: ID del contenidor
C-->>U: 3f2a9c1b7e4d...
Pas a pas, en paraules:
- Tu escrius la comanda. El client l'analitza i valida les opcions.
- El client crida l'API. Tradueix la teva ordre a peticions HTTP contra el socket.
- El daemon busca la imatge en local. Si
nginx:alpineja està descarregada, salta al pas 5. - Si falta, el daemon contacta amb el registre. Demana primer el manifest (la llista de capes que componen la imatge) i després descarrega les capes que no tingui ja. Són aquestes descàrregues les que veus com a
Pull complete. - El daemon crea el contenidor. Prepara el seu sistema de fitxers apilant les capes de la imatge i afegint-hi a sobre una capa d'escriptura, reserva el nom
aurora-web-demo, i configura la xarxa virtual i la regla de mapatge del port 8080 de l'amfitrió al 80 del contenidor. - El daemon demana a containerd que l'arrenqui.
- containerd invoca runc, que és qui realment diu al nucli: crea aquests espais de noms, aplica aquests límits de recursos, munta aquest sistema de fitxers i llança aquest procés.
- runc acaba i desapareix. La seva feina era arrencar el procés, no supervisar-lo.
- El daemon retorna l'ID al client, que te l'imprimeix.
Que runc desaparegui després d'arrencar el contenidor és la raó per la qual Docker pot actualitzar-se o reiniciar-se sense matar contenidors: el procés del contenidor ja no en penja.
- containerd i runc: per què hi ha tres capes
A primera vista, tres components per arrencar un procés sembla exagerat. La raó és històrica i estratègica.
Els primers anys, Docker era un binari monolític que ho feia tot. A mesura que els contenidors es van convertir en infraestructura crítica, la indústria va demanar estàndards per no dependre d'un únic proveïdor. D'aquí va néixer l'OCI (Open Container Initiative), que va publicar dues especificacions clau:
- OCI Image Spec: com s'estructura una imatge (capes, manifest, configuració).
- OCI Runtime Spec: com es descriu i s'arrenca un contenidor a partir d'un sistema de fitxers i un fitxer de configuració JSON.
Docker es va trossejar per encaixar en aquests estàndards:
| Component | Nivell | Responsabilitat |
|---|---|---|
dockerd |
Alt | API REST, construcció d'imatges, xarxes, volums, orquestració local |
containerd |
Mitjà | Gestió del cicle de vida de contenidors, emmagatzematge d'imatges, transferència des de registres, supervisió |
runc |
Baix | Crear un contenidor a partir d'una spec OCI parlant amb el nucli, i sortir |
Mira-t'ho com una cadena de delegació, cada baula més específica i més simple que l'anterior:
flowchart TB
CLI["Client docker"] -->|API REST| DAEMON["dockerd<br/>(alt nivell)"]
DAEMON -->|gRPC| CTRD["containerd<br/>(nivell mitjà, estàndard de l'ecosistema)"]
CTRD -->|executa| SHIM["containerd-shim<br/>(supervisa el contenidor)"]
SHIM -->|invoca un cop| RUNC["runc<br/>(baix nivell, OCI Runtime)"]
RUNC -->|syscalls| KERNEL["Nucli Linux<br/>namespaces · cgroups · capabilities"]
KERNEL --> PROC["Procés del contenidor"]
SHIM -.supervisa.-> PROC
Aquest containerd-shim intermedi és la peça que explica el "reinici sense morts": hi ha un shim per contenidor que es queda viu supervisant-lo, en recull el codi de sortida i manté oberts els seus fluxos d'entrada/sortida, de manera que ni dockerd ni runc necessiten continuar presents.
Per què t'importa això com a usuari?
- Perquè containerd és avui un estàndard de l'ecosistema, i altres plataformes el fan servir directament (Kubernetes, per exemple, parla amb containerd sense passar per Docker). Ho veuràs al mòdul 6.
- Perquè explica que existeixin alternatives compatibles a Docker que executen exactament les mateixes imatges (tema de la lliçó 07-05).
- Perquè quan llegeixis un error que esmenti
containerdorunc, sabràs a quin nivell està fallant alguna cosa.
El que passa exactament a la fletxa final —què són els namespaces, els cgroups i com s'apilen les capes del sistema de fitxers— és el contingut de la lliçó 05-07. Aquí ens quedem al mapa.
- Els objectes que gestiona el daemon
El daemon manté quatre tipus d'objecte. Tot el que faràs al curs és crear, llistar, inspeccionar i esborrar objectes d'aquests quatre tipus, i la CLI moderna està organitzada literalment així (ho veuràs a la lliçó 01-04).
| Objecte | Què és | Comanda arrel | On s'hi aprofundeix |
|---|---|---|---|
| Imatges | Plantilles immutables de només lectura | docker image |
Lliçó 01-05 i mòdul 2 |
| Contenidors | Instàncies en execució d'una imatge | docker container |
Lliçó 01-06 i mòdul 3 |
| Volums | Emmagatzematge persistent independent del cicle de vida del contenidor | docker volume |
Lliçó 03-06 |
| Xarxes | Xarxes virtuals que connecten contenidors entre si i amb l'exterior | docker network |
Lliçó 03-05 |
Tots ells es materialitzen al disc sota el directori de dades del daemon, normalment /var/lib/docker:
Què és cada cosa rellevant:
overlay2: les capes de les imatges i les capes d'escriptura dels contenidors. És el que més ocupa amb diferència.image: les metadades que relacionen imatges amb les seves capes.containers: configuració i registres de cada contenidor.volumes: les dades dels volums.network: la configuració de les xarxes virtuals.buildkit: la memòria cau de construcció d'imatges.
Regla d'or: no toquis mai a mà res de /var/lib/docker. El daemon hi manté bases de dades internes d'estat; editar o esborrar fitxers directament és la manera més ràpida de corrompre la instal·lació. Tot es gestiona amb comandes.
- Els registres i el seu paper
Un registre és un servei que emmagatzema i distribueix imatges. És la tercera pota de l'arquitectura i la que dona a Docker la seva capacitat de distribució.
El registre per defecte és Docker Hub (docker.io). Quan escrius docker pull nginx:alpine, el client completa silenciosament el nom:
On docker.io és el registre, library és l'espai de noms de les imatges oficials i nginx el repositori. Per això a la sortida de hello-world vas veure Pulling from library/hello-world.
Per fer servir un altre registre n'hi ha prou d'anomenar-lo explícitament:
docker pull ghcr.io/aurora-libros/aurora-api:1.0.0
docker pull registry.intern.auroralibros.local:5000/aurora-api:1.0.0- El primer descarrega del GitHub Container Registry.
- El segon, d'un registre privat autoallotjat a la xarxa de l'empresa, que escolta al port 5000.
Tipus habituals de registre:
| Tipus | Exemples | Quan es fa servir |
|---|---|---|
| Públic gestionat | Docker Hub, GitHub Container Registry, Quay | Imatges base i projectes oberts |
| Privat gestionat al núvol | Amazon ECR, Google Artifact Registry, Azure ACR | Imatges d'empresa desplegades en aquell núvol |
| Privat autoallotjat | Harbor, el registre oficial registry:2, Nexus |
Control total, xarxes aïllades, compliment normatiu |
El paper del registre a l'arquitectura és el de magatzem i punt d'intercanvi: el daemon puja (push) i baixa (pull) imatges, però no el necessita per executar el que ja té descarregat. Un servidor sense connexió a Internet pot aixecar contenidors perfectament si les seves imatges ja són en local.
L'autenticació (docker login), la publicació i l'organització de repositoris es tracten al mòdul 2, especialment a les lliçons 02-01 i 02-06.
- Demostració pràctica:
docker info i docker system df
docker info i docker system dfLlegim l'arquitectura reflectida a la sortida real de dues comandes.
docker info
Client: Docker Engine - Community
Version: 28.1.1
Context: default
Plugins:
buildx: Docker Buildx (Docker Inc.) v0.23.0
compose: Docker Compose (Docker Inc.) v2.35.1
Server:
Containers: 4
Running: 2
Paused: 0
Stopped: 2
Images: 7
Server Version: 28.1.1
Storage Driver: overlay2
Backing Filesystem: extfs
Logging Driver: json-file
Cgroup Driver: systemd
Cgroup Version: 2
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Swarm: inactive
Runtimes: io.containerd.runc.v2 runc
Default Runtime: runc
containerd version: 05f951a3781f4f2c1911b05e61c160e9c30eaa8e
runc version: v1.2.5-0-g59923ef
Kernel Version: 6.8.0-52-generic
Operating System: Ubuntu 24.04.2 LTS
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 15.35GiB
Docker Root Dir: /var/lib/docker
Registry: https://index.docker.io/v1/
Live Restore Enabled: falseAra que coneixes l'arquitectura, cada bloc té sentit:
| Camp | Què t'indica |
|---|---|
Blocs Client: / Server: |
La separació client-servidor en persona. Són dues entitats diferents |
Context: default |
Amb quin daemon està parlant el client |
Containers / Running / Stopped |
L'inventari d'objectes "contenidor" que custodia el daemon. Fixa't que n'hi ha 2 d'aturats: existeixen i ocupen disc |
Images: 7 |
Els objectes "imatge" emmagatzemats |
Storage Driver: overlay2 |
Com apila les capes d'imatge (lliçó 01-05) |
Logging Driver: json-file |
On van els registres dels contenidors (lliçó 05-06) |
Cgroup Driver / Version |
Com s'apliquen els límits de recursos (lliçons 03-07 i 05-07) |
Network: bridge host ipvlan... |
Els drivers de xarxa disponibles (lliçons 03-05 i 05-01) |
containerd version / runc version |
Les dues capes inferiors de l'apartat 6, llistades explícitament |
Kernel Version |
El nucli de l'amfitrió, que és el que faran servir els teus contenidors |
Docker Root Dir |
El directori de l'apartat 7 |
Registry: https://index.docker.io/v1/ |
El registre per defecte de l'apartat 8 |
Live Restore Enabled |
Si està en true, els contenidors sobreviuen a un reinici del daemon |
A Windows o macOS, fixa't que Operating System i Kernel Version no són els del teu equip, sinó els de la màquina virtual Linux de Docker Desktop. És la demostració més clara del que es va explicar a la lliçó 01-02.
docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 7 2 1.842GB 1.376GB (74%)
Containers 4 2 12.4MB 8.2MB (66%)
Local Volumes 3 1 248.6MB 102.3MB (41%)
Build Cache 18 0 421.7MB 421.7MB (100%)Aquesta comanda respon a "en què se me'n va el disc?". Columna a columna:
- TYPE: els tipus d'objecte de l'apartat 7, més la memòria cau de construcció.
- TOTAL: quants objectes hi ha d'aquest tipus.
- ACTIVE: quants estan en ús. Una imatge està activa si algun contenidor (encara que estigui aturat) la fa servir; un volum, si està muntat per algun contenidor.
- SIZE: espai total ocupat. Compte: a
Images, aquest nombre té en compte que les capes compartides es compten una sola vegada (lliçó 01-05). - RECLAIMABLE: quant recuperaries netejant el que no es fa servir. A l'exemple, 1,376 GB d'imatges que cap contenidor no referencia.
Per al detall per objecte:
Hi afegeix taules desglossades: cada imatge amb la seva mida i quants contenidors la fan servir, cada contenidor amb la mida de la seva capa d'escriptura, cada volum amb els seus enllaços. És l'eina per localitzar el culpable concret d'un disc ple.
La neteja (docker system prune) la veuràs a la lliçó 01-04.
Errors Habituals i Consells
- Creure que
docker"és" Docker. La comanda és només un client. Si t'acostumes a pensar "jo demano, el daemon fa", entendràs per què el daemon pot ser en una altra màquina, per què tancar el terminal no atura res i per què l'estat no és on escrius. - Confondre "no trobo el contenidor" amb "no existeix". Si tens diversos contextos o un
DOCKER_HOSTposat a l'entorn, pots estar consultant un altre daemon. Verifica-ho ambdocker context lsiecho $DOCKER_HOST. - Exposar el daemon per TCP sense TLS. Obrir
-H tcp://0.0.0.0:2375és lliurar la màquina. Existeixen botnets que rastregen aquest port contínuament. Si necessites accés remot, fes servir el context per SSH (docker context create --docker host=ssh://...), que és simple i segur. - Muntar
/var/run/docker.sockdins d'un contenidor a la lleugera. És una escalada a root de l'amfitrió. De vegades cal, però ha de ser una decisió conscient (lliçó 05-03). - Tocar
/var/lib/dockera mà. Esborrar directoris allà per "alliberar espai" corromp l'estat del daemon. Fes servir sempre les comandes de la CLI. - Consell:
docker infoés el teu primer diagnòstic. Davant de qualsevol comportament estrany, mira-hi: versió, driver d'emmagatzematge, cgroups, arquitectura i espai. Molts problemes "misteriosos" s'expliquen amb una línia d'aquesta sortida. - Consell: recorda la cadena de delegació. dockerd → containerd → shim → runc → nucli. Amb aquest esquema al cap, els missatges d'error de baix nivell deixen de ser soroll.
Exercicis
Exercici 1: parla amb l'API sense fer servir el client
Sense executar cap comanda docker (llevat de per comparar al final), aconsegueix mitjançant curl sobre el socket Unix: (a) la versió del daemon, (b) el nombre de contenidors en execució, i (c) la llista d'imatges locals. Després, compara cada resultat amb la seva comanda docker equivalent i explica quina relació hi ha entre totes dues.
Exercici 2: segueix el rastre de les capes
Executa aquestes comandes i respon a les preguntes:
(a) Quines xifres canvien i per què? (b) Quants objectes de tipus imatge hi ha ara actius i quants en total? (c) Si el RECLAIMABLE d'imatges és alt, què significa exactament això en termes de l'arquitectura que has estudiat?
Exercici 3: dibuixa la fallada
Per a cadascun d'aquests tres símptomes, indica en quin punt exacte de la cadena client → API/socket → daemon → registre → containerd → runc → nucli és el problema, i què comprovaries:
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?Error response from daemon: pull access denied for aurora-api, repository does not exist or may require 'docker login'docker: Error response from daemon: driver failed programming external connectivity on endpoint aurora-web-demo: Bind for 0.0.0.0:8080 failed: port is already allocated.
Solucions
Solució a l'exercici 1
# (a) versió del daemon
curl -s --unix-socket /var/run/docker.sock http://localhost/version
# (b) contenidors en execució (compte d'elements de l'array JSON)
curl -s --unix-socket /var/run/docker.sock http://localhost/v1.49/containers/json | grep -o '"Id"' | wc -l
# (c) imatges locals
curl -s --unix-socket /var/run/docker.sock http://localhost/v1.49/images/jsonComentaris:
-ssilencia la barra de progrés decurlper deixar només el JSON.--unix-socketés el que ho fa possible tot: en lloc d'una connexió TCP,curlescriu HTTP directament al fitxer socket. L'http://localhostés només un farciment sintàctic per formar una URL vàlida; el nom d'amfitrió s'ignora./v1.49/és la versió de l'API; la pots ometre i el daemon farà servir la més recent que suporti. Si la teva versió difereix, mira-la a la sortida dedocker version(campAPI version).- A (b), el
grep -o '"Id"' | wc -lcompta quants objectes porta l'array. Ambjqinstal·lat seria més net:| jq 'length'.
Els equivalents són docker version, docker ps i docker image ls. La relació és directa: el client docker fa exactament aquestes mateixes crides HTTP i es limita a formatar la resposta en taules llegibles. Comprovar-ho de primera mà és la millor manera d'interioritzar que el client no executa res.
Solució a l'exercici 2
(a) Canvien dues coses a la fila Images: el TOTAL puja en 1 (hi ha una imatge més) i el SIZE augmenta, però normalment menys que la mida anunciada de la imatge, perquè les capes que ja tinguessis d'altres imatges basades en Alpine no es descarreguen ni es compten dues vegades. A més, el RECLAIMABLE puja en la mida de la nova imatge, perquè acabes de descarregar-la i encara cap contenidor no la fa servir.
(b) TOTAL és el nombre d'imatges emmagatzemades; ACTIVE compta només les referenciades per algun contenidor (encara que estigui aturat). L'acabada de descarregar suma al total però no a les actives.
(c) Un RECLAIMABLE alt significa que el daemon està custodiant a /var/lib/docker capes d'imatges que cap contenidor no referencia. No fan mal més enllà del disc que ocupen, i serveixen de memòria cau: si tornes a fer servir aquesta imatge, no cal descarregar-la. S'alliberen amb docker system prune -a, que veuràs a la lliçó 01-04.
Solució a l'exercici 3
-
Fallada entre el client i el socket/daemon. El client no aconsegueix ni tan sols establir la conversa. Dues causes possibles: el daemon està aturat (comprova-ho amb
systemctl status docker; a Windows/macOS, que Docker Desktop estigui iniciat) o el teu context apunta a un endpoint que no respon (comprovadocker context lsiecho $DOCKER_HOST). Compte amb la diferència respecte apermission denied: això seria un problema de permisos sobre el socket, no de connexió. -
Fallada entre el daemon i el registre. El missatge comença per
Error response from daemon, així que el client va arribar al daemon sense problema; va ser el daemon qui no va poder obtenir la imatge. Comprovaries: que el nom i l'etiqueta siguin correctes, que el repositori existeixi, si és privat (llavors faltadocker login), i si el registre és intern, que sigui accessible des de la màquina. -
Fallada al daemon, a la fase de configuració de xarxa prèvia a l'arrencada. El contenidor ni tan sols ha arribat a containerd/runc: el daemon va intentar reservar el port 8080 de l'amfitrió i el sistema operatiu l'hi va negar perquè ja està ocupat. Comprovaries què l'ocupa (
ss -tlnp | grep 8080, odocker psper si és un altre contenidor teu) i, o bé alliberes aquest port, o publiques el contenidor en un altre (-p 8081:80).
Conclusió
Docker no és un programa: és un sistema client-servidor. El client docker només tradueix les teves ordres a crides d'una API REST que viatja pel socket /var/run/docker.sock —els permisos del qual expliquen, d'un cop d'ull, tant l'ús de sudo com el fet que el grup docker equivalgui a root—. A l'altra banda, el daemon dockerd fa la feina real i delega cap avall en containerd (cicle de vida i emmagatzematge) i runc (creació del procés aïllat segons l'especificació OCI), una separació en capes que existeix per respectar estàndards i que permet que l'ecosistema no depengui d'un únic producte.
El daemon custodia quatre tipus d'objecte —imatges, contenidors, volums i xarxes— a /var/lib/docker, i fa servir els registres només per intercanviar imatges, no per executar-les. Tot això està reflectit, literalment, a la sortida de docker info i docker system df, que ara ja saps llegir.
Amb el mapa mental complet, ja pots començar a donar ordres amb criteri. A la lliçó següent, Comandes Bàsiques de Docker, veuràs que la CLI està organitzada exactament segons aquests quatre objectes (docker <objecte> <acció>), aprendràs les comandes essencials sobre imatges, contenidors i sistema, i recorreràs una sessió completa comentada de principi a fi.
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
