El teu compose.yaml de la lliçó anterior fa servir set claus. L'especificació de Compose en defineix més de seixanta, però no cal que les memoritzis: la majoria són la traducció directa d'una opció de docker run que ja domines del mòdul 3.

Aquesta lliçó és la referència pràctica d'un servei, organitzada per blocs i aplicada a Aurora Libros. Al final tindràs els quatre serveis declarats en un sol fitxer. L'explicació de com interactuen entre ells és la lliçó 04-04, i les variables d'entorn tenen lliçó pròpia, la 04-05.

Contingut

  1. Taula mestra: claus de servei i el seu equivalent a docker run
  2. Imatge i construcció: image i build
  3. Identitat: container_name i hostname
  4. Execució: command, entrypoint, user, init i l'aturada
  5. Xarxa i ports: ports, expose, networks, àlies
  6. Dades: volumes, tmpfs, read_only
  7. Salut i dependències: healthcheck i depends_on
  8. Recursos i reinici: restart i deploy.resources
  9. Etiquetes: labels
  10. Blocs de nivell superior: volumes: i networks:
  11. Àncores i referències YAML per no repetir-te
  12. Aurora Libros: els quatre serveis declarats

  1. Taula mestra: claus de servei i el seu equivalent a docker run

Clau de Compose Opció de docker run Per a què serveix
image argument final Imatge de la qual parteix el contenidor
build docker build a part Construir la imatge des d'un Dockerfile
container_name / hostname --name / --hostname Nom del contenidor i nom de host intern
command / entrypoint arguments després de la imatge / --entrypoint Substitueixen el CMD i l'ENTRYPOINT de la imatge
user / working_dir -u / -w UID:GID del procés i directori de treball
init --init Insereix tini com a PID 1
stop_signal / stop_grace_period --stop-signal / --stop-timeout Senyal d'aturada i marge abans de SIGKILL
environment / env_file -e / --env-file Variables dins del contenidor
ports -p Publicar ports al host
expose --expose Documentar ports interns
networks --network Xarxes a les quals es connecta
volumes -v / --mount Muntatges de dades
tmpfs / read_only --tmpfs / --read-only Fitxers a RAM i arrel immutable
healthcheck --health-* Sonda de salut
depends_on (no existeix) Ordre d'arrencada entre serveis
restart --restart Política de reinici
deploy.resources.limits --memory, --cpus Límits de recursos
labels --label Metadades
cap_add / cap_drop --cap-add / --cap-drop Capacitats del nucli
extra_hosts --add-host Entrades a /etc/hosts

L'única fila sense equivalent és depends_on, i no és casualitat: la relació entre serveis és exactament allò que docker run no sap expressar.

  1. Imatge i construcció: image i build

image pren una referència igual que docker run: repositori i etiqueta (postgres:16-alpine) o, millor per a producció, un digest immutable (postgres@sha256:9f3d0e...).

build diu a Compose que construeixi la imatge en comptes de descarregar-la. En forma curta és només el context (build: ./api); en forma llarga, tot el que vas aprendre al mòdul 2:

    build:
      context: ./api                    # directori del context de build
      dockerfile: Dockerfile            # relatiu al context
      args: { NODE_VERSION: "22" }      # valors per a les instruccions ARG
      target: produccio                 # etapa concreta en builds multietapa
      cache_from: ["auroralibros/aurora-api:cache"]
    image: auroralibros/aurora-api:1.2.0   # nom amb què s'etiqueta

Quan apareixen les dues claus juntes, build mana a l'hora de construir i image dóna el nom del resultat. És la combinació més útil: docker compose build etiqueta la imatge amb aquest nom i docker compose push la publica.

Situació Fes servir Motiu
Servei de tercers (Postgres, Redis, Nginx) image No en tens el codi
Desenvolupament del teu propi codi build (+ image) Reconstrueixes en canviar
Producció image amb etiqueta immutable Desplegues el mateix que vas provar
CI que construeix i publica Totes dues build + push amb un nom fix

Només amb build, si no poses image, Compose etiqueta la imatge com a <projecte>-<servei>.

  1. Identitat: container_name i hostname

    container_name: aurora-db     # gairebé sempre: NO el posis
    hostname: aurora-db           # nom que retorna `hostname` a dins

