Instalación de Docker
La instalación de Docker es el primer paso en nuestro viaje. El proceso varía según tu sistema operativo, pero es relativamente sencillo en todas las plataformas.
Un dato interesante es que, según las estadísticas de JetBrains de 2024, el 76% de los desarrolladores que instalan Docker correctamente desde el principio reportan una experiencia mucho más fluida en su aprendizaje.
Windows
La instalación en Windows ha mejorado significativamente en los últimos años. Docker Desktop para Windows ahora ofrece una experiencia casi nativa gracias a WSL 2 (Windows Subsystem for Linux 2).
Requisitos previos:
- Windows 10/11 Pro, Enterprise o Education (Build 16215 o posterior)
- Virtualización habilitada en BIOS
- WSL 2 instalado y configurado
Proceso de instalación:
- Descarga Docker Desktop para Windows
- Ejecuta el instalador con privilegios de administrador
- En el asistente de instalación, asegúrate de:
- Marcar “Use WSL 2 instead of Hyper-V”
- Seleccionar “Add to PATH”
- Habilitar “Install required Windows components for WSL 2”
Verificación de la instalación:
Una vez instalado, puedes verificar la instalación con los siguientes comandos por medio de la terminal, tanto desde el símbolo del sistema (CMD) como desde el terminal de PowerShell, incluso desde Git Bash.
# Verifica la versión de Docker
docker --version
Docker version 25.0.3, build 4debf41
# Verifica que el daemon está corriendo
docker info
# Ejecuta un contenedor de prueba
docker run hello-world
Si ves el mensaje de “Hello from Docker!”, ¡felicitaciones! Docker está correctamente instalado.
Linux (Ubuntu)
Linux es el hogar natural de Docker, y la instalación en Ubuntu es particularmente directa. Las estadísticas muestran que el 85% de los servidores en producción ejecutan Docker en Linux debido a su rendimiento superior y menor sobrecarga.
# 1. Actualiza los repositorios
sudo apt-get update
# 2. Instala paquetes necesarios para permitir apt usar HTTPS
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release
# 3. Agrega la clave GPG oficial de Docker
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 4. Configura el repositorio estable
echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 5. Instala Docker Engine y herramientas relacionadas
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 6. Configura el usuario para usar Docker sin sudo
sudo usermod -aG docker $USER
newgrp docker
Como puedes ver, la instalación en Linux es un proceso un poco más detallado, pero esencialmente igual de simple.
macOS
macOS ofrece una experiencia similar a Windows con Docker Desktop:
Requisitos previos:
- macOS 10.15 o posterior
- Al menos 4GB de RAM
- No tener conflictos con VirtualBox anterior a v6.0
Proceso de instalación:
- Descarga Docker Desktop para Mac
- Arrastra Docker.app a la carpeta Aplicaciones
- Haz doble clic en Docker.app para iniciar Docker
- Autoriza con tu contraseña cuando se solicite
Configuración recomendada en Docker Desktop:
- Ajusta los recursos (CPU, memoria) según tus necesidades
- Habilita la característica “Use Docker Compose V2”
- Configura la ubicación de los archivos de caché
Aprende a desarrollar webs optimizadas
Comienza 15 días gratis en OpenWebinars y accede cursos, talleres y laboratorios prácticos de JavaScript, React, Angular, HTML, CSS y más.
Primeros conceptos básicos
Antes de sumergirnos en la creación de imágenes, es crucial entender los conceptos fundamentales. Un estudio reciente de DevOps Research and Assessment (DORA) reveló que los equipos que comprenden bien estos conceptos básicos son 1.5 veces más productivos.
Como todo en la vida, si aprendes correctamente los fundamentos, tendrás un mayor éxito en el futuro en cualquier actividad.
Si aún no estás familiarizado con los conceptos básicos de Docker, te recomiendo comenzar con nuestro artículo Introducción a Docker: Desarrollo y despliegue con contenedores, donde explicamos los fundamentos y beneficios de esta tecnología. Una vez que tengas claros estos conceptos, este tutorial te guiará paso a paso en la creación de tu primera imagen y contenedor Docker.
Imágenes Docker
Una imagen Docker es como una plantilla de solo lectura que contiene todo lo necesario para ejecutar una aplicación. Piensa en ella como una “fotografía” de un sistema:
- Sistema operativo base
- Runtime environment
- Dependencias de la aplicación
- Código fuente
- Variables de entorno
- Configuración
Las imágenes se construyen en capas, lo que permite:
- Reutilización eficiente del espacio
- Caché inteligente durante la construcción
- Distribución rápida de actualizaciones
# Listar imágenes locales con detalles
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}\t{{.CreatedSince}}"
REPOSITORY TAG SIZE CREATED
nginx latest 133MB 2 weeks ago
python 3.9 889MB 3 weeks ago
node 16-slim 167MB 1 month ago
# Inspeccionar una imagen en detalle
docker image inspect nginx:latest
# Mostrar el historial de capas de una imagen
docker history nginx:latest
Contenedores Docker
Un contenedor es una instancia ejecutable de una imagen. La analogía perfecta sería:
- La imagen es como una clase en programación orientada a objetos
- El contenedor es como una instancia de esa clase
Características clave de los contenedores:
-
Aislamiento:
- Sistema de archivos propio
- Networking independiente
- Recursos limitados (CPU, memoria)
- Procesos aislados
-
Eficiencia:
- Inicio rápido (segundos vs minutos en VMs)
- Bajo consumo de recursos
- Alta densidad de aplicaciones
-
Portabilidad:
- Mismo comportamiento en cualquier entorno
- Fácil distribución
- Configuración consistente
# Listar contenedores con formato personalizado
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}"
CONTAINER ID IMAGE STATUS PORTS NAMES
3f4ab82c0fc1 nginx Up 10 minutes 0.0.0.0:80->80/tcp web-server
9a8b7c6d5e4f redis Up 2 hours 0.0.0.0:6379->6379/tcp cache
# Ver estadísticas en tiempo real
docker stats
# Inspeccionar configuración del contenedor
docker inspect web-server
Comandos iniciales
Los comandos de Docker siguen una estructura lógica y consistente. Aquí una guía completa:
Gestión de Imágenes
Comando | Descripción | Ejemplo y uso común |
---|---|---|
docker pull |
Descarga una imagen | docker pull nginx:latest - Obtiene la última versión de nginx |
docker build |
Construye una imagen | docker build -t myapp:1.0 . - Construye y etiqueta una imagen |
docker images |
Lista imágenes | docker images --filter "dangling=true" - Muestra imágenes sin usar |
docker rmi |
Elimina imágenes | docker rmi $(docker images -q -f "dangling=true") - Limpieza de imágenes |
docker tag |
Etiqueta imágenes | docker tag myapp:1.0 registry.example.com/myapp:1.0 - Prepara para push |
Gestión de Contenedores
Comando | Descripción | Ejemplo y uso común |
---|---|---|
docker run |
Crea y ejecuta un contenedor | docker run -d --name web -p 80:80 nginx - Servidor web en background |
docker ps |
Lista contenedores | docker ps -a --filter "status=exited" - Muestra contenedores detenidos |
docker stop |
Detiene contenedores | docker stop $(docker ps -q) - Detiene todos los contenedores |
docker rm |
Elimina contenedores | docker rm -f $(docker ps -aq) - Fuerza eliminación de todos |
docker logs |
Muestra logs | docker logs -f --tail 100 web - Últimas 100 líneas y seguimiento |
Comandos de Red y Volúmenes
Comando | Descripción | Ejemplo y uso común |
---|---|---|
docker network |
Gestiona redes | docker network create --driver bridge mynet - Crea red personalizada |
docker volume |
Gestiona volúmenes | docker volume create --name mydata - Crea volumen persistente |
docker cp |
Copia archivos | docker cp ./app.conf web:/etc/nginx/ - Copia configuración al contenedor |
Cómo crear tu primera imagen Docker
La creación de una imagen Docker es un proceso sistemático que requiere planificación y buenas prácticas. Las estadísticas muestran que el 73% de los problemas en producción se pueden evitar con una correcta construcción de imágenes.
Preparación del Proyecto
Estructura del proyecto:
mi-primera-app-docker/
├── app/
│ ├── static/
│ │ └── style.css
│ ├── templates/
│ │ └── index.html
│ └── app.py
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
└── README.md
Aplicación Flask mejorada (app/app.py):
Este script python es el encargado de la lógica de la aplicación. Específicamente se está creando un servidor web con Flask que muestra el hostname y la fecha actual.
from flask import Flask, render_template
import socket
import datetime
app = Flask(__name__)
@app.route('/')
def hello_world():
host_name = socket.gethostname()
current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
return render_template('index.html',
hostname=host_name,
time=current_time)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Plantilla HTML (app/templates/index.html):
Este archivo HTML es el encargado de la presentación de la aplicación. Específicamente se está creando un servidor web con Flask que muestra el hostname y la fecha actual en el frontend.
<!DOCTYPE html>
<html>
<head>
<title>Mi Primera App Docker</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<div class="container">
<h1>¡Hola desde Docker!</h1>
<p>Hostname: {{ hostname }}</p>
<p>Tiempo: {{ time }}</p>
</div>
</body>
</html>
Estilos CSS (app/static/style.css):
Este archivo CSS es el encargado de la estética de la aplicación.
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
text-align: center;
font-family: Arial, sans-serif;
}
h1 {
color: #2c3e50;
}
p {
color: #7f8c8d;
}
Requirements (requirements.txt):
Este archivo contiene las dependencias de la aplicación. Tanto Flask como gunicorn son necesarios para ejecutar la aplicación y werkzeug es un framework web de Python.
Flask==2.0.1
Werkzeug==2.0.1
gunicorn==20.1.0
Dockerfile Optimizado
El Dockerfile es el corazón de tu imagen. Cada instrucción crea una nueva capa, y el orden importa para optimizar el caché y el tamaño final.
# Usa una imagen base oficial de Python
FROM python:3.9-slim
# Establece variables de entorno
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
FLASK_APP=app/app.py \
FLASK_ENV=production
# Crea y establece el directorio de trabajo
WORKDIR /app
# Instala dependencias del sistema
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
&& rm -rf /var/lib/apt/lists/*
# Copia e instala requirements primero para aprovechar la caché
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copia el resto del código
COPY . .
# Usuario no root por seguridad
RUN useradd -m myuser && chown -R myuser:myuser /app
USER myuser
# Expone el puerto
EXPOSE 5000
# Comando para ejecutar la aplicación con gunicorn
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app.app:app"]
Docker Compose para Desarrollo
Docker Compose es una herramienta que permite definir y ejecutar aplicaciones multi-contenedor. En este caso, usamos Docker Compose para desplegar un servidor web con Flask y Redis. También observamos que se abrirán los puertos 5000 y 6379 para levantar la aplicación y Redis respectivamente.
version: '3.8'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- ./app:/app/app
environment:
- FLASK_ENV=development
- FLASK_DEBUG=1
command: flask run --host=0.0.0.0
restart: unless-stopped
redis:
image: redis:alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
volumes:
redis_data:
Construcción y Optimización
A continuación, te muestro instrucciones de comandos para construir la imagen y optimizarla.
# Construir la imagen con etiquetas
docker build -t mi-primera-app:latest -t mi-primera-app:1.0 .
# Verificar el tamaño de la imagen
docker images mi-primera-app
# Analizar capas de la imagen
docker history mi-primera-app:latest --no-trunc
# Escanear vulnerabilidades
docker scan mi-primera-app:latest
Cómo ejecutar tu primer contenedor
La ejecución de contenedores es donde Docker realmente brilla. Un estudio reciente mostró que los equipos que utilizan Docker correctamente reducen su tiempo de despliegue en un 70%.
Ejecución básica
Cada instrucción en docker tiene un conjunto de parámetros que permite configurarlo a medida, haciendo que sea personalizable según las necesidades.
# Ejecutar en modo detached con nombre personalizado
docker run -d \
--name mi-app \
-p 5000:5000 \
--restart unless-stopped \
mi-primera-app:latest
# Verificar el estado
docker ps -a --filter name=mi-app --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
Ejecución avanzada
Para aplicar una ejecución avanzada de Docker, se necesita tener en consideración diferentes factores o necesidades a cubrir cómo los healthchecks, que hace revisiones de la salud del contenedor o servicio.
# Ejecutar con límites de recursos
docker run -d \
--name mi-app-prod \
-p 5000:5000 \
--memory="512m" \
--cpus="0.5" \
--health-cmd="curl -f http://localhost:5000/ || exit 1" \
--health-interval=30s \
--health-retries=3 \
--health-timeout=5s \
mi-primera-app:latest
# Monitorear la salud del contenedor
docker inspect --format='{{json .State.Health}}' mi-app-prod
Gestión de logs
Los logs eran útiles ayer, hoy y seguramente en el futuro, puesto que es un indicador de fallos o rastros de las ejecuciones o eventos ocurridos en un determinado momento que nos da una pista de cuál es la problemática que está ocurriendo.
# Ver logs en tiempo real con timestamp
docker logs -f --timestamps mi-app
# Rotar logs automáticamente
docker run -d \
--name mi-app-logs \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
mi-primera-app:latest
Gestión de contenedores e imágenes
La gestión efectiva de contenedores e imágenes es crucial para mantener un entorno Docker saludable. Las estadísticas indican que el 65% de los problemas de rendimiento en producción se deben a una gestión inadecuada de recursos.
Sistema de tags y versionado
# Etiquetar para diferentes entornos
docker tag mi-primera-app:latest mi-primera-app:dev
docker tag mi-primera-app:latest mi-primera-app:staging
docker tag mi-primera-app:latest mi-primera-app:prod-1.0.0
# Listar todas las tags
docker images mi-primera-app --format "table {{.Tag}}\t{{.Size}}\t{{.CreatedAt}}"
Gestión de recursos
# Monitoreo detallado de recursos
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}"
# Limpieza inteligente
docker system prune --volumes --filter "until=24h"
# Backup de volúmenes
docker run --rm \
-v mi-app-data:/source:ro \
-v $(pwd):/backup \
alpine tar czf /backup/volume-backup-$(date +%Y%m%d).tar.gz -C /source .
Networking avanzado
# Crear red personalizada
docker network create \
--driver bridge \
--subnet=172.20.0.0/16 \
--gateway=172.20.0.1 \
mi-app-net
# Conectar contenedor a la red
docker network connect mi-app-net mi-app
# Inspeccionar configuración de red
docker network inspect mi-app-net