Compartir en Twitter
Go to Homepage

GUÍA COMPLETA DE DOCKER PARA DESARROLLADORES EN 2025

November 24, 2025

Introducción a Docker para Desarrolladores

Docker se ha consolidado como una herramienta fundamental en el desarrollo de software, permitiendo a los programadores crear, gestionar y desplegar aplicaciones en entornos consistentes. En 2025, su relevancia sigue creciendo gracias a su capacidad para resolver problemas comunes, como las inconsistencias entre entornos de desarrollo y producción. Este tutorial está diseñado para introducir a los desarrolladores en los conceptos clave de Docker, desde la instalación hasta la creación de aplicaciones contenerizadas, con un enfoque práctico y orientado a sitios web de programación y noticias tecnológicas. A lo largo de esta guía, exploraremos qué es Docker, cómo funciona, sus ventajas, y proporcionaremos ejemplos de código para ilustrar cada concepto.

Docker es una plataforma de código abierto que utiliza virtualización a nivel de sistema operativo para empaquetar aplicaciones y sus dependencias en unidades estandarizadas llamadas contenedores. A diferencia de las máquinas virtuales, que requieren un sistema operativo completo, los contenedores comparten el núcleo del sistema operativo del host, lo que los hace ligeros, rápidos y portátiles. Esta característica permite que una aplicación empaquetada en un contenedor se ejecute de manera idéntica en cualquier máquina, eliminando el problema clásico de “funciona en mi máquina”.

Para comenzar, instalaremos Docker en un sistema operativo común, como Ubuntu, y verificaremos su funcionamiento. Los requisitos mínimos para Docker en 2025 incluyen un sistema operativo de 64 bits, al menos 4 GB de RAM, y soporte para virtualización habilitado en el BIOS.

# Actualizar el índice de paquetes
sudo apt update

# Instalar dependencias necesarias
sudo apt install apt-transport-https ca-certificates curl software-properties-common

# Añadir la clave GPG oficial de Docker
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

# Añadir el repositorio de Docker
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

# Instalar Docker
sudo apt update
sudo apt install docker-ce

# Verificar la instalación
docker --version
Docker version 27.2.0, build 1234567

Tras la instalación, es importante añadir el usuario actual al grupo de Docker para ejecutar comandos sin privilegios de administrador.

# Añadir usuario al grupo docker
sudo usermod -aG docker $USER

# Aplicar cambios sin cerrar sesión
newgrp docker

Conceptos Fundamentales de Docker

Antes de profundizar en la creación de aplicaciones, es crucial entender los componentes principales de Docker: imágenes, contenedores y Dockerfiles. Una imagen de Docker es una plantilla de solo lectura que contiene el código de la aplicación, las bibliotecas, las dependencias y las configuraciones necesarias para ejecutarla. Un contenedor es una instancia ejecutable de una imagen, similar a un proceso aislado que corre en el sistema operativo del host.

El Dockerfile es un archivo de texto que define los pasos para construir una imagen. A continuación, crearemos un ejemplo sencillo de un contenedor que ejecuta un servidor web básico con Python.

# Usar una imagen base de Python
FROM python:3.9-slim

# Establecer el directorio de trabajo
WORKDIR /app

# Copiar el archivo de la aplicación
COPY server.py .

# Exponer el puerto 8000
EXPOSE 8000

# Ejecutar el servidor
CMD ["python", "-m", "http.server", "8000"]

En este ejemplo, el archivo server.py no es estrictamente necesario, ya que usamos el módulo http.server de Python para servir contenido estático. Para construir y ejecutar esta imagen:

# Construir la imagen
docker build -t mi-servidor-web .

# Ejecutar el contenedor
docker run -d -p 8080:8000 mi-servidor-web

Al abrir un navegador en http://localhost:8080, se visualizará el contenido servido por el contenedor. Este proceso demuestra cómo Docker simplifica la creación de entornos portátiles.

Ventajas de Usar Docker

Docker ofrece múltiples beneficios que lo han convertido en una herramienta esencial para desarrolladores. En primer lugar, garantiza consistencia entre entornos, ya que el contenedor incluye todas las dependencias necesarias, eliminando conflictos entre versiones de bibliotecas o configuraciones del sistema. Además, los contenedores son rápidos, ya que no requieren cargar un sistema operativo completo, a diferencia de las máquinas virtuales.