container_name fixa el nom exacte i desactiva el prefixat de projecte. Sona còmode, i per això molta gent el posa; té tres inconvenients seriosos: impedeix docker compose up --scale (dos contenidors no es poden dir igual), impedeix aixecar dos projectes del mateix fitxer a la mateixa màquina, i no el necessites, perquè per parlar entre serveis es fa servir el nom del servei. Posa'l només quan alguna cosa externa —un script heretat, un agent de monitoratge— exigeixi un nom concret.

  1. Execució: command, entrypoint, user i l'aturada

    entrypoint: ["/usr/local/bin/arrencada.sh"]    # substitueix l'ENTRYPOINT
    command: ["node", "server.js"]                 # substitueix el CMD
    user: "1001:1001"                              # UID:GID sense privilegis
    working_dir: /app
    init: true                                     # tini com a PID 1
    stop_signal: SIGQUIT                           # nginx s'atura ordenadament amb aquest
    stop_grace_period: 30s                         # marge abans de SIGKILL

command i entrypoint admeten forma de cadena (command: node server.js, que passa pel shell) i forma de llista (["node", "server.js"], execució directa). Prefereix la llista: és la forma exec i garanteix que el teu procés sigui PID 1 i rebi SIGTERM, tal com vas veure a la lliçó 03-02. init: true insereix un init mínim com a PID 1 que reenvia senyals i enterra zombis, útil quan el teu procés llança fills i no els neteja. I stop_grace_period accepta unitats (10s, 1m30s): per a PostgreSQL, que necessita tancar un checkpoint abans de morir, puja'l a 30 segons.

  1. Xarxa i ports: ports, expose, networks, àlies

ports publica un port del contenidor al host. Forma curta, "[IP:]portHost:portContenidor[/protocol]":

    ports:
      - "8080:80"                  # totes les interfícies del host
      - "127.0.0.1:5432:5432"      # només localhost
      - "3000"                     # port aleatori del host → 3000
      - "5514:514/udp"             # protocol explícit

La forma llarga és més verbosa però explícita: - {target: 80, published: "8080", protocol: tcp, mode: host}, on target és el port intern, published el del host i mode: ingress només té sentit a Swarm.

expose no publica res: documenta quins ports escolta el contenidor. És informatiu, perquè dins d'una xarxa d'usuari tots els ports entre contenidors ja són accessibles.

networks connecta el servei a les xarxes declarades al bloc de nivell superior. Sense aquesta clau, el servei va a la xarxa default del projecte.

    networks:
      posterior:
        aliases: [base-de-dades]   # nom DNS addicional dins d'aquesta xarxa

Un servei pot estar en diverses xarxes alhora —és exactament el que farà aurora-api a la lliçó 04-04— i els aliases li donen noms DNS extra, útils per migrar sense tocar el codi dels clients.

  1. Dades: volumes, tmpfs, read_only

La forma curta és la sintaxi origen:destí[:opcions] de docker run -v, i l'origen decideix el tipus de muntatge:

    volumes:
      - aurora-dades:/var/lib/postgresql/data          # volum amb nom
      - ./db/init.sql:/docker-entrypoint-initdb.d/init.sql:ro   # bind (comença per ./)
      - /app/node_modules                              # volum anònim

La regla és la del mòdul 3: si l'origen comença per . o / és un bind mount; si no, és un volum amb nom que s'ha de declarar al bloc volumes: de nivell superior. La forma llarga equival a --mount:

    volumes:
      - type: volume
        source: aurora-dades
        target: /var/lib/postgresql/data
      - type: bind
        source: ./db/init.sql
        target: /docker-entrypoint-initdb.d/init.sql
        read_only: true
      - type: tmpfs
        target: /tmp
        tmpfs: { size: 67108864 }    # 64 MB, en bytes

Una diferència important: amb la forma curta, si l'origen d'un bind no existeix, Docker crea un directori buit; amb la forma llarga, falla amb un error clar i t'estalvia el clàssic "vaig muntar un directori on esperava un fitxer".

    read_only: true          # arrel del contenidor immutable
    tmpfs: [/tmp, /run]      # el poc que sí que necessita escriure

read_only: true amb un parell de tmpfs és una de les mesures d'enduriment més barates que existeixen; el tema complet és la lliçó 05-03.

  1. Salut i dependències: healthcheck i depends_on

