# Backup di un container Docker ## Backup dei dati di un container ```bash [15:06 Sun Feb 25]root@snikket (264):/etc/snikket > ll Permissions Size User Date Modified Name drwxr-xr-x - root 25 Feb 15:06  backup .rw-r--r-- 1.0k root 10 Jan 21:16  docker-compose.yml .rw-r--r-- 250 root 23 Dec 2023  snikket.conf [15:06 Sun Feb 25]root@snikket (265):/etc/snikket > docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fb9ed97becbd snikket/snikket-web-proxy:stable "/usr/bin/tini /bin/…" 7 days ago Up 7 days snikket-proxy 658a76171366 snikket/snikket-web-portal:stable "/bin/sh /entrypoint…" 7 days ago Up 7 days (healthy) snikket-portal e02f21267ab8 snikket/snikket-server:stable "/bin/entrypoint.sh" 7 days ago Up 7 days (healthy) snikket 35bf10b99eb4 snikket/snikket-cert-manager:stable "/usr/bin/tini /bin/…" 7 days ago Up 43 minutes snikket-certs bcb2056929a0 hello-world "/hello" 2 months ago Exited (0) 2 months ago practical_chandrasekhar ``` Per ottenere la lista solo dei containerID: ```bash > docker container ls -q fb9ed97becbd 658a76171366 e02f21267ab8 37bf10b99eb4 [15:11 Sun Feb 25]root@snikket (269):/etc/snikket > docker container ls -q | xargs fb9ed97becbd 658a76171366 e02f21267ab8 35bf10b99eb4 ``` Quindi, come dalla documentazione: - commit del container - salvare i dati dell'immagine in un archivio .tar ```bash [15:15 Sun Feb 25]root@snikket (273):/etc/snikket > docker container commit fb9ed97becbd sha256:681c6db0e0d23535b0c3fd3ec29544e462e13463a906ac646998bb0f5d30d3f4 [15:15 Sun Feb 25]root@snikket (274):/etc/snikket > docker image save -o backup/snikket-web-proxy.tar snikket/snikket-web-proxy:stable [15:16 Sun Feb 25]root@snikket (275):/etc/snikket > ll backup/ Permissions Size User Date Modified Name .rw------- 101M root 25 Feb 15:16  snikket-web-proxy.tar ``` ## Backup di un volume Ad esempio, creare un nuovo container denominato `dbstore`: ```bash docker run -v /dbdata --name dbstore ubuntu /bin/bash ``` Per eseguire un backup del volume `dbdata`, eseguire il seguente comando: ```bash docker run --rm --volumes-from dbstore -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata ``` Nel comando `docker run`, vengono impostate due opzioni relative ai volumi: * `--volumes-from dbstore`: Consente di montare automaticamente il volume definito nel container `dbstore` nel nuovo container appena creato. * `-v $(pwd):/backup`: Permette di collegare una directory host locale nel nuovo container. In questo caso, `$(pwd)` rappresenta la directory di lavoro corrente sulla macchina host. Tutte le azioni intraprese all'interno del container relativamente a tale cartella verranno riflesse anche nella directory host. Oppure, meglio sarebbe utilizzare, per questo scopo, **busybox**, uno strumento software che combina molti programmi Unix essenziali in un singolo binario compatto. È molto leggero, efficiente e versatile. ```bash docker run --rm --mount source=snikket_data,target=/volume-snikket-data_backup -v $(pwd):/backup busybox tar -czvf /backup/snikket-data_bk_$(date +%F).tar.gz /volume-snikket-data_backup ``` - `docker run`: avvia un nuovo container Docker partendo da un'immagine specificata. - `--rm`: rimuove automaticamente il container subito dopo la sua interruzione. - `--mount source=snikket_data,target=/volume-snikket-data_backup`: monta il volume `snikket_data` nel path `/volume-snikket-data_backup` del nuovo container. - `-v $(pwd):/backup`: monta la directory di lavoro corrente dell'host nel path `/backup` all'interno del nuovo container. - `busybox`: specifica l'immagine base da utilizzare per creare il container. - `tar -czvf /backup/snikket-data_bk_$(date +%F).tar.gz /volume-snikket-data_backup`: all'avvio del container, viene eseguito il comando `tar`, salvando il contenuto del volume `/volume-snikket-data_backup` nel file `/backup/snikket-data_bk_$(date +%F).tar.gz`, dove `$(date +%F)` rappresenta la data corrente. - Infine, viene rimosso il container, ma il file di backup rimane presente nella cartella di lavoro corrente: ```bash [15:43 Sun Feb 25]root@snikket (297):/etc/snikket/backup > ll Permissions Size User Date Modified Name .rw-r--r-- 259 root 25 Feb 15:42  snikket-data_bk_2024-02-25.tar.gz ``` ## Script di esempio ```bash #!/bin/bash TOPIC="nomedeltopic" SERVER="ntfy.server.net" BACKUP_DIR="/etc/snikket/backup" CONTAINER_LIST=$(docker container ls -q) # Lista di immagini con il tag 'stable' IMAGE_LIST=$(docker images --filter "reference=snikket/*:stable" -q) VOLUME_LIST=$(docker volume ls --format '{{.Name}}') # Funzioni per inviare notifiche send_success_notification() { curl -H "X-Tags: tada" -H "Attach: https://yanbin.blog/wp-content/uploads/2020/03/docker-2.png" -d "Backup volume $VOLUME_NAME OK! :)" $SERVER/$TOPIC } # Funzione per inviare notifica di errore send_error_notification() { curl -H "X-Tags: skull" -d "Backup volume $VOLUME_NAME ERROR!" $SERVER/$TOPIC } notify_backup_removed() { curl -H "X-Tags: warning" -d "Some backups have been deleted" $SERVER/$TOPIC } # Rimozione dei backup piu' vecchi di 7 giorni remove_old_backups() { if [ find $BACKUP_DIR -type f -name "*.tar.gz" -mtime +7 -exec rm {} \; ]; then notify_backup_removed else echo "Nessun backup eliminato!" fi } ### BACKUP #### cd $BACKUP_DIR # Commit per ogni container nella lista for CONTAINER_ID in $CONTAINER_LIST; do docker container commit $CONTAINER_ID || send_error_notification done # tr (translate or delete characters): # tr: un comando che serve per tradurre o eliminare caratteri in un flusso di dati. # tr '/' '-' traduce ogni carattere '/' in '-' # Backup delle immagini for IMAGE_ID in $IMAGE_LIST; do # Ottieni il nome dell'immagine con il tag IMAGE_NAME_WITH_TAG=$(docker inspect --format='{{.RepoTags}}' $IMAGE_ID | tr -d '[] ') docker image save -o $(echo $IMAGE_NAME_WITH_TAG | cut -d '/' -f 2 | tr ':' '-')_$(date +%F)_IMAGE.tar.gz $IMAGE_NAME_WITH_TAG || send_error_notification done # Backup dei volumi for VOLUME_NAME in $VOLUME_LIST; do docker run --rm --mount source=$VOLUME_NAME,target=/$VOLUME_NAME -v $(pwd):/backup busybox tar -czvf /backup/$VOLUME_NAME\_bk_$(date +%F)_VOLUME.tar.gz /$VOLUME_NAME && send_success_notification || send_error_notification done # Rimozione dei backup piu' vecchi di 7 giorni remove_old_backups ``` ## Collegamenti - [https://docs.docker.com/desktop/backup-and-restore/](https://docs.docker.com/desktop/backup-and-restore/) - [https://www.geeksforgeeks.org/backing-up-a-docker-container/](https://www.geeksforgeeks.org/backing-up-a-docker-container/) - [https://docs.docker.com/storage/volumes/#back-up-restore-or-migrate-data-volumes](https://docs.docker.com/storage/volumes/#back-up-restore-or-migrate-data-volumes)