Docker es la plataforma que empaqueta una aplicación con todo lo que necesita para funcionar y la ejecuta igual en el portátil del desarrollador, en un servidor de la oficina o en la nube. Esta guía reúne lo que un profesional de TI debe tener a mano: qué es, para qué lo usan las empresas, en qué sistemas funciona, cómo se instala, cómo se hace el primer despliegue y qué comandos se usan a diario.
Además, está escrita en dos niveles. Si nunca ha trabajado con contenedores, los primeros apartados explican el concepto sin tecnicismos. En cambio, si ya los usa, vaya directo a la instalación, al Dockerfile comentado y a la tabla de comandos.
Dónde encaja esta guía
Es la primera de tres guías construidas sobre la misma aplicación: un servicio web interno llamado inventario, con un proxy, la aplicación, una base de datos y una caché. En esta primera se construye su imagen; después, en la segunda, se describe completa en un solo archivo, y por último, en la tercera, se reparte entre tres servidores. Además, las cifras cuadran entre las tres.
- Docker — está leyéndola: qué es, instalación, primer despliegue y comandos esenciales.
- Docker Compose — la aplicación completa descrita en un archivo, con redes, volúmenes y secretos.
- Docker Swarm — el clúster de tres nodos, los comandos avanzados y las buenas prácticas.
Qué es Docker y qué problema resuelve
Casi todo el que ha instalado software conoce la frase «en mi equipo funciona». La aplicación va bien en el portátil de quien la escribió y falla en el servidor, porque allí hay otra versión del lenguaje, falta una librería o cambia una ruta. Docker ataca ese problema de raíz: la aplicación viaja junto con su entorno completo, así que lo que se probó es exactamente lo que se ejecuta.
Ese paquete se llama imagen. Cuando una imagen se pone en marcha se convierte en un contenedor: un proceso aislado que cree tener un sistema de archivos, una red y unos procesos propios. En realidad comparte el núcleo del sistema operativo anfitrión, y por eso arranca en uno o dos segundos y consume solo la memoria que de verdad usa.
El proyecto nació en 2013 y hoy es el estándar de hecho para distribuir software de servidor. Su motor, Docker Engine, es software libre bajo licencia Apache 2.0. Además, el formato de sus imágenes lo gobierna un estándar abierto, el de la Open Container Initiative, así que una imagen construida con Docker funciona también en otros motores compatibles.
Las piezas de Docker en una tabla
De hecho, seis términos bastan para leer cualquier documentación del tema sin perderse.
| Pieza | Qué es | Analogía |
|---|---|---|
| Imagen | Plantilla de solo lectura con el programa, sus librerías y su configuración | El instalador sellado |
| Contenedor | Una imagen en ejecución, con una capa propia donde escribir | El programa abierto |
| Dockerfile | Archivo de texto con las instrucciones para construir una imagen | La receta |
| Registro | Almacén de imágenes: Docker Hub, Azure Container Registry o uno privado | La tienda de aplicaciones |
| Volumen | Espacio de disco que sobrevive al contenedor | El disco externo |
| Red | Conexión virtual entre contenedores, con nombres que se resuelven solos | El switch del rack |
Contenedor o máquina virtual
No compiten: se complementan. Una máquina virtual emula un equipo entero y lleva su propio sistema operativo; un contenedor solo aísla procesos. Por eso lo habitual en una empresa es ejecutar Docker dentro de máquinas virtuales, que aportan el aislamiento fuerte, la migración en caliente y las copias de la plataforma. La guía de virtualización de servidores explica esa capa, y la de Proxmox muestra cómo se reparte un clúster en máquinas donde luego viven los contenedores.
| Criterio | Máquina virtual | Contenedor |
|---|---|---|
| Qué aísla | Un equipo completo, con su núcleo | Procesos, sobre el núcleo del anfitrión |
| Arranque | Decenas de segundos | Uno o dos segundos |
| Tamaño típico | Gigabytes | Decenas o cientos de megas |
| Sistema operativo | Cualquiera | El del anfitrión: Linux sobre Linux, Windows sobre Windows |
| Mejor para | Aislar clientes, sistemas distintos, cargas con estado | Empaquetar y repetir aplicaciones |
Usos comunes de Docker en una empresa
Sin embargo, Docker no es solo cosa de desarrolladores: en la operación diaria de TI también aparece en seis situaciones recurrentes.
| Uso | Ejemplo | Qué aporta |
|---|---|---|
| Publicar aplicaciones internas | Intranet, portal de proveedores, una API | El mismo paquete en pruebas y en producción |
| Herramientas de TI | Monitoreo, proxy inverso, DNS interno, gestor de contraseñas | Una orden para instalar y otra para actualizar |
| Aplicaciones heredadas | Un programa que exige una versión antigua de PHP o de Java | La dependencia vieja viaja dentro del contenedor, no en el servidor |
| Entornos de prueba | Una base de datos desechable para validar un cambio | Se crea en segundos y se borra sin dejar rastro |
| Pruebas automatizadas | Ejecutar la batería de pruebas en cada cambio de código | Cada ejecución parte de un entorno limpio e idéntico |
| Tareas programadas | Un informe nocturno, una exportación, una limpieza | El contenedor arranca, trabaja y desaparece |
De hecho, buena parte del software de servidor ya se distribuye así. Por ejemplo, un sistema de monitoreo como los que describe la guía de monitoreo de servidores se instala hoy con una imagen oficial en lugar de un instalador de veinte pasos.
Beneficios de Docker y lo que no resuelve
- Consistencia. Lo que se prueba es lo que se ejecuta, sin diferencias de versión entre entornos.
- Densidad. Un servidor aloja muchos más contenedores que máquinas virtuales, porque no hay un sistema operativo por servicio.
- Velocidad. Desplegar, reiniciar o volver a la versión anterior es cuestión de segundos.
- Actualizaciones limpias. Se cambia la imagen entera, no se parchea un servidor a mano; así que el estado siempre es conocido.
- Documentación viva. El Dockerfile y el archivo de Compose describen el servicio con exactitud, y se guardan en control de versiones.
Conviene conocer también sus límites, porque ahí se cometen los errores caros. En primer lugar, un contenedor no es una copia de seguridad: si los datos viven dentro y se borra, se pierden. Además, todos los contenedores comparten el núcleo del anfitrión, así que una vulnerabilidad del núcleo los afecta a todos. Por último, Docker no elimina la administración: la traslada del servidor a las imágenes, que también hay que actualizar.
Sistemas operativos que soportan Docker
Hay dos productos distintos y conviene no confundirlos. Docker Engine es el motor que se instala en un servidor Linux, gratuito y sin interfaz gráfica. Docker Desktop es la aplicación de escritorio para Windows, macOS y Linux, que incluye el motor dentro de una pequeña máquina virtual y añade una interfaz gráfica. A continuación, estas son las plataformas que publica la documentación oficial de instalación.
| Sistema | Producto | Versiones y arquitecturas |
|---|---|---|
| Ubuntu | Docker Engine | 26.04, 24.04 y 22.04 LTS · amd64, arm64, arm 32 bits, ppc64le y s390x |
| Debian | Docker Engine | 13 Trixie y 12 Bookworm · amd64, arm64, arm 32 bits y ppc64le |
| RHEL | Docker Engine | amd64, arm64 y s390x |
| Fedora y CentOS | Docker Engine | amd64, arm64 y ppc64le |
| Windows 10 y 11 | Docker Desktop | 10 22H2 (compilación 19045) o 11 23H2 (22631) en adelante, ediciones Pro, Enterprise o Education |
| macOS | Docker Desktop | La versión actual y las dos anteriores, en Apple silicon o Intel |
| Windows Server | Motor aparte | Docker Desktop no está soportado; los contenedores de Windows usan un motor instalado por separado |
Además, hay dos avisos de la versión 29 del motor, la actual, que afectan a equipos existentes. Por un lado, ya no se publican paquetes oficiales para Raspbian de 32 bits. Por otro lado, el soporte de cgroup v1 queda obsoleto, con continuidad hasta al menos mayo de 2029, así que los servidores con distribuciones antiguas deberían pasar a cgroup v2 cuanto antes. Ambos puntos figuran en las notas de versión.
¿Docker Desktop es gratis para una empresa?
Depende del tamaño, y es un punto que suele pasarse por alto. Para empezar, Docker Engine en un servidor Linux es gratuito sin condiciones. En cambio, el uso comercial de Docker Desktop exige una suscripción de pago en empresas de más de 250 empleados o más de 10 millones de dólares de ingresos anuales. Por debajo de ambos umbrales es gratuito, igual que para uso personal, educativo o de proyectos de código abierto sin ánimo de lucro.
Cómo instalar Docker paso a paso
Para un servidor se instala Docker Engine desde el repositorio oficial del proyecto, mientras que en un equipo de escritorio se instala Docker Desktop. Además, en ambos casos conviene evitar los paquetes de la propia distribución, que suelen ir varias versiones por detrás.
Instalar Docker en Ubuntu o Debian
Primero se retiran los paquetes que chocan con los oficiales. Después se añade la clave y el repositorio de Docker, y por último se instalan el motor y sus complementos. Los comandos son los de la guía oficial para Ubuntu; en cambio, en Debian basta con cambiar ubuntu por debian en las dos direcciones.
# 1. Retirar paquetes que entran en conflicto
for pkg in docker.io docker-doc docker-compose docker-compose-v2 docker-buildx podman-docker containerd runc; do
sudo apt remove -y $pkg
done
# 2. Clave y repositorio oficial
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
# 3. Motor, cliente y complementos
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 4. Comprobación
sudo docker run hello-world
Finalmente, la última orden descarga una imagen de prueba, la ejecuta y muestra un mensaje de bienvenida. Así que, si aparece, el motor funciona. Si tiene dudas con alguno de los comandos del sistema, la guía de comandos básicos de Linux los explica uno por uno.
Por otro lado, existe también un guion de instalación rápida en get.docker.com. Sirve para un laboratorio, pero la propia documentación desaconseja usarlo en producción: instala sin pedir confirmación, puede saltar de versión mayor sin avisar y no está pensado para actualizar una instalación existente.
Instalar Docker Desktop en Windows
Docker Desktop para Windows usa WSL 2, el subsistema de Linux de Windows, como motor por defecto. Los requisitos son 8 GB de memoria, un procesador de 64 bits con SLAT, la virtualización activada en la BIOS o UEFI y WSL en la versión 2.1.5 o posterior. Por eso, antes de ejecutar el instalador, conviene dejar WSL al día.
# En PowerShell como administrador
wsl --install
wsl --update
wsl --version
# Instalación silenciosa para el usuario actual, desde la carpeta del instalador
"Docker Desktop Installer.exe" install --user
Tras reiniciar sesión, Docker Desktop arranca el motor y el comando docker queda disponible en PowerShell y en la terminal de WSL. Por defecto ejecuta contenedores de Linux; en cambio, los contenedores de Windows se activan desde el menú de la aplicación, en las ediciones que los admiten.
Instalar Docker Desktop en macOS
Primero se descarga el archivo .dmg que corresponde al procesador, Apple silicon o Intel, y después se arrastra a Aplicaciones. Además, hacen falta al menos 4 GB de memoria. En los equipos con Apple silicon ya no es obligatorio instalar Rosetta 2, aunque algunas herramientas opcionales de línea de comandos todavía la usan. Si el disco del Mac anda justo, la guía para liberar espacio en Mac ayuda antes de empezar, porque las imágenes ocupan sitio rápido.
Después de instalar: tres ajustes que ahorran problemas
El primero es el acceso sin sudo. Se consigue añadiendo el usuario al grupo docker, pero hay que saber lo que implica: ese grupo equivale a ser root, porque quien controla el motor puede montar cualquier carpeta del anfitrión dentro de un contenedor. Por lo tanto, solo deben estar en él los administradores.
sudo usermod -aG docker $USER
newgrp docker
# Arranque automático con el sistema
sudo systemctl enable docker.service
sudo systemctl enable containerd.service
El segundo es la rotación de registros. Por defecto el motor guarda la salida de cada contenedor en archivos JSON que crecen sin límite, y es una causa clásica de discos llenos. Por suerte, se corrige en /etc/docker/daemon.json con el controlador local, que rota solo. El cambio se aplica a los contenedores que se creen después de reiniciar el servicio.
{
"log-driver": "local",
"log-opts": { "max-size": "10m", "max-file": "3" }
}
El tercero es el firewall. Hay que saber que los puertos que publica un contenedor se saltan las reglas de ufw y de firewalld, porque el motor escribe sus propias reglas de filtrado. Así que, si un servicio solo debe verse desde el propio servidor, se publica en la dirección local: -p 127.0.0.1:8080:80. La guía del firewall de Proxmox explica por qué conviene filtrar lo más cerca posible del servicio.
Primer despliegue con Docker
El recorrido tiene dos pasos. Primero se ejecuta una imagen ajena, para entender el ciclo de vida de un contenedor. Después se construye la imagen propia de la aplicación inventario, que las otras dos guías de la serie reutilizan.
Un servidor web en una sola línea
docker run -d --name web -p 8080:80 nginx:1.30-alpine
docker ps
curl -I http://localhost:8080
docker logs web
docker stop web
docker rm web
La primera línea hace cuatro cosas: descarga la imagen si no está, crea el contenedor, lo deja corriendo en segundo plano con -d y conecta el puerto 8080 del equipo con el 80 del contenedor. Además, el nombre web evita tener que copiar identificadores. Las líneas siguientes lo listan, lo prueban, leen su registro, lo detienen y lo borran. Todo el ciclo de vida cabe en seis comandos.
Por otro lado, fíjese en la etiqueta 1.30-alpine. Pedir nginx a secas equivale a pedir nginx:latest, que cambia sin avisar cada vez que el proyecto publica una versión. Por eso, en producción se fija siempre la versión.
El Dockerfile de la aplicación inventario
La aplicación de la serie es una pequeña API en Python que publica el inventario de máquinas de un clúster, como el de la serie de Proxmox. El proyecto tiene tres archivos: el código, la lista de dependencias y el Dockerfile.
inventario/
├── app/
│ └── main.py
├── requirements.txt
├── Dockerfile
└── .dockerignore
# app/main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/salud")
def salud():
return {"estado": "ok"}
# requirements.txt
fastapi==0.141.1
uvicorn==0.53.0
psycopg[binary]==3.3.6
redis==8.1.0
# Dockerfile
FROM python:3.14-slim
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1
WORKDIR /app
# Primero las dependencias: esta capa se reutiliza mientras no cambie requirements.txt
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Después el código, que cambia a menudo
COPY app/ ./app/
# Nunca como root
RUN useradd --uid 10001 --no-create-home inventario
USER inventario
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
El orden de las instrucciones no es casual. Cada instrucción genera una capa y, además, el motor reutiliza las capas que no han cambiado. Como las dependencias van antes que el código, un cambio en main.py reconstruye solo la última parte y tarda segundos. En cambio, si el código fuera primero, cada cambio reinstalaría todas las librerías.
El archivo .dockerignore evita enviar al motor lo que no debe entrar en la imagen, igual que un .gitignore. Como mínimo debe excluir .git, los entornos virtuales, las cachés de Python y cualquier archivo .env con secretos.
docker build -t inventario:1.0 .
docker run -d --name inventario -p 8000:8000 inventario:1.0
curl http://localhost:8000/salud
# {"estado":"ok"}
Por qué la imagen base decide el tamaño
Estas son las imágenes que usa la aplicación completa, con su tamaño comprimido para linux/amd64 consultado en Docker Hub el 18 de septiembre de 2026. Es decir, es lo que viaja por la red en cada descarga; en cambio, docker images muestra una cifra mayor, porque mide la imagen ya descomprimida en disco.
| Servicio | Imagen | Comprimida (amd64) |
|---|---|---|
| proxy | nginx:1.30-alpine | 26,1 MB |
| app | inventario:1.0 sobre python:3.14-slim | 46,4 + 9,4 = 55,8 MB |
| db | postgres:17-alpine | 117,2 MB |
| cache | redis:8-alpine | 39,0 MB |
| Total | 4 imágenes | 238,1 MB |
Los 9,4 MB de la aplicación son la suma de sus dependencias en PyPI, y más de la mitad es el controlador de PostgreSQL. Sin embargo, la comparación que importa es otra: si el Dockerfile partiera de python:3.14 en lugar de la variante slim, la base pesaría 415,0 MB y la imagen de la aplicación rondaría los 424 MB. Serían siete veces y media más por el mismo programa, y ese peso se paga en cada servidor que la descarga. De hecho, la tercera guía hace esa cuenta nodo por nodo.
Además, las cuatro imágenes oficiales se publican para ocho plataformas, entre ellas linux/amd64 y linux/arm64. El motor elige por sí mismo la que corresponde al procesador, así que el mismo comando funciona en un servidor Intel y en uno ARM. La guía de AMD64 vs ARM64 explica la diferencia entre ambas arquitecturas.
Comandos de Docker esenciales
Esta es la tabla para tener a mano. Cubre el día a día; en cambio, los comandos de filtrado, formato y diagnóstico están en la tercera guía.
| Comando | Para qué sirve |
|---|---|
docker version | Versión del cliente y del motor |
docker info | Estado del motor: contenedores, almacenamiento, cgroups |
docker pull nginx:1.30-alpine | Descargar una imagen |
docker run -d --name web -p 8080:80 imagen | Crear y arrancar un contenedor en segundo plano |
docker ps · docker ps -a | Contenedores en marcha · todos, también los parados |
docker logs -f web | Seguir el registro en vivo |
docker exec -it web sh | Abrir una consola dentro de un contenedor en marcha |
docker stop web · docker start web | Detener y volver a arrancar |
docker restart web | Reiniciar |
docker rm web | Borrar un contenedor detenido |
docker images | Imágenes descargadas |
docker rmi nginx:1.30-alpine | Borrar una imagen |
docker build -t inventario:1.0 . | Construir una imagen desde el Dockerfile |
docker tag · docker push | Renombrar una imagen y subirla a un registro |
docker inspect web | Toda la configuración de un objeto, en JSON |
docker cp web:/etc/nginx/nginx.conf . | Copiar archivos entre el contenedor y el equipo |
docker volume ls · docker network ls | Volúmenes y redes existentes |
docker system df | Cuánto disco ocupan imágenes, contenedores y volúmenes |
docker system prune | Borrar contenedores parados, redes sin uso e imágenes huérfanas |
Un apunte sobre el último comando: docker system prune no toca los volúmenes salvo que se le añada --volumes. Esa opción borra los datos de los volúmenes que ningún contenedor esté usando en ese momento, así que merece una segunda lectura antes de pulsar Intro.
Volúmenes y redes: lo mínimo para no perder datos
Todo lo que un contenedor escribe dentro de sí mismo desaparece al borrarlo. Por eso los datos que importan van a un volumen, que el motor guarda aparte y que sobrevive a cualquier número de contenedores.
# Volumen con nombre: lo administra el motor
docker volume create datos-db
docker run -d --name db -v datos-db:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=cambiar postgres:17-alpine
# Carpeta del anfitrión: útil para archivos de configuración
docker run -d --name web -v /srv/web/nginx.conf:/etc/nginx/conf.d/default.conf:ro \
-p 8080:80 nginx:1.30-alpine
Eso sí, la contraseña escrita en la línea de comandos solo vale para un laboratorio, ya que queda en el historial y en la configuración del contenedor. Por eso la segunda guía la saca a un secreto. Del mismo modo, las redes merecen un minuto. En la red por defecto los contenedores no se encuentran por nombre, pero en una red creada por el usuario sí, porque el motor incluye un servidor DNS interno. Así la aplicación se conecta a db por su nombre y no por una dirección que cambia en cada reinicio.
docker network create interna
docker run -d --name db --network interna -v datos-db:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=cambiar postgres:17-alpine
docker run -d --name inventario --network interna -p 8000:8000 inventario:1.0
# Dentro de "inventario", el host "db" ya resuelve
Repetir estas órdenes a mano para cuatro servicios es lento y propenso a errores. Precisamente para eso existe el archivo de Compose, que es el tema de la segunda guía.
Errores frecuentes al empezar con Docker
| Síntoma | Causa | Solución |
|---|---|---|
permission denied sobre docker.sock | El usuario no está en el grupo docker | Usar sudo o añadirlo al grupo, sabiendo que equivale a root |
port is already allocated | Otro proceso o contenedor usa ese puerto | Cambiar el puerto del anfitrión: -p 8081:80 |
| El contenedor se detiene al instante | Su proceso principal terminó o falló | Leer docker logs: el motivo casi siempre está en las últimas líneas |
| Los datos desaparecieron | Vivían dentro del contenedor y se borró | Volumen con nombre para todo lo que deba persistir |
| Disco lleno | Imágenes viejas, capas de construcción y registros sin rotar | docker system df, docker system prune y rotación de registros |
toomanyrequests al descargar | Límite de Docker Hub: 100 descargas cada 6 horas por dirección sin sesión | docker login con una cuenta: sube a 200; los planes de pago no tienen límite |
| Un puerto visible desde fuera pese a ufw | El motor escribe reglas que ufw no ve | Publicar en 127.0.0.1 o filtrar en el perímetro |
Preguntas frecuentes sobre Docker
¿Docker reemplaza a la virtualización?
No, porque resuelven problemas distintos y conviven. Mientras las máquinas virtuales aíslan sistemas completos, los contenedores empaquetan aplicaciones. Por eso lo normal es que los contenedores corran dentro de máquinas virtuales, y que la plataforma de virtualización aporte la alta disponibilidad y las copias de la máquina.
¿Se pueden ejecutar aplicaciones de Windows en contenedores?
Sí, con contenedores de Windows sobre un anfitrión Windows. Sin embargo, un contenedor comparte el núcleo del anfitrión, así que una imagen de Windows no corre en un servidor Linux ni al revés. Docker Desktop resuelve el caso inverso, Linux sobre Windows, gracias a la máquina virtual de WSL 2.
¿Es seguro descargar imágenes de Docker Hub?
Las imágenes oficiales y las de editores verificados, sí, con la precaución de fijar la versión. En cambio, una imagen cualquiera de un usuario desconocido es software de terceros sin revisar. De hecho, en 2022 se detectó código malicioso en más de mil imágenes públicas, la mayoría con mineros de criptomonedas camuflados.
¿Qué pasa con los datos si el servidor se daña?
Lo mismo que sin contenedores: si no hay copia fuera del servidor, se pierden. Al fin y al cabo, un volumen es un directorio del disco del anfitrión, no un respaldo. La segunda guía muestra cómo sacar copias de los volúmenes, y la página de continuidad y respaldo describe cómo se administra eso en una empresa.
Qué llevarse sobre Docker
Docker empaqueta una aplicación con su entorno y la ejecuta igual en cualquier sitio. Para un servidor se instala Docker Engine desde el repositorio oficial; en el escritorio, Docker Desktop, con su licencia de pago por encima de 250 empleados o 10 millones de dólares. El primer despliegue cabe en una línea, pero lo que marca la diferencia son los detalles: versiones fijadas, un usuario sin privilegios, una base slim, registros que rotan y datos en volúmenes.
Si su empresa quiere contenedores sin cargar con la operación del servidor que los aloja, en KHARONTE administramos esa capa dentro del servicio de infraestructura de TI. Y la siguiente guía toma la aplicación inventario y la describe entera en un solo archivo: el docker-compose.yml de sus cuatro servicios.




