# Comprendere e gestire i volumi dei container Docker

[Docker](https://www.ionos.it/digitalguide/server/know-how/cose-docker/) è un software open source per creare e gestire container. Un volume di Docker permette di scambiare dati tra questi container o rendere persistenti dati provenienti da un container Docker.

## Requisiti

- [Docker è installato](https://www.ionos.it/digitalguide/server/configurazione/tutorial-di-docker/) e funziona correttamente.
- Disponete delle conoscenze basilari delle funzionalità e dei [comandi di Docker](https://www.ionos.it/digitalguide/server/know-how/comandi-docker/).

## Il file system di Docker

Per comprendere i volumi di Docker, è fondamentale avere prima di tutto una panoramica sul funzionamento del file system di Docker.

Un’immagine Docker è composta da più livelli protetti da scrittura. Quando si crea un container da un’immagine, Docker inserisce un nuovo livello descrivibile in cima al sistema. Con Docker questo processo prende il nome di **union file system**.

Ogni volta che si modifica un file, Docker ne crea una copia dai livelli protetti da scrittura sul livello descrivibile situato in cima. In questo modo, il file originario (protetto da scrittura) resta invariato.

Cancellando il container, si perde il livello descrivibile più in alto. Ciò significa che tutte le modifiche apportate dopo l’avvio del container non saranno più disponibili.

## Come correggere un problema con i volumi di Docker

Un volume di container permette di mantenere inalterati i file anche quando si eliminano i container Docker. I volumi rappresentano inoltre una possibilità pratica per scambiare dati tra l’host e il container.

Collegare un volume di un container Docker rappresenta una buona soluzione per eseguire le seguenti operazioni:

- Trasmettere dati in un container Docker
- Salvare dati da un container Docker
- Scambiare dati tra container Docker

I volumi di Docker esistono al di fuori dello union file system grazie all’accesso di sola lettura e al livello descrivibile. Il volume è una cartella condivisa tra il container e il computer host. È possibile anche condividere volumi tra container.

---

### Consiglio

Sul [server cloud di IONOS](https://www.ionos.it/cloud/cloud-server "Cloud Apps - IONOS") potete selezionare Docker come applicazione preinstallata sul cloud così potrete accedere alle vostre applicazioni dappertutto!

---

## Nozioni di base dei volumi di Docker

Un volume di un container “vive” al di fuori del container in questione sul computer host. Dal container il volume si comporta come una cartella in cui salvare file o da cui recuperare dati. Si tratta del cosiddetto **mount point (punto di montaggio)** in una directory dell’host.

Esistono diverse possibilità per creare e gestire volumi di Docker. Ciascun metodo presenta i suoi vantaggi e svantaggi.

## Utilizzo del comando “volume create” di Docker

Dalla versione 1.9.0 rilasciata il 3/11/2015, è possibile creare e gestire volumi di Docker in modo semplice grazie al comando integrato ***docker volume***.

### Primo passaggio: creare e denominare i volumi

Il comando ***docker volume create*** crea un volume denominato. Il nome vi permette di trovare in modo semplice il vostro volume di Docker e di assegnarlo ai container.

Per creare un volume utilizzate il comando:

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

### Secondo passaggio: utilizzare il volume in un container Docker

Per avviare un container che utilizza un volume che avete creato con ***docker volume create***, inserite al comando ***docker run*** il seguente argomento:

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

Ad esempio, per avviare un container dall’immagine **CentOS** chiamato ***my-volume-test*** e assegnare il **Data-Volume** nella directory */****data*** del container, il comando è il seguente:

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

### Terzo passaggio: lista dei volumi

Per visualizzare in una lista tutti i volumi di Docker, utilizzate il comando:

```none
sudo docker volume ls
```

Questo comando vi restituirà un elenco di tutti i volumi di Docker creati sull’host.

### Quarto passaggio: ispezionare i volumi

Per ispezionare un volume denominato, utilizzate il comando:

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

Questo comando vi fornisce informazioni sul volume, incluso il mount point e la directory sul sistema host con cui accedere al volume di Docker.

Per ricevere, ad esempio, maggiori informazioni sul volume denominato “**Data**” che abbiamo creato qui in alto, inserite il comando:

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

### Quinto passaggio: cancellare un volume

Per cancellare un volume creato con questa procedura, utilizzate il comando:

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

Non sarà possibile cancellare un volume se è utilizzato da un container disponibile. **Prima di poter cancellare il volume**, dovete interrompere e rimuovere il container Docker con i seguenti comandi:

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

Ad esempio, per eliminare il volume denominato “**Data**”, dovete prima di tutto interrompere e rimuovere il container che lo utilizza con ***my-volume-test***:

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

Il **volume di dati** può essere poi **eliminato** con il seguente comando:

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

## Creare un volume di Docker e indicare una directory sull’host

Se desiderate montare un file system di una directory precisa sul vostro computer host come volume di Docker, inserite al vostro comando *docker run* il seguente argomento:

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

Ad esempio, per avviare un nuovo container e assegnare la cartella */webfiles* sull’host alla cartella*/var/wwww/html* del container, il comando è:

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

Per fare un test, potete creare una directory che utilizzerete come volume di Docker. Per farlo, vi servirà il comando seguente:

```none
sudo mkdir /hostvolume
```

Inserite con questo comando un piccolo file di prova alla directory:

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

Successivamente avviate il container denominato *my-directory-test* e assegnate */hostvolume* dell’host a */containervolume* del container con il comando seguente:

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

Non appena vi troverete nel prompt dei comandi del nuovo container, elencate i file nel volume condiviso con il comando:

```none
ls /containervolume
```

Vedrete il file ***host-hello.txt*** che avete creato sull’host.

Questo procedimento funziona anche al contrario e cioè i file inseriti in questa directory sono mostrati sull’host. È possibile verificarlo dal container inserendo al volume condiviso un altro file con il comando seguente:

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

Abbandonate il container con **\[CTRL\] + \[P\]** e **\[CTRL\] + \[Q\]** per ritornare al prompt dei comandi del computer host. Qui potete visualizzare i file nel volume condiviso con il comando successivo:

```none
sudo ls /hostvolume
```

Vedrete **entrambi i file di prova** che avete creato dall’host e dal container.

## Creare un volume di Docker con un Dockerfile

Utilizzate il comando seguente in un Dockerfile per creare un **volume di archiviazione condiviso** in un container:

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

Per esempio, per creare un volume ***/myvolume*** nel container che deve essere avviato con un Dockerfile, utilizzate il comando:

```none
VOLUME /myvolume
```

Per fare una prova, create un file denominato ***Dockerfile*** con il comando:

```none
sudo nano Dockerfile
```

Inserite al file il seguente contenuto:

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

Salvate e chiudete il file.

Successivamente, da questo Dockerfile, create un’immagine denominata ***dockerfile-volumetest*** con il comando seguente:

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

Infine, avviate un container denominato ***my-dockerfile-test*** da questa immagine con il comando:

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

Non appena vi troverete nel prompt dei comandi del nuovo container, create un piccolo file di prova nel volume condiviso con questo comando:

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

Abbandonate il container con **\[CTRL\] + \[P\]** e **\[CTRL\] + \[Q\]** per ritornare al prompt dei comandi del computer host.

Come passaggio successivo cercate il **mount point** con il comando:

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

Scorrete tra i risultati fino a trovare una sezione denominata “**Mounts**” che dovrebbe apparire più o meno così:

[![Immagine: Il mount point del Dockerfile nel terminale](https://www.ionos.it/digitalguide/fileadmin/_processed_/b/2/csm_find-the-mount-point_55e9808df2.webp "Il mount point del Dockerfile nel terminale")](https://www.ionos.it/digitalguide/fileadmin/DigitalGuide/Screenshots_2020/find-the-mount-point.jpg) Nel terminale, alla voce “Mounts” potete verificare in modo semplice quali file avete creato sul vostro container Docker. Per farlo, basta consultare il punto “Source”.       ***Sorgente/Source*** è la directory sul computer host.

***Destinazione/Destination*** è la cartella sul container.

Controllate la cartella sorgente sul vostro computer host. Nell’esempio il comando è:

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

Qui trovate il file ***dockerfile-container-hello.txt*** che avete creato nel container.

## Panoramica dei vantaggi e svantaggi dei diversi metodi

<table>
  <tbody>
    <tr>
      <td><strong>Metodo</strong></td>
      <td><strong>Vantaggi</strong></td>
      <td><strong>Svantaggi</strong></td>
    </tr>
    <tr>
      <td>Comando “volume create”</td>
      <td>Gestione semplice e rapida</td>
      <td>Il volume sull’host è creato automaticamente ed è difficile da trovare</td>
    </tr>
    <tr>
      <td>Creare un volume di Docker con una directory sull’host</td>
      <td>Il container può essere assegnato a una cartella precisa dell’host</td>
      <td>Non è possibile denominare il volume o automatizzare attraverso il [Dockerfile](https://www.ionos.it/digitalguide/server/know-how/dockerfile/)</td>
    </tr>
    <tr>
      <td>Creazione di un Dockerfile</td>
      <td>Automatizzazione del processo</td>
      <td>Non è possibile assegnare una cartella dell’host o denominare il volume</td>
    </tr>
  </tbody>
</table>

<table>
  <thead>
    <tr>
      <th>Metodo</th>
      <th>Vantaggi</th>
      <th>Svantaggi</th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Comando “volume create”</td>
      <td>Gestione semplice e rapida</td>
      <td>Il volume sull’host è creato automaticamente ed è difficile da trovare</td>
      <td></td>
    </tr>
    <tr>
      <td>Creare un volume di Docker con una directory sull’host</td>
      <td>Il container può essere assegnato a una cartella precisa dell’host</td>
      <td>Non è possibile denominare il volume o automatizzare attraverso il ((Dockerfile</td>
      <td>server/knowhow/dockerfile/))</td>
    </tr>
    <tr>
      <td>Creazione di un Dockerfile</td>
      <td>Automatizzazione del processo</td>
      <td>Non è possibile assegnare una cartella dell’host o denominare il volume</td>
      <td></td>
    </tr>
  </tbody>
</table>

## Condivisione di volumi di Docker tra container

Ci sono situazioni in cui è utile condividere un volume di Docker tra container ed esistono diversi modi per farlo.

### Condividere un volume sull’host

Se create un volume sul computer host, potete utilizzarlo contemporaneamente su diversi container e scambiare file tra container e host.

Per questo esempio dovete creare una directory sull’host da utilizzare come volume condiviso tra due container.

Cominciate **creando una directory** da utilizzare come volume di Docker con il comando seguente:

```none
sudo mkdir /webdata
```

Inserite in questa directory un piccolo **file di prova** con questo comando:

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

Nel prossimo passaggio avviate un **container** con il nome ***sql-database*** dall’immagine ufficiale PostgreSQL e assegnate ***/webdata*** sull’host al container con il comando ***/data***:

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

Non appena vi troverete nel prompt dei comandi del nuovo container, verificate la corretta configurazione del volume condiviso con il comando:

```none
ls /data
```

Vedrete il file ***host-hello.txt*** che avete creato sull’host. Con il seguente comando inserite un file al volume condiviso:

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

Abbandonate il container con **\[CTRL\] + \[P\]** e **\[CTRL\] + \[Q\]** per ritornare al prompt dei comandi del computer host.

Avviate il container dal nome “**Webapp”** dall’immagine ufficiale PHP+Apache e assegnate ***/webdata*** sull’host al container ***/var/www/html***.

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

Non appena vi troverete nel prompt dei comandi del nuovo container, verificate la corretta configurazione del volume condiviso con il comando:

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

Vedrete sia il file ***host-hello.txt***, che avete creato sull’host, sia il file *sql-hello.txt*, che avete creato sul container **del database di SQL**.

Inserite adesso un file proveniente dal container appena creato:

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

Abbandonate il container con **\[CTRL\] + \[P\]** e **\[CTRL\] + \[Q\]** per ritornare al prompt dei comandi del computer host. Sull’host sarete in grado di visualizzare tutti e tre i file con il comando seguente:

```none
sudo ls /webdata
```

Poiché entrambi i container condividono una cartella che “vive” sull’host, è possibile **trasmettere immediatamente i file in tutte e tre le posizioni** trascinandoli semplicemente in questa cartella.

### Configurare un container come volume di dati condiviso

È anche possibile configurare un container separato come volume di dati condiviso.

Per farlo create un container di dati. Una volta creato il container che dovrà utilizzare il container di dati, inserite al comando ***docker run*** il seguente argomento:

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

---

### N.B.

Questo funziona indipendentemente dall’esecuzione o meno del container di destinazione. I volumi di Docker non sono cancellati e restano inalterati anche dopo l’interruzione del container.

---

Per questo esempio create un container di dati denominato “Data-Storage” che funge da volume di dati. In aggiunta, saranno utilizzati altri due container che condividono il container di dati come volume di archiviazione.

Avviate adesso il **container Data-Storage** dall’immagine ufficiale CentOS-7:

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

Inserite un piccolo file alla cartella ***/shared-data***:

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

Abbandonate il container con **\[CTRL\] + \[P\]** e **\[CTRL\] + \[Q\]** per ritornare al prompt dei comandi del computer host.

Avviate il **container App** dall’immagine ufficiale di Python e montate il **container di memoria di dati** come volume:

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

Qui potete visualizzare i file nel volume condiviso con il comando seguente:

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

Come vedete, la cartella ***/shared-data*** è stata montata come file system dalla cartella ***/shared-data*** sul container di memoria di dati e contiene il file ***data-storage-hello.txt***.

Inserite adesso un file proveniente dal container app:

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

Abbandonate il container con **\[CTRL\] + \[P\]** e **\[CTRL\] + \[Q\]** per ritornare al prompt dei comandi del computer host.

Avviate, infine, il **container Web** dall’immagine ufficiale di Apache e montate il **container di memoria di dati** come volume:

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

Qui potete visualizzare i file nel volume condiviso con questo comando:

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

Adesso vedrete i file creati da noi sui **container di memoria** e **app**.

## Montare volumi protetti da scrittura

Finora, in questo articolo, abbiamo creato o montato volumi con accesso in lettura e scrittura.

Se desiderate che l’**accesso** a un container sia **limitato soltanto alla lettura** di un volume, vi basterà semplicemente inserire ***:ro*** per “read-only” alle indicazioni ***v*** dei volumi di container:

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

Questo procedimento può essere molto utile per la sicurezza. L’accesso read-only (di sola lettura) rappresenta una buona soluzione anche se volete assicurarvi che i file di un volume preciso siano protetti da sovrascrittura o eliminazione involontaria da parte di altri container Docker.

Create, ad esempio, un volume sull’host con il nome ***limited-access*** con il comando seguente:

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

Avviate un container dall’immagine di **CentOS** con il nome ***allowed-to-write*** e assegnate al volume “**Limited-Access”** un normale volume (read-write):

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

Non appena vi troverete nel prompt dei comandi di questo container, create un **file di prova** con il comando:

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

Abbandonate il container con **\[CTRL\] + \[P\]** e **\[CTRL\] + \[Q\]** per ritornare al prompt dei comandi del computer host.

Adesso avviate un container dall’**immagine di CentOS** con il nome ***not-allowed-to-write*** e assegnatelo al **volume Limited-Access** come **volume Read-only**:

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

Se provate a creare un file di prova nel volume condiviso con un comando così:

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

riceverete un messaggio di errore che vi spiega che questo container non ha accesso di scrittura alla directory.

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


This is a markdown version of: [https://www.ionos.it/digitalguide/server/know-how/volumi-dei-container-docker/](https://www.ionos.it/digitalguide/server/know-how/volumi-dei-container-docker/) for AI/LLM consumption.