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, mysql o nginx) 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

ComandoPropósito
docker run <image>Ejecutar un contenedor a partir de una imagen
docker psListar los contenedores en ejecución
docker ps -aListar todos los contenedores, incluidos los detenidos
docker imagesListar 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> bashAbrir 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 --build para forzar la reconstrucción.
  • Conectarte a localhost en lugar de al nombre del servicio. Dentro de Docker Compose, los contenedores se alcanzan entre sí por el nombre del servicio (como db), no por localhost.
  • 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.yml en un proyecto real; usa mejor un archivo .env una 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.