Arriba el moment de la pràctica seriosa. En aquesta lliçó no llegiràs teoria: teclejaràs, t'equivocaràs i veuràs resultats al navegador. Començaràs amb el contenidor més simple possible —un que imprimeix alguna cosa i mor— per entendre el cicle més curt que existeix. Després aixecaràs un servidor web real en segon pla, en publicaràs el port i el visitaràs des del navegador, aprenent pel camí què significa exactament -p 8080:80, que és probablement l'opció que escriuràs més vegades a la teva carrera. Recorreràs el cicle complet d'aquest contenidor: veure'l, llegir-ne els registres, aturar-lo, arrencar-lo i esborrar-lo. Després entraràs dins d'un contenidor amb un shell interactiu per tocar el seu sistema de fitxers aïllat amb les teves pròpies mans. I acabaràs servint la primera pàgina web d'Aurora Libros des d'un contenidor, muntant-hi a dins un fitxer de la teva màquina.
Contingut
- Abans de començar: comprovacions
- El teu primer contenidor: en primer pla
- Què passa quan el procés acaba
- Un contenidor de servei en segon pla
- El mapatge de ports explicat
- El cicle complet: logs, stop, start i rm
- Un contenidor interactiu: entrar a dins
- Servint la pàgina d'Aurora Libros amb
-v - Neteja final
- Abans de començar: comprovacions
Assegura't que tot està en ordre:
El primer ha de mostrar els blocs Client i Server. El segon, una taula (probablement buida) sense errors. Si alguna cosa falla, torna a la lliçó 01-02.
Comprova també que el port que farem servir està lliure:
ss -tln llista els ports TCP en escolta (-t TCP, -l en escolta, -n sense resoldre noms). Si no hi ha coincidències, grep falla i el || executa l'echo. Si alguna cosa estigués escoltant al 8080, fes servir el 8081 a totes les comandes de la lliçó.
- El teu primer contenidor: en primer pla
Comencem pel mínim:
Sembla trivial, però han passat moltes coses. Desglossament de la línia:
| Part | Significat |
|---|---|
docker run |
Crea un contenidor nou i l'arrenca |
alpine:3.20 |
La imatge a partir de la qual crear-lo |
echo "Hola des d'Aurora Libros" |
La comanda que s'ha d'executar dins del contenidor, substituint la comanda per defecte de la imatge |
I la seqüència interna, que ja coneixes de la lliçó 01-03: el client va cridar el daemon, el daemon va comprovar que tenia alpine:3.20 en local, va crear un contenidor apilant una capa d'escriptura sobre les capes de la imatge, va demanar a containerd que arrenqués el procés echo, aquest va escriure a la seva sortida estàndard, i aquesta sortida es va transmetre pel socket fins al teu terminal.
Com que no has fet servir -d, el contenidor s'executa en primer pla: el teu terminal queda connectat a la seva sortida i no en recupera el control fins que el procés acaba.
Provem alguna cosa una mica més llarga:
docker run alpine:3.20 sh -c "echo 'Cataleg:'; echo '- Rayuela'; echo '- El jardín de senderos que se bifurcan'"Aquí la comanda és sh -c "...": es llança un shell dins del contenidor i se li passa una cadena amb diverses ordres. És el patró habitual quan necessites encadenar comandes, perquè docker run només accepta un executable amb els seus arguments, no una línia de shell amb ; o &&.
I alguna cosa que duri una estona, perquè vegis el primer pla de debò:
docker run alpine:3.20 sh -c "for i in 1 2 3 4 5; do echo \"Processant la comanda \$i\"; sleep 1; done"Processant la comanda 1
Processant la comanda 2
Processant la comanda 3
Processant la comanda 4
Processant la comanda 5Les línies surten d'una en una, amb un segon de pausa. El teu terminal està bloquejat mentrestant: això és primer pla. Si prems Ctrl+C durant l'execució, envies un senyal d'interrupció al procés i el contenidor acaba abans d'hora.
- Què passa quan el procés acaba
Aquesta és la regla més important de tota la lliçó:
Un contenidor viu exactament el que viu el seu procés principal. Quan aquest procés acaba, el contenidor passa a estat Exited. No hi ha res més per "apagar".
Comprova-ho:
Buit: cap dels tres contenidors anteriors continua viu.
NAMES COMMAND STATUS
happy_bardeen "sh -c 'for i in 1 2…" Exited (0) 10 seconds ago
festive_curie "sh -c 'echo Cataleg…" Exited (0) 1 minute ago
vibrant_torvalds "echo 'Hola des d'Au…" Exited (0) 2 minutes agoTots tres hi són, aturats, amb codi de sortida 0 (van acabar bé). Ocupen una mica de disc cadascun.
Aquest comportament explica un ensopec clàssic de principiants:
La segona comanda no mostra res, i la reacció típica és "el contenidor no arrenca". Sí que va arrencar: la imatge alpine té com a comanda per defecte /bin/sh, un shell que, en no tenir terminal interactiu ni entrada, no troba res a fer i acaba immediatament. El contenidor va fer la seva feina i va morir en mil·lisegons.
Perquè un contenidor continuï viu li cal un procés que no acabi: un servidor web esperant peticions, una base de dades, o un shell amb un terminal interactiu connectat. Això és el que veurem ara.
- Un contenidor de servei en segon pla
Aixequem un servidor web Nginx, que és exactament això: un procés que es queda escoltant indefinidament.
Unable to find image 'nginx:alpine' locally
alpine: Pulling from library/nginx
f18232174bc9: Already exists
2c8d4f7e1a09: Pull complete
...
Status: Downloaded newer image for nginx:alpine
7c3e9a1f5b2d84e0a6c7d9f3b1e5a7c9d2f4b6e8a0c2d4f6b8e0a2c4d6f8b0e2Analitzem-ho opció per opció, perquè cadascuna resol un problema concret:
| Opció | Nom llarg | Què fa |
|---|---|---|
-d |
--detach |
Executa el contenidor en segon pla i et retorna el control del terminal immediatament, imprimint-ne l'ID |
--name aurora-web-demo |
Li dona un nom llegible en lloc d'un d'aleatori. T'hi podràs referir per aquest nom a totes les comandes | |
-p 8080:80 |
--publish |
Publica el port 80 del contenidor al port 8080 de la teva màquina |
nginx:alpine |
La imatge. No hi indiquem comanda, així que es fa servir la de la imatge: arrencar Nginx |
Aquella llarga cadena hexadecimal de l'última línia és l'ID complet del contenidor. Com que has fet servir --name, no et caldrà.
Ara sí:
CONTAINER ID IMAGE COMMAND STATUS PORTS NAMES
7c3e9a1f5b2d nginx:alpine "/docker-entrypoint.…" Up 8 seconds 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp aurora-web-demoUp 8 seconds: està viu, i continuarà viu perquè Nginx no acaba mai per si sol. Fixa't que docker ps sense -a ja el mostra, a diferència dels contenidors anteriors.
- El mapatge de ports explicat
La columna PORTS mereix un apartat propi perquè és on més gent s'encalla.
Un contenidor té la seva pròpia pila de xarxa: la seva pròpia interfície, la seva pròpia adreça IP interna i els seus propis ports. Nginx escolta al port 80 d'aquesta xarxa interna, que des de la teva màquina no és accessible directament. L'opció -p crea un pont.
flowchart LR
NAV["El teu navegador<br/>http://localhost:8080"]
subgraph HOST["La teva màquina (amfitrió)"]
P8080["Port 8080<br/>(reservat per Docker)"]
subgraph NET["Xarxa bridge de Docker · 172.17.0.0/16"]
subgraph CNT["Contenidor aurora-web-demo · 172.17.0.2"]
P80["Port 80<br/>Nginx escoltant"]
end
end
end
NAV --> P8080
P8080 -->|"-p 8080:80<br/>reenviament"| P80
La sintaxi es llegeix sempre de fora cap a dins:
- El primer és el de la teva màquina: el que escrius al navegador. El tries tu i ha d'estar lliure.
- El segon és el del contenidor: aquell on escolta l'aplicació. No el tries tu, el determina l'aplicació (Nginx fa servir el 80, PostgreSQL el 5432, Redis el 6379, i l'API d'Aurora Libros farà servir el 3000).
Variants útils:
| Sintaxi | Efecte |
|---|---|
-p 8080:80 |
Port 8080 de totes les interfícies de l'amfitrió → 80 del contenidor |
-p 127.0.0.1:8080:80 |
Només accessible des de la teva pròpia màquina, no des de la xarxa local. Més segur |
-p 80:80 |
Port 80 de l'amfitrió (a Linux pot requerir privilegis) |
-p 8080:80 -p 8443:443 |
Diversos ports publicats alhora |
-P |
Publica tots els ports declarats per la imatge en ports aleatoris alts |
Sense -p, el contenidor funciona perfectament però és inabastable des de fora. És el correcte per a serveis interns: al mòdul 4, aurora-db i aurora-cache no publicaran ports, perquè només han de ser accessibles des d'aurora-api, no des d'Internet.
Comprovació amb curl i amb el navegador
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
...
</html>Només les capçaleres, per veure l'estat HTTP:
-I demana només les capçaleres (mètode HEAD). El 200 OK confirma que el servidor respon.
Obre ara http://localhost:8080 al teu navegador: hi veuràs la pàgina de benvinguda de Nginx. Acabes de servir un web des d'un contenidor sense haver instal·lat Nginx al teu sistema. Si executes nginx -v al teu terminal, el més probable és que la comanda no existeixi: tot és dins del contenidor.
- El cicle complet: logs, stop, start i rm
Veure els registres
/docker-entrypoint.sh: Configuration complete; ready for start up
2026/08/04 10:15:03 [notice] 1#1: nginx/1.27.4
2026/08/04 10:15:03 [notice] 1#1: start worker processes
172.17.0.1 - - [04/Aug/2026:10:16:12 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/8.5.0"
172.17.0.1 - - [04/Aug/2026:10:16:45 +0000] "GET / HTTP/1.1" 200 615 "-" "Mozilla/5.0 ..."Aquí hi ha les teves dues visites: la de curl i la del navegador, identificades pel seu user agent. La IP 172.17.0.1 és la de la teva màquina vista des de la xarxa interna de Docker.
Opcions molt útils:
docker logs -f aurora-web-demo # seguir en directe (Ctrl+C per sortir)
docker logs --tail 20 aurora-web-demo # només les 20 últimes línies
docker logs -t aurora-web-demo # amb marca de temps de Docker
docker logs --since 5m aurora-web-demo # només els últims 5 minutsProva docker logs -f aurora-web-demo, torna a carregar el navegador i veuràs aparèixer la línia en temps real. Ctrl+C talla el seguiment sense afectar el contenidor (un dubte molt habitual: no, no l'atures).
Aturar el contenidor
Retorna el nom del que ha aturat. Verifica-ho:
Dues coses: docker ps ja no el mostra, i a docker ps -a la columna PORTS està buida (el mapatge del port 8080 s'ha alliberat). Confirma-ho:
Ningú no escolta. El contenidor continua existint, però no està en execució.
Arrencar-lo de nou
Torna a funcionar, amb la mateixa configuració. I aquí hi ha un detall conceptual important: no has hagut de repetir -p 8080:80. La configuració es va fixar en crear el contenidor i en forma part. docker start només el reprèn.
Corol·lari: no pots canviar el mapatge de ports d'un contenidor existent. Si necessites un altre port, cal esborrar-lo i crear-ne un de nou. És una manifestació de la filosofia de contenidors rebutjables.
Hi veuràs els registres de la primera arrencada i els de la segona, un darrere l'altre: els registres es conserven mentre el contenidor existeixi.
Esborrar-lo
Si intentes docker rm sense aturar-lo primer:
Error response from daemon: cannot remove container "aurora-web-demo": container is running:
stop the container before removing or force removeHo pots forçar amb docker rm -f aurora-web-demo, que atura i esborra en un sol pas. És còmode en desenvolupament, però mata el procés sense donar-li temps de tancar-se ordenadament.
Verifica-ho:
El contenidor ha desaparegut de la llista; la imatge nginx:alpine hi continua sent. Un cop més: esborrar un contenidor no esborra la seva imatge.
- Un contenidor interactiu: entrar a dins
Fins ara executaves comandes soltes. Ara obriràs un shell dins d'un contenidor i t'hi mouràs.
Tres opcions noves:
| Opció | Nom llarg | Què fa |
|---|---|---|
-i |
--interactive |
Manté oberta l'entrada estàndard, perquè puguis escriure |
-t |
--tty |
Assigna un terminal virtual: prompt, colors, format |
--rm |
Esborra el contenidor automàticament en sortir |
-i i -t gairebé sempre van junts (-it): amb -i sense -t podries escriure però sense prompt ni format; amb -t sense -i veuries el prompt però no podries escriure.
El teu prompt canvia:
Ets dins del contenidor. Explora:
El nom d'amfitrió és l'ID curt del contenidor, no el de la teva màquina.
Un sistema de fitxers Linux complet... que no és el teu. Comprova-ho:
Alpine, encara que la teva màquina sigui Ubuntu, Windows o macOS.
Buits: els teus documents no són aquí. L'aïllament del sistema de fitxers és real.
Això és revelador: només hi ha dos processos, i el shell té el PID 1. A la teva màquina hi ha centenars de processos i el PID 1 és systemd. El contenidor té el seu propi espai de noms de processos i no veu els de l'amfitrió (el mecanisme exacte, a la lliçó 05-07).
I tanmateix:
El nucli és el del teu amfitrió. Espai d'usuari d'Alpine, nucli d'Ubuntu. Aquesta frase resumeix què és un contenidor.
Instal·lar alguna cosa a dins
Alpine fa servir apk com a gestor de paquets:
No està instal·lat. Instal·lem-lo:
fetch https://dl-cdn.alpinelinux.org/alpine/v3.20/main/x86_64/APKINDEX.tar.gz
(1/8) Installing ca-certificates (20240705-r0)
...
(8/8) Installing curl (8.12.1-r0)
Executing busybox-1.36.1-r29.trigger
OK: 13 MiB in 23 packagesapk addinstal·la paquets (l'equivalent d'apt install).--no-cacheevita desar l'índex de paquets al disc; és l'opció estàndard en contenidors perquè en redueix la mida.
Funciona. I una cosa important: has instal·lat curl al contenidor, no a la teva màquina. El teu sistema no s'ha tocat.
Crea també un fitxer per a la comprovació següent:
Ara surt:
Tornes al teu prompt normal.
La màgia de --rm
No hi apareix. Gràcies a --rm, el contenidor es va eliminar automàticament en acabar el seu procés. Amb ell se'n van anar la seva capa d'escriptura, el curl que hi vas instal·lar i el fitxer /prova.txt.
Confirma-ho obrint-ne un altre:
És la lliçó 01-05 en carn i ossos: cada contenidor neix net de la imatge immutable. Els canvis viuen a la seva capa d'escriptura i moren amb ell.
--rm és una opció excel·lent per a proves i comandes puntuals: t'estalvia l'acumulació de contenidors aturats. No la facis servir en serveis que vulguis poder reprendre.
- Servint la pàgina d'Aurora Libros amb
-v
-vNginx servint la seva pàgina per defecte està bé per provar, però volem el nostre contingut. Crearem la primera pàgina d'Aurora Libros.
Crear la pàgina
Crea index.html amb aquest contingut:
<!DOCTYPE html>
<html lang="ca">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Aurora Libros · Llibreria en línia</title>
<style>
body { font-family: system-ui, sans-serif; max-width: 42rem; margin: 3rem auto; padding: 0 1rem; color: #222; }
h1 { color: #6b3fa0; }
li { margin-bottom: .6rem; }
footer { margin-top: 2rem; font-size: .85rem; color: #666; }
</style>
</head>
<body>
<h1>Aurora Libros</h1>
<p>La teva llibreria en línia. Catàleg destacat:</p>
<ul>
<li><strong>El jardín de senderos que se bifurcan</strong> — Jorge Luis Borges — 14,50 €</li>
<li><strong>Rayuela</strong> — Julio Cortázar — 19,90 €</li>
<li><strong>Cien años de soledad</strong> — Gabriel García Márquez — 17,95 €</li>
</ul>
<footer>Aurora Libros S.L. · Servit des d'un contenidor Docker</footer>
</body>
</html>Muntar-la al contenidor
docker run -d --name aurora-web-demo -p 8080:80 \
-v ~/aurora-libros/web/index.html:/usr/share/nginx/html/index.html:ro \
nginx:alpineL'opció nova és -v (--volume), i la seva sintaxi es llegeix igual que la de -p, de fora cap a dins:
| Part | Significat |
|---|---|
~/aurora-libros/web/index.html |
El fitxer de la teva màquina. Ha de ser una ruta absoluta (~ l'expandeix el shell) |
/usr/share/nginx/html/index.html |
On apareixerà dins del contenidor. Aquesta ruta és on la imatge de Nginx busca els seus fitxers |
:ro |
read-only: el contenidor el pot llegir però no modificar. Bona pràctica quan no hi ha d'escriure |
Comprova-ho:
I al navegador, a http://localhost:8080, hi veuràs la pàgina d'Aurora Libros amb el seu catàleg. El fitxer continua estant al teu disc; el contenidor simplement el veu muntat al seu sistema de fitxers.
L'avantatge: edició en directe
Edita index.html al teu editor i afegeix-hi un llibre:
Desa i torna a carregar el navegador. El canvi apareix a l'instant, sense reconstruir res ni reiniciar el contenidor. El muntatge és una finestra en directe entre el teu disc i el contenidor.
Aquest patró —muntar el codi font dins del contenidor per desenvolupar sense reconstruir— és la base del flux de treball de desenvolupament local que veuràs a la lliçó 04-07.
Nota important. Aquest ús de
-vés purament introductori: és un bind mount, que munta una ruta de la teva màquina. N'hi ha un altre tipus, els volums gestionats per Docker, que és el que necessitaràaurora-dbper no perdre el catàleg. Les diferències, quan fer servir cadascun i les implicacions de permisos i rendiment són el contingut complet de la lliçó 03-06.
- Neteja final
Deixem el sistema com estava:
- Les dues primeres aturen i esborren el contenidor de Nginx.
container prune -felimina qualsevol altre contenidor aturat que hagis deixat pel camí.
Comprova-ho:
Sense contenidors; les imatges (alpine:3.20, nginx:alpine, hello-world) intactes, a punt per reutilitzar-se sense tornar-les a descarregar. El teu fitxer ~/aurora-libros/web/index.html també continua al seu lloc: el necessitaràs a les properes lliçons.
Errors Habituals i Consells
Bind for 0.0.0.0:8080 failed: port is already allocated. El port de l'amfitrió ja està ocupat, gairebé sempre per un altre contenidor teu. Busca'l ambdocker psi atura'l, o publica en un altre port (-p 8081:80).- Invertir l'ordre de
-p.-p 80:8080amb Nginx no funciona: estaries reenviant el port 80 de l'amfitrió al 8080 del contenidor, on no escolta ningú. Recorda: amfitrió:contenidor, de fora cap a dins. docker run -damb una comanda que acaba.docker run -d alpine echo holaarrenca i mor a l'instant.-dno manté viu res: només desconnecta el teu terminal. Per continuar viu cal un procés que no acabi.- Rutes relatives a
-v.-v ./web:/usr/share/nginx/htmlpot fallar segons la versió i el shell. Fes servir sempre rutes absolutes:$(pwd)/webo~/.... - Muntar un directori sobre un que ja té contingut. El muntatge oculta el que hi hagués en aquesta ruta dins de la imatge. Si muntes un directori buit sobre
/usr/share/nginx/html, Nginx retornarà 403 o 404 perquè ja no veu el seuindex.html. - Confondre
Ctrl+Camb aturar el contenidor. Adocker logs -fodocker attach,Ctrl+Cnomés talla la teva connexió. En un contenidor en primer pla, sí que interromp el procés i l'acaba. - Consell: fes servir
--rmper a tot el que sigui rebutjable. Proves, comandes puntuals, shells exploratoris. T'estalviarà neteges. - Consell: posa sempre nom amb
--name.aurora-web-demoés infinitament més manejable questupefied_swanson, i fa que els filtres per nom funcionin. - Consell: si un contenidor mor tot just arrencar,
docker logsprimer. Els registres es conserven encara que estigui aturat, i allà hi ha gairebé sempre l'explicació.
Exercicis
Exercici 1: dos aparadors alhora
Aixeca dos contenidors de Nginx simultàniament a partir de la mateixa imatge: un anomenat aurora-web-ca al port 8080 i un altre aurora-web-en al 8081, cadascun servint un index.html diferent (un en català i l'altre en anglès). Comprova amb curl que cada port retorna la seva pàgina. Després respon: quantes còpies de la imatge nginx:alpine hi ha al teu disc?, quant ocupa la capa d'escriptura de cada contenidor (docker ps -as)? En acabar, esborra'ls tots dos amb una única comanda.
Exercici 2: el detectiu de registres
Executa aquest contenidor, que està mal configurat expressament:
docker run -d --name aurora-fallada -p 8080:80 \
-v /tmp/carpeta-que-no-faig-servir:/usr/share/nginx/html:ro \
nginx:alpine(Crea abans /tmp/carpeta-que-no-faig-servir buida amb mkdir -p /tmp/carpeta-que-no-faig-servir.)
Visita http://localhost:8080 i observa l'error. Després: (a) està el contenidor en execució?, (b) quin codi HTTP retorna i per què?, (c) fes servir docker logs per trobar el missatge d'error exacte de Nginx, i (d) explica en termes de muntatges què ha passat i com ho arreglaries.
Exercici 3: exploració interactiva comparada
Obre un contenidor interactiu d'alpine:3.20 i un altre de nginx:alpine (en dos terminals, tots dos amb --rm). En cadascun, esbrina: (a) el sistema operatiu de l'espai d'usuari, (b) la versió del nucli, (c) el PID 1 i quants processos hi ha, i (d) si existeix el directori /usr/share/nginx/html i què conté. Explica les diferències i les coincidències entre els dos contenidors, i què et diu cadascuna sobre la naturalesa dels contenidors.
Solucions
Solució a l'exercici 1
mkdir -p ~/aurora-libros/web-ca ~/aurora-libros/web-en
echo '<h1>Aurora Libros</h1><p>Benvingut a la nostra llibreria.</p>' > ~/aurora-libros/web-ca/index.html
echo '<h1>Aurora Books</h1><p>Welcome to our bookstore.</p>' > ~/aurora-libros/web-en/index.html
docker run -d --name aurora-web-ca -p 8080:80 \
-v ~/aurora-libros/web-ca:/usr/share/nginx/html:ro nginx:alpine
docker run -d --name aurora-web-en -p 8081:80 \
-v ~/aurora-libros/web-en:/usr/share/nginx/html:ro nginx:alpine
curl -s http://localhost:8080
curl -s http://localhost:8081<h1>Aurora Libros</h1><p>Benvingut a la nostra llibreria.</p>
<h1>Aurora Books</h1><p>Welcome to our bookstore.</p>Aquí es munten directoris en lloc de fitxers solts, que és el més habitual amb Nginx. Els dos contenidors fan servir ports diferents de l'amfitrió (8080 i 8081) però tots dos el 80 a dins: no hi ha conflicte, perquè cada contenidor té la seva pròpia pila de xarxa i el seu propi port 80.
Respostes: hi ha una sola còpia de la imatge al disc, compartida pels dos contenidors. Cada capa d'escriptura ocupa al voltant d'1 kB. El "virtual 52.5MB" inclou les capes compartides de la imatge, que no es compten dues vegades. Aixecar el segon contenidor va costar pràcticament zero disc: és la densitat de la lliçó 01-01, mesurada.
rm -f atura i esborra en un sol pas, i accepta diversos noms.
Solució a l'exercici 2
(a) Sí, el contenidor està en execució:
CONTAINER ID IMAGE STATUS PORTS NAMES
b2c8f4a1e7d9 nginx:alpine Up 20 seconds 0.0.0.0:8080->80/tcp aurora-falladaNginx va arrencar correctament. El problema no és l'arrencada, sinó el contingut que serveix.
(b) Retorna 403 Forbidden:
És 403 i no 404 perquè el directori arrel existeix (l'has muntat) però està buit: no hi ha cap index.html per servir i Nginx no permet llistar directoris per defecte.
(c) Els registres:
2026/08/04 11:02:41 [error] 30#30: *1 directory index of "/usr/share/nginx/html/" is forbidden,
client: 172.17.0.1, server: localhost, request: "GET / HTTP/1.1", host: "localhost:8080"El missatge és explícit: directory index ... is forbidden.
(d) Què ha passat: el muntatge oculta el contingut original d'aquesta ruta a la imatge. La imatge nginx:alpine porta el seu propi index.html a /usr/share/nginx/html, però en muntar-hi a sobre un directori buit de la teva màquina, aquell contingut deixa de ser visible (no s'esborra: continua a la capa de la imatge, simplement queda tapat). Nginx troba un directori buit i respon 403.
Arranjaments possibles: posar un index.html a /tmp/carpeta-que-no-faig-servir, muntar un directori que sí que tingui contingut, o no muntar res si volies la pàgina per defecte.
echo '<h1>Aurora Libros</h1>' > /tmp/carpeta-que-no-faig-servir/index.html
curl -s http://localhost:8080
docker rm -f aurora-falladaFixa't que no cal reiniciar el contenidor: el muntatge és en directe, així que tan bon punt el fitxer existeix al teu disc, Nginx el serveix.
Solució a l'exercici 3
(La imatge de Nginx també porta un shell, així que s'hi pot entrar igual.)
En cadascun:
Resultats i la seva lectura:
| Comprovació | alpine:3.20 |
nginx:alpine |
Què significa |
|---|---|---|---|
| (a) SO de l'espai d'usuari | Alpine Linux v3.20 | Alpine Linux (versió de la imatge base de Nginx) | Totes dues es construeixen sobre Alpine: comparteixen capes base, com vas veure a 01-05 |
| (b) Nucli | El del teu amfitrió (p. ex. 6.8.0-52-generic) |
El mateix | Confirma que tots dos contenidors comparteixen el nucli de l'amfitrió. No hi ha SO convidat |
| (c) PID 1 i nre. de processos | sh com a PID 1, 2 processos |
sh com a PID 1, 2 processos |
Cada contenidor té el seu propi espai de noms de processos, aïllat. I compte: aquí Nginx no s'està executant, perquè en passar sh vas substituir la comanda per defecte de la imatge |
(d) /usr/share/nginx/html |
No existeix (ls: ... No such file or directory) |
Existeix, amb index.html i 50x.html |
El sistema de fitxers l'aporta la imatge: són diferents perquè les imatges porten contingut diferent |
Les conclusions importants: els contenidors comparteixen el nucli (b) però tenen sistemes de fitxers i espais de processos aïllats (c, d); dues imatges poden compartir la seva base i diferenciar-se només en les capes superiors (a); i passar una comanda a docker run substitueix la comanda per defecte de la imatge, per la qual cosa entrar amb sh a la imatge de Nginx et dona el sistema de fitxers de Nginx sense Nginx executant-se.
Conclusió
Ja has creat, gestionat i destruït contenidors amb les teves pròpies mans. T'endús la regla que governa tota la resta: un contenidor viu el que viu el seu procés principal; si aquest procés acaba, el contenidor passa a Exited, i per això docker run alpine "no fa res" mentre que docker run nginx:alpine es queda viu indefinidament.
Saps llançar contenidors en primer pla i en segon pla amb -d, posar-los nom amb --name, i sobretot publicar ports amb -p amfitrió:contenidor, llegint la sintaxi sempre de fora cap a dins; has comprovat que el mapatge es fixa en crear el contenidor i que docker start el reprèn amb la mateixa configuració. Has recorregut el cicle complet —logs, stop, start, rm—, has entrat dins d'un contenidor amb -it per veure amb els teus ulls l'aïllament del sistema de fitxers i dels processos al costat del nucli compartit, i has confirmat amb --rm que tot el que escrius a dins mor amb el contenidor. I has servit la primera pàgina d'Aurora Libros muntant un fitxer del teu disc amb -v, amb edició en directe inclosa.
Tens les tres peces del trencaclosques —imatges, contenidors i comandes— i una pàgina web funcionant. El que encara no tens és el problema real que justifica tot això. A l'última lliçó del mòdul, El Projecte del Curs: la Plataforma Aurora Libros, coneixeràs l'empresa, la seva arquitectura objectiu i el codi complet de la seva API, i intentaràs arrencar-la sense Docker per viure en primera persona el calvari que la resta del curs resoldrà.
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