Otra ventaja es la portabilidad. Un contenedor creado en una máquina local puede ejecutarse sin modificaciones en un servidor en la nube o en un clúster de producción. Esto facilita la colaboración en equipos, ya que los desarrolladores pueden compartir imágenes a través de Docker Hub, un registro público de imágenes.

Por ejemplo, para usar una imagen de Node.js desde Docker Hub:

# Descargar la imagen de Node.js
docker pull node:18

# Ejecutar un contenedor interactivo
docker run -it node:18 bash
root@container:/# node --version
v18.20.4

Docker también mejora la eficiencia al permitir que múltiples contenedores compartan el mismo núcleo del sistema operativo, consumiendo menos recursos que las máquinas virtuales. Esto es ideal para aplicaciones de microservicios, donde cada componente se ejecuta en un contenedor independiente.

Diferencias entre Contenedores y Máquinas Virtuales

Es común confundir contenedores con máquinas virtuales, pero sus enfoques son distintos. Las máquinas virtuales emulan un sistema operativo completo, incluyendo el núcleo, lo que las hace más pesadas y lentas. Los contenedores, por otro lado, comparten el núcleo del sistema operativo del host, aislando solo los procesos y las dependencias de la aplicación.

Esta diferencia se ilustra en la siguiente estructura:

├── Máquina Virtual
│   ├── Sistema Operativo Invitado
│   ├── Bibliotecas
│   ├── Aplicación
├── Contenedor Docker
│   ├── Bibliotecas
│   ├── Aplicación

Los contenedores son ideales para entornos donde la escalabilidad y rapidez son prioritarias, como en arquitecturas de microservicios o despliegues en la nube. Sin embargo, las máquinas virtuales son más adecuadas cuando se requiere aislar completamente sistemas operativos distintos.

Creación de una Aplicación con Docker

Para ilustrar el proceso completo, crearemos una aplicación web simple en Python con Flask, empaquetada en un contenedor. Supongamos que tenemos la siguiente estructura de directorios:

├── Dockerfile
├── app.py
├── requirements.txt

El archivo app.py contiene una aplicación Flask básica:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
    return '¡Hola desde Docker!'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

El archivo requirements.txt especifica las dependencias:

Flask==3.0.3

El Dockerfile define cómo construir la imagen:

# Usar una imagen base de Python
FROM python:3.9-slim

# Establecer el directorio de trabajo
WORKDIR /app

# Copiar los archivos de requisitos
COPY requirements.txt .

# Instalar dependencias
RUN pip install --no-cache-dir -r requirements.txt

# Copiar el código de la aplicación
COPY app.py .

# Exponer el puerto 5000
EXPOSE 5000

# Ejecutar la aplicación
CMD ["python", "app.py"]

Para construir y ejecutar la aplicación:

# Construir la imagen
docker build -t mi-app-flask .

# Ejecutar el contenedor
docker run -d -p 5000:5000 mi-app-flask

Al visitar http://localhost:5000, se mostrará el mensaje “¡Hola desde Docker!”. Este ejemplo demuestra cómo Docker permite empaquetar una aplicación con todas sus dependencias, asegurando que funcione de manera consistente en cualquier entorno.

Gestión de Contenedores

Docker proporciona comandos para gestionar contenedores en ejecución. Por ejemplo, para listar los contenedores activos:

docker ps
CONTAINER ID   IMAGE           COMMAND                  CREATED         STATUS         PORTS                    NAMES
a842945e2414   mi-app-flask    "python app.py"          2 minutes ago   Up 2 minutes   0.0.0.0:5000->5000/tcp   fervent_hodgkin

Para detener un contenedor:

docker stop a842945e2414

Para eliminar un contenedor detenido:

docker rm a842945e2414

También es posible gestionar imágenes. Para listar las imágenes disponibles:

docker images
REPOSITORY        TAG       IMAGE ID       CREATED         SIZE
mi-app-flask      latest    7b3c4e9a2b1c   5 minutes ago   128MB
python            3.9-slim  8f3d7a2b1c9e   2 weeks ago     115MB

