Si alguna vez escuchaste a un desarrollador decir “simplemente ejecútalo en Docker” y no tenías idea de qué significaba, estás exactamente en el lugar correcto. Docker para principiantes no tiene por qué ser intimidante: en el fondo, resuelve un problema con el que todos nos identificamos: lograr que una aplicación funcione igual en tu máquina que en la de otra persona.
Docker empaqueta una aplicación junto con todo lo que necesita para funcionar (código, dependencias, herramientas del sistema, incluso las versiones exactas del software) en una unidad ligera y portátil llamada contenedor. En lugar de instalar manualmente Python, MySQL y una docena de dependencias más en tu computadora, puedes describirlas una sola vez y ejecutarlas en cualquier lugar donde esté instalado Docker.
Esta guía cubre lo básico de Docker que todo principiante debería saber: qué son realmente los contenedores, los conceptos y comandos centrales de Docker, y cómo Docker Compose te permite ejecutar una aplicación de varias partes, como una app de Flask conectada a una base de datos MySQL, con un solo comando.
¿Qué Es Docker?
Docker es una plataforma para construir, ejecutar y compartir aplicaciones dentro de contenedores. Un contenedor agrupa una aplicación con sus dependencias para que funcione de manera consistente, ya sea en tu laptop, en la máquina de un compañero o en un servidor de producción.
Contenedores vs. Máquinas Virtuales
Si leíste sobre las máquinas virtuales, los contenedores pueden sonarte familiares, pero resuelven el mismo problema de forma distinta:
- Una máquina virtual incluye un sistema operativo invitado completo, lo que la hace más pesada y lenta para iniciar.
- Un contenedor comparte el núcleo del sistema operativo de la máquina anfitriona y solo empaqueta la aplicación y sus dependencias, lo que lo hace mucho más ligero y rápido de iniciar, normalmente en segundos.
Los contenedores intercambian parte del aislamiento de una máquina virtual por velocidad y eficiencia, y es justo por eso que se han vuelto el estándar para ejecutar aplicaciones web modernas.
Conceptos Centrales de Docker
Unos cuantos términos aparecen constantemente cuando empiezas a usar Docker:
- Imagen: una plantilla de solo lectura que define lo que va dentro de un contenedor (código, dependencias, configuración).
- Contenedor: una instancia en ejecución de una imagen.
- Dockerfile: un archivo de texto con las instrucciones para construir una imagen.
- Docker Hub: un registro público de imágenes ya hechas (como
python,mysqlonginx) sobre las que puedes construir. - Docker Compose: una herramienta para definir y ejecutar aplicaciones de varios contenedores con un solo archivo de configuración.
Cómo Instalar Docker
Docker Desktop ofrece todo lo que necesitas en Windows y macOS, incluyendo Docker Engine, Docker Compose y una interfaz gráfica para administrar contenedores. En Linux, puedes instalar Docker Engine directamente con el administrador de paquetes de tu distribución. Una vez instalado, confirma que funciona:
docker --version
docker run hello-world
Si ves un mensaje de bienvenida del contenedor hello-world, Docker está instalado correctamente.
Hoja de Referencia de Comandos Básicos de Docker
| Comando | Propósito |
|---|---|
docker run <image> | Ejecutar un contenedor a partir de una imagen |
docker ps | Listar los contenedores en ejecución |
docker ps -a | Listar todos los contenedores, incluidos los detenidos |
docker images | Listar las imágenes descargadas |
docker build -t <name> . | Construir una imagen a partir de un Dockerfile |
docker stop <container> | Detener un contenedor en ejecución |
docker rm <container> | Eliminar un contenedor detenido |
docker rmi <image> | Eliminar una imagen |
docker exec -it <container> bash | Abrir una shell dentro de un contenedor en ejecución |
docker logs <container> | Ver la salida y los registros de un contenedor |
¿Qué Es Docker Compose?
La mayoría de las aplicaciones reales no son una sola pieza: una aplicación web típica necesita como mínimo un servidor y una base de datos. Docker Compose te permite definir cada parte de esa aplicación en un solo archivo docker-compose.yml y luego iniciar toda la pila con un comando, en lugar de ejecutar y conectar manualmente cada contenedor tú mismo.
Ejemplo: Flask + MySQL con Docker Compose
Pongamos esto en práctica con un proyecto común para principiantes: una app de Flask que se conecta a una base de datos MySQL, ambas ejecutándose en sus propios contenedores.
Estructura del Proyecto
flask-mysql-app/
├── app.py
├── requirements.txt
├── Dockerfile
└── docker-compose.yml
La App de Flask
# app.py
import os
import mysql.connector
from flask import Flask
app = Flask(__name__)
def get_db_connection():
return mysql.connector.connect(
host=os.environ.get("MYSQL_HOST", "localhost"),
user=os.environ.get("MYSQL_USER", "root"),
password=os.environ.get("MYSQL_PASSWORD", ""),
database=os.environ.get("MYSQL_DB", "exampledb"),
)
@app.route("/")
def index():
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute("SELECT VERSION()")
db_version = cursor.fetchone()
cursor.close()
conn.close()
return f"Connected to MySQL version: {db_version[0]}"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
# requirements.txt
flask
mysql-connector-python
Observa que MYSQL_HOST tiene como valor predeterminado localhost, pero en Docker Compose se establecerá en db, el nombre del servicio de MySQL, que Docker resuelve automáticamente a través de su red interna.
El Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]
El Archivo docker-compose.yml
services:
web:
build: .
ports:
- "5000:5000"
environment:
MYSQL_HOST: db
MYSQL_USER: root
MYSQL_PASSWORD: examplepass
MYSQL_DB: exampledb
depends_on:
db:
condition: service_healthy
db:
image: mysql:8.0
restart: always
environment:
MYSQL_ROOT_PASSWORD: examplepass
MYSQL_DATABASE: exampledb
ports:
- "3306:3306"
volumes:
- db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 5s
timeout: 5s
retries: 10
volumes:
db_data:
Por qué importa el healthcheck: MySQL puede tardar unos segundos en iniciarse por completo dentro de su contenedor. Sin el healthcheck y la condición service_healthy, el contenedor de Flask podría iniciar e intentar conectarse antes de que MySQL esté realmente listo, un problema clásico de principiantes que parece un error de conexión aleatorio en la primera ejecución.
Ejecutar el Proyecto
Inicia todo con un solo comando desde la carpeta del proyecto:
docker compose up --build
Una vez que ambos contenedores estén en ejecución, visita http://localhost:5000 en tu navegador. Deberías ver un mensaje que confirma que la app de Flask se conectó correctamente a MySQL.
Para detener todo:
docker compose down
Agrega la opción -v (docker compose down -v) si también quieres eliminar los datos almacenados de la base de datos.
Errores Comunes de Principiantes que Debes Evitar
- Olvidar reconstruir tras cambiar el Dockerfile. Usa
docker compose up --buildpara forzar la reconstrucción. - Conectarte a
localhosten lugar de al nombre del servicio. Dentro de Docker Compose, los contenedores se alcanzan entre sí por el nombre del servicio (comodb), no porlocalhost. - Omitir el healthcheck en un servicio de base de datos y luego preguntarte por qué la app no logra conectarse en el primer arranque.
- Escribir las credenciales directamente en
docker-compose.ymlen un proyecto real; usa mejor un archivo.envuna vez que pases de un ejemplo de aprendizaje.
Conclusión
Docker para principiantes se reduce a una idea central: empaquetar una aplicación y todo lo que necesita en un contenedor portátil, para que funcione igual en todas partes. A partir de ahí, Docker Compose extiende esa idea a las aplicaciones de varias partes, como el ejemplo de Flask y MySQL de esta guía, permitiéndote levantar una pila completa con un solo comando en lugar de configurar cada pieza a mano.
Empieza por sentirte cómodo con los comandos básicos de Docker y la diferencia entre imagen y contenedor, y luego trabaja con un pequeño proyecto de Compose como el de aquí. Una vez que hayas conectado una aplicación real con una base de datos real a través de Docker Compose, el resto del ecosistema de Docker (arquitecturas de varios servicios, pipelines de despliegue, herramientas de orquestación como Kubernetes) se vuelve mucho menos intimidante y mucho más accesible.