El healthcheck de Compose substitueix o complementa el HEALTHCHECK del Dockerfile:

    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000/salut"]
      interval: 10s        # cada quant s'executa
      timeout: 3s          # quant espera la resposta
      retries: 3           # fallades seguides abans de marcar unhealthy
      start_period: 20s    # gràcia inicial: les fallades d'aquí no compten
      start_interval: 2s   # sondeig més freqüent durant start_period

Tres maneres d'escriure test:

Forma Exemple Com s'executa
CMD ["CMD", "pg_isready", "-U", "aurora"] Directa, sense shell
CMD-SHELL ["CMD-SHELL", "curl -f localhost/salut || exit 1"] Amb /bin/sh -c: admet canonades i ||
Cadena test: pg_isready -U aurora Equival a CMD-SHELL
Desactivar test: ["NONE"] Anul·la el HEALTHCHECK de la imatge

start_period és la clau que gairebé ningú fa servir i gairebé tothom necessita: PostgreSQL triga uns segons a acceptar connexions la primera vegada, i sense aquest marge el contenidor es marca unhealthy abans d'haver tingut oportunitat d'arrencar.

depends_on en forma curtadepends_on: [aurora-db, aurora-cache]— només garanteix l'ordre d'arrencada: Compose llança el contenidor de PostgreSQL, espera que el procés estigui en marxa i tot seguit llança l'API. Però PostgreSQL triga cinc segons més a acceptar connexions, així que l'API arrenca contra una base de dades que encara no respon. La forma llarga resol exactament això:

    depends_on:
      aurora-db:
        condition: service_healthy      # espera que passi el healthcheck
        restart: true                   # reinicia aquest servei si la dependència es recrea
      aurora-cache:
        condition: service_started      # n'hi ha prou que estigui arrencat
      aurora-migracions:
        condition: service_completed_successfully   # espera que acabi amb codi 0
Condició Espera que la dependència... Requereix
service_started Estigui en marxa (equival a la forma curta) Res
service_healthy Passi la seva sonda de salut Un healthcheck definit
service_completed_successfully Acabi amb codi de sortida 0 Un servei d'un sol ús

La distinció entre "arrencat" i "preparat" és la que separa un compose.yaml que funciona a la teva màquina d'un que funciona sempre. Es desenvolupa a la lliçó 04-04.

  1. Recursos i reinici: restart i deploy.resources

restart accepta els quatre valors de docker run amb el mateix significat: no (per defecte), always, on-failure[:n] i unless-stopped. Els límits, en canvi, viuen sota deploy, un bloc que originalment era exclusiu de Swarm:

    deploy:
      resources:
        limits:
          memory: 512M       # equival a --memory 512m
          cpus: "1.0"        # equival a --cpus 1.0
          pids: 200          # equival a --pids-limit 200
        reservations:
          memory: 256M       # garantia mínima (equival a --memory-reservation)
          cpus: "0.25"

Aquí hi ha una confusió clàssica que convé aclarir: fora de Swarm, docker compose sí que aplica deploy.resources.limits. El que s'ignora són replicas, placement, update_config i rollback_config, perquè no tenen sentit en un sol host. I recorda de la lliçó 03-07 que limits és un sostre dur —superar el de memòria significa OOM i codi 137— mentre que reservations és una garantia tova que influeix en qui cedeix memòria sota pressió.

  1. Etiquetes: labels

    labels:
      com.auroralibros.component: "base-de-dades"
      com.auroralibros.equip: "plataforma"

Admet també forma de llista (- "clau=valor"). Fes servir la notació de DNS invers a les claus per no xocar amb les d'altres eines. Serveixen per filtrar (docker ps --filter "label=..."), i moltes eines de l'ecosistema —proxies inversos automàtics, agents de mètriques— es configuren exclusivament amb etiquetes.

  1. Blocs de nivell superior: volumes: i networks:

Tot volum amb nom que facis servir en un servei s'ha de declarar a dalt:

volumes:
  aurora-dades:                    # el més habitual: driver local per defecte

  aurora-copies:
    name: copies-aurora-libros     # nom exacte, SENSE prefix de projecte
    labels: { com.auroralibros.retencio: "30d" }

  aurora-compartit:
    external: true                 # ja existeix; Compose ni el crea ni l'esborra

  aurora-nfs:
    driver: local
    driver_opts:                   # opcions que es passen al driver
      { type: nfs, o: "addr=10.0.0.20,rw,nfsvers=4", device: ":/exports/aurora" }

