Todo desarrollador ha vivido esta situación: una aplicación funciona perfectamente en su entorno local, pero al desplegarla en un servidor de pruebas o producción, falla de maneras inesperadas. Este problema, conocido como "funciona en mi máquina", suele originarse por diferencias sutiles entre entornos:
Estos inconvenientes generan retrasos, frustración y dificultan la colaboración en equipo. La solución histórica a este problema fue la virtualización.
Tanto las máquinas virtuales como los contenedores buscan aislar una aplicación y sus dependencias para que se ejecute de forma consistente en cualquier lugar. Sin embargo, lo hacen de maneras fundamentalmente distintas.
Una VM emula un sistema informático completo, incluyendo el hardware. Sobre el sistema operativo anfitrión (host), se ejecuta un software llamado hipervisor (como VirtualBox, VMware o Hyper-V), que crea y gestiona una o más máquinas virtuales. Cada VM tiene su propio sistema operativo completo (invitado), con sus propios binarios, librerías y, finalmente, la aplicación.
Los contenedores, popularizados por Docker, adoptan un enfoque más ligero. En lugar de virtualizar el hardware, virtualizan el sistema operativo. Todos los contenedores se ejecutan sobre el mismo kernel del SO anfitrión. Un motor de contenedores (como Docker Engine) se encarga de aislar los procesos.
Un contenedor empaqueta únicamente la aplicación y sus dependencias (librerías y binarios). No incluye un sistema operativo invitado completo, lo que lo hace extremadamente ligero y rápido.
Docker no es solo una herramienta, sino un completo ecosistema de productos que facilitan el ciclo de vida de las aplicaciones en contenedores: