Cómo utilizar bind mounts en Docker sobre Ubuntu 20.04

Cómo utilizar bind mounts en Docker sobre Ubuntu 20.04

Además de los volúmenes, existe otra alternativa para disponer de datos persistentes en un contenedor. Aunque su origen se remonta a los primeros días de Docker, sus posibilidades resultan un tanto limitadas. Sin embargo, saber de su existencia puede resultar útil en determinados casos que comentaremos más adelante. En esta guía aprenderás cómo utilizar bind mounts en Docker sobre Ubuntu 20.04.

Las características más distintivas de los bind mounts son las siguientes:

  • Un directorio cualquiera del sistema host puede montarse en el contenedor.
  • Los procesos del contenedor tienen acceso a tal directorio, por lo que pueden llegar a crear, modificar, o borrar su contenido. Por supuesto, existe la posibilidad de montar el directorio como solo lectura para resolver este inconveniente.
  • Permiten compartir archivos de configuración desde el host hacia el contenedor. De hecho, Docker realiza la resolución de nombres montando el archivo /etc/resolv.conf del sistema anfitrión en cada contenedor.

Por estas razones, no resultan la mejor opción bajo ciertos escenarios (en los cuales los volúmenes son la decisión más acertada):

  • Cuando necesitemos compartir datos entre varios contenedores en ejecución, o si los archivos se encuentran en un host remoto.
  • Si no tenemos la seguridad de que el host tendrá una estructura determinada en el sistema de archivos.
  • Para migrar datos de un host a otro (no entre contenedores).
  • En caso de que se desee usar la CLI de Docker para manejar directamente el recurso de almacenamiento.

La documentación oficial de Docker contiene una comparación más detallada sobre volúmenes y bind mounts. Además, detalla una lista de casos de uso para cada uno.

Requisitos previos

Paso 1: Creación del directorio para el bind mount

En esta instancia, simplemente vamos a crear un nuevo directorio para alojar un simple index.html. Para propósitos ilustrativos, no hará falta que tenga la estructura formal de un documento HTML.

mkdir ~/website
cd ~/website
echo "Soy un archivo en un bind mount" > index.html

Para agregar más contenido después, no hay necesidad de recrear el contenedor que usará el bind mount.

Paso 2: Ejecución del contenedor

Para comenzar, recordemos el comando para crear un contenedor basado en la imagen oficial de Nginx:

sudo docker container run --name=nginx --publish 8080:80 --detach --restart=always nginx

Antes de ejecutarlo, agreguemos la opción -v seguida de:

  • la ruta al directorio que creamos en el paso anterior,
  • dos puntos, y
  • la ubicación donde deseamos montarlo en el contenedor
sudo docker container run --name=nginx -v ~/website:/usr/share/nginx/html --publish 8080:80 --detach --restart=always nginx

Ahora sí podemos presionar Enter y esperar el resultado. Una vez que el contenedor esté ejecutándose, inspeccionemos su configuración con especial atención a la sección Mounts:

sudo docker container inspect nginx

La información más relevante que muestra la imagen de arriba es:

  • La solución de almacenamiento (Type)
  • El origen o Source (/home/gabriel/website dentro del sistema anfitrión)
  • El destino o Destination (/usr/share/nginx/html en el contenedor)
  • El modo (RW: read/write, o lectura/escritura)

Ahora nos damos cuenta de que no especificamos que el bind mount fuera de solo lectura. ¡No importa! Podemos detener el contenedor, eliminarlo, volver a crearlo con la opción :ro acompañando a -v:

sudo docker container stop nginx
sudo docker container rm nginx
sudo docker container run --name=nginx -v ~/website:/usr/share/nginx/html:ro --publish 8080:80 --detach --restart=always nginx

Al finalizar, volvamos a inspeccionar la nueva sección Mounts:

De esta manera, los procesos del contenedor no podrán modificar el contenido del directorio origen.

Paso 3: Manipulación del contenido del bind mount

Con el contenedor en ejecución, accedamos a la raíz del sitio desde un navegador:

Y ahora modifiquemos su contenido para luego refrescar la página:

echo "<br>Hoy es $(date +%d/%m/%Y)" >> ~/website/index.html

Como podemos ver, el contenido se actualizó como esperábamos. Este ejemplo, si bien simple, nos permite ver una ventaja de los bind mounts. Podemos emplearlos ya que son fáciles de utilizar para desarrollar una aplicación, guardar cambios, y ver su efecto en el contenedor de forma rápida.

Conclusión

En esta guía aprendiste cómo utilizar bind mounts para solucionar la necesidad de persistencia. Al repasar la lista de características que compartimos en la introducción podrás identificar si representa la mejor alternativa. En caso de que no lo sea, siempre puedes recurrir a los volúmenes y contar con todas las herramientas de la CLI de Docker.

¿Te resultó útil esta guía?

Imagen por defecto
Gabriel Cánepa
Gabriel trabaja actualmente como desarrollador full-stack en Scalar, una firma que se dedica a hacer valuaciones de empresas. Es Administrador de Sistemas certificado por la Fundación Linux y previamente ha escrito un gran número de artículos y contenidos técnicos sobre el tema para: DigitalOcean, Linode, Carrera Linux Argentina y Tecmint. Tiene una certificación en programación de la Universidad de Brigham Young-Idaho, y está completando las carreras de programador y analista de sistemas en la Universidad Nacional de Villa Mercedes (UNViMe). En su tiempo libre, Gabriel disfruta leyendo libros de Stephen R. Covey, tocando piano y guitarra, y enseñando conocimientos de programación a su dos hijas.