external: true és la protecció definitiva per a dades crítiques: Compose assumeix que el volum existeix i ni tan sols down -v el toca. Si no existeix, l'up falla en comptes de crear-ne un de buit en silenci.

Les xarxes segueixen el mateix patró:

networks:
  frontal:
    driver: bridge

  posterior:
    driver: bridge
    internal: true                 # sense accés a Internet ni a l'exterior
    labels: { com.auroralibros.zona: "dades" }

  externa:
    external: true
    name: aurora-net               # una xarxa creada fora de Compose

internal: true és la clau que sosté la segmentació de la lliçó 04-04: els contenidors d'aquesta xarxa no tenen ruta cap a l'exterior, ni l'exterior cap a ells. Una base de dades allà dins no pot descarregar res d'Internet encara que algú aconsegueixi executar-hi codi.

  1. Àncores i referències YAML per no repetir-te

Quan quatre serveis comparteixen política de reinici, logging i etiquetes, copiar-ho quatre vegades és demanar que es desincronitzin. YAML ofereix àncores (&), referències (*) i fusió de mapes (<<:), i Compose hi afegeix les claus d'extensió x-, que ignora en processar el fitxer:

x-comu: &comu                         # defineix l'àncora "comu"
  restart: unless-stopped
  logging:
    driver: json-file
    options: { max-size: "10m", max-file: "3" }

x-sonda-rapida: &sonda-rapida
  { interval: 10s, timeout: 3s, retries: 3, start_period: 20s }

services:
  aurora-cache:
    <<: *comu                         # fusiona tot el contingut de l'àncora
    image: redis:7-alpine
    healthcheck:
      <<: *sonda-rapida               # les àncores també valen per a subblocs
      test: ["CMD", "redis-cli", "ping"]

  aurora-web:
    <<: *comu
    image: nginx:alpine
    restart: always                   # les claus locals GUANYEN a les fusionades

Dos límits que convé conèixer: les àncores només funcionen dins del mateix fitxer (no travessen diversos -f), i <<: fusiona al primer nivell, no en profunditat: si l'àncora porta labels i el servei també defineix labels, el del servei substitueix el de l'àncora per complet, no els barreja. Comprova sempre el resultat amb docker compose config.

  1. Aurora Libros: els quatre serveis declarats

Amb tot l'anterior, aquest és el fitxer complet. Les credencials continuen escrites a mà —això s'arregla a la lliçó 04-05— i hi ha una sola xarxa; la segmentació arriba a la 04-04.

# compose.yaml — Aurora Libros S.L.
name: aurora-libros

x-comu: &comu
  restart: unless-stopped
  logging:
    driver: json-file
    options: { max-size: "10m", max-file: "3" }
  labels:
    com.auroralibros.projecte: "aurora-libros"

x-sonda: &sonda
  { interval: 10s, timeout: 3s, retries: 3, start_period: 20s }

services:

  aurora-db:
    <<: *comu
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: aurora
      POSTGRES_PASSWORD: aurora_secreta
      POSTGRES_DB: aurora_llibres
    ports:
      - "127.0.0.1:5432:5432"
    volumes:
      - aurora-dades:/var/lib/postgresql/data
      - ./db/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
    healthcheck:
      <<: *sonda
      test: ["CMD-SHELL", "pg_isready -U aurora -d aurora_llibres"]
      start_period: 30s          # la primera inicialització triga més
    stop_grace_period: 30s
    deploy:
      resources:
        limits: { memory: 512M, cpus: "1.0", pids: 200 }
        reservations: { memory: 256M }
    networks: [aurora-net]

  aurora-cache:
    <<: *comu
    image: redis:7-alpine
    command: ["redis-server", "--maxmemory", "200mb", "--maxmemory-policy", "allkeys-lru"]
    healthcheck:
      <<: *sonda
      test: ["CMD", "redis-cli", "ping"]
    deploy:
      resources:
        limits: { memory: 256M, cpus: "0.5", pids: 100 }
    networks: [aurora-net]

  aurora-api:
    <<: *comu
    build:
      context: ./api
      dockerfile: Dockerfile
    image: auroralibros/aurora-api:1.2.0
    environment:
      PORT: "3000"
      DB_HOST: aurora-db
      DB_USER: aurora
      DB_PASSWORD: aurora_secreta
      DB_NAME: aurora_llibres
      REDIS_HOST: aurora-cache
    ports:
      - "3000:3000"          # només per a proves directes contra l'API
    healthcheck:
      <<: *sonda
      test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000/salut"]
    restart: on-failure:3    # sobreescriu l'unless-stopped de l'àncora
    deploy:
      resources:
        limits: { memory: 256M, cpus: "1.0", pids: 100 }
        reservations: { memory: 128M }
    networks: [aurora-net]

  aurora-web:
    <<: *comu
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./web/index.html:/usr/share/nginx/html/index.html:ro
      - ./web/nginx.conf:/etc/nginx/conf.d/default.conf:ro
    stop_signal: SIGQUIT
    healthcheck:
      <<: *sonda
      test: ["CMD", "wget", "--spider", "-q", "http://localhost/"]
    deploy:
      resources:
        limits: { memory: 128M, cpus: "0.5", pids: 50 }
    networks: [aurora-net]

