# Comprender y gestionar los Docker volumes

[Docker](https://www.ionos.com/es-us/digitalguide/servidores/know-how/que-es-docker/) es un software de código abierto para crear y gestionar contenedores. Con un Docker volume (también volumen), es posible intercambiar datos entre contenedores o guardar los datos de un Docker container de manera permanente.

## Requisitos

- Tener Docker instalado (puedes usar el [tutorial de Docker](https://www.ionos.com/es-us/digitalguide/servidores/configuracion/tutorial-docker-instalacion-y-primeros-pasos/) de la Digital Guide para ello) y en funcionamiento.
- Tener conocimientos básicos del funcionamiento y los [comandos de Docker](https://www.ionos.com/es-us/digitalguide/servidores/know-how/comandos-de-docker/).

## El sistema de archivos de Docker

Para entender los Docker volumes, es importante tener primero una visión general de cómo funciona el sistema de archivos de Docker.

Una Docker Image consta de varias capas de solo lectura. Cuando se inicia una imagen desde un contenedor, Docker añade una nueva capa editable en la parte superior del sistema. El sistema de archivos de Docker se llama **Union File System** (UnionFS).

Cada vez que se modifica un archivo, Docker crea una copia de este mismo incluyendo las capas de solo lectura hasta la capa más alta, la que sí se puede editar. De esta manera queda una copia del archivo original (de solo lectura) sin cambios.

Si se elimina un contenedor, se pierde la capa más alta, la que tiene permisos de escritura. Esto significa que todos los cambios realizados después de iniciar el contenedor se pierden.

## Remedios con Docker volumes

Un volumen de contenedor permite conservar los datos, aunque se elimine el Docker container. Los volúmenes también permiten un intercambio práctico de datos entre el host y el container.

Crear un volumen de Docker es una buena solución para poder:

- Transferir datos a un contenedor de Docker
- Guardar los datos de un contenedor de Docker
- Intercambiar datos entre contenedores de Docker

Los Docker volumes existen fuera del Union File System con su acceso de solo lectura y la capa de escritura. El volumen es una carpeta compartida entre el contenedor y el ordenador host. Los volúmenes también pueden ser compartidos entre contenedores.

## La base de los Docker volumes

Un container volume “vive” fuera del propio contenedor en el ordenador host. Fuera del container, el volumen se comporta como una carpeta en la que se pueden almacenar datos y desde la que se pueden recuperar datos. Se trata del **mount point** de un directorio en el host.

Hay varias formas de crear y gestionar Docker volumes. Cada método tiene sus propias ventajas e inconvenientes.

## Uso del comando “volume create” de Docker

A partir de la versión 1.9.0, que salió el 3 de noviembre de 2015, los Docker volumes se pueden crear y gestionar fácilmente con el comando *docker volume* integrado.

### Paso 1. Crear y nombrar el volumen

El comando *docker volume create* crea un volumen identificado con un nombre. El nombre te permite encontrar fácilmente los Docker volumes y poder asignarlos a los contenedores específicos.

Para crear un volume, utiliza el siguiente comando:

```none
sudo docker volume create - - name [volume name]
```

### Paso 2. Usar el volume en un contenedor de Docker

Para crear un container que utilice un volume creado con *docker volume create*, añade el siguiente parámetro al comando *docker run*:

```none
-v [volume name]:[container directory]
```

Para, por ejemplo, ejecutar un contenedor desde una imagen de CentOS llamada *my-volume-test* y asignar el **data-volume** al directorio o el *data* al container, el comando es el siguiente:

```none
sudo docker run -it --name my-volume-test -v data-volume:/data centos /bin/bash
```

### Paso 3. Listar los volumes

Para listar los Docker volumes que hay en el sistema, utiliza el siguiente comando:

```none
sudo docker volume ls
```

Este comando emite una lista de todos los Docker volumes creados en el host.

### Paso 4. Inspeccionar el volume

Para inspeccionar un volume concreto, utiliza el siguiente comando:

```none
sudo docker volume inspect [volume name]
```

Este comando te proporciona información sobre el volume que hayas indicado, incluyendo el mount point y el directorio en el sistema host a través del cual se puede acceder al Docker volume.

Para, por ejemplo, obtener más información sobre el volume llamado “data” que hemos creado anteriormente, el comando a utilizar es el siguiente:

```none
sudo docker volume inspect data-volume
```

### Paso 5. Eliminar el volume

Para eliminar un volume creado de esta manera, utiliza el siguiente comando:

```none
sudo docker volume rm [volume name]
```

No se puede eliminar un volume si está siendo utilizado por un contenedor existente. **Antes de poder eliminar el volume**, debes detener y eliminar el contenedor de Docker con los siguientes comandos:

```none
sudo docker stop [container name or ID]
sudo docker rm [container name or ID]
```

Para, por ejemplo, eliminar el volume llamado “Data”, primero debes detener y eliminar el container que lo utiliza con my-volume-test:

```none
sudo docker stop my-volume-test
sudo docker rm my-volume-test
```

El data-volume puede ser **borrado** con el siguiente comando:

```none
sudo docker volume rm data-volume
```

## Crear un Docker volume e indicar el directorio del host deseado

Si quieres hacer que un directorio concreto del ordenador host se monte como Docker volume en el contenedor, añade el siguiente parámetro a tu comando *docker run*:

```none
-v [host directory]:[container directory]
```

Para, por ejemplo, crear un nuevo contenedor y asignar la carpeta /webfiles del host a la carpeta /var/www/html del contenedor, el comando es:

```none
sudo docker run -it -v /webfiles:/var/www/html centos /bin/bash
```

Prueba esto creando un directorio que luego puedas usar como Docker volume. Para ello ejecuta el siguiente comando:

```none
sudo mkdir /hostvolume
```

Añade un pequeño archivo de prueba a este directorio con el siguiente comando:

```none
sudo echo "Hello World" >> /hostvolume/host-hello.txt
```

A continuación, crea un contenedor llamado *my-directory-test* y asigna la carpeta */hostvolume* del host a la carpeta */containervolume* del contenedor con el siguiente comando:

```none
sudo docker run -it --name my-directory-test -v /hostvolume:/containervolume centos /bin/bash
```

Una vez te encuentres en la línea de comandos del nuevo contenedor, puedes mostrar una lista de los archivos del volumen compartido con el siguiente comando:

```none
ls /containervolume
```

Verás el archivo ***host-hello.txt*** que hemos creado en el ordenador host.

Esto también funciona en sentido contrario. Los archivos que pongas en este directorio se mostrarán también en el host. Puedes probarlo desde el contenedor añadiendo otro archivo al volumen compartido con el siguiente comando:

```none
echo "Hello from the container." >> /containervolume/container-hello.txt
```

Sal del container con **\[Ctrl\] + \[P\]** y **\[Ctrl\] + \[Q\]** y vuelve a la línea de comandos del ordenador host. Allí, muestra una lista de los archivos en el volumen compartido con este comando:

```none
sudo ls /hostvolume
```

Puedes ver los **dos archivos de prueba** que hemos creado desde el host y el contenedor.

## Crear un Docker volume con un archivo Docker

Utiliza el siguiente comando en un archivo Docker para crear un **espacio de almacenamiento compartido** en el contenedor:

```none
VOLUME [volume path]
```

Para, por ejemplo, crear un volume */myvolume* en el contenedor lanzado desde un archivo Docker, el comando es:

```none
VOLUME /myvolume
```

Para poder probarlo, primero crea un archivo llamado *Dockerfile* con el siguiente comando:

```none
sudo nano Dockerfile
```

Introduce el siguiente contenido en el archivo:

```none
# The source image to start with
FROM centos
# Create a volume
VOLUME /dockerfilevolume
```

Guarda y cierra el archivo.

Luego, crea una imagen llamada *dockerfile-volumetest* a partir del archivo Docker que acabas de redactar. Crea la imagen con el siguiente comando:

```none
sudo docker build -t dockerfile-volumetest
```

A continuación, crea un contenedor llamado *my-dockerfile-test* desde la imagen que acabas de crear, para ello usa el siguiente comando:

```none
sudo docker run --name my-dockerfile-test -it dockerfile-volumetest /bin/bash
```

Una vez estés en la línea de comandos del nuevo contenedor, utiliza este comando para crear un pequeño archivo de prueba en el volumen compartido:

```none
echo "Hello World" >> /dockerfilevolume/dockerfile-container-hello.txt
```

Sal del contenedor con **\[Ctrl\] + \[P\]** y **\[Ctrl\] + \[Q\]** y vuelve a la línea de comandos del ordenador host.

A continuación, busca el **mount point**. Para ello, utiliza el siguiente comando:

```none
sudo docker inspect my-dockerfile-test
```

Busca en el resultado del comando una sección titulada **“Mounts”** que se parezca a:

[![Imagen: Mount Point del archivo Docker en el terminal](https://www.ionos.com/es-us/digitalguide/fileadmin/_processed_/b/2/csm_find-the-mount-point_55e9808df2.webp "Mount Point del archivo Docker en el terminal")](https://www.ionos.com/es-us/digitalguide/fileadmin/DigitalGuide/Screenshots_2020/find-the-mount-point.jpg) En el terminal, bajo el apartado denominado “Mounts”, puedes comprobar fácilmente qué archivos has creado en tu Docker container. Estos van a aparecer en el subapartado “Source”.       *Fuente/Source* es el directorio en el ordenador host.

*Destino/Destination* es la carpeta del container.

Comprueba el directorio de origen en tu ordenador host. Para nuestro ejemplo, el comando es el siguiente:

```none
sudo ls  /var/lib/docker/volumes/30275034a424251a771c91b65ba44261a27f91e3f6af31097b5226b1f46bfe20/_data/test
```

Aquí encontrarás el archivo *dockerfile-container-hello.txt* que has creado en el container.

## Resumen de las ventajas y desventajas de los distintos métodos

<table>
  <tbody>
    <tr>
      <td><strong>Método</strong></td>
      <td><strong>Ventajas</strong></td>
      <td><strong>Desventajas</strong></td>
    </tr>
    <tr>
      <td>Comando “volume create”</td>
      <td>Manejo rápido y sencillo</td>
      <td>El volume del host se crea automáticamente, pero es difícil de encontrar</td>
    </tr>
    <tr>
      <td>Crear un Docker volume con directorio en el host</td>
      <td>El container se puede asignar a una carpeta específica del host</td>
      <td>No es posible dar nombre al volume ni automatizarlo mediante [Dockerfile](https://www.ionos.com/es-us/digitalguide/servidores/know-how/dockerfile/)</td>
    </tr>
    <tr>
      <td>Crear un volumen con un archivo Docker</td>
      <td>Automatización del proceso</td>
      <td>No se asigna una carpeta host ni se puede dar nombre a el volume</td>
    </tr>
  </tbody>
</table>

## Compartir Docker volumes entre contenedores

Hay muchas situaciones en las que tiene sentido compartir un Docker volume entre containers, y hay varias maneras de compartirlo.

### Compartir un volume del host

Cuando creas un volume en el ordenador host, este puede ser utilizado por varios contenedores diferentes al mismo tiempo. Esto te permite intercambiar datos entre los contenedores y el host.

Para este ejemplo, crea un directorio en el host y utiliza este directorio como un volume compartido entre dos contenedores.

Comienza utilizando el siguiente comando para **crear un directorio** que puedas utilizar como Docker volume:

```none
sudo mkdir /webdata
```

Crea un pequeño **archivo de prueba** en este directorio con el siguiente comando:

```none
sudo echo "Hello from the host." >> /webdata/host-hello.txt
```

A continuación, crea un **container** llamado *sql-database* desde la imagen oficial de PostgreSQL y asigna */webdata* del host con el comando */data* del contenedor:

```none
sudo docker run -it --name sql-database -v /webdata:/data postgres /bin/bash
```

Una vez estés en la línea de comandos del nuevo contenedor, comprueba con el siguiente comando que el volume compartido está configurado correctamente:

```none
ls /data
```

Verás el archivo *host-hello.txt* que hemos creado en el host. Añade un archivo al volume compartido con el siguiente comando:

```none
echo "Hello from the sql-database container." >> /data/sql-hello.txt
```

Sal del container con **\[Ctrl\] + \[P\]** y **\[Ctrl\] + \[Q\]** y vuelve a la línea de comandos del ordenador host.

Ahora crea un container llamado “**Webapp**” desde la imagen oficial de PHP+Apache y asigna */webdata* del host a */var/www/html* del container.

```none
sudo docker run -it --name webapp -v /webdata:/var/www/html php:5.6-apache /bin/bash
```

Una vez estés en la línea de comandos del nuevo contenedor, utiliza el siguiente comando para comprobar si el volume compartido se ha configurado correctamente:

```none
ls /var/www/html
```

Verás tanto el archivo *host-hello.txt* que creaste en el host como el archivo *sql-hello.txt* que creaste en el contenedor de la base de datos SQL.

Ahora añade un archivo del último contenedor que has creado:

```none
echo "Hello from the webapp container." >> /var/www/html/webapp-hello.txt
```

Sal del contenedor con **\[Ctrl\] + \[P\]** y **\[Ctrl\] + \[Q\]** y vuelve a la línea de comandos del ordenador host. En el host, puedes ver los tres archivos con el siguiente comando:

```none
sudo ls /webdata
```

Dado que los dos contenedores comparten ahora un directorio que “vive” en el host, los **datos pueden transferirse instantáneamente entre las tres ubicaciones** con simplemente ser movidos a este directorio.

### Configurar un contenedor como volumen de datos compartidos

También puedes configurar un contenedor independiente como volumen de datos compartido.

Para ello, primero debes crear el contenedor de datos. A continuación, a la hora de crear el contenedor que utilizará este contenedor de datos, añade el siguiente parámetro al comando *docker run*:

```none
--volumes-from [name or ID of data container]
```

---

### Nota

Esto funciona independientemente de si el contenedor de destino se está ejecutando o no. Los Docker volumes nunca se borran y permanecen incluso después de que el contenedor deje de ejecutarse.

---

Para este ejemplo, crea un contenedor de datos llamado “Data-Storage” que sirve como volumen de datos. Además, se crean otros dos contenedores que comparten el contenedor de datos como espacio de almacenamiento.

Lo primero es iniciar el **contenedor de almacenamiento de datos** desde la imagen oficial de CentOS 7:

```none
sudo docker run -it -v /shared-data --name data-storage centos /bin/bash
```

A continuación, añade un pequeño archivo de prueba a la carpeta */shared-data*:

```none
echo "Hello from the data-storage container." >> /shared-data/data-storage-hello.txt
```

Sal del contenedor con **\[Ctrl\] + \[P\]** y **\[Ctrl\] + \[Q\]** y vuelve a la línea de comandos del ordenador host.

Ahora inicia el **contenedor** **de aplicaciones** desde la imagen oficial de Python y monta el **contenedor** **de almacenamiento de datos** como un volume:

```none
sudo docker run -it --name app --volumes-from data-storage python /bin/bash
```

Muestra una lista de los archivos en el volume compartido con el siguiente comando:

```none
ls /shared-data
```

Como puedes ver, la carpeta */shared-data* ha sido montada en el contenedor de almacenamiento de datos y contiene el archivo *data-storage-hello.txt*.

Ahora añade un archivo del contenedor de aplicaciones:

```none
echo "Hello from the app container." >> /shared-data/app-hello.txt
```

Sal del contenedor con **\[Ctrl\] + \[P\]** y **\[Ctrl\] + \[Q\]** y vuelve a la línea de comandos del ordenador host.

Por último, inicia el **contenedor** **web** desde la imagen oficial de Apache y monta el **contenedor** **de almacenamiento de datos** como un volume:

```none
sudo docker run -it --name web --volumes-from data-storage httpd /bin/bash
```

Muestra una lista de los archivos en el volumen compartido con el siguiente comando:

```none
ls /shared-data
```

Así podrás ver los archivos que hemos creado en los **contenedores** **de almacenamiento y de** **aplicaciones**.

## Montar un volume con protección contra la escritura

Hasta ahora, en este artículo hemos creado y montado volumes con acceso de lectura y de escritura.

Si quieres limitar el acceso de un contenedor a un volume permitiéndole **únicamente** **acceso de lectura** al volume, simplemente añade *:ro* de “read-only” al parámetro -v tras el directorio del container:

```none
docker run -v /directory:/path:ro
```

Esto puede ser útil para, por ejemplo, fines de seguridad. Además, si quieres asegurarte de que los datos de un determinado volume están protegidos contra la sobreescritura o el borrado accidental por parte de otro Docker container, vale la pena considerar la opción de dar acceso de read-only (solo lectura).

Crea, por ejemplo, un volume en el host llamado *limited-access* con el siguiente comando:

```none
sudo docker volume create --name limited-access
```

A continuación, crea un contenedor llamado *allowed-to-write* de la imagen de CentOS y asigna el volume llamado **“limited-access”** como un volume normal (de lectura y escritura):

```none
sudo docker run -it --name allowed-to-write -v limited-access:/data centos /bin/bash
```

Una vez estés en la línea de comandos de este contenedor, crea un **archivo de prueba** con el siguiente comando:

```none
echo "Hello from the container that is allowed to write." >> /data/hello.txt
```

Sal del contenedor con **\[Ctrl\] + \[P\]** y **\[Ctrl\] + \[Q\]** y vuelve a la línea de comandos del ordenador host.

A continuación, crea un container desde la imagen de CentOS llamado *not-allowed-to-write* y asígnale el **volume** llamado **limited-access** como **volume** de **read-only** (solo lectura):

```none
sudo docker run -it --name not-allowed-to-write -v limited-access:/data:ro centos /bin/bash
```

Si intentas crear un archivo de prueba en el volume compartido con un comando como este:

```none
echo "Hello from the container that is not allowed to write." >> /data/no-access.txt
```

obtendrás un error explicando que este contenedor no tiene derecho de escritura en este directorio.

```none
bash: /data/no-access.txt: Read-only file system
```


This is a markdown version of: [https://www.ionos.com/es-us/digitalguide/servidores/know-how/docker-container-volumes/](https://www.ionos.com/es-us/digitalguide/servidores/know-how/docker-container-volumes/) for AI/LLM consumption.