Empezar con Docker desde cero
Una guía para hacer en orden, en Windows. Al terminar vas a tener Docker instalado, vas a haber corrido tu primer contenedor y vas a haber empaquetado una app propia en una imagen. Cada paso explica qué hace y muestra lo que deberías ver.
Términos de esta página
Las ideas con más detalle y diagramas están en Conceptos.
- Docker
- Una herramienta para empaquetar una aplicación junto con todo lo que necesita (sistema base, dependencias, configuración) y correrla igual en cualquier computadora.
- Imagen
- El paquete: una plantilla de solo lectura con la app y su entorno. Se descarga de internet o se construye con un Dockerfile.
- Contenedor
- Una imagen en ejecución. Es un proceso aislado: tiene sus propios archivos, red y procesos, pero comparte el núcleo del sistema con tu PC (por eso arranca en segundos).
- Docker Desktop
- El programa que instala Docker en Windows y Mac. Trae el motor, la terminal
dockery una ventana para ver contenedores e imágenes. - Motor (daemon)
- El servicio de fondo que realmente crea y corre los contenedores. El comando
dockersolo le da órdenes. Si Docker Desktop está cerrado, el motor no corre. - WSL 2
- Windows Subsystem for Linux: la función de Windows que permite correr Linux por dentro. Docker Desktop la usa porque la mayoría de las imágenes son de Linux.
- Docker Hub
- El catálogo público de imágenes en internet (
hub.docker.com): ahí estánnginx,node,mongoy miles más. - Tag
- La versión de una imagen, después de los dos puntos: en
node:22el tag es22. Sin tag se usalatest. - Puerto
- El “número de puerta” por el que se habla con un programa en red.
-p 8080:80conecta el puerto 8080 de tu PC con el 80 del contenedor. - Dockerfile
- Un archivo de texto con las instrucciones para construir tu propia imagen.
Qué problema resuelve Docker
El clásico “en mi máquina funciona”: una app necesita cierta versión de Node, una base de datos, variables de entorno y librerías del sistema. Instalar todo eso a mano en cada computadora (la tuya, la de un compañero, el servidor) es lento y siempre algo queda distinto.
Docker empaqueta la app con su entorno en una imagen. Esa imagen corre igual en cualquier lado que tenga Docker. Y como cada contenedor está aislado, podés tener una app con Node 18 y otra con Node 22 en la misma PC sin que se peleen, o levantar una base de datos sin instalarla.
¿Es una máquina virtual? No exactamente. Una máquina virtual simula una computadora entera con su propio sistema operativo: pesa gigas y tarda en arrancar. Un contenedor comparte el núcleo del sistema y solo aísla la app: pesa megas y arranca en segundos.
Instalar Docker Desktop
Una sola vez por computadora. Necesita Windows 10/11 de 64 bits.
Instalación
winget install -e --id Docker.DockerDesktopdocker.com y dejar las opciones por defecto (“Use WSL 2” marcado).wsl --installReiniciá la PC cuando el instalador lo pida.
Primer arranque
- Abrí Docker Desktop desde el menú Inicio.
- Aceptá los términos. Iniciar sesión con una cuenta de Docker es opcional: podés tocar Skip.
- Esperá a que abajo a la izquierda diga Engine running (el motor está listo).
Docker Desktop tiene que estar abierto (puede quedar minimizado en la bandeja) para que funcionen los comandos docker.
Verificar que funciona
En una terminal nueva (PowerShell o la de VS Code).
docker versiondocker) y Server (el motor). Si aparecen las dos, está todo bien.Client:
Version: 28.x.x
...
Server: Docker Desktop
Engine:
Version: 28.x.x
Si aparece Client pero en Server dice “error during connect”, Docker Desktop está cerrado o todavía arrancando.
docker run hello-worldUnable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
...
Hello from Docker!
This message shows that your installation appears to be working correctly.
Unable to find image locally no es un error: como no la tenías, la bajó de Docker Hub (Pulling). La segunda vez ya no la descarga.
Tu primer contenedor útil: un servidor web
docker run -d --name web -p 8080:80 nginxrun: descarga la imagen si hace falta, crea el contenedor y lo arranca.-d: en segundo plano (detached), así te devuelve la terminal.--name web: le pone un nombre para referirte a él.-p 8080:80: el puerto 8080 de tu PC lleva al 80 del contenedor (donde escucha nginx).nginx: la imagen a usar.
3f9c1d2e8a7b... ← el ID del contenedor nuevo
Probarlo
Abrí http://localhost:8080 en el navegador: tiene que aparecer “Welcome to nginx!”. Esa página la está sirviendo el contenedor.
localhost significa “esta misma computadora”.
Si el puerto 8080 ya lo usa otro programa, elegí otro del lado izquierdo: -p 8081:80 y entrá a localhost:8081.
Ver, mirar logs, parar y borrar
docker psCONTAINER ID IMAGE COMMAND STATUS PORTS NAMES
3f9c1d2e8a7b nginx "/docker-entrypoint.…" Up 2 minutes 0.0.0.0:8080->80/tcp web
STATUS “Up” = corriendo. PORTS muestra el mapeo de puertos. NAMES es el nombre que le diste.
docker logs web-f se queda mostrando las nuevas; Ctrl+C para salir.docker stop webdocker ps -a) y se puede volver a arrancar con docker start web.docker rm webnginx queda descargada para la próxima vez.docker imagesdocker image rm nginx.Todo esto también se ve y se hace con botones desde la ventana de Docker Desktop (secciones Containers e Images).
Empaquetar tu propia app
Una app Node mínima, de cero a contenedor.
a) Los archivos
Creá una carpeta hola-docker con estos dos archivos (con tu editor):
const http = require("node:http");
http.createServer((req, res) => {
res.end("Hola desde un contenedor\n");
}).listen(3000, () => console.log("escuchando en 3000"));
# 1. partir de una imagen que ya trae Node
FROM node:22-alpine
# 2. carpeta de trabajo dentro del contenedor
WORKDIR /app
# 3. copiar el código de tu PC a la imagen
COPY app.js .
# 4. documentar el puerto donde escucha la app
EXPOSE 3000
# 5. comando que se ejecuta al arrancar el contenedor
CMD ["node", "app.js"]
node:22-alpine es Node 22 sobre Alpine, un Linux muy liviano. Esta app no usa dependencias externas, así que no hace falta package.json ni npm install.
b) Construir la imagen
cd hola-docker
docker build -t hola:1 .build lee el Dockerfile y arma la imagen. -t hola:1 le pone nombre y versión. El . final indica la carpeta con los archivos (el contexto de build): no te lo olvides.[+] Building 8.2s (8/8) FINISHED
=> [1/3] FROM docker.io/library/node:22-alpine
=> [2/3] WORKDIR /app
=> [3/3] COPY app.js .
=> naming to docker.io/library/hola:1
c) Correrla
docker run -d --name hola -p 3000:3000 hola:1http://localhost:3000: dice “Hola desde un contenedor”.d) Cambiar el código
La imagen tiene una copia del código del momento del build. Si editás app.js, para ver el cambio hay que reconstruir y recrear el contenedor:
docker rm -f hola
docker build -t hola:2 .
docker run -d --name hola -p 3000:3000 hola:2rm -f detiene y borra en un paso. Para no hacer esto en cada cambio durante el desarrollo, existe el “bind mount” (ver Compose de desarrollo).Siguientes pasos
- Conceptos: el ciclo de vida de un contenedor, puertos, redes y volúmenes, con diagramas.
- Comandos CLI: todos los comandos de
dockerexplicados, con buscador. - Dockerfile: escribir imágenes de producción y de desarrollo.
- Docker Compose: levantar una app con su base de datos con un solo comando.
- Problemas comunes: cuando algo no arranca.