volumes:
  aurora-dades:

networks:
  aurora-net:
    driver: bridge

Cinquanta línies de bash imperatiu s'han convertit en un fitxer declaratiu, versionable i llegible, i de passada ha guanyat coses que l'script no tenia: sondes de salut als quatre serveis, rotació de logs i etiquetes coherents. Valida'l i aixeca'l:

cd ~/aurora-libros
docker compose config --quiet && docker compose up -d --build
docker compose ps --format "table {{.Service}}\t{{.Status}}"
SERVICE        STATUS
aurora-api     Up 25 seconds (healthy)
aurora-cache   Up 35 seconds (healthy)
aurora-db      Up 35 seconds (healthy)
aurora-web     Up 24 seconds (healthy)

Els quatre serveis healthy. Que hagin arrencat en l'ordre correcte és sort, perquè encara no hi ha ni un depends_on; això s'arregla a la lliçó 04-04.

Errors Habituals i Consells

Posar container_name per costum. Trenca l'escalat i la coexistència de projectes, i no aporta res: per parlar entre serveis es fa servir el nom del servei.

Fer servir un volum amb nom sense declarar-lo a dalt. Compose falla amb service refers to undefined volume. Els bind mounts no necessiten declaració; els volums amb nom, sí.

Esperar que depends_on a seques esperi que el servei estigui preparat. Només espera que arrenqui. Sense condition: service_healthy continuaràs tenint curses d'arrencada.

Definir un healthcheck sense start_period. El servei es marca unhealthy durant la seva arrencada normal i arrossega tot el que en depengui.

Escriure test: curl -f http://localhost/salut en una imatge Alpine. curl no ve instal·lat a les imatges Alpine oficials; wget sí. Un healthcheck que invoca un binari inexistent falla sempre, i el símptoma —unhealthy sense més pistes— despista molt.

Consell: comença cada servei nou amb image, restart i healthcheck, i afegeix la resta només quan ho necessitis. Un compose.yaml amb claus que ningú sap per què hi són és tan dolent com un script de bash.

Exercicis

Exercici 1. Tradueix a un servei de Compose aquesta comanda, sense ometre cap opció, i explica on va cadascuna:

docker run -d --name aurora-informes --network aurora-net \
  -u 1001:1001 -w /app -e TZ=Europe/Madrid --read-only --tmpfs /tmp \
  -v aurora-informes-sortida:/sortida --memory 192m --cpus 0.5 \
  --restart on-failure:2 --stop-timeout 20 \
  --health-cmd 'wget --spider -q http://localhost:4000/salut' --health-interval 15s \
  auroralibros/aurora-informes:0.3.0 node informes.js --diari

Exercici 2. El bloc x-comu del fitxer d'Aurora Libros inclou labels. Afegeix a aurora-db una etiqueta pròpia com.auroralibros.component: "base-de-dades" i comprova amb docker compose config què passa amb l'etiqueta heretada. Explica el resultat i proposa una solució.

Exercici 3. Declara un volum aurora-copies que apunti a un volum extern ja existent anomenat copies-aurora, munta'l de només lectura a aurora-db a /copies, i demostra que docker compose down -v no l'esborra.

Solucions

Solució 1.

  aurora-informes:
    image: auroralibros/aurora-informes:0.3.0
    command: ["node", "informes.js", "--diari"]    # tot el que va després de la imatge
    user: "1001:1001"
    working_dir: /app
    environment: { TZ: Europe/Madrid }
    read_only: true
    tmpfs: [/tmp]
    volumes:
      - aurora-informes-sortida:/sortida
    restart: on-failure:2
    stop_grace_period: 20s
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "http://localhost:4000/salut"]
      interval: 15s
    deploy:
      resources:
        limits: { memory: 192M, cpus: "0.5" }
    networks: [aurora-net]

