Docker ha revolucionado la forma en que se desarrollan, despliegan y ejecutan aplicaciones. En lugar de instalar dependencias directamente en el servidor (y rezar para que todo funcione igual que en desarrollo), Docker empaqueta cada aplicación en un contenedor aislado que funciona de forma idéntica en cualquier entorno. Esta guía te lleva desde la instalación hasta desplegar aplicaciones reales con Docker Compose.
📦 ¿Qué es Docker?
Docker es una plataforma de código abierto que automatiza el despliegue de aplicaciones dentro de contenedores: entornos aislados y ligeros que comparten el kernel del sistema operativo anfitrión. Fue lanzado en 2013 por Solomon Hykes y en pocos años se convirtió en el estándar de la industria para empaquetar y distribuir software.
Un contenedor es como una caja que contiene tu aplicación, sus bibliotecas, configuración y todo lo necesario para funcionar. A diferencia de una máquina virtual, no necesita un sistema operativo completo propio, lo que lo hace mucho más ligero y rápido.
Aspecto
Contenedor (Docker)
Máquina virtual
Arranque
Segundos
Minutos
Tamaño
MB (solo app + deps)
GB (SO completo)
RAM
Compartida con host
Reservada por VM
Aislamiento
A nivel de proceso (namespaces)
A nivel de hardware (hipervisor)
Densidad
Decenas por servidor
Unas pocas por servidor
Portabilidad
Imagen idéntica en cualquier host Linux
Depende del hipervisor
💡 ¿Por qué Docker triunfó?
Antes de Docker, desplegar una aplicación significaba configurar el servidor manualmente: instalar la versión correcta de cada biblioteca, configurar variables de entorno, resolver conflictos de dependencias. Docker resolvió esto empaquetando todo junto. El resultado: «si funciona en Docker, funciona en producción».
🔧 Instalar Docker en Linux
La instalación oficial de Docker en Ubuntu y Debian utiliza el repositorio de Docker, no el paquete docker.io de los repositorios de la distribución, que suele estar desactualizado.
terminal — Instalar Docker Engine en Ubuntu
# 1. Prerrequisitossudoapt update
sudoapt install ca-certificates curl gnupg -y
# 2. Añadir la clave GPG oficial de Dockersudoinstall-m 0755 -d /etc/apt/keyrings
curl-fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# 3. Añadir el repositorioecho"deb [arch=$(dpkg --print-architecture) \
signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo $VERSION_CODENAME) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list
# 4. Instalar Docker Engine + Composesudoapt update
sudoapt install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y
# 5. Permitir usar Docker sin sudosudousermod-aG docker $USER
# (cerrar sesión y volver a abrir para que surta efecto)# 6. Verificar la instalacióndocker run hello-world
🧱 Imágenes, contenedores y registros
Docker se basa en tres conceptos fundamentales que conviene entender antes de usar cualquier comando.
Una imagen es una plantilla de solo lectura que contiene el sistema de archivos, las bibliotecas y la configuración necesaria para ejecutar una aplicación. Es como una ISO de un sistema operativo, pero mucho más ligera y específica. Se construye a partir de un Dockerfile.
Un contenedor es una instancia en ejecución de una imagen. Puedes crear múltiples contenedores a partir de la misma imagen, igual que puedes instalar varias máquinas desde la misma ISO. Cada contenedor tiene su propio sistema de archivos, red y procesos aislados.
Un registro (registry) es un repositorio de imágenes. Docker Hub es el registro público más grande, con miles de imágenes oficiales (nginx, mysql, python, node, etc.). Las empresas suelen tener registros privados para sus imágenes internas.
terminal — Flujo básico de Docker
# Descargar una imagen desde Docker Hubdocker pull nginx
# Crear y ejecutar un contenedordocker run -d --name mi-web -p 8080:80 nginx
# -d = segundo plano (detached)# --name = nombre del contenedor# -p 8080:80 = mapear puerto local 8080 al 80 del contenedor# Ahora: http://localhost:8080 muestra la página de nginx
🎛️ Comandos esenciales
terminal — Gestión de contenedores
# Listar contenedores en ejecucióndocker ps
# Listar TODOS (incluidos los parados)docker ps -a
# Parar / Iniciar / Reiniciardocker stop mi-web
docker start mi-web
docker restart mi-web
# Ver logs del contenedordocker logs mi-web
docker logs -f mi-web # Seguir en tiempo real# Ejecutar un comando dentro del contenedordocker exec -it mi-web bash
# Ver recursos consumidosdocker stats
# Eliminar un contenedor (debe estar parado)docker rm mi-web
# Eliminar todos los contenedores paradosdocker container prune
terminal — Gestión de imágenes
# Listar imágenes localesdocker images
# Buscar imágenes en Docker Hubdocker search python
# Eliminar una imagendocker rmi nginx
# Eliminar imágenes sin usardocker image prune -a
# Inspeccionar una imagen (capas, configuración)docker inspect nginx
📝 Dockerfile: crear imágenes propias
Un Dockerfile es la receta para construir una imagen Docker personalizada. Cada instrucción crea una capa en la imagen, y Docker cachea las capas para reconstrucciones más rápidas.
# Imagen base
FROM python:3.12-slim
# Metadatos
LABEL maintainer="ana@ciberaula.com"
LABEL description="API REST con Flask"
# Directorio de trabajo dentro del contenedor
WORKDIR /app
# Copiar dependencias primero (para aprovechar caché)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copiar el código de la aplicación
COPY . .
# Variables de entorno
ENV FLASK_APP=app.py
ENV FLASK_ENV=production
# Puerto que expone la aplicación
EXPOSE 5000# Usuario no-root (seguridad)
RUN useradd -r appuser
USER appuser
# Comando de inicio
CMD ["python", "-m", "flask", "run", "--host=0.0.0.0"]
terminal — Construir y ejecutar
# Construir la imagen (. = directorio actual con Dockerfile)docker build -t mi-api:1.0 .
# Ejecutardocker run -d --name api -p 5000:5000 mi-api:1.0
# Verificarcurl http://localhost:5000
✅ Buenas prácticas en Dockerfile
Usa imágenes base slim o alpine para reducir tamaño. Copia primero requirements.txt antes del código para aprovechar la caché de capas. No ejecutes como root (usa USER). Incluye un .dockerignore para excluir archivos innecesarios (node_modules, .git, etc.).
💾 Volúmenes: datos persistentes
Por defecto, los datos dentro de un contenedor desaparecen cuando el contenedor se elimina. Los volúmenes permiten que los datos persistan y se compartan entre contenedores.
terminal — Volúmenes Docker
# Crear un volumen con nombredocker volume create datos-mysql
# Usar el volumen en un contenedordocker run -d --name mysql \
-v datos-mysql:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=secreto \
mysql:8
# Montar un directorio del host (bind mount)docker run -d --name web \
-v /home/ana/sitio:/usr/share/nginx/html:ro \
-p 8080:80 nginx
# :ro = solo lectura (el contenedor no puede modificar los archivos)# Listar volúmenesdocker volume ls
# Inspeccionar un volumendocker volume inspect datos-mysql
# Eliminar volúmenes sin usardocker volume prune
🌐 Redes Docker
Docker crea redes virtuales que permiten que los contenedores se comuniquen entre sí de forma aislada. Por defecto, cada contenedor puede acceder a Internet pero los contenedores en distintas redes no se ven entre sí.
terminal — Redes Docker
# Crear una red personalizadadocker network create mi-red
# Ejecutar contenedores en la misma reddocker run -d --name db --network mi-red \
-e MYSQL_ROOT_PASSWORD=secreto mysql:8
docker run -d --name app --network mi-red \
-e DB_HOST=db mi-api:1.0
# 'app' puede conectarse a 'db' usando el nombre como hostname# Listar redesdocker network ls
# Inspeccionar una reddocker network inspect mi-red
🐙 Docker Compose: aplicaciones multi-contenedor
Docker Compose permite definir toda una arquitectura de servicios en un solo archivo docker-compose.yml. Con un comando levantas la base de datos, el backend, el frontend, la caché y lo que necesites, todo interconectado y configurado.
docker-compose.yml — Stack LAMP completo
services:
# Servidor web Apache + PHP
web:
image: php:8.2-apache
ports:
- "8080:80"
volumes:
- ./src:/var/www/html
depends_on:
- db
environment:
DB_HOST: db
DB_NAME: miapp
DB_USER: root
DB_PASS: secreto
restart: unless-stopped
# Base de datos MySQL
db:
image: mysql:8
volumes:
- mysql_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: secreto
MYSQL_DATABASE: miapp
restart: unless-stopped
# phpMyAdmin para gestión visual
phpmyadmin:
image: phpmyadmin
ports:
- "8081:80"
environment:
PMA_HOST: db
depends_on:
- db
volumes:
mysql_data:
terminal — Gestionar Docker Compose
# Levantar todos los serviciosdocker compose up -d
# Ver estado de los serviciosdocker compose ps
# Ver logs de todos los serviciosdocker compose logs -f
# Ver logs de un servicio específicodocker compose logs -f web
# Parar todos los serviciosdocker compose stop
# Parar y eliminar contenedores, redes y volúmenesdocker compose down
# Reconstruir imágenes (después de cambiar Dockerfile)docker compose build
docker compose up -d --build
🛡️ Seguridad y buenas prácticas
Práctica
Riesgo si no se aplica
Cómo aplicar
No ejecutar como root
Un exploit obtiene acceso root al host
USER appuser en Dockerfile
Usar imágenes oficiales
Imágenes con malware o vulnerabilidades
Solo imágenes de Docker Hub verificadas
Fijar versiones
Actualizaciones rompen la aplicación
FROM python:3.12-slim, no :latest
Escanear vulnerabilidades
Dependencias con CVEs conocidos
docker scout cves mi-imagen
Limitar recursos
Un contenedor consume todo el servidor
--memory=512m --cpus=1
No guardar secretos en imágenes
Contraseñas expuestas en capas
Usar variables de entorno o Docker secrets
⚠️ El grupo docker equivale a root
Cualquier usuario en el grupo docker puede ejecutar contenedores con acceso completo al sistema de archivos del host. Añadir un usuario al grupo docker le otorga, en la práctica, privilegios de root. Solo añade usuarios de confianza.
✏️ Ejercicios prácticos
Ejercicio 1: Contenedorizar una aplicación Node.js
Enunciado: Crea un Dockerfile para una aplicación Node.js Express que sirve una API REST en el puerto 3000. La imagen debe usar node:20-slim, instalar dependencias con npm ci y ejecutarse como usuario no-root.
▶ Ver solución
Dockerfile
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN useradd -r nodeuser
USER nodeuser
EXPOSE 3000
CMD ["node", "server.js"]
terminal
docker build -t mi-node-api:1.0 .
docker run -d --name api -p 3000:3000 mi-node-api:1.0
curl http://localhost:3000
Ejercicio 2: Stack WordPress con Docker Compose
Enunciado: Crea un docker-compose.yml que levante WordPress con MySQL y phpMyAdmin. WordPress en el puerto 8080, phpMyAdmin en 8081. Los datos de MySQL deben persistir en un volumen.
❓ Preguntas frecuentes sobre Docker en Linux: guía completa de contenedores
Las dudas más comunes respondidas de forma clara y directa.
Docker es una plataforma de contenedores que permite empaquetar una aplicación con todas sus dependencias en una unidad estandarizada llamada contenedor. Esto garantiza que la aplicación funcione igual en cualquier entorno: tu portátil, un servidor de pruebas o producción en la nube. Elimina el clásico problema de 'en mi máquina funciona'.
Una máquina virtual incluye un sistema operativo completo y necesita un hipervisor, consumiendo varios GB de RAM. Un contenedor comparte el kernel del sistema anfitrión y solo incluye la aplicación y sus dependencias, arrancando en segundos y consumiendo mucha menos memoria. Los contenedores son más ligeros y rápidos, las VMs ofrecen mayor aislamiento.
Docker fue diseñado para Linux y es donde mejor funciona, ya que los contenedores usan directamente el kernel de Linux. En Windows y macOS, Docker Desktop ejecuta una máquina virtual Linux ligera de forma transparente. Para desarrollo profesional y producción, Linux es la plataforma recomendada.
Docker Compose es una herramienta para definir y ejecutar aplicaciones multi-contenedor. Con un archivo docker-compose.yml describes todos los servicios (web, base de datos, cache, etc.), sus configuraciones, volúmenes y redes. Un solo comando 'docker compose up' levanta toda la infraestructura.
Sí, con la configuración adecuada. Las mejores prácticas incluyen: no ejecutar contenedores como root, usar imágenes oficiales y verificadas, escanear vulnerabilidades con docker scout, limitar recursos con --memory y --cpus, usar redes aisladas y mantener Docker actualizado. Empresas como Google, Netflix y Spotify usan Docker en producción.
Un Dockerfile es un archivo de texto con instrucciones paso a paso para construir una imagen Docker. Define la imagen base (FROM), los archivos a copiar (COPY), los paquetes a instalar (RUN), las variables de entorno (ENV), el puerto a exponer (EXPOSE) y el comando de inicio (CMD). Es la receta para crear imágenes reproducibles.
Es prácticamente imprescindible en 2026. La mayoría de empresas tecnológicas usan contenedores en producción. Docker es requisito en ofertas de trabajo de sysadmin, DevOps e ingeniero de plataformas. Además, simplifica enormemente el despliegue, la escalabilidad y la gestión de aplicaciones.
★★★★★
Valora este artículo
¿Útil?
💬 Foro de discusión
¿Tienes dudas sobre Docker en Linux: guía completa de contenedores? Comparte tu pregunta con la comunidad.
¿Tienes cuenta?o comenta como invitado ↓
Iniciar sesión
🔑 Recuperar contraseña
Introduce el email con el que te registraste. Te enviaremos un enlace para crear una nueva contraseña.
Crear cuenta
Solo necesitas nombre, email y contraseña. Sin verificación por email.
Todavía no hay mensajes. ¡Sé el primero en participar!
🚀 ¿Quieres dominar Linux profesionalmente?
Cursos bonificados por FUNDAE para empresas — formación 100% subvencionada
Usamos cookies propias para mejorar tu experiencia de navegación y analizar
el uso del sitio. No compartimos datos con terceros ni usamos cookies de
publicidad. Puedes aceptar todas, aceptar solo las necesarias o configurar
tus preferencias.
Política de privacidad
Imprescindibles para el funcionamiento del sitio: preferencias de interfaz,
gestión de sesiones y este mismo aviso de cookies. No recogen datos
identificativos.
Nos permiten entender cómo navegas por el contenido para mejorar la
experiencia de aprendizaje. Utilizan identificadores anónimos (UUID) sin
vinculación a datos personales. Retención máxima: 6 meses.
¿Cómo valorarías tu experiencia aprendiendo en esta sección?