En la entrada anterior del blog comentaba cómo hacer multi-stage build de imágenes Docker, donde tenía especial utilidad en Windows. Como ejemplo ponía la generación de una imagen Docker para compilar el código de nuestra aplicación .NET Standard valiéndonos de las Visual Studio Build Tools, lo que nos dejaba un resultado de 36 GB de imagen.

He caído en la cuenta en que en la configuración por defecto de Docker Desktop para Windows e incluso de Docker en Windows Server, no seremos capaces de instalar las Visual Studio Build Tools. ¿Por qué? Si miramos el log de la instalación veremos lo siguiente:

Error: Pre-check verification: Visual Studio needs at least 71.6 GB of disk space. Try to free up space on C:\ or change your target drive.
Prompting: Failed pre-checks: `[SizePreCheckEvaluator, Visual Studio needs at least 71.6 GB of disk space. Try to free up space on C:\ or change your target drive.]

Por defecto, el Docker Engine asigna un tamaño máximo de 30 GB por contenedor en ejecución, algo que en GNU/Linux suele ser más que suficiente, pero no en Windows. ¿Qué podemos hacer?

Gestionando el espacio de almacenamiento en el Docker Engine

Solucionarlo es realmente sencillo, sólo tenemos que modificar la configuración del demonio a través del archivo daemon.json que encontraremos en:

  • GNU/Linux: /etc/docker/daemon.json
  • Windows: C:\ProgramData\Docker\config\daemon.json. En el caso de Docker Desktop bajo Windows 10 podemos editarlo desde la interfaz gráfica de condiguración. Más detalles a continuación. En el caso de Windows Server, puede que el archivo ni exista y debamos crearlo.

En el caso de que nuestros contenedores sean muy grandes hay dos operaciones que puede que nos interese hacer:

  • Llevarnos las imágenes Docker otra unidad de disco o directorio del sistema operativo. Esto lo conseguimos mediante el uso de la clave `"data-root".
  • Aumentar la asignación de tamaño. Esto lo conseguimos mediante el array "storage-opts" y la cadena `size".

Así pues imaginemos que quiero almacenar mis imágenes Docker en la unidad E, carpeta Docker y que el tamaño máximo que van a tener es de 127 GB. Tendría que agregar lo siguiente a mi daemon.json:

{
   "data-root": "E:\\Docker",
   "storage-opts": [
     "size=127GB"
   ]
}

En el caso de Windows 10 con Docker Desktop se haría de la siguiente manera:

  1. Nos vamos a la configuración de Docker Desktop. En mi caso estoy en modo Windows Server Containers.
  2. En la pestaña Daemon activamos en modo avanzado, que no es otra cosa que un editor de texto para escribir la configuración.
  3. Finalmente agregamos la configuración de la que hemos hablado antes y aplicamos.

Veremos como la estructura de carpetas de Docker en la nueva ubicación. Aunque aquí lo he explicado para Windows 10, el proceso es bastante similar en GNU/Linux -donde tras editar el archivo tendremos que reiniciar el demonio de Docker con $ sudo systemctl restart docker- o en Windows Server -donde habrá que hacer lo ídem, pero reiniciando el servicio con Restart-Service docker desde PowerShell-.

Limpiando carpetas de datos del Docker Engine bajo Windows

Cuando usamos data-root múltiples veces para mover los archivos a otras ubicaciones, puede que nos interese limpiar los directorios que ya no usemos. Sin embargo, nos encontraremos la desagradable sorpresa de que Windows no nos lo permite, ni aún siendo administradores del sistema. El motivo es que el motor de Docker se ha hecho propietario de todos ellos y ha trabajado con estructuras de bajo nivel del NTFS para simular los UnionFS.

Afortunadamente John Howard del equipo de Windows Server Containers en Microsoft ha diseñado una pequeñísima utilidad de línea de comandos que le manda el trabajo al propio motor de Docker. La podemos encontrar en este repo de Github y utilizarla es tan sencillo como hacer docker-ci-zap.exe -folder E:\Docker (en el caso del ejemplo de este artículo).

Cuidado si -a fecha de escribir estas líneas- usas Windows 10 1903

A fecha de escribir estas líneas hay un problema entre Windows 10 1903 y el uso de storage-opts y size en daemon.json. Se puede seguir el problema en este issue de Github, donde John nos cuenta:

The problem is now understood. It looks like it will require a fix for a regression in docker, and a fix in Windows itself. For now, the only workaround is as others have put here to take out the storage-opt in daemon.json. It also affects docker run where --storage-opt size=30GB for example (any number, 30 is just arbitrary for demonstration). It also means that it is not possible to build layers larger than 20GB in Windows 1903 builds.

To add, it has nothing to do with Windows Defender, or whether the data root has been moved to another location.

Así que si necesitas incrementar el tamaño de tus imágenes Docker en Windows, te recomiendo -de momento- no actualizar a la build 1903.

Eso es todo por hoy, ¡happy dockering!