# Montajes de tipo bind


Cuando utilizas un montaje de tipo bind, un archivo o directorio de la máquina anfitriona se monta desde el anfitrión en un contenedor. Por el contrario, cuando utilizas un volumen, se crea un nuevo directorio dentro del directorio de almacenamiento de Docker en la máquina anfitriona. Docker crea y mantiene esta ubicación de almacenamiento, pero los contenedores acceden a ella directamente utilizando operaciones estándar del sistema de archivos.

## Cuándo utilizar montajes de tipo bind

Los montajes de tipo bind son apropiados para los siguientes tipos de casos de uso:

- Compartir código fuente o artefactos de compilación entre un entorno de desarrollo en el anfitrión de Docker y un contenedor.

- Cuando quieres crear o generar archivos en un contenedor y persistir los archivos en el sistema de archivos del anfitrión.

- Compartir archivos de configuración de la máquina anfitriona con los contenedores. Así es como Docker proporciona resolución DNS a los contenedores por defecto, montando `/etc/resolv.conf` de la máquina anfitriona en cada contenedor.

Los montajes de tipo bind también están disponibles para las compilaciones (builds): puedes montar el código fuente del anfitrión en el contenedor de compilación para probar, analizar (lint) o compilar un proyecto.

## Montajes de tipo bind sobre datos existentes

Si montas un archivo o directorio en un directorio del contenedor en el que ya existen archivos o directorios, los archivos preexistentes quedarán ocultos por el montaje. Esto es similar a si guardaras archivos en `/mnt` en un anfitrión Linux y luego montaras una unidad USB en `/mnt`. El contenido de `/mnt` quedaría oculto por el contenido de la unidad USB hasta que esta se desmontara.

En el caso de los contenedores, no existe una forma sencilla de eliminar un montaje para volver a mostrar los archivos ocultos. Tu mejor opción es volver a crear el contenedor sin el montaje.

## Consideraciones y restricciones

- Los montajes de tipo bind tienen acceso de escritura a los archivos del anfitrión por defecto.

  Un efecto secundario de usar montajes de tipo bind es que puedes cambiar el sistema de archivos del anfitrión a través de procesos que se ejecutan en un contenedor, incluyendo la creación, modificación o eliminación de archivos o directorios importantes del sistema. Esta capacidad puede tener implicaciones de seguridad. Por ejemplo, puede afectar a los procesos que no son de Docker en el sistema anfitrión.

  Puedes utilizar la opción `readonly` o `ro` para evitar que el contenedor escriba en el montaje.

- Los montajes de tipo bind se crean en el anfitrión del demonio de Docker, no en el cliente.

  Si estás utilizando un demonio de Docker remoto, no puedes crear un montaje de tipo bind para acceder a los archivos de la máquina cliente en un contenedor.

  En el caso de Docker Desktop, el demonio se ejecuta dentro de una máquina virtual Linux, no directamente en el anfitrión nativo. Docker Desktop cuenta con mecanismos integrados que gestionan los montajes de tipo bind de forma transparente, permitiéndote compartir rutas del sistema de archivos del anfitrión nativo con contenedores que se ejecutan en la máquina virtual.

- Los contenedores con montajes de tipo bind están fuertemente vinculados al anfitrión.

  Los montajes de tipo bind dependen de que el sistema de archivos de la máquina anfitriona tenga disponible una estructura de directorios específica. Esta dependencia significa que los contenedores con montajes de tipo bind pueden fallar si se ejecutan en un anfitrión diferente que no disponga de la misma estructura de directorios.

## Sintaxis

Para crear un montaje de tipo bind, puedes utilizar la bandera `--mount` o `--volume`.

```console
$ docker run --mount type=bind,src=<host-path>,dst=<container-path>
```

```console
$ docker run --volume <host-path>:<container-path>
```

En general, se prefiere `--mount`. La principal diferencia es que la bandera `--mount` es más explícita y admite todas las opciones disponibles.

