Despliegue de aplicaciones locales con Docker. Desplegar una aplicación localmente con Docker significa ejecutarla en un contenedor en tu propio ordenador, con todas sus dependencias incluidas y accesible desde el navegador exactamente igual que en producción.
Sin instalar dependencias en el sistema operativo, sin conflictos entre proyectos y con la certeza de que lo que funciona en local funcionará igual en cualquier otro entorno.
Esta guía cubre el proceso completo de despliegue local: desde el Dockerfile hasta la aplicación corriendo en localhost, pasando por el mapeo de puertos, los volúmenes de persistencia y la orquestación multi-servicio con Docker Compose.
Si todavía no tienes claro qué es Docker y cómo funciona la arquitectura de contenedores, el artículo sobre qué es Docker explica los fundamentos antes de entrar en el despliegue.
Paso 1: el Dockerfile de tu aplicación
El punto de partida de cualquier despliegue Docker es el Dockerfile: el archivo que define cómo construir la imagen de tu aplicación. Sin una imagen, no hay contenedor que desplegar.
Un Dockerfile básico para una aplicación Node.js:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Para Python con FastAPI:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
🔴 ¿Quieres entrar de lleno al mundo DevOps & Cloud Computing? 🔴
Descubre el DevOps & Cloud Computing Full Stack Bootcamp de KeepCoding. La formación más completa del mercado y con empleabilidad garantizada
👉 Prueba gratis el Bootcamp en DevOps & Cloud Computing por una semanaEl artículo sobre qué es un Dockerfile cubre todas las instrucciones disponibles, el sistema de capas y las buenas prácticas de construcción en profundidad.
Paso 2: construir la imagen con docker build

Con el Dockerfile en el directorio del proyecto, se construye la imagen:
docker build -t miapp:latest .
El flag -t asigna el nombre y la etiqueta a la imagen. El punto final indica que el Dockerfile está en el directorio actual.
Para verificar que la imagen se ha construido correctamente:
docker images
La imagen aparecerá en la lista con su nombre, etiqueta, ID y tamaño.
Paso 3: ejecutar el contenedor con docker run
Una vez construida la imagen, se crea y arranca el contenedor:
docker run -d -p 3000:3000 --name miapp miapp:latest
Los flags más importantes:
| Flag | Qué hace |
|---|---|
-d |
Ejecuta en segundo plano (detached). Sin este flag el terminal queda bloqueado. |
-p 3000:3000 |
Mapea el puerto 3000 del host al puerto 3000 del contenedor. Formato: host:contenedor. |
--name miapp |
Asigna un nombre al contenedor para referenciarlo fácilmente en comandos posteriores. |
-e VARIABLE=valor |
Pasa variables de entorno al contenedor. |
--rm |
Elimina el contenedor automáticamente cuando se detiene. Útil para pruebas rápidas. |
-v ruta:/app |
Monta un volumen o bind mount en el contenedor. |
Con el contenedor en marcha, la aplicación es accesible en http://localhost:3000.
Mapeo de puertos: cómo acceder desde el navegador
El mapeo de puertos es lo que permite acceder a la aplicación que corre dentro del contenedor desde el navegador del host. Sin mapeo, el contenedor está aislado y no es accesible desde fuera.
La sintaxis es siempre puerto-host:puerto-contenedor:
# Aplicación en puerto 3000 del contenedor → accesible en localhost:3000
docker run -p 3000:3000 miapp
# Mismo contenedor en puerto diferente del host
docker run -p 8080:3000 miapp
# Accesible en http://localhost:8080
# Múltiples puertos (web + API)
docker run -p 3000:3000 -p 4000:4000 miapp
Una situación frecuente es el conflicto de puertos: si el puerto del host ya está en uso por otro proceso o contenedor, Docker devuelve un error. En ese caso, se cambia el puerto del host (el primero) por cualquier otro disponible.
Gestión de logs del contenedor
Ver los logs de la aplicación es esencial para verificar que el despliegue ha funcionado y para diagnosticar problemas.
# Ver todos los logs del contenedor
docker logs miapp
# Seguir los logs en tiempo real
docker logs -f miapp
# Ver solo las últimas 50 líneas
docker logs --tail 50 miapp
# Ver logs con timestamps
docker logs -t miapp
Para acceder a una terminal interactiva dentro del contenedor en ejecución:
docker exec -it miapp sh
# o bash si la imagen tiene bash instalado
docker exec -it miapp bash
Volúmenes: persistencia de datos en local
Los contenedores son efímeros. Cuando se elimina un contenedor, todos los datos que ha generado desaparecen con él. Para persistir datos entre reinicios y eliminaciones de contenedores se usan volúmenes.
Volúmenes nombrados
Son gestionados por Docker y persisten independientemente del ciclo de vida del contenedor. Son la forma correcta de persistir datos de bases de datos:
# Crear un volumen nombrado
docker volume create datos-postgres
# Usar el volumen al ejecutar el contenedor
docker run -d \
-p 5432:5432 \
-v datos-postgres:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=password \
--name postgres \
postgres:16-alpine
El volumen datos-postgres persiste aunque el contenedor se elimine. Al crear un nuevo contenedor con el mismo volumen, los datos siguen ahí.
Bind mounts para desarrollo
Los bind mounts montan un directorio del host directamente en el contenedor. Los cambios en el directorio local se reflejan instantáneamente en el contenedor. Son la base del hot reload en desarrollo:
# Montar el directorio actual como código fuente del contenedor
docker run -d \
-p 3000:3000 \
-v $(pwd):/app \
-v /app/node_modules \
--name miapp-dev \
miapp:dev
Despliegue multi-servicio con Docker Compose
La mayoría de las aplicaciones reales necesitan más de un servicio: base de datos, caché, servidor de archivos. Levantar cada contenedor manualmente con docker run se vuelve inmanejable rápidamente.
Docker Compose permite definir todos los servicios en un único archivo y levantarlos con un solo comando. Un ejemplo completo con Node.js, PostgreSQL y Redis:
services:
app:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=development
- DATABASE_URL=postgresql://user:password@db:5432/myapp
- REDIS_URL=redis://cache:6379
depends_on:
db:
condition: service_healthy
volumes:
- .:/app
- /app/node_modules
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: myapp
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user"]
interval: 5s
retries: 5
cache:
image: redis:7-alpine
volumes:
postgres_data:
Con este archivo en el directorio del proyecto, docker compose up levanta los tres servicios en el orden correcto. La aplicación es accesible en http://localhost:3000 y la base de datos espera a estar lista antes de que arranque la app.
Para una guía completa de Docker Compose con todos sus parámetros y casos de uso, el artículo sobre qué es Docker Compose lo cubre en profundidad.
Gestión del ciclo de vida del contenedor
| Comando | Qué hace |
|---|---|
docker ps |
Lista los contenedores en ejecución |
docker ps -a |
Lista todos los contenedores, incluidos los detenidos |
docker stop miapp |
Detiene el contenedor de forma limpia |
docker start miapp |
Reinicia un contenedor detenido |
docker restart miapp |
Detiene y vuelve a arrancar el contenedor |
docker rm miapp |
Elimina el contenedor (debe estar detenido) |
docker rm -f miapp |
Fuerza la eliminación aunque esté en ejecución |
docker inspect miapp |
Muestra la configuración completa del contenedor en JSON |
docker stats |
Muestra el uso de CPU, memoria y red en tiempo real |
docker system prune |
Elimina contenedores detenidos, imágenes sin usar y redes huérfanas |
Solución de problemas frecuentes en despliegue local

