Cómo correr contenedores Docker sobre Bash sobre Windows

Cuando el WSL (Windows Subsystem Linux), que así es como lo llaman estos de Microsoft, Bash en Ubuntu en Windows, fue anunciado en la conferencia Microsoft’s Build en 2016, muchos ingenieros informáticos abrimos los ojos ante el atajo que suponía disponer de forma directa de todas esas herramientas de Linux pero en Windows. Personalmente, aunque trabajo con Mac, hay temporadas en que por exigencias del cliente conviene hacerse con un potente Lenovo con Windows, donde me da un poco igual programar esos scripts que normalmente se necesitan tanto en PowerShell, Bash o en texto plano con el cmd. Pero hay algo que si que se echa de menos y es correr Docker en el Bash este de Windows. Hasta hace muy poco, os cuento…

Docker, como sabéis o podéis imaginar, requiere varias llamadas directas al sistema que no necesariamente están implementadas en Windows, así que conseguir que corra bajo WSL no es precisamente algo fácil. Sin embargo, podemos darle otro enfoque y correr el Docker Engine en Windows y conectarnos a él desde el Bash, con lo cual tendríamos ya la potencia que buscamos. Esto, además, tiene la ventaja de que puedes iniciar un contenedor desde PowerShell e interactuar con él desde Bash; o, en otras palabras, tu sistema todavía se percibe como una sola máquina.

Me puse a buscar información y estos son los pasos que di:

  1. Instalar Docker en Windows
  2. Conectar Docker en WSL a Docker en Windows

Vamos paso a paso…

Instalar Docker en Windows

Instalar la Docker engine en Windows es algo trivial, basta ir a docker.com, descargar la distribución apropiada y, si no lo tienes activado, activar la virtualización de hardware en la BIOS y asegurarte de que Hyper-V esté instalado.

Actualización de Windows 10 de abril 2017

Con la actualización de Windows 10 incluso se ha simplificado el tema porque permite ejecutar aplicaciones de Windows desde el Bash (era lógico, pero no estaba inicialmente). Basta añadir estas líneas al .bashrc y recargar el entorno, y estará todo listo.


export PATH="$HOME/bin:$HOME/.local/bin:$PATH"
export PATH="$PATH:/mnt/c/Program\ Files/Docker/Docker/resources/bin"
alias docker=docker.exe
alias docker-compose=docker-compose.exe

 

Ahora ya puedes probar con docker –version desde Bash, y si funciona te puedes ahorrar el resto del post 🙂 Si no… pues continúa.

Para instalar Docker en la WSL necesitamos unos pasos más. Hay una descripción para Ubuntu de forma generalizada aquí, que funciona bien para WSL también, a excepción de algunos pasos opcionales. Aquí está lo que hice:


# Install packages to allow apt to use a repository over HTTPS
$ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
# Add Docker's official GPG key
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# Set up the repository
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# Update source lists
sudo apt-get update
# Install Docker
sudo apt-get install docker-ce

 

Por supuesto, también existe la opción de descargarlo y extraer los binarios que necesitamos y ponerlos en el path. Esto nos lleva a tener Docker instalado tanto en Windows como en la WSL, pero no iniciado en ambos. El instalador de Windows crea un acceso directo en el escritorio y el correspondiente del menú. Abre Docker y entonces ya puedes probar a ejecutar un comando cualquiera como docker images.

En Bash todavía no podremos ejecutar docker: cannot connect to the Docker daemon… etc etc. Nos faltan un par de pasos.

 

Conectar Docker en WSL a Docker en Windows

Ejecutar docker contra la máquina desde otra máquina diferente es muy fácil ya que Docker puede abrir un endpoint TCP donde se puede dejar escuchando el CLI. Si este endpoint no está activado se puede activar en las preferencias de Docker.

Con esto hecho, con este endpoint activo, todo lo que necesitamos es dar instrucciones al CLI en Bash para que se conecte a la máquina que está corriendo en Windows en lugar de la máquina en Bash que no existe.


$ docker -H tcp://0.0.0.0:2375 images

 

$ echo "export DOCKER_HOST='tcp://0.0.0.0:2375'" >> ~/.bashrc
$source ~/.bashrc

 

Y con esto ya podemos ejecutar Docker desde Bash. Misión cumplida. Espero que te sirva.