Quin problema resol Docker?

Si alguna vegada has sentit "a la meva màquina funciona" saps exactament el problema. Una aplicació depèn de versions específiques de biblioteques, configuracions del sistema operatiu i variables d'entorn. Reproduir aquest entorn en un altre servidor era una feina tediosa i propensa a errors.

Docker empaqueta l'aplicació juntament amb tot el que necessita en un contenidor: unitat aïllada, lleugera i reproduïble que funciona igual a qualsevol màquina que tingui Docker instal·lat.

Conceptes bàsics

  • Imatge: plantilla de només lectura amb el sistema de fitxers i configuració. Pensa-la com una "foto" de l'entorn
  • Contenidor: instància en execució d'una imatge. Pots tenir diversos contenidors de la mateixa imatge
  • Dockerfile: fitxer de text que defineix com construir una imatge
  • Docker Hub: registre públic d'imatges. Com npm o PyPI però per a contenidors
  • Volum: emmagatzematge persistent que sobreviu a la destrucció del contenidor

Comandes essencials

# Descarregar i executar una imatge
docker run nginx
docker run -d -p 8080:80 --name el-meu-nginx nginx
# -d: en segon pla, -p: mapejar port host:contenidor

# Gestionar contenidors
docker ps           # Contenidors en execució
docker ps -a        # Tots (inclosos aturats)
docker stop el-meu-nginx
docker start el-meu-nginx
docker rm el-meu-nginx   # Eliminar contenidor

# Veure logs
docker logs el-meu-nginx
docker logs -f el-meu-nginx   # Seguir en temps real

# Entrar en un contenidor
docker exec -it el-meu-nginx bash

# Gestionar imatges
docker images
docker pull ubuntu:22.04
docker rmi ubuntu:22.04

# Netejar tot el que no s'usa
docker system prune -a

Dockerfile: construir la teva pròpia imatge

FROM node:20-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY . .

EXPOSE 3000
CMD ["node", "server.js"]
# Construir i executar
docker build -t la-meva-app:1.0 .
docker run -d -p 3000:3000 la-meva-app:1.0

Bones pràctiques al Dockerfile:

  • Fes servir imatges base alpine (més petites i segures)
  • Posa COPY package.json abans del codi per aprofitar la memòria cau de capes
  • No executis com a root — afegeix un usuari sense privilegis
  • Fes servir .dockerignore per excloure node_modules, .git, etc.

Docker Compose: orquestrar múltiples serveis

La majoria d'aplicacions necessiten diversos serveis: web, base de dades, memòria cau... Docker Compose els defineix en un fitxer compose.yml:

services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/lamelvaapp
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=pass
      - POSTGRES_DB=lamelvaapp

volumes:
  postgres_data:
docker compose up -d      # Arrancar tot
docker compose down       # Aturar i eliminar
docker compose logs -f    # Veure logs de tots els serveis
docker compose ps         # Estat de tots els serveis

Seguretat bàsica a Docker

  • No facis servir la imatge latest en producció. Especifica versions
  • Escaneja imatges amb docker scout o Trivy abans de fer-les servir
  • No muntis el socket de Docker (/var/run/docker.sock) en contenidors sense necessitat absoluta
  • Sistema de fitxers de només lectura quan el contenidor no necessita escriure: --read-only
  • Limita recursos: --memory="512m" --cpus="0.5"

Casos d'ús que més faig servir

Al meu homelab faig servir Docker Compose per a gairebé tot:

  • Nextcloud (emmagatzematge personal)
  • Portainer (interfície web per gestionar Docker)
  • Nginx Proxy Manager (proxy invers amb SSL automàtic)
  • Vaultwarden (Bitwarden self-hosted)
  • Grafana + Prometheus (monitoratge)

Docker va convertir el que abans requeria hores de configuració en un docker compose up de 2 minuts.