Lo que hemos visto al acompañar a equipos que empiezan con Docker es que la mayoría de los problemas en el despliegue local caen en tres categorías.
El contenedor arranca y se para inmediatamente. Suele ser porque el proceso principal termina. Para diagnosticarlo: docker logs miapp. Si el CMD del Dockerfile termina, el contenedor se detiene. La solución es asegurarse de que el proceso principal siga en ejecución.
La aplicación no es accesible en localhost. Comprueba que el mapeo de puertos es correcto con docker ps, que muestra los puertos mapeados de cada contenedor. Verifica que la aplicación dentro del contenedor escucha en 0.0.0.0 (todas las interfaces) y no solo en 127.0.0.1 (localhost del contenedor).
Los cambios en el código no se reflejan. Si no hay bind mount configurado, los cambios en el código no afectan al contenedor en ejecución. La imagen se construyó con una copia del código en ese momento. Tienes que reconstruir la imagen con docker build o configurar un bind mount para desarrollo.
Esther llegó al Bootcamp DevOps de KeepCoding desde la psicología y los recursos humanos, sin base técnica previa. Hoy trabaja como DevOps Engineer en un proyecto bancario de gran escala donde gestiona el despliegue de contenedores Docker en producción a diario.
Lo que más la sorprendió fue que con pocos meses de experiencia real ya recibía más ofertas en LinkedIn que en toda su etapa anterior. La clave fue aprender con proyectos reales desde el primer módulo, no solo con teoría.
Cómo aprender a desplegar con Docker de forma profesional
Desplegar una aplicación simple con Docker es algo que cualquier desarrollador puede hacer siguiendo una guía en su primera tarde.
Lo que diferencia ese primer despliegue del trabajo profesional es la capacidad de gestionar el ciclo de vida completo en entornos reales: configurar healthchecks, gestionar variables de entorno de forma segura, integrar el despliegue en un pipeline CI/CD y diagnosticar problemas cuando la aplicación no arranca como se espera.
Ese criterio se construye con práctica en proyectos reales donde cada decisión tiene consecuencias directas.
Para aprender a desplegar aplicaciones con Docker en proyectos reales, el DevOps y Cloud Computing Full Stack Bootcamp de KeepCoding cubre el recorrido completo en 6 meses.
Conclusión

Desplegar aplicaciones locales con Docker es el primer paso para adoptar una forma de trabajar que elimina los problemas de entorno, garantiza la reproducibilidad y escala directamente a producción sin cambios. DevOps y Cloud Computing Full Stack Bootcamp de KeepCoding.
El flujo es siempre el mismo: Dockerfile, docker build, docker run con el mapeo de puertos correcto. Para aplicaciones con múltiples servicios, Docker Compose orquesta todo desde un único archivo.
Y los volúmenes garantizan que los datos persisten independientemente del ciclo de vida del contenedor.
Una vez dominado el despliegue local, el siguiente paso natural es automatizar ese proceso en un pipeline CI/CD que construya y distribuya las imágenes automáticamente en cada cambio al repositorio.
La documentación oficial de Docker sobre despliegue y gestión de contenedores está disponible en docs.docker.com.



