🐳 Docker
Contenedores
No todos los programas son compatibles con todos los sistemas operativos. Cada vez que un programa es compilado, se hace para un sistema determinado (Windows, Linux, Mac, etc.), lo que genera el clásico problema de incompatibilidad de entornos.
Para los desarrolladores esto supone un problema constante: en un equipo de trabajo con sistemas heterogéneos, cada uno necesita las mismas dependencias instaladas, con las mismas versiones, lo que desemboca en el conocido problema de "en mi máquina funciona".
Un contenedor es una unidad ligera y portátil que permite empaquetar una aplicación junto con todas sus dependencias (bibliotecas, configuraciones y binarios) en un entorno aislado.
A diferencia de las máquinas virtuales, los contenedores no incluyen un sistema operativo completo: comparten el núcleo (kernel) del sistema operativo del anfitrión, lo que los hace más eficientes en consumo de recursos (memoria y CPU).
BENEFICIOS DE LOS CONTENEDORES
- Portabilidad: Al empaquetar la aplicación con todas sus dependencias, se elimina la posibilidad de problemas relacionados con configuraciones del SO, bibliotecas o versiones de software. Un contenedor funciona igual en local, en staging y en producción.
- Eficiencia: Comparten el núcleo del SO anfitrión en lugar de requerir un sistema operativo completo para cada instancia. El tiempo de arranque es casi instantáneo y el consumo de CPU/memoria/almacenamiento es mínimo comparado con las VMs.
- Escalabilidad: Ideales para arquitecturas de microservicios. Cada servicio se ejecuta en su propio contenedor y se puede escalar de forma independiente. Combinados con orquestadores como Kubernetes, permiten la gestión automatizada de la escalabilidad horizontal y vertical.
BREVE HISTORIA
| Año | Hito |
|---|---|
| ~1970s | chroot en UNIX: primer concepto de aislamiento de procesos |
| 2000s | FreeBSD Jails y tecnologías avanzadas en el kernel de Linux |
| 2013 | Nace Docker: democratiza los contenedores con herramientas fáciles de usar y Docker Hub |
| 2014 | Google lanza Kubernetes para orquestación de contenedores |
| 2020+ | Alternativas como Podman emergen: sin daemon, ejecución rootless |
| Actualidad | Componente esencial de la infraestructura moderna, microservicios y DevOps |
Contenedor vs. Máquina Virtual
| Característica | Contenedor | Máquina Virtual |
|---|---|---|
| Virtualización | Nivel de SO (kernel compartido) | Hardware completo |
| SO propio | No (comparte el kernel) | Sí, uno por instancia |
| Peso | Ligero (MB) | Pesado (GB) |
| Tiempo de inicio | Casi instantáneo | Minutos |
| Aislamiento | Proceso/aplicación | Sistema completo |
| Eficiencia de recursos | Alta | Menor |
Docker
Docker es la plataforma de contenedores más popular del mundo. Facilita la creación, distribución y ejecución de aplicaciones en contenedores. Ha contado con el apoyo de grandes empresas como Red Hat, Google, IBM y Microsoft.
Componentes
Docker Engine es el núcleo de la plataforma y está compuesto por:
- Daemon de Docker (
dockerd): servicio en segundo plano que gestiona imágenes, contenedores, redes y volúmenes. Responde a las solicitudes del cliente. - CLI de Docker: interfaz de línea de comandos para interactuar con Docker (docker run, docker build, docker ps, etc.).
- API REST de Docker: interfaz programática para comunicarse con el daemon, utilizada tanto por la CLI como por aplicaciones externas.
Herramientas
- Docker Desktop: Aplicación de escritorio para Mac, Windows y Linux con GUI integrada
- Docker Engine: Motor de ejecución de contenedores (daemon + CLI + API)
- Docker Compose: Define y ejecuta aplicaciones multi-contenedor con un archivo YAML
- Docker Hub: Registro público y privado de imágenes de contenedores
- Docker Swarm: Orquestación nativa de clústeres de Docker
- Docker CLI: Interfaz de línea de comandos
- Docker Volume: Gestión de almacenamiento persistente
COMANDOS generales esenciales
docker version # Muestra la versión de Docker
docker info # Información del sistema Docker
docker help # Ayuda general
docker login # Inicia sesión en Docker Hub
docker logout # Cierra sesión
1. Imágenes
Una imagen Docker es un paquete inmutable de solo lectura que contiene todo lo necesario para ejecutar una aplicación: código, ejecutables, librerías, configuraciones, variables de entorno y el sistema de archivos que usarán los contenedores.
Conceptos clave
- Plantilla de solo lectura: Las imágenes no se modifican. A partir de una imagen se crean los contenedores (instancias en ejecución).
- Sistema de capas (layers): Las imágenes se construyen en capas apiladas, como una cebolla. Cada instrucción del Dockerfile genera una nueva capa. Las capas son inmutables y se pueden compartir entre imágenes, lo que ahorra espacio y acelera las descargas.
- Tags (etiquetas): Identifican versiones de una imagen. Por ejemplo,
ubuntu:22.04onginx:latest. - Imagen base: Toda imagen parte de otra imagen (
FROM). Las imágenes base suelen ser distribuciones Linux minimalistas como Alpine (~5 MB), Debian slim, o imágenes oficiales de servicios. - De la misma imagen puedes lanzar múltiples contenedores simultáneamente.
Docker-Hub
Repositorio de imágenes donde puedes registrarte y subir tus propias imágenes, además contiene:
- Imágenes oficiales (mantenidas por Docker y los propios proyectos): nginx, postgres, python, node, ubuntu...
- Imágenes de la comunidad:
usuario/imagen - Repositorios públicos o privados (con plan de suscripción)
Otros registros populares: GitHub Container Registry, Google Container Registry, Amazon ECR, Azure Container Registry...
COMANDOS de imágenes
# Comandos más utilizados
docker image ls # Listar todas las imágenes locales
docker images # equivalente
docker image inspect ubuntu # Información detallada de una imagen
docker image history ubuntu # Historial de capas de una imagen
docker image rm ubuntu # Eliminar una imagen
docker rmi ubuntu # equivalente
docker image prune # Eliminar imágenes no utilizadas
# Repositorio de imágenes
docker search nginx # Buscar imágenes en Docker Hub
# ──────────────────────────────────
docker image pull ubuntu # Descargar una imagen desde Docker Hub
docker pull ubuntu # equivalente
docker pull ubuntu:22.04 # versión específica
docker pull ubuntu:latest # última versión (por defecto)
# ──────────────────────────────────
docker image build -t mi-app:1.0 . # Construir una imagen desde un Dockerfile
docker build -t mi-app:1.0 . # equivalente
docker image tag mi-app:1.0 mi-usuario/mi-app:1.0 # Etiquetar una imagen
# ──────────────────────────────────
docker image push mi-usuario/mi-app:1.0 # Subir una imagen a Docker Hub
docker push mi-usuario/mi-app:1.0 # equivalente
2. Contenedores
Un contenedor es una instancia ejecutable de una imagen. Se crea a partir de ella y representa el proceso en ejecución de la aplicación con su entorno aislado. Características:
- Puede tener más de un proceso en ejecución, aunque la buena práctica es un proceso por contenedor.
- Está aislado de otros contenedores y del host (red, sistema de archivos, procesos).
- Cuando se elimina un contenedor, se pierden los datos que no estén en un volumen persistente.
- Se puede conectar a redes, adjuntar volúmenes y publicar puertos.
COMANDOS de contenedores
# Comandos más utilizados
docker container run nginx # Crear y ejecutar un contenedor
docker run nginx # equivalente
docker container ls # Listar contenedores en ejecución
docker ps # equivalente
docker container ls -a # Listar TODOS los contenedores (incluidos parados)
docker ps -a # equivalente
docker container rm mi-nginx # Eliminar un contenedor (debe estar parado)
docker rm mi-nginx # equivalente
docker rm -f mi-nginx # forzar eliminación aunque esté activo
docker container prune # Elimina todos los contenedores parados
# Opciones comunes de docker run:
docker run -d nginx # -d: segundo plano (detached)
docker run -it ubuntu bash # -it: modo interactivo + terminal
docker run --name mi-nginx nginx # --name: asignar nombre
docker run -p 8080:80 nginx # -p: mapear puertos host:contenedor
docker run -e VAR=valor nginx # -e: variable de entorno
docker run -v /host:/contenedor nginx # -v: montar volumen
docker run --rm nginx # --rm: eliminar al parar
docker run --network mi-red nginx # --network: conectar a red
# Iniciar/detener/reiniciar/pausar/reanudar un contenedor
docker container start mi-nginx
docker container stop mi-nginx
docker container restart mi-nginx
docker container pause mi-nginx
docker container unpause mi-nginx
# Otros comandos importantes
docker container logs mi-nginx # Ver logs de un contenedor
docker logs -f mi-nginx # seguir logs en tiempo real
docker logs --tail 100 mi-nginx # últimos 100 logs
docker container exec mi-nginx ls /etc/nginx # Ejecutar comando en contenedor activo
docker exec -it mi-nginx bash # abrir terminal interactivo
docker container inspect mi-nginx # Información detallada del contenedor
docker stats mi-nginx # Estadísticas de uso de recursos
docker container cp mi-nginx:/etc/nginx/nginx.conf ./nginx.conf # Copiar archivos entre host y contenedor
docker cp ./index.html mi-nginx:/usr/share/nginx/html/ # equivalente
docker container inspect` # Información detallada del contenedor
Columnas que muestra docker ps -a
CONTAINER ID: Identificador único del contenedorIMAGE: Imagen desde la que se creóCOMMAND: Proceso que se está ejecutando dentroCREATED: Tiempo desde que se creóSTATUS: Estado actual y tiempo en ese estadoPORTS: Mapeo de puertosNAMES: Nombre del contenedor (aleatorio si no se especifica)
3. Redes
Las redes Docker permiten definir cómo se comunican los contenedores entre sí y con el exterior. El componente principal que gestiona la conectividad es libnetwork y existen diferentes tipos de redes: (6)
1. Bridge (por defecto)-Red puente
Red predeterminada para los contenedores. Proporciona aislamiento básico y permite la comunicación entre contenedores en el mismo host. Los contenedores pueden referenciarse por nombre y se pueden exponer puertos al host.
docker run -d --name web --network bridge -p 8080:80 nginx
2. Host
Elimina el aislamiento de red entre el contenedor y el host. El contenedor comparte directamente la interfaz de red del sistema, usando la misma IP. Mejor rendimiento pero mayor riesgo de conflicto de puertos.
docker run -d --network host nginx
3. Overlay
Utilizada para contenedores distribuidos en diferentes hosts. Es la red usada en entornos de Docker Swarm para comunicar servicios entre nodos.
4. Macvlan
Asigna una dirección MAC propia a cada contenedor, haciéndolos aparecer como dispositivos físicos en la red. Útil para aplicaciones que necesitan estar directamente en la red LAN.
5. None
Desactiva completamente la conectividad de red del contenedor. Útil para tareas de procesamiento aislado sin necesidad de red.
6. Redes personalizadas (recomendado)
Las redes bridge personalizadas son la práctica recomendada ya que ofrecen:
- Resolución DNS automática entre contenedores por nombre.
- Mejor aislamiento que la red bridge por defecto.
- Mayor control sobre la subnet y el gateway.
docker network create mi-red # Crear una red personalizada
# Crear red con subnet específica
docker network create --driver bridge --subnet 172.20.0.0/16 mi-red
# Conectar contenedores a mi-red personalizada
docker run -d --name app --network mi-red mi-app
# Ahora 'app' puede llegar a 'db' usando su nombre
docker run -d --name db --network mi-red postgres
COMANDOS de redes
# Comandos más utilizados
docker network create mi-red # Crear una red
docker network create --driver overlay mi-overlay # tipo overlay
docker network ls # Listar todas las redes
docker network rm mi-red # Eliminar una red
docker network prune # Eliminar todas las redes no utilizadas
# ──────────────────────────────────
docker network inspect mi-red # Información detallada de una red
docker network inspect bridge # red por defecto
# ──────────────────────────────────
docker network connect mi-red mi-contenedor # Conectar un contenedor a una red (en caliente)
docker network disconnect mi-red mi-contenedor # Desconectar un contenedor de una red
# ──────────────────────────────────
# Publicación y mapeo de puertos del host al contenedor
docker run -p 8080:80 nginx # host:contenedor
docker run -p 127.0.0.1:8080:80 nginx # solo desde localhost
docker run -P nginx # mapeo automático de todos los puertos expuestos
4. Volúmenes
Un volumen Docker permite conservar los datos más allá del ciclo de vida de un contenedor. Sin volúmenes, todos los datos generados dentro de un contenedor se pierden cuando este se elimina.
Casos de uso:
- Transferir datos a un contenedor.
- Guardar datos persistentes (bases de datos, logs, configuraciones).
- Compartir datos entre múltiples contenedores.
Características de los volúmenes
- Persistencia de datos: Los datos sobreviven a la eliminación del contenedor.
- Compartir datos entre contenedores: Varios contenedores pueden montar el mismo volumen simultáneamente.
- Desacoplamiento datos/contenedor: Se puede actualizar o reemplazar el contenedor sin perder datos.
- Integración con el host: Los datos son accesibles desde fuera del contenedor.
- Flexibilidad: Volúmenes con nombre, anónimos o gestionados externamente (NFS, cloud storage...).
- Escalabilidad: Facilitan la distribución de datos en entornos orquestados.
TIPOS
Docker permite persistir y compartir datos entre el host y los contenedores (o entre contenedores) mediante tres mecanismos principales. Todos "montan algo dentro del contenedor", pero cada uno tiene un propósito y una gestión muy distintos.
1. Named volumes - volúmenes con nombre (recomendado)
Son gestionados completamente por Docker. Viven en una zona del sistema de archivos que Docker controla (normalmente /var/lib/docker/volumes/ en Linux), y tú solo interactúas con ellos por su nombre.
Cuándo usarlos: para datos que debe gestionar Docker y que sobreviven a la eliminación del contenedor (bases de datos, uploads de una app, etc.). Es la opción recomendada para producción porque Docker se encarga de permisos, backups más sencillos
El volumen empieza vacío y se va llenando solo, a medida que el contenedor trabaja, igual que un disco duro vacío se va llenando cuando instalas un sistema operativo en él.
docker volume create datos_mysql
docker run -d --name mysql -v datos_mysql:/var/lib/mysql mysql:8
2. Bind Mounts (montajes de enlace)
Montan un directorio o archivo específico del host dentro del contenedor. Tú controlas exactamente dónde está el archivo o carpeta, no Docker.
Cuándo usarlos: en desarrollo, cuando quieres que los cambios que haces en tu editor (VS Code, etc.) se reflejen al instante dentro del contenedor sin reconstruir la imagen. Reflejar cambios del código fuente en tiempo real.
docker run -d -v /ruta/en/host:/ruta/en/contenedor nginx
docker run -d --name web -v /home/yeray/apuntes:/usr/share/nginx/html nginx
3. tmpfs Mounts
Almacenamiento temporal en memoria RAM. Los datos no se persisten y desaparecen cuando el contenedor para.
Cuándo usarlos: datos temporales sensibles o de alto rendimiento que no necesitas persistir (cachés, secretos temporales, ficheros de sesión). Solo funciona en Linux.
docker run -d --tmpfs /tmp nginx
COMANDOS de volúmenes
# Comandos más utilizados
docker volume create mi-volumen # Crear un volumen
docker volume ls # Listar volúmenes
docker volume rm mi-volumen # Eliminar un volumen
docker volume prune # Eliminar todos los volúmenes no utilizados
# ──────────────────────────────────
docker volume inspect mi-volumen # Información detallada de un volumen
# ──────────────────────────────────
docker run -d -v mi-volumen:/datos mi-app # Usar un volumen al crear un contenedor
docker run -d --mount source=mi-volumen,target=/datos mi-app # Usar un volumen al crear un contenedor
docker run -d -v mi-volumen:/datos:ro mi-app # Contenedor de solo lectura
📖 Dockerfile
Un Dockerfile es un archivo de texto con una serie de instrucciones que Docker utiliza para construir una imagen de forma automatizada y reproducible. Cada instrucción genera una nueva capa en la imagen.
Instrucciones del Dockerfile
| Instrucción | Descripción |
|---|---|
FROM |
Obligatoria. Indica la imagen base. Siempre es la primera instrucción. |
RUN |
Ejecuta un comando durante la construcción y guarda el resultado como capa. |
CMD |
Comando por defecto al iniciar el contenedor (puede ser sobreescrito). |
ENTRYPOINT |
Comando principal que se ejecuta siempre al arrancar el contenedor. |
COPY |
Copia archivos/directorios del host a la imagen. |
ADD |
Como COPY pero también soporta URLs y descomprime archivos tar. |
EXPOSE |
Documenta el puerto que escuchará el contenedor (no lo publica). |
ENV |
Declara variables de entorno disponibles en la imagen y el contenedor. |
ARG |
Define variables disponibles solo durante el proceso de construcción. |
WORKDIR |
Establece el directorio de trabajo para RUN, CMD, COPY, ADD, ENTRYPOINT. |
USER |
Define el usuario con el que se ejecutarán las instrucciones posteriores. |
VOLUME |
Declara un punto de montaje de volumen. |
LABEL |
Añade metadatos a la imagen (autor, versión, descripción...). |
MAINTAINER |
Indica el autor del Dockerfile. Usar LABEL. |
ONBUILD |
Instrucción que se ejecuta cuando la imagen es usada como base de otra. |
HEALTHCHECK |
Define un comando para comprobar el estado de salud del contenedor. |
STOPSIGNAL |
Define la señal de sistema para detener el contenedor. |
Buenas prácticas en Dockerfile
- Usar imágenes base oficiales y ligeras (alpine, slim).
- Ordenar las instrucciones por frecuencia de cambio (lo que menos cambia, al principio) para aprovechar la caché.
- Minimizar el número de capas combinando comandos RUN con
&&. - No ejecutar como root: crear un usuario no privilegiado con
USER. - Usar
.dockerignorepara excluir archivos innecesarios (comonode_modules,.git). - Un proceso por contenedor: simplifica el escalado y los logs.
- Usar variables ARG y ENV para hacer el Dockerfile configurable.
Ejemplos
Ejemplo 1: Aplicación Python simple
# Imagen base oficial de Python
FROM python:3.11-slim
# Metadatos
LABEL maintainer="tu@email.com"
LABEL version="1.0"
# Variables de entorno
ENV APP_HOME=/app
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
# Directorio de trabajo
WORKDIR $APP_HOME
# Copiar e instalar dependencias primero (aprovecha caché de capas)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copiar el código fuente
COPY . .
# Exponer el puerto
EXPOSE 8000
# Usuario no root (buena práctica de seguridad)
RUN adduser --disabled-password --gecos '' appuser
USER appuser
# Comando por defecto
CMD ["python", "app.py"]
Ejemplo 2: Servidor web Nginx con contenido personalizado
FROM nginx:alpine
# Copiar configuración personalizada
COPY nginx.conf /etc/nginx/nginx.conf
# Copiar contenido web
COPY html/ /usr/share/nginx/html/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Ejemplo 3: Imagen con Alpine y Python (ejemplo del temario)
FROM alpine:latest
RUN apk update && apk add python3
RUN ln -sf python3 /usr/bin/python
CMD ["python3"]
Ejemplo 4: Multi-stage build (construcción en múltiples etapas)
# Técnica avanzada para reducir el tamaño de la imagen final
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Etapa de producción (imagen final ligera)
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Ejemplo 5: Combinar comandos RUN para reducir capas
RUN apt-get update && \
apt-get install -y curl git && \
rm -rf /var/lib/apt/lists/*
COMANDOS para construir imágenes
docker build -t mi-app:1.0 . # Construir imagen desde el directorio actual
docker build -f ruta/al/Dockerfile -t mi-app:1.0 . # Especificar ubicación del Dockerfile
docker build --build-arg VERSION=2.0 -t mi-app:2.0 . # Pasar argumentos de construcción
docker history mi-app:1.0 # Ver las capas generadas
📖 Docker Compose
Docker Compose es una herramienta para definir y ejecutar aplicaciones Docker multi-contenedor mediante un archivo YAML (docker-compose.yml). Con un solo comando se crean e inician todos los servicios de la aplicación.
Casos de uso
- Aplicaciones con varios servicios (frontend + backend + base de datos + cache...).
- Despliegues en entornos de desarrollo sencillos (staging, desarrollo).
- Testing e integración continua.
Buenas prácticas con Docker Compose
- Usar archivos
.envpara las variables sensibles (contraseñas, claves API). - Definir políticas de reinicio (
restart: unless-stopped) en producción. - Usar
healthcheckpara quedepends_onespere a que el servicio esté realmente listo. - Separar configuraciones por entorno:
docker-compose.yml(base) +docker-compose.override.yml(desarrollo) +docker-compose.prod.yml(producción). - Definir redes y volúmenes explícitos para facilitar su gestión e identificación.
Estructura
# Ejemplo de plantilla definiendo cada variable
services: # Sección principal donde defines tus contenedores
nombre-servicio:
image: node:18-alpine # Imagen Docker a usar (desde Docker Hub o registro)
build: . # Directorio para construir tu propia imagen (Dockerfile)
container_name: app # Nombre personalizado para el contenedor
ports: # Mapeo de puertos: "anfitrión:contenedor"
- "8080:3000"
volumes: # Montaje de volúmenes persistentes o carpetas compartidas
- ./data:/app/data # "anfitrión:contenedor"
environment: # Variables de entorno directamente en el archivo
- NODE_ENV=production
env_file: # Carga variables de entorno desde un archivo externo
- .env
depends_on: # Orden de inicio: espera a que otros servicios arranquen
- db
networks: # Redes a las que se debe conectar este servicio
- mi-red
restart: always # Reinicio (no, always, unless-stopped, on-failure)
command: npm start # Sobreescribe el comando por defecto (CMD) de la imagen
entrypoint: /app.sh # Sobreescribe el punto de entrada principal de la imagen
healthcheck: # Comando para verificar si el servicio está sano
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 1m30s
timeout: 10s
retries: 3
volumes: # Declarar volúmenes con nombre (persistencia)
nombre-volumen:
networks: # Definir redes personalizadas (aislamiento de red)
nombre-red:
Ejemplos
Aplicación web + Base de datos (con un Dockerfile)
services:
web:
build: . # Construye desde el Dockerfile del directorio actual
image: mi-app:latest
container_name: mi-web
ports:
- "8080:80" # host:contenedor
environment:
- DATABASE_URL=postgres://user:pass@db:5432/midb
- DEBUG=false
volumes:
- ./static:/app/static
depends_on:
- db
networks:
- app-network
restart: unless-stopped
db:
image: postgres:15-alpine
container_name: mi-db
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: midb
volumes:
- postgres-data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
networks:
- app-network
restart: unless-stopped
cache:
image: redis:7-alpine
container_name: mi-cache
networks:
- app-network
volumes:
postgres-data: # Volumen persistente para la base de datos
networks:
app-network:
driver: bridge
Aplicación web con Nginx + PHP-FPM + MySQL
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./src:/var/www/html
- ./nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
php:
image: php:8.2-fpm
volumes:
- ./src:/var/www/html
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: app
volumes:
- mysql-data:/var/lib/mysql
volumes:
mysql-data:
COMANDOS de Docker Compose
# Gestión de Ciclo de Vida
docker compose up -d # Iniciar todos los servicios (en segundo plano)
docker compose up -d --build # Iniciar y reconstruir imágenes si hay cambios
docker compose down # Detener y eliminar contenedores y redes
docker compose down -v # también elimina volúmenes
docker compose start # Inicia servicios que ya estaban creados pero parados
docker compose restart # Reinicia los servicios
docker compose stop # Detiene los servicios sin eliminarlos
# Construcción y Preparación
docker compose build # Construye o reconstruye las imágenes (si cambias Dockerfile)
docker compose pull # Descarga las imágenes de los servicios desde el registro
docker compose create # Crea los contenedores pero no los inicia
# Mantenimiento y Visualización
docker compose ps # Lista el estado de los contenedores del proyecto
docker compose logs -f # Muestra los logs de los servicios (en tiempo real)
docker compose config # Valida y muestra la configuración final del archivo YAML
docker compose top # Muestra los procesos que se ejecutan en cada contenedor
# Escalado y Ejecución
docker compose exec servicio bash # Entra a la terminal de un contenedor en ejecución
docker compose run servicio # Ejecuta un comando puntual en un servicio nuevo
docker compose scale servicio=3 # Escala el número de instancias/réplicas de un servicio
Comandos esenciales
# ── IMÁGENES ──────────────────────────────────────
docker pull nginx:alpine # Descargar imagen
docker images # Listar imágenes
docker rmi nginx:alpine # Eliminar imagen
docker build -t mi-app . # Construir imagen
# ── CONTENEDORES ──────────────────────────────────
docker run -d -p 8080:80 --name web nginx # Crear y ejecutar
docker ps -a # Listar todos los contenedores
docker start web # Iniciar
docker rm web # Eliminar
docker exec -it web bash # Terminal interactivo
# ── REDES ─────────────────────────────────────────
docker network ls # Listar redes
docker network create mi-red # Crear red
docker network inspect mi-red # Inspeccionar
docker network connect mi-red web # Conectar contenedor
# ── VOLÚMENES ─────────────────────────────────────
docker volume create mis-datos # Crear volumen
docker volume ls # Listar volúmenes
docker volume inspect mis-datos # Inspeccionar
docker run -v mis-datos:/data nginx # Usar volumen
# ── DOCKER COMPOSE ────────────────────────────────
docker compose up -d # Iniciar servicios
docker compose down # Parar y eliminar
docker compose ps # Ver estado
docker compose logs -f # Ver logs
docker compose exec web bash # Terminal en servicio



