logo-andres-saumet

logo-andres-saumet
Docker para Desarrolladores: Containeriza tus Aplicaciones
7 de febrero de 2026

Docker para Desarrolladores: Containeriza tus Aplicaciones

Aprende Docker desde cero. Containeriza tus aplicaciones y domina Docker Compose para desarrollo local.

AS
Andres Saumet
dockerdevopscontainerizationdevelopment

Docker para Desarrolladores: Containeriza tus Aplicaciones

Docker ha revolucionado la forma en que desarrollamos, empaquetamos y distribuimos aplicaciones. Esta guía completa te enseña desde conceptos fundamentales hasta Docker Compose avanzado, permitiéndote containerizar tus aplicaciones y eliminar completamente el problema "funciona en mi máquina".

¿Qué es Docker y por qué deberías usarlo?

Docker es una plataforma de containerización que permite empaquetar tu aplicación, código, runtime, sistema operativo y todas sus dependencias en un contenedor standarizado llamado Docker image. Este contenedor puede ejecutarse en cualquier máquina con Docker instalado, independientemente del sistema operativo o configuración.

El problema que Docker resuelve

Alguna vez has escuchado: "Pero funciona perfectamente en mi máquina..."? Docker elimina este problema completamente garantizando que tu aplicación funcione exactamente igual en desarrollo, testing y producción.

Ventajas principales de Docker

  • Consistencia: Tu app funciona identicamente en todas partes
  • Aislamiento: Cada contenedor es independiente, evita conflictos de dependencias
  • Ligereza: Mucho más ligero que máquinas virtuales (MB vs GB)
  • Escalabilidad: Ejecuta múltiples instancias fácilmente
  • DevOps-friendly: Facilita CI/CD y deployments automáticos
  • Microservicios: Ideal para arquitecturas de microservicios

Empresas como Netflix, Uber, Spotify y PayPal dependen de Docker para sus operaciones diarias.

Conceptos fundamentales de Docker

Docker Image - El blueprint

Una Docker image es una plantilla inmutable que contiene:

  • Un sistema operativo base (Alpine, Ubuntu, etc)
  • Todas las dependencias necesarias
  • Tu código de aplicación
  • Variables de entorno y configuraciones
  • Instrucciones para ejecutar la app

Las images son inmutables: una vez construidas no cambian. Esto garantiza consistencia.

Docker Container - La instancia viva

Un contenedor es una instancia en ejecución de una imagen Docker. Es como la diferencia entre un plano (image) y una casa construida (container).

# Correr un contenedor
docker run -it ubuntu:22.04

# Ver contenedores en ejecución
docker ps

# Ver todos los contenedores (incluyendo detenidos)
docker ps -a

Dockerfile - La receta

Un Dockerfile es un archivo de texto con instrucciones paso-a-paso para construir una imagen Docker.

# Usar imagen base oficial de Node
FROM node:18-alpine

# Establece el directorio de trabajo
WORKDIR /app

# Copia archivos package
COPY package*.json ./

# Instala dependencias
RUN npm ci --only=production

# Copia el código de la aplicación
COPY . .

# Expone puerto
EXPOSE 3000

# Define el comando al iniciar
CMD ["node", "server.js"]

Instrucciones comunes en Dockerfile

  • FROM: Especifica la imagen base (siempre debe ser la primera)
  • WORKDIR: Establece el directorio de trabajo
  • COPY/ADD: Copia archivos del host al contenedor
  • RUN: Ejecuta un comando durante la construcción
  • ENV: Establece variables de entorno
  • EXPOSE: Documenta qué puerto escucha la app
  • CMD: Comando por defecto al ejecutar el contenedor
  • ENTRYPOINT: Punto de entrada del contenedor

Construir y ejecutar tu primera imagen Docker

Paso 1: Crear un Dockerfile

FROM node:18-alpine

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 3000

CMD ["npm", "start"]

Paso 2: Construir la imagen

# Construir imagen con tag
docker build -t mi-app:1.0 .

# Ver imágenes
docker images

Paso 3: Ejecutar un contenedor

# Ejecutar contenedor mapeando puerto
docker run -p 3000:3000 --name mi-contenedor mi-app:1.0

# Ejecutar en background
docker run -d -p 3000:3000 --name mi-contenedor mi-app:1.0

# Ver logs
docker logs mi-contenedor

Mejores prácticas para Dockerfiles

  • Usa imágenes base ligeras: alpine vs ubuntu (5MB vs 77MB)
  • Multi-stage builds: Separa build de runtime
  • Minimiza layers: Agrupa RUN commands
  • No ejecutes como root: Crea usuario no-root por seguridad
  • Usa .dockerignore: Excluye archivos innecesarios
  • Especifica versiones: No uses "latest"

Multi-Stage Builds - Optimizar tamaño de imagen

Los multi-stage builds permiten usar múltiples FROM statements para reducir drásticamente el tamaño final de la imagen.

# Stage 1: Build
FROM node:18-alpine AS builder

WORKDIR /app

COPY package*.json ./

RUN npm ci

COPY . .

RUN npm run build

# Stage 2: Runtime (mucho más pequeño)
FROM node:18-alpine

WORKDIR /app

COPY package*.json ./

