¿Por qué empecé a usar Docker?
Nota editorial: este artículo fue publicado originalmente en diciembre de 2020 y revisado en julio de 2026 para actualizar referencias técnicas e incorporar el criterio adquirido tras años de uso continuado. Los conceptos base sobre contenedores, imágenes y virtualización siguen siendo válidos, pero tanto el ecosistema como mi forma de entenderlo han evolucionado.
Cuando Docker empezó a extenderse, yo trabajaba con virtualización tradicional: VMware, VirtualBox, QEMU. Cada servicio nuevo significaba crear una máquina virtual completa, instalar un sistema operativo, configurarlo, desplegar la aplicación y mantenerlo todo como si fuera un sistema independiente.
Funcionaba. Pero era lento, pesado y, para muchos proyectos, excesivo.
Cuando empecé a probar Docker en mi laboratorio personal, no empecé aprendiendo Docker. Empecé intentando entender qué problemas resolvía realmente y si encajaba en mi forma de trabajar. Porque esa es mi forma de hacer las cosas: primero lo pruebo en un entorno controlado, necesito romperlo, necesito entenderlo. Nunca llevo una tecnología directamente a producción sin haberla visto fallar antes.
Lo que vi no fue una herramienta más. Fue un cambio de paradigma en la forma de empaquetar, desplegar y operar aplicaciones y servicios.
Nota de alcance: este artículo es divulgativo y presenta conceptos generales sobre Docker. No documenta configuraciones, sistemas, procedimientos ni decisiones de ninguna organización concreta.
El problema que intentaba resolver
Antes de Docker, mi flujo para un proyecto nuevo era más o menos así:
- Coger un servidor o crear una máquina virtual.
- Instalar el sistema operativo desde cero o clonar una plantilla.
- Configurar actualizaciones, firewall, usuarios, acceso remoto.
- Instalar dependencias: bases de datos, librerías, runtime, herramientas.
- Desplegar la aplicación.
- Repetir el proceso completo para cada proyecto.
Con el tiempo, aquello generaba un montón de sistemas que había que mantener, actualizar y recordar qué hacía cada uno. Además, reproducir el mismo entorno en otro sitio exigía repetir pasos manuales que casi siempre dejaban diferencias entre entornos.
Docker aceleró radicalmente ese flujo de trabajo. Me permitió encapsular proyectos enteros con sus dependencias, reducir los problemas de versiones y evitar instalar servicios directamente sobre el sistema anfitrión.
Cómo cambió mi laboratorio
Antes de Docker, mi laboratorio personal era un conjunto de máquinas virtuales, cada una con su sistema operativo, sus actualizaciones y su configuración. Cada vez que quería probar algo nuevo, el proceso era el mismo: buscar una VM libre, arrancarla, actualizarla, instalar dependencias y, solo entonces, empezar a probar.
Con Docker, ese proceso se redujo drásticamente. Ahora puedo levantar un servicio nuevo en segundos con solo definir su configuración en un archivo. Si algo falla, lo borro y lo vuelvo a crear. Si quiero probar una alternativa, cambio la imagen y arranco otro contenedor. El laboratorio se volvió más ágil, más limpio y mucho más fácil de mantener.
Eso no significa que haya desaparecido la virtualización. Sigo teniendo máquinas virtuales para separar entornos, para probar configuraciones de red complejas o para aislar sistemas completos. Pero para el día a día, los contenedores se llevan la mayor parte del trabajo.
Mi forma de evaluar una tecnología
Cuando pruebo una tecnología nueva en el laboratorio, no busco aprender sus comandos. Busco descubrir cómo falla, cómo se recupera y qué dependencias introduce. Un servicio que se levanta en cinco minutos puede esconder problemas que solo aparecen al actualizar, al reiniciar el servidor o al quedarte sin espacio en disco.
Con Docker aprendí que lo importante no es solo que un contenedor arranque. Es entender qué pasa si el contenedor se para, si el volumen se llena, si la red cambia, si la imagen deja de estar disponible o si necesitas reconstruir todo desde cero en otro equipo.
Esa forma de evaluar no cambió con Docker. Docker simplemente hizo más fácil hacer ese tipo de pruebas. En lugar de tener que montar y desmontar máquinas virtuales enteras para cada experimento, podía lanzar un contenedor, probar, romper, destruir y empezar de nuevo en cuestión de segundos.
Cómo funciona Docker realmente
Cuando empecé a entender cómo funcionaba Docker por debajo, lo primero que me llamó la atención fue que no virtualiza hardware como una máquina virtual tradicional. Un contenedor ejecuta procesos aislados que comparten el kernel del sistema operativo host. Ese aislamiento se apoya en tecnologías de Linux como namespaces, cgroups, sistemas de archivos por capas y redes virtuales.
Traducido: cada contenedor ve su propio entorno, sus procesos, sus librerías y su sistema de archivos, pero no carga un sistema operativo completo con su propio kernel. Por eso los contenedores son mucho más ligeros que una máquina virtual: arrancan en segundos, ocupan menos recursos y permiten desplegar servicios de forma mucho más ágil.
Pero conviene ser preciso: un contenedor no es una VM pequeña. Un contenedor puede ser más ligero y más rápido, pero no sustituye automáticamente al aislamiento de una máquina virtual. Es otra forma de aislar y empaquetar aplicaciones. Más ligera, más rápida, pero con un modelo de aislamiento distinto. Ese matiz es importante cuando trabajas en entornos donde el aislamiento real importa.
La analogía del transporte marítimo
Para entender los contenedores, piensa en el transporte marítimo. Antes de los contenedores estandarizados, mover mercancía era un caos. Cada carga tenía su forma, su tamaño, su manera de manipularse y sus problemas. Había que gestionar cada tipo de carga de forma distinta, y eso hacía que todo fuera más lento, más caro y más propenso a errores.
El contenedor cambió la logística porque estandarizó el formato. Da igual si dentro hay ropa, piezas industriales o electrónica. Desde fuera, el contenedor se maneja igual, se apila igual y se transporta igual. Lo importante no es lo que contiene, sino que puede moverse de forma predecible.
Con Docker pasa algo muy parecido. Una imagen Docker empaqueta una aplicación con todo lo que necesita para ejecutarse: código, librerías, variables de entorno, configuración. El contenedor es la ejecución de esa imagen. Da igual si dentro tienes un servidor web, una base de datos o un bot de Telegram: desde fuera, se despliega igual.
Y al igual que en el transporte marítimo, lo que realmente cambió no fue la mercancía, sino la forma de moverla.
Docker vs máquinas virtuales
La diferencia principal está en la capa que se virtualiza. Una máquina virtual virtualiza hardware y ejecuta un sistema operativo invitado completo. Docker ejecuta procesos aislados sobre el kernel del host.
| Característica | Máquina virtual | Contenedor Docker |
|---|---|---|
| Arranque | Normalmente minutos | Normalmente segundos |
| Consumo | Más alto, incluye SO invitado | Más bajo, comparte kernel |
| Aislamiento | Muy fuerte, VM/hipervisor | A nivel de proceso, kernel compartido |
| Tamaño | Habitualmente GB | Habitualmente MB |
| Mantenimiento | Un SO completo por VM | Imagen + contenedor + host |
| Portabilidad | Según hipervisor | Muy alta, si hay runtime |
Mi regla práctica:
- Si necesito aislar un sistema completo, uso VM.
- Si necesito desplegar servicios ligeros y reproducibles, uso contenedores.
- Si quiero ambas cosas, uso VMs para separar entornos y Docker dentro para desplegar servicios.
Lo que más me costó entender
Aprender Docker fue relativamente rápido. Los conceptos de imagen, contenedor y volumen se entienden bien en poco tiempo. Pero la verdadera curva no estaba en Docker, sino en todo lo que rodea a los contenedores.
Lo que más me costó fue entender las redes: modos host, bridge, NAT, comunicación entre contenedores, cómo se resuelven los nombres dentro de una red Docker, qué puertos se exponen realmente y cómo aislar servicios que no deberían comunicarse entre sí.
La persistencia de datos también exigió su tiempo. Al principio es fácil pensar que los datos dentro del contenedor son permanentes. Hasta que borras el contenedor y desaparecen. Ahí aprendes la diferencia entre volúmenes, bind mounts y el sistema de archivos efímero del contenedor. Y aprendes también que un backup sin probar no es un backup.
Y después están los permisos. Los contenedores no siempre se ejecutan con el usuario que esperas, y montar carpetas del host con el UID incorrecto puede hacer que un servicio no pueda escribir donde debería. Problemas típicos que no aparecen en el tutorial de inicio, pero que aparecen en cuanto montas algo real.
Nada de esto es un problema de Docker. Es parte del aprendizaje real de cualquier tecnología que cambia la forma en que despliegas software. Si empiezas sabiendo que redes, persistencia y permisos van a ser los puntos donde más tendrás que profundizar, te ahorrarás más de un dolor de cabeza.
Qué es una imagen y qué es un contenedor
Una imagen es la plantilla. Contiene la aplicación, dependencias, librerías y configuración base. Un contenedor es una instancia en ejecución de esa imagen.
Puedes crear varios contenedores desde la misma imagen. Puedes parar uno, borrarlo y levantar otro. La imagen sigue ahí. Por eso en Docker es importante entender la persistencia desde el principio: los datos importantes deben ir en volúmenes o bind mounts, no dentro del contenedor.
Servicios como Vaultwarden, bases de datos, Uptime Kuma o cualquier aplicación con datos propios necesitan que planifiques dónde se guarda esa información antes de lanzar el primer contenedor, no después.
Docker Compose: cuando todo empieza a encajar
Puedes lanzar contenedores con comandos docker run, pero en cuanto tienes más de dos parámetros, mantenerlo se vuelve complicado. Docker Compose permite definir servicios, redes, volúmenes, variables y dependencias en un archivo YAML. En lugar de recordar comandos largos, tienes un archivo que describe exactamente cómo debe funcionar tu servicio. Y lo levantas con docker compose up -d.
Eso cambió mi forma de trabajar. En lugar de instalar servicios manualmente o mantener scripts dispersos, pasé a tener definiciones limpias, versionables y reproducibles. Si un equipo fallaba, sabía exactamente cómo reconstruirlo. Si quería probar una configuración distinta, duplicaba el archivo, lo modificaba y lo probaba sin miedo a romper nada.
El cambio de mentalidad
Hasta entonces, cuando pensaba en un nuevo proyecto, mi mente iba directamente al servidor: qué sistema operativo instalar, qué recursos asignar, cómo mantenerlo. Con Docker, empecé a pensar en servicios. Ya no necesitaba un sistema completo para cada aplicación. Necesitaba definir qué necesitaba ese servicio para funcionar, empaquetarlo y decidir dónde ejecutarlo.
Ese cambio de mentalidad fue más importante que aprender los comandos. Pasé de gestionar máquinas a gestionar servicios. Pasé de instalar a definir. Pasé de mantener sistemas a mantener definiciones. Y eso, con el tiempo, afectó también a cómo empiezo a pensar cualquier proyecto, dentro y fuera del laboratorio.
No es que los servidores dejaran de importar. Es que dejaron de ser el centro de atención.
Seguridad en contenedores: criterio, no lista
Docker no es inseguro por defecto, pero la seguridad en contenedores no se resuelve marcando casillas. Se resuelve entendiendo qué estás ejecutando y cómo se comporta.
Antes de usar una imagen, revisa si es oficial, cuándo se actualizó, qué puertos expone, qué volúmenes necesita y si ejecuta como root. Docker facilita desplegar software, pero también facilita desplegar basura si no miras lo que estás ejecutando. Mi regla: si va a tocar datos importantes, no uso una imagen que no entiendo.
En la práctica, aplico siempre estas medidas:
- No expongo puertos sin necesidad.
- No ejecuto contenedores con
--privilegedsalvo que sepa exactamente por qué. - No guardo contraseñas en imágenes; uso archivos
.envcon permisos restringidos. - Mantengo las imágenes actualizadas.
- Hago backup de volúmenes y carpetas persistentes.
- Uso redes Docker para aislar servicios.
Ninguna de estas medidas es nueva. Pero aplicarlas de forma consistente marca la diferencia entre un laboratorio que funciona y uno que da más de un susto.
Primeros pasos reales
Si nunca has usado Docker, no empieces por teoría infinita. Empieza por algo sencillo:
docker run --rm hello-world
Luego algo útil:
docker run -d --name nginx-demo -p 8080:80 nginx:latest
Cuando entiendas eso, pasa a Compose. La curva inicial es pequeña si vienes de virtualización, pero redes, persistencia y permisos serán donde más tengas que profundizar.
Hoy intento contenerizar todo aquello que tenga sentido aislar y reproducir, pero Docker no es la respuesta para todo. Sigo usando máquinas virtuales cuando necesito un aislamiento más fuerte o sistemas completos. No dejé de utilizarlas. Dejé de necesitar una máquina virtual completa para cada servicio.
El criterio no está en la herramienta. Está en saber cuándo usar cada una. Docker es una de las tecnologías que más ha cambiado mi forma de trabajar y desplegar servicios. Pero no porque sea la mejor herramienta, sino porque me obligó a repensar cómo empaqueto, cómo aíslo y cómo mantengo lo que despliego.
La tecnología nunca debe elegirse por moda. Primero se entiende el problema. Después se decide la herramienta.
Más contenido relacionado
- Vaultwarden con Docker — gestor de contraseñas self-hosted.
- Proxy inverso con Caddy — HTTPS automático y dominios limpios.
- Monitoriza tus servicios con Uptime Kuma.
- Descarga tu librería de iCloud con Docker.
- Mi homelab: el laboratorio de un CIO.
¿Quieres seguir explorando?
Puedes descubrir más artículos, seguir mis publicaciones en LinkedIn o escribirme.