Docker es una pequeña maravilla de la ingeniería de sistemas. Lo mejor para entender qué es y para lo qué sirve es comentar un posible caso práctico.
Imagina que necesitas instalar en un servidor una aplicación web que tiene un montón de dependencias para funcionar: una base de datos mongo, un servidor de apps como nginx, una máquina virtual de java, etc. Tras un día de duro trabajo, todo funciona a la perfección pero al cabo de unos días viene el jefe y dice: «el servidor en el que has montado la infraestructura no sirve, hemos encontrado una alternativa más barata». Un día de trabajo a la basura.
Seguro que muchas veces has encontrado el término «contenedor» asociado a Docker y es posible que no te quedara del todo claro cual es el símil en realidad. El símil es que el contenedor es, ni más ni menos, que la aplicación y todo lo necesario para que funcione, preparado para correr en cualquier equipo con Docker instalado. Es un «paquete» con todas las dependencias necesarias y configuradas para ejecutar la aplicación que has desarrollado ejecutando un par de comandos y despreocupándote completamente del nuevo entorno de despliegue.
¿Que tienen que ver las máquinas virtuales en todo esto?
Pues no mucho, por no decir nada. Estamos más acostumbrados a trabajar con máquinas virtuales y por eso tendemos a usarlas como comparativa para definir qué es Docker. La diferencia fundamental es que las máquinas virtuales usan como base un sistema operativo con todos sus procesos al margen del sistema operativo host, mientras que Docker usa al propio host, por lo que es muchísimo más ligero. Las máquinas virtuales virtualizan equipos y Docker virtualiza procesos. Esto conlleva que Docker sea mucho más ligero tanto en espacio de disco duro como RAM. Otra gran diferencia con respecto a las máquinas virtuales es su concepción de vida útil. Podemos crear contenedores como churros y destruirlos sin mayor preocupación (se pueden persistir datos en el host fácilemnte), no así las máquinas virtuales, por razones obvias.
Puedes pensar en Docker como en la MV de Java y en los contenedores como en los .jar o .war con todas las librerias y código necesarios para la ejecución del programa.
Con Docker en definitiva se simplifica todo lo que tiene que ver con la portabilidad de aplicaciones, asumiendo el rol de interfaz común.