RUN npm ci --only=production

# Copiar solo el build desde stage anterior
COPY --from=builder /app/dist ./dist

EXPOSE 3000

CMD ["npm", "start"]

Beneficio: La imagen final no incluye herramientas de build, reduciendo tamaño de 500MB a 150MB.

Docker Compose - Múltiples contenedores

Docker Compose permite definir y ejecutar aplicaciones multi-contenedor con un simple archivo YAML.

Un docker-compose.yml real

version: '3.8'

services:
  # Aplicación Node.js
  web:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://postgres:password@db:5432/myapp
      - NODE_ENV=development
    depends_on:
      - db
    volumes:
      - .:/app        # Hot reload en desarrollo
      - /app/node_modules
    restart: unless-stopped
    networks:
      - app-network

  # Base de datos PostgreSQL
  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=myapp
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped
    networks:
      - app-network

  # Redis para caching
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    restart: unless-stopped
    networks:
      - app-network

volumes:
  postgres_data:

networks:
  app-network:
    driver: bridge

Comandos útiles de Docker Compose

# Inicia todos los servicios
docker-compose up

# Modo background
docker-compose up -d

# Ver logs
docker-compose logs -f web

# Ejecutar comando en contenedor
docker-compose exec db psql -U postgres -d myapp

# Detener servicios
docker-compose down

# Reconstruir imágenes
docker-compose build

Volúmenes y Redes de Docker

Volúmenes - Persistencia de datos

Los volúmenes permiten que los datos persistan cuando un contenedor se detiene o elimina.

# Crear un volumen
docker volume create mi-volume

# Usar volumen al ejecutar contenedor
docker run -v mi-volume:/data mi-app

# Bind mount (directorio local)
docker run -v /ruta/local:/ruta/contenedor mi-app

Redes de Docker

Las redes permiten que los contenedores se comuniquen entre sí por nombre de servicio.

# Crear una red
docker network create app-network

# Conectar contenedor a red
docker run --network app-network --name web mi-app

# Los contenedores pueden conectarse por nombre
# Ej: desde web contenedor: curl http://db:5432

Seguridad en Docker

Prácticas de seguridad esenciales

  • No ejecutes como root: Crea usuario no-root en Dockerfile
  • Scanea imágenes: Busca vulnerabilidades con docker scan o Trivy
  • Mantén imágenes actualizado: Aplica parches regularmente
  • No incluyas secrets: Usa variables de entorno o secrets managers
  • Lee-only filesystem: Hace el filesystem read-only cuando sea posible
  • Limita recursos: Establece memory y CPU limits
FROM node:18-alpine

# No ejecutar como root
RUN addgroup -g 1001 -S nodejs && adduser -S nodejs -u 1001

WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY . .

# Cambiar a usuario no-root
USER nodejs

EXPOSE 3000

CMD ["node", "server.js"]

Debugging y troubleshooting

Comandos útiles de debugging

# Inspeccionar imagen
docker inspect mi-app

# Entrar a un contenedor en ejecución
docker exec -it mi-contenedor sh

# Ver recursos usados
docker stats

# Ver diferencias en contenedor
docker diff mi-contenedor

# Copiar archivos hacia/desde contenedor
docker cp mi-contenedor:/app/file.txt ./
docker cp ./file.txt mi-contenedor:/app/

Problemas comunes y soluciones

  • Puerto ya en uso: `docker run -p 3001:3000` mapea a otro puerto
  • Contenedor se detiene inmediatamente: Revisa logs con `docker logs`
  • No puedo conectar a base de datos: Asegúrate de usar el nombre del servicio (no localhost)
  • Cambios no se reflejan: Reconstruye la imagen después de cambios

Docker es esencial en 2024

Docker se ha convertido en una habilidad fundamental para todo desarrollador moderno. Ya sea que trabajes en startups o empresas grandes, aprender Docker te hace más valioso como ingeniero y facilita enormemente el deployment y la colaboración en equipo.

Comienza hoy mismo containerizando una de tus aplicaciones. Verás cuánto más fácil se vuelve el desarrollo cuando cada componente está aislado y definido claramente.

Escrito por Andrés Saumet - Especialista en DevOps, containerización y arquitectura de microservicios.

Andres Saumet

Sobre el autor

Andres Saumet

Desarrollador Web & Móvil Full Stack · Colombia

Hay mil desarrolladores que pueden hacer que algo funcione. Yo me obsesiono con hacer que funcione y genere dinero.

Soy Andres Saumet, desarrollador Web y Móvil con foco en rentabilidad. Trabajo con startups, emprendedores y empresas que ya tienen una visión clara y necesitan a alguien que la convierta en un producto digital real — uno que los usuarios quieran usar y que el negocio quiera escalar.

Domino React, Next.js, React Native y Node.js. Pero más allá del stack, entiendo cómo piensan los usuarios, cómo fluye un negocio y qué decisiones técnicas impactan directamente en los ingresos.

Cada línea de código que escribo tiene un propósito: que tu producto web o móvil sea más rápido, más usable y más rentable.

¿Tienes un producto que necesita crecer? Construyámoslo juntos.

Compartir:
Volver al Blog

Todos los derechos reservados Andres Saumet 2026 ©