Para eliminar una imagen sin contenedores asociados:

docker rmi mi-app-flask

Estos comandos son esenciales para mantener un entorno limpio y eficiente, especialmente en proyectos con múltiples contenedores.

Docker Compose para Aplicaciones Multicontenedor

En aplicaciones más complejas, es común necesitar varios contenedores que interactúen, como una aplicación web y una base de datos. Docker Compose simplifica la gestión de aplicaciones multicontenedor mediante un archivo YAML que define los servicios, redes y volúmenes.

Supongamos que queremos una aplicación Flask con una base de datos PostgreSQL. La estructura sería:

├── docker-compose.yml
├── Dockerfile
├── app.py
├── requirements.txt

El archivo docker-compose.yml define los servicios:

version: "3.8"
services:
    web:
        build: .
        ports:
            - "5000:5000"
        depends_on:
            - db
    db:
        image: postgres:13
        environment:
            POSTGRES_USER: user
            POSTGRES_PASSWORD: password
            POSTGRES_DB: mydb
        volumes:
            - db-data:/var/lib/postgresql/data

volumes:
    db-data:

El Dockerfile y app.py son similares al ejemplo anterior, pero app.py ahora se conecta a la base de datos:

from flask import Flask
import psycopg2

app = Flask(__name__)

def get_db_connection():
    conn = psycopg2.connect(
        host="db",
        database="mydb",
        user="user",
        password="password"
    )
    return conn

@app.route('/')
def home():
    conn = get_db_connection()
    cur = conn.cursor()
    cur.execute('CREATE TABLE IF NOT EXISTS test (id serial PRIMARY KEY, name varchar);')
    cur.execute('INSERT INTO test (name) VALUES (%s);', ('Prueba',))
    cur.execute('SELECT * FROM test;')
    result = cur.fetchall()
    cur.close()
    conn.close()
    return f'Registros: {result}'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

El archivo requirements.txt incluye la dependencia para PostgreSQL:

Flask==3.0.3
psycopg2-binary==2.9.9

Para iniciar la aplicación:

docker-compose up --build

Esto construye la imagen de la aplicación, descarga la imagen de PostgreSQL, y ejecuta ambos contenedores en una red compartida. Al visitar http://localhost:5000, se mostrará el contenido de la tabla de la base de datos.

Para detener y eliminar los contenedores:

docker-compose down

Docker Compose es particularmente útil para entornos de desarrollo, ya que permite definir y gestionar aplicaciones complejas con un solo comando.

Mejores Prácticas en Docker

Para aprovechar al máximo Docker, es importante seguir algunas mejores prácticas. En primer lugar, utiliza imágenes base ligeras, como python:slim o alpine, para reducir el tamaño de las imágenes y mejorar la seguridad. Por ejemplo:

FROM python:3.9-alpine
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]

Además, minimiza el número de capas en el Dockerfile agrupando comandos cuando sea posible. Por ejemplo, en lugar de:

RUN apt update
RUN apt install -y curl

Usa:

RUN apt update && apt install -y curl

Otra práctica clave es ignorar archivos innecesarios durante la construcción de la imagen mediante un archivo .dockerignore. Por ejemplo:

__pycache__
*.pyc
.env
.git

Finalmente, utiliza volúmenes para datos persistentes, como en el ejemplo de Docker Compose, para evitar la pérdida de datos al eliminar contenedores.

Conclusiones

Docker es una herramienta poderosa que transforma la manera en que los desarrolladores construyen, despliegan y gestionan aplicaciones. Su capacidad para garantizar entornos consistentes, junto con su ligereza y portabilidad, lo convierte en un pilar de las arquitecturas modernas de software, especialmente en entornos de microservicios y DevOps. A lo largo de este tutorial, hemos cubierto desde la instalación de Docker hasta la creación de aplicaciones multicontenedor con Docker Compose, proporcionando ejemplos prácticos para cada concepto. Al adoptar Docker en 2025, los desarrolladores pueden optimizar sus flujos de trabajo, reducir errores relacionados con dependencias y acelerar el despliegue de aplicaciones. Con práctica y el uso de mejores prácticas, Docker se convertirá en una herramienta indispensable en cualquier proyecto de programación.