Si utilizas `--volume` para montar un archivo o directorio que aún no existe en el anfitrión de Docker, Docker crea automáticamente el directorio en el anfitrión por ti. Siempre se crea como un directorio.

Por defecto, `--mount` no crea automáticamente un directorio si la ruta de montaje especificada no existe en el anfitrión. En su lugar, produce un error:

```console
$ docker run --mount type=bind,src=/dev/noexist,dst=/mnt/foo alpine
docker: Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /dev/noexist.
```

Puedes utilizar la opción `bind-create-src` para crear automáticamente el directorio de origen en el anfitrión si no existe:

```console
$ docker run --mount type=bind,src=/home/user/mydir,dst=/mnt/foo,bind-create-src alpine
```

### Opciones para --mount

La bandera `--mount` consta de múltiples pares clave-valor, separados por comas, cada uno de los cuales consiste en una tupla `<key>=<value>`. El orden de las claves no es relevante.

```console
$ docker run --mount type=bind,src=<host-path>,dst=<container-path>[,<key>=<value>...]
```

Las opciones válidas para `--mount type=bind` incluyen:

| Opción | Descripción |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `source`, `src`                | La ubicación del archivo o directorio en el anfitrión. Puede ser una ruta absoluta o relativa.                                                                        |
| `destination`, `dst`, `target` | La ruta donde se monta el archivo o directorio en el contenedor. Debe ser una ruta absoluta.                                                                         |
| `readonly`, `ro`               | Si está presente, hace que el montaje de tipo bind se [monte en el contenedor como de solo lectura](#use-a-read-only-bind-mount).                                                     |
| `bind-propagation`             | Si está presente, cambia la [propagación del montaje (bind propagation)](#configure-bind-propagation).                                                                                            |
| `bind-create-src`              | Crea automáticamente el directorio de origen en el anfitrión si no existe. Por defecto, `--mount` produce un error si la ruta de origen no existe en el demonio. |

```console {title="Example"}
$ docker run --mount type=bind,src=.,dst=/project,ro,bind-propagation=rshared
```

### Opciones para --volume

La bandera `--volume` o `-v` consta de tres campos, separados por caracteres de dos puntos (`:`). Los campos deben estar en el orden correcto.

```console
$ docker run -v <host-path>:<container-path>[:opts]
```

El primer campo es la ruta en el anfitrión para realizar el montaje de tipo bind en el contenedor. El segundo campo es la ruta donde se monta el archivo o directorio en el contenedor.

El tercer campo es opcional y consiste en una lista de opciones separadas por comas. Las opciones válidas para `--volume` con un montaje de tipo bind incluyen:

| Opción | Descripción |
| -------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `readonly`, `ro`     | Si está presente, hace que el montaje de tipo bind se [monte en el contenedor como de solo lectura](#use-a-read-only-bind-mount).    |
| `z`, `Z`             | Configura el etiquetado de SELinux. Consulta [Configurar la etiqueta de SELinux](#configure-the-selinux-label)                       |
| `rprivate` (default) | Establece la propagación del montaje en `rprivate` para este montaje. Consulta [Configurar la propagación del montaje](#configure-bind-propagation). |
| `private`            | Establece la propagación del montaje en `private` para este montaje. Consulta [Configurar la propagación del montaje](#configure-bind-propagation).  |
| `rshared`            | Establece la propagación del montaje en `rshared` para este montaje. Consulta [Configurar la propagación del montaje](#configure-bind-propagation).  |
| `shared`             | Establece la propagación del montaje en `shared` para este montaje. Consulta [Configurar la propagación del montaje](#configure-bind-propagation).   |
| `rslave`             | Establece la propagación del montaje en `rslave` para este montaje. Consulta [Configurar la propagación del montaje](#configure-bind-propagation).   |
| `slave`              | Establece la propagación del montaje en `slave` para este montaje. Consulta [Configurar la propagación del montaje](#configure-bind-propagation).    |

```console {title="Example"}
$ docker run -v .:/project:ro,rshared
```

## Iniciar un contenedor con un montaje de tipo bind

Considera un caso en el que tienes un directorio `source` y que cuando compilas el código fuente, los artefactos se guardan en otro directorio, `source/target/`. Quieres que los artefactos estén disponibles para el contenedor en `/app/` y quieres que el contenedor tenga acceso a una nueva compilación cada vez que compiles el código fuente en tu anfitrión de desarrollo. Utiliza el siguiente comando para montar el directorio `target/` en tu contenedor en `/app/`. Ejecuta el comando desde el directorio `source`. El subcomando `$(pwd)` se expande al directorio de trabajo actual en anfitriones Linux o macOS. Si estás en Windows, consulta también las [Conversiones de rutas en Windows](/desktop/troubleshoot-and-support/troubleshoot/topics/).

Los siguientes ejemplos de `--mount` y `-v` producen el mismo resultado. No puedes ejecutarlos ambos a menos que elimines el contenedor `devtest` después de ejecutar el primero.

**`--mount`**



```console
$ docker run -d \
  -it \
  --name devtest \
  --mount type=bind,source="$(pwd)"/target,target=/app \
  nginx:latest
```

**`-v`**



```console
$ docker run -d \
  -it \
  --name devtest \
  -v "$(pwd)"/target:/app \
  nginx:latest
```



Utiliza `docker inspect devtest` para verificar que el montaje de tipo bind se haya creado correctamente. Busca la sección `Mounts`:

```json
"Mounts": [
    {
        "Type": "bind",
        "Source": "/tmp/source/target",
        "Destination": "/app",
        "Mode": "",
        "RW": true,
        "Propagation": "rprivate"
    }
],
```

Esto muestra que el montaje es de tipo `bind`, muestra el origen y destino correctos, muestra que el montaje es de lectura-escritura y que la propagación está configurada en `rprivate`.

Detén y elimina el contenedor:

```console
$ docker container rm -fv devtest
```

### Montar en un directorio no vacío en el contenedor

Si montas un directorio en un directorio no vacío del contenedor, el contenido existente de ese directorio quedará oculto por el montaje de tipo bind. Esto puede ser beneficioso, por ejemplo, cuando quieres probar una nueva versión de tu aplicación sin necesidad de compilar una nueva imagen. Sin embargo, también puede ser sorprendente y este comportamiento difiere del de los [volúmenes](/engine/storage/bind-mounts/volumes/).

Este ejemplo se ha forzado para ser extremo, pero reemplaza el contenido del directorio `/usr/` del contenedor con el directorio `/tmp/` de la máquina anfitriona. En la mayoría de los casos, esto resultaría en un contenedor que no funciona.

Los ejemplos de `--mount` y `-v` tienen el mismo resultado final.

**`--mount`**



```console
$ docker run -d \
  -it \
  --name broken-container \
  --mount type=bind,source=/tmp,target=/usr \
  nginx:latest

docker: Error response from daemon: oci runtime error: container_linux.go:262:
starting container process caused "exec: \"nginx\": executable file not found in $PATH".
```

**`-v`**



```console
$ docker run -d \
  -it \
  --name broken-container \
  -v /tmp:/usr \
  nginx:latest

docker: Error response from daemon: oci runtime error: container_linux.go:262:
starting container process caused "exec: \"nginx\": executable file not found in $PATH".
```



El contenedor se crea pero no se inicia. Elimínalo:

```console
$ docker container rm broken-container
```

## Usar un montaje de tipo bind de solo lectura

Para algunas aplicaciones de desarrollo, el contenedor necesita escribir en el montaje de tipo bind, de modo que los cambios se propaguen de vuelta al anfitrión de Docker. En otras ocasiones, el contenedor solo necesita acceso de lectura.

Este ejemplo modifica el anterior, pero monta el directorio como un montaje de tipo bind de solo lectura, añadiendo `ro` a la lista de opciones (vacía por defecto), después del punto de montaje dentro del contenedor. Si hay varias opciones presentes, sepáralas por comas.

Los ejemplos de `--mount` y `-v` tienen el mismo resultado.

**`--mount`**



```console
$ docker run -d \
  -it \
  --name devtest \
  --mount type=bind,source="$(pwd)"/target,target=/app,readonly \
  nginx:latest
```

**`-v`**



```console
$ docker run -d \
  -it \
  --name devtest \
  -v "$(pwd)"/target:/app:ro \
  nginx:latest
```



Utiliza `docker inspect devtest` para verificar que el montaje de tipo bind se haya creado correctamente. Busca la sección `Mounts`:

```json
"Mounts": [
    {
        "Type": "bind",
        "Source": "/tmp/source/target",
        "Destination": "/app",
        "Mode": "ro",
        "RW": false,
        "Propagation": "rprivate"
    }
],
```

Detén y elimina el contenedor:

```console
$ docker container rm -fv devtest
```

## Montajes recursivos

Cuando montas una ruta que a su vez contiene montajes, esos submontajes también se incluyen en el montaje de tipo bind por defecto. Este comportamiento es configurable mediante la opción `bind-recursive` para `--mount`. Esta opción solo es compatible con la bandera `--mount`, no con `-v` ni `--volume`.

Si el montaje de tipo bind es de solo lectura, Docker Engine realiza un intento de mejor esfuerzo para que los submontajes también sean de solo lectura. Esto se denomina montajes de solo lectura recursivos. Los montajes de solo lectura recursivos requieren la versión 5.12 o posterior del kernel de Linux. Si ejecutas una versión del kernel anterior, los submontajes se montan automáticamente como lectura-escritura por defecto. Intentar configurar los submontajes como de solo lectura en una versión del kernel anterior a la 5.12, utilizando la opción `bind-recursive=readonly`, produce un error.

Los valores admitidos para la opción `bind-recursive` son:

| Valor | Descripción |
| :------------------ | :---------------------------------------------------------------------------------------------------------------- |
| `enabled` (default) | Los montajes de solo lectura se hacen recursivamente de solo lectura si el kernel es v5.12 o posterior. De lo contrario, los submontajes son de lectura-escritura. |
| `disabled`          | Los submontajes se ignoran (no se incluyen en el montaje de tipo bind).                                                           |
| `writable`          | Los submontajes son de lectura-escritura.                                                                                         |
| `readonly`          | Los submontajes son de solo lectura. Requiere la versión del kernel v5.12 o posterior.                                                          |

## Configurar la propagación del montaje

La propagación del montaje (bind propagation) se establece de forma predeterminada en `rprivate` tanto para montajes de tipo bind como para volúmenes. Solo se puede configurar para montajes de tipo bind y únicamente en máquinas anfitrionas Linux. La propagación del montaje es un tema avanzado y muchos usuarios nunca necesitarán configurarla.

La propagación del montaje se refiere a si los montajes creados dentro de un montaje de tipo bind determinado pueden propagarse a las réplicas de ese montaje. Considera un punto de montaje `/mnt`, que también está montado en `/tmp`. Los ajustes de propagación controlan si un montaje en `/tmp/a` también estaría disponible en `/mnt/a`. Cada configuración de propagación tiene una contraparte recursiva. En el caso de la recursividad, considera que `/tmp/a` también está montado como `/foo`. Los ajustes de propagación controlan si existiría `/mnt/a` y/o `/tmp/a`.

> [!NOTE]
> La propagación de montaje no funciona con Docker Desktop.

| Configuración de propagación | Descripción |
| :------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `shared`            | Los submontajes del montaje original se exponen a los montajes réplica, y los submontajes de los montajes réplica también se propagan al montaje original. |
| `slave`             | Similar a un montaje compartido, pero solo en una dirección. Si el montaje original expone un submontaje, el montaje réplica puede verlo. Sin embargo, si el montaje réplica expone un submontaje, el montaje original no puede verlo. |
| `private`           | El montaje es privado. Los submontajes dentro de él no se exponen a los montajes réplica, y los submontajes de los montajes réplica no se exponen al montaje original. |
| `rshared`           | Lo mismo que compartido, pero la propagación también se extiende hacia y desde los puntos de montaje anidados dentro de cualquiera de los puntos de montaje originales o réplicas. |
| `rslave`            | Lo mismo que esclavo, pero la propagación también se extiende hacia y desde los puntos de montaje anidados dentro de cualquiera de los puntos de montaje originales o réplicas. |
| `rprivate`          | El predeterminado. Lo mismo que privado, lo que significa que ningún punto de montaje dentro de los puntos de montaje originales o réplicas se propaga en ninguna dirección. |

Antes de poder configurar la propagación del montaje en un punto de montaje, el sistema de archivos del anfitrión ya debe admitir la propagación del montaje.

Para obtener más información sobre la propagación del montaje, consulta la [documentación del kernel de Linux para subárboles compartidos (shared subtree)](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt).

El siguiente ejemplo monta el directorio `target/` en el contenedor dos veces, y el segundo montaje establece tanto la opción `ro` como la opción de propagación de montaje `rslave`.

Los ejemplos de `--mount` y `-v` tienen el mismo resultado.

**`--mount`**



```console
$ docker run -d \
  -it \
  --name devtest \
  --mount type=bind,source="$(pwd)"/target,target=/app \
  --mount type=bind,source="$(pwd)"/target,target=/app2,readonly,bind-propagation=rslave \
  nginx:latest
```

**`-v`**



```console
$ docker run -d \
  -it \
  --name devtest \
  -v "$(pwd)"/target:/app \
  -v "$(pwd)"/target:/app2:ro,rslave \
  nginx:latest
```



Ahora, si creas `/app/foo/`, `/app2/foo/` también existirá.

## Configurar la etiqueta de SELinux

Si utilizas SELinux, puedes añadir las opciones `z` o `Z` para modificar la etiqueta SELinux del archivo o directorio del anfitrión que se está montando en el contenedor. Esto afecta al propio archivo o directorio de la máquina anfitriona y puede tener consecuencias fuera del ámbito de Docker.

- La opción `z` indica que el contenido del montaje de tipo bind se comparte entre múltiples contenedores.
- La opción `Z` indica que el contenido del montaje de tipo bind es privado y no compartido.

Utiliza estas opciones con extrema precaución. Realizar un montaje de tipo bind de un directorio del sistema como `/home` o `/usr` con la opción `Z` dejará inoperable tu máquina anfitriona y es posible que debas volver a etiquetar los archivos de la máquina anfitriona a mano.

> [!IMPORTANT]
>
> Al utilizar montajes de tipo bind con servicios, las etiquetas SELinux (`:Z` y `:z`), así como `:ro` se ignoran. Consulta [moby/moby #32579](https://github.com/moby/moby/issues/32579) para obtener más detalles.

Este ejemplo establece la opción `z` para especificar que múltiples contenedores pueden compartir el contenido del montaje de tipo bind:

No es posible modificar la etiqueta de SELinux utilizando la bandera `--mount`.

```console
$ docker run -d \
  -it \
  --name devtest \
  -v "$(pwd)"/target:/app:z \
  nginx:latest
```

## Usar un montaje de tipo bind con Docker Compose

Un único servicio de Docker Compose con un montaje de tipo bind se ve así:

```yaml
services:
  frontend:
    image: node:lts
    volumes:
      - type: bind
        source: ./static
        target: /opt/app/static
volumes:
  myapp:
```

Para obtener más información sobre el uso de volúmenes de tipo `bind` con Compose, consulta la [referencia de Compose sobre el elemento de nivel superior de volúmenes](/reference/compose-file/volumes/) y la [referencia de Compose sobre el atributo de volumen](/reference/compose-file/services/#volumes).

## Siguientes pasos

- Aprende sobre los [volúmenes](/engine/storage/volumes/).
- Aprende sobre los [montajes tmpfs](/engine/storage/tmpfs/).
- Aprende sobre los [controladores de almacenamiento](/engine/storage/drivers/).

