Vas tancar el mòdul 1 amb les eines a la mà i el problema mesurat: quinze passos manuals per posar en marxa Aurora Libros. El mòdul 2 comença a enderrocar-los, i ho fa des del principi de la cadena: d'on surten les imatges. Fins ara has escrit docker pull node:22-alpine o docker run nginx:alpine sense preguntar-te gaire qui hi ha a l'altre costat, qui va publicar aquesta imatge ni per què t'hi hauries de refiar. En aquesta lliçó obres aquesta capsa. Entendràs què és exactament un registre d'imatges i què és un repositori dins seu, t'autenticaràs amb docker login i veuràs on queden les teves credencials (amb una sorpresa desagradable inclosa), aprendràs a distingir una imatge oficial d'una imatge que algú va pujar un dimarts del 2019 i no va tornar a tocar mai més, coneixeràs els límits de descàrrega que et poden tallar una build en el pitjor moment, i muntaràs el teu propi registre en un contenidor per veure que el mecanisme no té cap mena de màgia. Al final triaràs el repositori on viurà la imatge d'aurora-api durant la resta del curs.
Contingut
- Registre, repositori i etiqueta: les tres capes del magatzem
- Docker Hub: compte i interfície
docker login,docker logouti on queden les teves credencials- Tipus d'imatge a Docker Hub i com avaluar-ne la confiança
- Límits de descàrrega: anònim davant d'autenticat
- Cercar imatges des del terminal amb
docker search - Repositoris públics i privats
- Registres alternatius a Docker Hub
- El teu propi registre en un contenidor
- El repositori d'Aurora Libros
- Registre, repositori i etiqueta: les tres capes del magatzem
A la lliçó 01-05 vas aprendre a llegir un nom complet d'imatge:
Ara toca entendre què hi ha darrere de cada tram, perquè són tres coses diferents que la gent confon constantment quan en parla.
- Un registre d'imatges (registry) és un servei: un servidor amb una API HTTP que emmagatzema i serveix imatges. Docker Hub és un registre.
ghcr.ion'és un altre. El que muntaràs a l'apartat 9 al teu portàtil també ho és. Un registre conté molts repositoris. - Un repositori (repository) és una col·lecció d'imatges relacionades entre si, que comparteixen nom i es distingeixen per l'etiqueta.
library/nginxés un repositori: a dins hi viuennginx:1.27,nginx:alpine,nginx:latest… totes són "nginx", en versions o variants diferents. - Una etiqueta (tag) és una referència llegible que apunta a un manifest concret, identificat al seu torn per un digest
sha256:…immutable.
flowchart TB
subgraph REG["Registre · docker.io (Docker Hub)"]
subgraph R1["Repositori: library/node"]
T1["etiqueta 22-alpine"]
T2["etiqueta 22"]
T3["etiqueta latest"]
end
subgraph R2["Repositori: auroralibros/aurora-api"]
T4["etiqueta 1.0.0"]
T5["etiqueta latest"]
end
end
D1["sha256:9f2c…<br/>manifest + capes"]
D2["sha256:41ab…<br/>manifest + capes"]
T1 --> D1
T2 --> D2
T3 --> D2
T4 --> D1
T5 --> D1
Fixa't en dos detalls del diagrama que expliquen comportaments que ja has vist:
- Diverses etiquetes poden apuntar al mateix digest.
22ilatestsón, gairebé sempre, la mateixa imatge amb dos noms. Per això a la lliçó 01-05docker image lset mostrava dues files amb el mateix IMAGE ID: no eren dues imatges, era una amb dues referències. Hi tornaràs amb detall a la lliçó 02-06. - El digest és l'única cosa immutable. L'etiqueta
22-alpineavui apunta a un manifest i d'aquí a tres setmanes pot apuntar-ne a un altre (pedaç de seguretat de Node, actualització d'Alpine). El digestsha256:9f2c…sempre és exactament els mateixos bytes.
Una analogia útil: el registre és la biblioteca; el repositori és el prestatge dedicat a una obra; les etiquetes són els adhesius ("primera edició", "última edició", "edició de butxaca") enganxats a exemplars concrets. Moure un adhesiu no canvia l'exemplar; només canvia a quin exemplar apunta aquest nom.
El nom complet i les seves abreviatures
Quan escrius docker pull nginx:alpine, Docker expandeix el nom així:
| El que escrius | El que Docker entén realment |
|---|---|
nginx |
docker.io/library/nginx:latest |
nginx:alpine |
docker.io/library/nginx:alpine |
auroralibros/aurora-api:1.0.0 |
docker.io/auroralibros/aurora-api:1.0.0 |
ghcr.io/auroralibros/aurora-api:1.0.0 |
tal qual: registre explícit |
localhost:5000/aurora-api:1.0.0 |
tal qual: registre local al port 5000 |
Tres regles que es dedueixen de la taula:
- Si no hi poses registre, s'assumeix Docker Hub (
docker.io). És una decisió històrica del client de Docker, no un estàndard; altres eines (Podman, per exemple, lliçó 07-05) poden preguntar-te quin registre vols. - Si no hi poses usuari/organització, s'assumeix
library/, l'espai de noms reservat a les imatges oficials. Per aixònginxilibrary/nginxsón el mateix, i per això ningú més no pot publicar un repositori anomenat simplementnginx. - Si no hi poses etiqueta, s'assumeix
latest, amb tots els perills que ja coneixes.
Pots comprovar la primera i la segona amb una comanda que ja domines:
docker pull nginx:alpine
docker image ls nginx --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"Docker et mostra la forma curta perquè el registre és el predeterminat. Si fas el mateix amb una imatge d'un altre registre, el nom apareixerà complet, amb ghcr.io/… al davant. Aquesta asimetria en la sortida és una pista ràpida per saber d'on ve cada imatge de la teva màquina.
- Docker Hub: compte i interfície
Docker Hub (hub.docker.com) és el registre públic per defecte de Docker: allotja milions de repositoris i és on han anat a buscar totes les imatges que has descarregat fins ara. Necessitaràs un compte per a dues coses: pujar la imatge d'aurora-api (lliçó 02-06) i —més immediat— duplicar la teva quota de descàrregues.
Crear el compte
- Entra a
https://hub.docker.comi prem Sign Up. - Tria un Docker ID. Pensa-t'ho bé: serà l'espai de noms de totes les teves imatges públiques i no es pot canviar després. Al curs farem servir
auroralibroscom a Docker ID fictici de l'alumne; tu faràs servir el teu de debò allà on aparegui. - Verifica el correu electrònic.
- Activa la verificació en dos passos (Account Settings → Security). A la pràctica no és opcional: el teu compte pot acabar publicant imatges que altres executen, i un compte compromès és un vector d'atac de manual.
Recorregut per la interfície
Un cop a dins, aquestes són les zones que faràs servir:
| Zona | Per a què serveix |
|---|---|
| Repositories | Els teus repositoris: crear, veure, canviar visibilitat, esborrar |
| Explore | Cercador d'imatges públiques, amb filtres per tipus (Official, Verified Publisher…) |
| Organizations | Espais compartits per un equip, amb permisos per membre |
| Account Settings → Security | Contrasenya, 2FA i Personal Access Tokens |
| Usage | Consum de descàrregues i emmagatzematge del teu compte |
La pàgina d'un repositori
Obre https://hub.docker.com/_/node (la barra baixa indica imatge oficial) i observa'n l'estructura, perquè és idèntica a tots els repositoris:
- Descripció: què és la imatge, com es fa servir, variables d'entorn que accepta, exemples. A les imatges ben mantingudes, aquesta pàgina és la documentació real del producte.
- Comanda de descàrrega a dalt a la dreta: el
docker pull nodea punt per copiar. - Pestanya Tags: el catàleg d'etiquetes disponibles. És la pestanya que més faràs servir. Per a cada etiqueta et mostra la mida comprimida, les arquitectures disponibles (
linux/amd64,linux/arm64…) i quan es va actualitzar per última vegada. Buscar-hi "22-alpine" abans d'escriure-ho en unFROMt'estalvia el clàssicmanifest unknownper una etiqueta que no existeix. - Enllaç al Dockerfile: a les imatges serioses, cada etiqueta enllaça al repositori de GitHub on hi ha el Dockerfile que la va construir. Poder llegir aquest fitxer és una de les millors senyals de confiança que existeixen.
Un exercici de dos minuts que convé fer ara: entra a la pestanya Tags de node, busca 22-alpine i anota'n la mida comprimida i la data d'actualització. Compara-ho amb 22 a seques. La diferència de mida explica per què a la lliçó 01-07 vas triar Alpine per a aurora-api.
docker login, docker logout i on queden les teves credencials
docker login, docker logout i on queden les teves credencialsPer pujar imatges o per descarregar de repositoris privats necessites autenticar-te. La comanda és directa:
Log in with your Docker ID or email address to push and pull images from Docker Hub.
Username: auroralibros
Password:
Login SucceededSense arguments, docker login apunta a Docker Hub. Per a un altre registre, se li passa com a argument:
I per tancar sessió:
On queden les credencials (i per què t'ha de preocupar)
Després d'un login correcte, Docker desa la credencial a ~/.docker/config.json. Mira-t'ho:
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "YXVyb3JhbGlicm9zOmRja3JfcGF0X2VqZW1wbG8="
}
}
}Aquest camp auth no està xifrat. És simplement usuari:contrasenya codificat en base64, que és una codificació reversible, no un sistema de protecció. Comprova-ho tu mateix:
Qualsevol persona amb accés de lectura al teu ~/.docker/config.json —un altre usuari del sistema amb permisos, un procés maliciós, una còpia de seguretat mal protegida o un contenidor al qual li vas muntar el directori per descuit— té les teves credencials en clar. De fet, Docker t'ho avisa en iniciar sessió:
WARNING! Your password will be stored unencrypted in /home/joan/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/go/credential-store/Tres mesures concretes per mitigar-ho, de menys a més esforç:
a) Fes servir un token d'accés personal en lloc de la teva contrasenya. A Docker Hub, Account Settings → Personal Access Tokens → Generate new token, amb permisos mínims (Public Repo Read-only si només descarregues, Read & Write si publicaràs). Avantatges: si es filtra, es revoca aquest token sense canviar la teva contrasenya, no dona accés al web ni a la configuració del compte, i en pots tenir un per màquina. Es fa servir igual:
b) Evita docker login -p en scripts. Escriure la contrasenya a la línia de comandes la deixa a l'historial de l'intèrpret d'ordres i a la llista de processos. La manera correcta és per entrada estàndard:
--password-stdin llegeix la credencial de la canonada. És el patró obligatori a CI/CD (el veuràs aplicat a la lliçó 06-02).
c) Configura un credential helper. És un programa extern que desa les credencials al magatzem segur del sistema operatiu en lloc de fer-ho en un fitxer de text:
| Sistema | Helper | Magatzem real |
|---|---|---|
| Linux (escriptori) | docker-credential-secretservice |
Anellat de claus de GNOME / KWallet via D-Bus |
| Linux (servidor, sense GUI) | docker-credential-pass |
pass, recolzat en GPG |
| macOS | docker-credential-osxkeychain |
Clauer de macOS (ve amb Docker Desktop) |
| Windows | docker-credential-wincred |
Administrador de credencials de Windows |
Instal·lació i activació a Linux d'escriptori:
I edita ~/.docker/config.json per afegir-hi la línia del helper:
Ara torna a autenticar-te:
L'objecte d'auths està buit: la credencial ja no és al fitxer, sinó al clauer del sistema, i l'avís ha desaparegut. Docker la recupera del helper cada vegada que la necessita.
- Tipus d'imatge a Docker Hub i com avaluar-ne la confiança
Descarregar una imatge i executar-la és, al capdavall, executar programari d'un desconegut a la teva màquina. Docker Hub etiqueta els repositoris en categories que t'ajuden a decidir de qui et refies.
| Tipus | Distintiu al web | Qui la manté | Espai de noms | Quan fer-la servir |
|---|---|---|---|---|
| Docker Official Image | Docker Official Image | Equip de Docker + mantenidors designats, amb Dockerfiles públics i revisats | library/ (sense usuari: nginx, node, postgres) |
Primera opció sempre per a programari base: llenguatges, bases de dades, servidors web |
| Verified Publisher | Verified Publisher | L'empresa propietària del programari, amb identitat verificada per Docker | El de l'empresa (grafana/grafana, bitnami/…) |
Quan necessites el producte comercial d'aquest fabricant |
| Sponsored OSS | Sponsored OSS | Projecte de codi obert reconegut, patrocinat per Docker | El del projecte | Projectes oberts consolidats sense imatge oficial |
| Comunitat | cap | Qualsevol persona amb un compte | Qualsevol | Només després d'auditar-la, o mai en producció |
Per a Aurora Libros això es tradueix en una cosa molt concreta: node, postgres, redis i nginx són oficials, i per això són les quatre bases del projecte. No hi ha cap motiu per fer servir algunusuari/node-22-amb-tot al seu lloc.
Criteris pràctics d'avaluació
Els distintius no cobreixen tots els casos: tard o d'hora necessitaràs una imatge de la comunitat. Aquesta és la comprovació que convé aplicar abans d'escriure-la en un FROM:
- Data de l'última actualització. És a la pestanya Tags. Una imatge que no es toca des de fa un any arrossega un any de vulnerabilitats sense pedaçar del sistema base. És el criteri que més descarta.
- El Dockerfile és públic? Si no pots llegir com es va construir, estàs executant una caixa negra. Busca l'enllaç a GitHub a la descripció.
- Mida. Una imatge de 2 GB per servir un binari de 10 MB indica que porta a dins mig sistema operatiu amb eines que no necessites i que amplien la superfície d'atac.
- Nombre i contingut de les capes. Amb el que has après a 01-05 pots auditar això sense descarregar res més que la imatge:
docker pull redis:7-alpine
docker image history redis:7-alpine --no-trunc --format "table {{.Size}}\t{{.CreatedBy}}" | head -12El que busques en aquesta sortida: instruccions comprensibles i justificables. Una capa amb un curl http://…/installador.sh | sh apuntant a un domini desconegut és una bandera vermella immediata; vol dir que la imatge descarrega i executa codi arbitrari d'un tercer en temps de construcció.
- Descàrregues i estrelles, amb reserves. Un milió de descàrregues indica que molta gent la fa servir, no que sigui segura; les xifres s'inflen fàcilment amb automatitzacions. Fes-ho servir com a senyal feble, mai com a argument principal.
- Publica diverses arquitectures? Si treballes en un Mac amb Apple Silicon o en un servidor ARM, necessites
linux/arm64. La pestanya Tags ho indica. Si només hi haamd64, funcionarà per emulació, més lenta (els manifests multiarquitectura es veuen a la lliçó 05-05).
Tot això és avaluació manual i prèvia. L'anàlisi automàtica del contingut d'una imatge a la recerca de vulnerabilitats conegudes (docker scout, escàners al pipeline) i la signatura criptogràfica d'imatges són una altra disciplina, i es tracten a la lliçó 05-03.
- Límits de descàrrega: anònim davant d'autenticat
Docker Hub limita quantes imatges pots descarregar per unitat de temps. És un límit real que talla builds en producció, i convé conèixer-lo abans que et passi.
| Situació | Límit orientatiu | Com s'identifica |
|---|---|---|
Anònim (sense docker login) |
El més baix de tots, comptat per adreça IP | Per IP pública de sortida |
| Compte gratuït autenticat | Sensiblement superior a l'anònim | Per compte d'usuari |
| Compte de pagament (Pro / Team / Business) | Molt alt o sense límit pràctic | Per compte |
Les xifres exactes les revisa Docker periòdicament, així que consulta sempre la pàgina oficial de preus abans de dimensionar res. El que no canvia és l'estructura del problema, i hi ha un matís crític: en el cas anònim el comptador és per IP. Si ets en una oficina, en una universitat o darrere del NAT d'un proveïdor de núvol, comparteixes quota amb tots els altres. Una empresa sencera darrere d'una sola IP pública pot esgotar el límit en minuts sense que ningú hagi fet res estrany.
Quan el superes, l'error és aquest:
Error response from daemon: toomanyrequests: You have reached your pull rate limit.
You may increase the limit by authenticating and upgrading:
https://www.docker.com/increase-rate-limitI si passa a mitja construcció, la veuràs així:
ERROR: failed to solve: node:22-alpine: failed to resolve source metadata for
docker.io/library/node:22-alpine: toomanyrequests: You have reached your pull rate limit.Com evitar-ho, per ordre d'eficàcia:
- Autentica't sempre, fins i tot per descarregar imatges públiques. Un simple
docker logina la teva màquina i als agents de CI duplica la quota i l'aïlla per compte en lloc de fer-ho per IP. - Aprofita la memòria cau local. Les capes ja descarregades no es tornen a baixar. Un agent de CI efímer que comença sempre en blanc ho descarrega tot cada vegada: és l'escenari que més consumeix.
- Fes servir un registre mirall o una memòria cau d'estirades (pull-through cache) a la teva organització. El registre de l'apartat 9 es pot configurar justament per a això.
- Consumeix les imatges base des d'un altre registre. Moltes imatges estan replicades a
ghcr.io, a ECR Public o amcr.microsoft.com, amb polítiques de límit diferents.
Pots comprovar la teva situació consultant la capçalera que retorna el registre en demanar un manifest, sense descarregar la imatge:
TOKEN=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | grep -o '"token":"[^"]*' | cut -d'"' -f4)
curl -s --head -H "Authorization: Bearer $TOKEN" https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest | grep -i ratelimitLa lectura és: quota de 100 descàrregues en una finestra de 21.600 segons (6 hores), de les quals te'n queden 76. És una comprovació útil quan un pipeline comença a fallar de manera intermitent sense canvis al codi.
- Cercar imatges des del terminal amb
docker search
docker searchNo cal obrir el navegador per cercar a Docker Hub:
NAME DESCRIPTION STARS OFFICIAL
postgres The PostgreSQL object-relational database ... 14231 [OK]
bitnami/postgresql Bitnami container image for PostgreSQL 202
timescale/timescaledb TimescaleDB - time-series database ... 130
postgrest/postgrest REST API for any PostgreSQL database 102
paradedb/paradedb Postgres for Search and Analytics 8Columnes: nom del repositori, descripció, estrelles i si és oficial. La primera fila no porta usuari al davant, la marca inequívoca que viu a library/.
Filtres i format disponibles:
# Només imatges oficials
docker search --filter is-official=true node
# Només repositoris amb com a mínim 100 estrelles
docker search --filter stars=100 redis
# Amb format personalitzat, reaprofitant el que has après a 01-04
docker search nginx --limit 5 --format "table {{.Name}}\t{{.StarCount}}\t{{.IsOfficial}}"NAME STARS OFFICIAL
nginx 21045 [OK]
nginxinc/nginx-unprivileged 145
nginxproxy/nginx-proxy 130
bitnami/nginx 191
nginx/nginx-prometheus-exporter 58Dues limitacions importants de docker search que cal tenir clares:
- Només cerca a Docker Hub. No consulta
ghcr.ioni cap altre registre, encara que hi tinguis sessió oberta. És una limitació de la comanda mateixa, no de la teva configuració. - No llista etiquetes. Et diu que existeix el repositori
node, però no quines versions hi ha a dins. Per a això, la pestanya Tags del web o una consulta a l'API del registre:
curl -s "https://hub.docker.com/v2/repositories/library/node/tags?page_size=100&name=22-alpine" \
| grep -o '"name":"[^"]*' | cut -d'"' -f4Aquesta comanda consulta l'API pública de Docker Hub i n'extreu els noms de les etiquetes que contenen 22-alpine. És la manera ràpida de verificar des del terminal que una etiqueta existeix abans de posar-la en un FROM i descobrir l'error a mitja build.
- Repositoris públics i privats
En crear un repositori a Docker Hub en tries la visibilitat, i la decisió té conseqüències pràctiques:
| Aspecte | Públic | Privat |
|---|---|---|
| Qui pot descarregar | Qualsevol, sense autenticar-se | Només comptes amb permís, sempre autenticades |
| Qui pot pujar | Només tu o la teva organització | Només tu o la teva organització |
| Apareix a les cerques | Sí | No |
| Cost | Gratuït i il·limitat | Quota limitada al pla gratuït; de pagament a partir d'aquí |
| Consumeix quota de descàrregues del qui la baixa | Sí | Sí |
| Ús típic | Programari lliure, imatges d'exemple, formació | Aplicacions d'empresa, qualsevol cosa amb lògica de negoci |
La regla d'or: una imatge pública és codi publicat. Tot el que hi ha a dins —el teu server.js, les teves rutes internes, els comentaris del codi, qualsevol fitxer que es va colar al COPY— pot ser inspeccionat i extret per qualsevol. Això connecta directament amb l'advertència de l'exercici 3 de la lliçó 01-07: les credencials mai no entren a la imatge, i amb un repositori públic aquesta regla passa de ser una bona pràctica a ser crítica.
Per al curs, auroralibros/aurora-api serà públic: així en podràs compartir l'enllaç i executar-lo des de qualsevol màquina sense autenticar-te, que és exactament el que vols demostrar. A la lliçó 02-06 veuràs com canviar la visibilitat a privada i com donar accés a un equip, que és el que faria Aurora Libros de debò.
- Registres alternatius a Docker Hub
Docker Hub no és obligatori. Aquests són els registres que et trobaràs al món real:
| Registre | Prefix | Punt fort | Autenticació |
|---|---|---|---|
| Docker Hub | docker.io/ (implícit) |
El catàleg públic més gran; imatges oficials | Docker ID + token |
| GitHub Container Registry | ghcr.io/ |
Integrat amb el repositori de codi i amb GitHub Actions; privats gratuïts il·limitats | Usuari de GitHub + personal access token amb permís write:packages |
| Amazon ECR | <id>.dkr.ecr.<regió>.amazonaws.com/ |
Permisos amb IAM, proximitat a les càrregues d'AWS, escaneig integrat | Token temporal via aws ecr get-login-password |
| GitLab Container Registry | registry.gitlab.com/ |
Integrat amb GitLab CI, un registre per projecte | Usuari + deploy token o token de CI |
| Harbor | el teu domini | Registre autoallotjat de la CNCF: replicació, polítiques de retenció, control d'accés fi | LDAP/OIDC o usuaris locals |
Registry (registry:2) |
el teu domini o localhost:5000 |
La implementació de referència, mínima i sense interfície web | Opcional (bàsica o token) |
La bona notícia és que tots parlen el mateix protocol, l'OCI Distribution Specification. Per això les comandes són idèntiques a tots ells: canvia el prefix del nom i res més. Un docker push a Docker Hub i un a Harbor són la mateixa operació contra servidors diferents. Ho comprovaràs ara mateix.
- El teu propi registre en un contenidor
Res no aclareix millor què és un registre que aixecar-ne un. La imatge oficial registry:2 implementa el protocol de distribució i cap en uns pocs megabytes.
Unable to find image 'registry:2' locally
2: Pulling from library/registry
...
Status: Downloaded newer image for registry:2
7c9a1e4f0b2d8a3c6f1b5e2d4a8c7b9e3f1a6d2c8b4e7a9f1c3d5b8e2a4f6c9dRepassa les opcions, totes conegudes de la lliçó 01-06: -d el deixa en segon pla, --name li dona un nom manejable i -p 5000:5000 publica el port del registre a la teva màquina. Comprova que respon:
/v2/ és l'arrel de l'API de distribució OCI, i _catalog llista els repositoris. Està buit: acabes d'estrenar-lo. Hi posarem alguna cosa a dins.
# 1. Portar una imatge petita des de Docker Hub
docker pull alpine:3.21
# 2. Crear una referència nova que apunti al teu registre
docker tag alpine:3.21 localhost:5000/alpine:3.21
# 3. Pujar-la
docker push localhost:5000/alpine:3.21The push refers to repository [localhost:5000/alpine]
6e771e15690e: Pushed
3.21: digest: sha256:21dc6063fd678b478f57c0e13f47560d0ea4eeba26dfc947b2a4f81f686b9f45 size: 528Què acaba de passar, pas a pas:
docker tagno copia ni duplica res: crea un nom nou per a la mateixa imatge local.alpine:3.21ilocalhost:5000/alpine:3.21comparteixen IMAGE ID. És el mecanisme que estudiaràs a fons a 02-06.- El prefix
localhost:5000/és el que determina la destinació del push. Docker no té cap comanda "puja a aquest servidor": el servidor forma part del nom de la imatge. Aquesta és la idea clau de tota la lliçó. - La sortida mostra la capa pujada i el digest resultant, el mateix identificador immutable de l'apartat 1.
Verifica el catàleg i les etiquetes del repositori:
I ara la prova de foc: esborra la imatge local i recupera-la des del teu registre.
docker image rm localhost:5000/alpine:3.21 alpine:3.21
docker pull localhost:5000/alpine:3.21
docker run --rm localhost:5000/alpine:3.21 cat /etc/alpine-releaseHas completat un cicle sencer —pull de Docker Hub, tag, push al teu registre, esborrat local, pull del teu registre, run— amb les mateixes comandes que faries servir contra qualsevol registre del món. L'única diferència entre el teu registre de joguina i el d'una multinacional és el prefix del nom i qui administra el servidor.
Un detall important que descobriràs així que passis del localhost: Docker exigeix HTTPS per a qualsevol registre remot. localhost n'està exempt per ser local. Si intentes fer servir 192.168.1.50:5000 sense TLS, obtindràs:
Error response from daemon: Get "https://192.168.1.50:5000/v2/": http: server gave HTTP response to HTTPS clientLa solució correcta és posar un certificat vàlid davant del registre. La solució ràpida per a una xarxa de laboratori és declarar-lo com a registre insegur a /etc/docker/daemon.json i reiniciar el dimoni:
Fes-ho servir només en entorns aïllats i de prova: sense TLS, qualsevol persona de la xarxa pot llegir i alterar les imatges en trànsit.
Quan acabis d'experimentar, neteja:
Tingues en compte que les imatges que hi vas pujar vivien dins del contenidor i desapareixen amb ell, perquè no vas muntar cap volum. Un registre real necessita emmagatzematge persistent, i aquest és justament el tema de la lliçó 03-06.
- El repositori d'Aurora Libros
Amb tot això, ja pots prendre la decisió que governa la resta del mòdul. La imatge de l'API d'Aurora Libros viurà a:
Que escriuràs en la seva forma curta:
Justificació de cada tram:
| Tram | Valor | Per què |
|---|---|---|
| Registre | docker.io (implícit) |
És el predeterminat, no requereix configuració i és el que més gent pot consumir sense fricció |
| Usuari | auroralibros |
El Docker ID de l'organització. Substitueix-lo pel teu de debò |
| Repositori | aurora-api |
Un repositori per servei, no un per projecte: aurora-api i, si algun dia calgués, aurora-web |
| Visibilitat | Pública | Per poder executar-la des de qualsevol màquina sense autenticar-se, que és la demostració del mòdul |
La regla d'"un repositori per servei" mereix un comentari, perquè és un error freqüent fer-ho al revés: posar diverses imatges diferents en un mateix repositori distingint-les per l'etiqueta (aurora:api-1.0.0, aurora:web-1.0.0). Tècnicament funciona, però trenca tota la resta: no pots donar permisos diferents per servei, les etiquetes deixen de significar "versió" i la pestanya Tags esdevé il·legible. Un repositori per artefacte desplegable.
Com a preparació per a la lliçó 02-06, crea ja el repositori buit des del web (Repositories → Create repository), amb nom aurora-api, visibilitat pública i una descripció curta com "API REST del catàleg d'Aurora Libros S.L.". No és imprescindible —Docker Hub crea el repositori automàticament al primer push—, però així fixes la descripció i la visibilitat des del principi i evites publicar per accident una cosa privada en públic.
A 02-02 construiràs la imatge que omplirà aquest repositori.
Errors Habituals i Consells
- Confondre registre amb repositori. "Puja la imatge al repositori de Docker" no significa res de precís. El registre és el servidor (
docker.io); el repositori és el nom que hi ha a dins (auroralibros/aurora-api). Quan depuris unpushfallit, la primera pregunta sempre és a quin registre apunta el nom complet de la imatge. - Creure que
docker login"canvia de registre". No hi ha cap registre actiu. Pots tenir sessió oberta simultàniament a Docker Hub,ghcr.ioi el teu registre local; la destinació de cada operació la decideix el prefix del nom de la imatge, no un estat global. - Deixar la contrasenya real a
~/.docker/config.json. Base64 no és xifratge. Fes servir un token d'accés personal amb permisos mínims i, si pot ser, un credential helper. En un servidor compartit això no és una recomanació, és un requisit. docker login -p laMevaContrasenyaen un script. Queda a l'historial de l'intèrpret d'ordres i és visible apsper a qualsevol usuari de la màquina. Fes servir--password-stdinsempre.- Builds anònimes a CI. És la causa número u del
toomanyrequestsque apareix "de sobte" un dimarts a la tarda: la IP compartida del proveïdor va esgotar la quota. Autentica els agents de CI encara que només descarreguin imatges públiques. - Refiar-se de les estrelles. Una imatge de la comunitat amb moltes descàrregues i sense actualitzar des de fa catorze mesos és pitjor opció que una d'oficial menys popular. Prioritza en aquest ordre: oficial → verificada → comunitat amb Dockerfile públic i actualitzada.
- Consell: mira sempre la pestanya Tags abans d'escriure un
FROM. Confirma que l'etiqueta existeix, amb quines arquitectures i quan es va actualitzar. T'estalvia elmanifest unknowna mitja build. - Consell: un registre local és la millor eina d'aprenentatge. Quan alguna cosa del flux
tag/push/pullno et quadri, reprodueix-la contralocalhost:5000: és instantani, no consumeix quota i no publica res a Internet.
Exercicis
Exercici 1: audita tres imatges abans de confiar-hi
Tria tres repositoris de Docker Hub: un d'oficial (postgres), un de Verified Publisher o Sponsored OSS que triïs tu, i un de comunitat que trobis cercant "nodejs" a Explore. Per a cadascun, omple aquesta taula i decideix si el faries servir com a base d'un servei d'Aurora Libros:
| Criteri | Imatge A | Imatge B | Imatge C |
|---|---|---|---|
| Nom complet | |||
| Tipus (oficial/verificada/comunitat) | |||
| Última actualització de l'etiqueta que faries servir | |||
| Mida comprimida | |||
| Dockerfile públic? URL | |||
| Arquitectures disponibles | |||
| La faries servir en producció? Motiu |
Recolza't en el web per als tres primers criteris i en docker image history per inspeccionar com es van construir.
Exercici 2: munta un registre i publica-hi una imatge
- Aixeca un registre local al port 5001 (no el 5000, per practicar el mapatge) anomenat
aurora-registry-lab. - Descarrega
redis:7-alpinede Docker Hub. - Publica-la al teu registre local amb el nom
localhost:5001/aurora-cache:7. - Consulta el catàleg del registre i la llista d'etiquetes del repositori amb
curl. - Esborra totes dues referències locals i torna a descarregar la imatge des del teu registre.
- Arrenca un contenidor amb ella i comprova que Redis respon.
- Neteja-ho tot.
Exercici 3: diagnostica quatre problemes de registre
Explica la causa de cada missatge i la comanda exacta amb què el resoldries:
a) Error response from daemon: pull access denied for aurora-api, repository does not
exist or may require 'docker login': denied: requested access to the resource is denied
b) denied: requested access to the resource is denied
(en executar: docker push aurora-api:1.0.0)
c) Error response from daemon: toomanyrequests: You have reached your pull rate limit.
d) Error response from daemon: Get "https://registre.intern.local:5000/v2/":
x509: certificate signed by unknown authoritySolucions
Solució a l'exercici 1
Un resultat típic, amb els valors del moment d'escriure aquesta lliçó (els teus variaran, l'important és el raonament):
| Criteri | postgres:16-alpine |
grafana/grafana:11.4.0 |
algunusuari/nodejs:latest |
|---|---|---|---|
| Tipus | Docker Official Image | Verified Publisher | Comunitat |
| Última actualització | Fa dies | Fa dies | Fa 2 anys |
| Mida comprimida | ~110 MB | ~180 MB | ~380 MB |
| Dockerfile públic | Sí, github.com/docker-library/postgres |
Sí, github.com/grafana/grafana |
No |
| Arquitectures | amd64, arm64, i unes quantes més |
amd64, arm64 |
només amd64 |
| Producció? | Sí, és la referència | Sí, és el fabricant | No |
El raonament per descartar la tercera és acumulatiu, i qualsevol dels punts bastaria per si sol:
- Dos anys sense actualitzar significa dos anys de CVE sense pedaçar al sistema base. Encara que el codi de l'aplicació fos perfecte, la
libc,openssli la resta del sistema no ho són. - Sense Dockerfile públic no pots saber què hi ha a dins ni auditar-ho.
latestcom a única etiqueta és un símptoma de projecte no mantingut: no hi ha versionatge, així que no pots fixar res ni tornar enrere.- Només
amd64la fa inservible en un Mac amb Apple Silicon o en instàncies ARM llevat d'emulació. - La mida delata un sistema base complet amb eines innecessàries.
La conclusió pràctica per a Aurora Libros: les quatre bases del projecte (node, postgres, redis, nginx) són oficials, i aquesta és precisament la raó per la qual es van triar a la lliçó 01-07.
Solució a l'exercici 2
# 1. Registre al port 5001 de l'amfitrió
docker run -d --name aurora-registry-lab -p 5001:5000 registry:2Fixa't en -p 5001:5000: el registre sempre escolta al 5000 dins del contenidor; el que canvies és el port de l'amfitrió. És exactament el mapatge port-amfitrió → port-contenidor de la lliçó 01-06.
# 2. Descarregar de Docker Hub
docker pull redis:7-alpine
# 3. Reetiquetar i publicar
docker tag redis:7-alpine localhost:5001/aurora-cache:7
docker push localhost:5001/aurora-cache:7The push refers to repository [localhost:5001/aurora-cache]
7: digest: sha256:0d1a3e0c... size: 1571# 4. Consultar el registre
curl -s http://localhost:5001/v2/_catalog
curl -s http://localhost:5001/v2/aurora-cache/tags/list# 5. Esborrar totes dues referències locals i recuperar del registre propi
docker image rm redis:7-alpine localhost:5001/aurora-cache:7
docker image ls | grep -E "redis|aurora-cache" # no ha de retornar res
docker pull localhost:5001/aurora-cache:7El pas 5 és el que demostra l'objectiu de l'exercici: en esborrar les dues referències, la imatge desapareix de debò de la teva màquina (recorda de 01-05 que dues etiquetes sobre el mateix IMAGE ID compten com una sola imatge: mentre quedi una referència, les dades continuen sent-hi). Si el pull posterior funciona, els bytes vénen necessàriament del teu registre.
# 6. Arrencar i comprovar
docker run -d --name cache-lab -p 6379:6379 localhost:5001/aurora-cache:7
docker exec cache-lab redis-cli ping# 7. Neteja
docker stop cache-lab aurora-registry-lab
docker rm cache-lab aurora-registry-lab
docker image rm localhost:5001/aurora-cache:7Solució a l'exercici 3
(a) pull access denied ... may require 'docker login'. El missatge barreja dues causes perquè el registre no distingeix entre "no existeix" i "no tens permís": fer-ho permetria esbrinar quins repositoris privats té una organització. Les causes reals, per freqüència:
- El nom no porta usuari:
aurora-apis'expandeix adocker.io/library/aurora-api, ilibrary/està reservat a imatges oficials, així que no existeix. Correcte:docker pull auroralibros/aurora-api:1.0.0. - El repositori és privat i no hi tens sessió:
docker login. - Simplement hi ha una errada al nom.
(b) denied en fer push. Estàs intentant pujar a docker.io/library/aurora-api, un espai on ningú no té permís d'escriptura. La imatge ha de portar el teu espai de noms:
docker tag aurora-api:1.0.0 auroralibros/aurora-api:1.0.0
docker login
docker push auroralibros/aurora-api:1.0.0Regla general: si el push dona denied, mira el nom abans que les credencials. És més freqüent el nom mal format que la sessió caducada.
(c) toomanyrequests. Has esgotat la quota de descàrregues. Solució immediata:
Si ja estaves autenticat, la quota esgotada és la del teu compte i toca esperar que es renovi la finestra, fer servir un mirall o pujar de pla. A CI, la causa gairebé sempre és que els agents descarreguen de manera anònima: afegeix un pas de login amb --password-stdin al principi del pipeline (lliçó 06-02). Per confirmar el diagnòstic, la consulta de capçaleres ratelimit-* de l'apartat 5.
(d) x509: certificate signed by unknown authority. El registre sí que parla HTTPS, però el seu certificat està signat per una autoritat que la teva màquina no reconeix (típicament una CA interna de l'empresa). No és un problema de credencials. La solució correcta és instal·lar el certificat d'aquesta CA on Docker el busca:
sudo mkdir -p /etc/docker/certs.d/registre.intern.local:5000
sudo cp ca-empresa.crt /etc/docker/certs.d/registre.intern.local:5000/ca.crt
sudo systemctl restart dockerEl nom del directori ha de coincidir exactament amb l'amfitrió i el port que fas servir al nom de la imatge. L'alternativa d'afegir-lo a insecure-registries no arregla això: desactivaria la verificació en lloc de resoldre-la, i només és acceptable en un laboratori aïllat. Distingeix-lo de l'error de l'apartat 9 (server gave HTTP response to HTTPS client), que és el cas contrari: allà el servidor no té TLS en absolut.
Conclusió
Ja saps d'on vénen les imatges que executes. Un registre és un servidor que parla el protocol de distribució OCI; a dins té repositoris, col·leccions d'imatges que comparteixen nom; i dins de cada repositori, les etiquetes són punters mòbils a digests immutables. Aquest model de tres capes explica per què nginx significa realment docker.io/library/nginx:latest, per què dues etiquetes poden compartir IMAGE ID i per què la destinació d'un push no és un paràmetre de la comanda sinó part del nom de la imatge.
A més, ja tens compte a Docker Hub, saps que docker login deixa les teves credencials a ~/.docker/config.json en base64 —no xifrat— i com evitar-ho amb tokens d'accés personal, --password-stdin i un credential helper. Pots distingir una Docker Official Image d'una imatge de comunitat abandonada i aplicar una comprovació real de confiança: data d'actualització, mida, Dockerfile públic, capes comprensibles i arquitectures. Coneixes els límits de descàrrega, per què colpegen sobretot les builds anònimes darrere d'una IP compartida i quin error exacte produeixen. I has aixecat el teu propi registre amb registry:2 per comprovar, amb un cicle complet de tag, push, esborrat i pull, que el mecanisme no té res de màgic. La imatge de l'API d'Aurora Libros ja té adreça: auroralibros/aurora-api.
L'única cosa que falta és la imatge. A la lliçó següent, Construint Imatges Docker, passaràs de consumir imatges alienes a fabricar la teva: veuràs què fa exactament docker build, què significa aquell punt final de la comanda —el famós context de construcció—, com el fitxer .dockerignore que va quedar promès a 01-07 retalla aquest context, i com la memòria cau de capes de BuildKit converteix una build d'un minut en una de dos segons si ordenes bé les instruccions. En acabar-la tindràs auroralibros/aurora-api:0.1.0 construïda a la teva màquina, corrent en un contenidor i responent a curl http://localhost:3000/salut. El primer pas dels quinze comença a caure.
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