--name s'omet deliberadament (el nom del servei ja identifica el contenidor), --network passa a networks, els límits baixen a deploy.resources.limits, --stop-timeout es converteix en stop_grace_period amb unitats, i els arguments posteriors a la imatge es converteixen en command en forma de llista.

Solució 2. Afegint labels: { com.auroralibros.component: "base-de-dades" } al servei aurora-db:

docker compose config | grep -A3 "aurora-db:" | grep -A2 labels
    labels:
      com.auroralibros.component: base-de-dades

L'etiqueta com.auroralibros.projecte ha desaparegut: <<: fusiona només al primer nivell, i com que el servei defineix la seva pròpia clau labels, aquesta substitueix per complet el mapa heretat. La solució és una segona àncora per al contingut de les etiquetes:

x-etiquetes: &etiquetes
  com.auroralibros.projecte: "aurora-libros"

services:
  aurora-db:
    <<: *comu
    labels:
      <<: *etiquetes
      com.auroralibros.component: "base-de-dades"

Ara config en mostra les dues. Regla general: quan fusionis àncores, verifica-ho sempre amb docker compose config; el que creus que hereta i el que hereta de veritat no sempre coincideixen.

Solució 3. Després de docker volume create copies-aurora, afegeix el muntatge a aurora-db i la declaració externa:

    volumes:
      - aurora-copies:/copies:ro        # dins d'aurora-db

volumes:
  aurora-dades:
  aurora-copies:
    external: true
    name: copies-aurora
docker compose up -d
docker compose exec aurora-db touch /copies/prova   # ha de fallar: :ro
docker compose down -v
docker volume ls --format "{{.Name}}" | grep -E "copies|aurora-dades"
touch: /copies/prova: Read-only file system
copies-aurora

down -v ha esborrat aurora-libros_aurora-dades, que era del projecte, però copies-aurora continua allà: en ser external, Compose el considera prestat i no el gestiona. És el mecanisme que has de fer servir per a qualsevol volum la pèrdua del qual sigui inacceptable.

Conclusió

Ja tens la referència completa d'un servei de Compose, i sobretot el mapa mental que la sosté: gairebé cada clau és una opció de docker run amb un altre nom, i només depends_on expressa alguna cosa que la CLI imperativa no sabia dir. Saps quan fer servir image i quan build —i per què sovint totes dues juntes—, per què container_name sobra gairebé sempre, com es tradueixen command, entrypoint, user, init, stop_signal i stop_grace_period, i les dues formes —curta i llarga— de ports i volumes, amb el matís que la llarga falla en comptes de crear un directori buit quan el bind no existeix.

Domines el bloc healthcheck complet, inclòs el start_period que evita marcar com a malalt un servei que només està arrencant, i coneixes la diferència entre les tres condicions de depends_on: service_started, service_healthy i service_completed_successfully. Saps que restart té els mateixos quatre valors de sempre i que deploy.resources.limits sí que s'aplica fora de Swarm. Declares volums i xarxes als blocs de nivell superior, blindes les dades crítiques amb external: true, aïlles amb internal: true, i evites la repetició amb àncores x-/&/*/<<: sabent que la fusió és superficial. I tens el compose.yaml amb els quatre serveis d'Aurora Libros declarats.

A la lliçó següent, Comandes de Docker Compose, passaràs del fitxer a la CLI: el cicle de vida complet (up i la seva reconciliació, down i el perill de -v, start, stop, restart, pause), l'observació (ps, logs, top, stats, events), la diferència essencial entre exec i run, la construcció i publicació, l'escalat local amb --scale i per què xoca amb els ports fixos, i la selecció de fitxers i projecte amb -f, -p i COMPOSE_FILE.

Docker: De Principiant a Avançat

Mòdul 1: Introducció a Docker

Mòdul 2: Treballant amb Imatges Docker

Mòdul 3: Contenidors Docker

Mòdul 4: Docker Compose

Mòdul 5: Conceptes Avançats de Docker

Mòdul 6: Docker en Producció

Mòdul 7: Ecosistema i Eines de Docker

© Copyright 2026. Tots els drets reservats