🐳 Imágenes y contenedores Docker
Docker es una plataforma para crear, enviar y ejecutar aplicaciones en contenedores ligeros y aislados. A diferencia de las máquinas virtuales, los contenedores comparten el kernel del sistema operativo host, lo que los hace rápidos en su inicio y eficientes en el uso de recursos.
Conceptos básicos
- Imagen: una plantilla en capas de solo lectura creada a partir de un Dockerfile. Las imágenes se almacenan en registros.
- Contenedor: una instancia en ejecución de una imagen. Los contenedores son efímeros a menos que se utilicen volúmenes.
- Capa: cada instrucción de Dockerfile crea una capa inmutable. Las capas se almacenan en caché y se comparten entre imágenes.
- Registro: un repositorio de imágenes (Docker Hub, AWS ECR, GitHub Container Registry).
- Volumen: un almacén de datos persistente que sobrevive a los reinicios y eliminaciones de contenedores.
Escribir archivos Docker
Un Dockerfile es un archivo de texto con instrucciones que Docker utiliza para crear una imagen. Cada instrucción agrega una nueva capa a la imagen.
Almacenamiento en caché de capas Ordene las instrucciones de menor a mayor frecuencia. Coloque COPY package.json y RUN npm install antes de COPY . . para maximizar la reutilización de la caché.
FROM node:20-alpine AS base
WORKDIR /app
# Install dependencies first (cached until package.json changes)
COPY package.json package-lock.json ./
RUN npm ci --only=production && npm cache clean --force
# Copy source code
COPY src/ ./src/
COPY config/ ./config/
# Create non-root user for security
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
# Runtime configuration
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=10s --start-period=15s --retries=3 \
CMD wget -qO- http://localhost:8080/health || exit 1
CMD ["node", "src/index.js"]Construcciones de varias etapas
Las compilaciones de varias etapas reducen drásticamente el tamaño de la imagen final mediante el uso de etapas de compilación y tiempo de ejecución separadas. Las herramientas de compilación, los compiladores y las dependencias de prueba permanecen en la etapa de compilación y nunca llegan a producción.
# Stage 1: Build
FROM golang:1.22-alpine AS builder
WORKDIR /build
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build \
-ldflags="-w -s" \
-o /app/server ./cmd/server
# Stage 2: Production image (~12MB vs ~350MB)
FROM scratch
COPY --from=builder /app/server /server
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
EXPOSE 8080
ENTRYPOINT ["/server"]Redes
Docker proporciona tres controladores de red integrados:
- puente — Predeterminado. Red aislada en el host. Los contenedores pueden comunicarse por su nombre.
- host: el contenedor comparte la pila de red del host. Máximo rendimiento, sin aislamiento.
- ninguno: sin conexión a red. Se utiliza para trabajos por lotes que no necesitan acceso a la red.
docker network create --driver bridge app-network
# Run containers on the same network (they resolve by name)
docker run -d --name postgres --network app-network postgres:16-alpine
docker run -d --name api --network app-network \
-e DB_HOST=postgres \
-p 8080:8080 \
registry.maxiscomputers.com/api:2.1.0
# Inspect network
docker network inspect app-networkComponente acoplable
Docker Compose define y ejecuta aplicaciones de múltiples contenedores utilizando un archivo YAML. Ideal para desarrollo local y pruebas de integración.
services:
api:
build:
context: .
dockerfile: Dockerfile
target: builder
ports:
- "8080:8080"
environment:
- NODE_ENV=development
- DB_URL=postgresql://user:pass@postgres:5432/appdb
- REDIS_URL=redis://redis:6379
volumes:
- ./src:/app/src:ro # hot reload in dev
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
restart: unless-stopped
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: appdb
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d appdb"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
command: redis-server --appendonly yes
volumes:
- redis_data:/data
volumes:
postgres_data:
redis_data:Seguridad de contenedores
Nunca ejecute como root Cree siempre un usuario no root dedicado en su Dockerfile. Ejecutar como root dentro de un contenedor es un riesgo de seguridad crítico.
- Utilice imágenes base distroless o Alpine para minimizar la superficie de ataque.
- Escanee imágenes con
docker scout,trivyogrypeen su canal de CI.
- Utilice sistemas de archivos de solo lectura cuando sea posible: bandera
--read-only.
- Nunca conviertas secretos en imágenes. Utilice variables de entorno o montajes secretos.
- Establezca
--cap-drop=ALLy agregue solo las capacidades de Linux requeridas.
- Habilite Docker Content Trust (
DOCKER_CONTENT_TRUST=1) para la verificación de firma de imágenes.
Referencia de la CLI de Docker
docker build -t registry.maxiscomputers.com/api:2.1.0 --platform linux/amd64 .
docker tag registry.maxiscomputers.com/api:2.1.0 registry.maxiscomputers.com/api:latest
# Push & Pull
docker push registry.maxiscomputers.com/api:2.1.0
docker pull registry.maxiscomputers.com/api:2.1.0
# Run
docker run -d --name api -p 8080:8080 --restart unless-stopped \
-e NODE_ENV=production \
registry.maxiscomputers.com/api:2.1.0
# Inspect & Debug
docker ps -a
docker logs -f --tail 200 api
docker exec -it api sh
docker inspect api | jq '.[0].NetworkSettings'
docker stats # live resource usage
# Cleanup
docker system prune -af --volumes # remove ALL unused resources
docker image prune -f # remove dangling images only