{"id":325,"date":"2023-09-23T12:03:05","date_gmt":"2023-09-23T10:03:05","guid":{"rendered":"https:\/\/it4home.dk\/?p=325"},"modified":"2023-10-15T20:08:29","modified_gmt":"2023-10-15T18:08:29","slug":"how-to-backup-docker-data-to-a-different-location-in-your-lan","status":"publish","type":"post","link":"https:\/\/it4home.dk\/index.php\/2023\/09\/23\/how-to-backup-docker-data-to-a-different-location-in-your-lan\/","title":{"rendered":"How to Backup Docker Data to a Different Location in Your LAN"},"content":{"rendered":"<div class=\"pdfprnt-buttons pdfprnt-buttons-post pdfprnt-top-right\"><a href=\"https:\/\/it4home.dk\/index.php\/wp-json\/wp\/v2\/posts\/325?print=pdf\" class=\"pdfprnt-button pdfprnt-button-pdf\" target=\"_blank\" ><\/a><a href=\"https:\/\/it4home.dk\/index.php\/wp-json\/wp\/v2\/posts\/325?print=print\" class=\"pdfprnt-button pdfprnt-button-print\" target=\"_blank\" ><img decoding=\"async\" src=\"https:\/\/it4home.dk\/wp-content\/plugins\/pdf-print\/images\/print.png\" alt=\"image_print\" title=\"Print Content\" \/><\/a><\/div>\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Docker data located at <code>\/var\/lib\/docker\/volumes<\/code>.<\/li>\n\n\n\n<li>SSH access to the target backup system.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Passwordless SSH Login<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">First, set up passwordless SSH login:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ssh-keygen -t rsa\nssh-copy-id root@192.168.0.225\nssh root@192.168.0.225<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Docker Volume Backup Script<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create a backup script named <code>docker_backup.sh<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\nset -e\n\n# Define variables\nsource_dir=\"\/var\/lib\/docker\/volumes\"\nbackup_dir=\"\/opt\/docker_backups\"\nkeep_backups=10\ncurrent_datetime=$(date +\"%Y-%m-%d_%H-%M-%S\")\nbackup_filename=\"$current_datetime-backup.tar\"\nremote_user=\"root\"\nremote_server=\"192.168.0.225\"\nremote_dir=\"\/opt\/remote_docker_backups\"\n\n# Check if source and backup directories exist\nif &#91; ! -d \"$source_dir\" ]; then\n  echo \"Source directory does not exist.\"\n  exit 1\nfi\nif &#91; ! -d \"$backup_dir\" ]; then\n  echo \"Backup directory does not exist.\"\n  exit 1\nfi\n\n# Stop running Docker containers\nif &#91; \"$(docker ps -q)\" ]; then\n  docker stop $(docker ps -q)\nfi\n\n# Create the backup\ntar -cpf \"$backup_dir\/$backup_filename\" \"$source_dir\"\n\n# Start stopped Docker containers\nif &#91; \"$(docker ps -a -q)\" ]; then\n  docker start $(docker ps -a -q)\nfi\n\n# Compress and transfer the backup\ngzip \"$backup_dir\/$backup_filename\"\nbackup_filename=\"$current_datetime-backup.tar.gz\"\nscp \"$backup_dir\/$backup_filename\" \"$remote_user@$remote_server:$remote_dir\"\n\n# Remove old backups\nfind \"$backup_dir\" -type f -name \"*-backup.tar.gz\" -mtime +$keep_backups -exec rm {} \\;\nssh \"$remote_user@$remote_server\" \"find $remote_dir -type f -name '*-backup.tar.gz' -mtime +$keep_backups -exec rm {} \\;\"\n\necho \"Backup was created: $backup_dir\/$backup_filename and copied to $remote_server:$remote_dir.\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Run the script:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo su\nchmod +x docker_backup.sh\n.\/docker_backup.sh<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Ansible Alternative<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create an Ansible playbook named <code>docker_backup.yml<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>---\n- name: Docker Backup Playbook\n  hosts: rpidocker\n  become: yes\n  vars:\n    source_dir: \"\/var\/lib\/docker\/volumes\"\n    backup_dir: \"\/opt\/docker_backups\"\n    keep_backups: 10\n    current_datetime: \"{{ lookup('pipe', 'date +%Y-%m-%d_%H-%M-%S') }}\"\n    backup_filename: \"{{ current_datetime }}-backup.tar\"\n    remote_user: \"root\"\n    remote_server: \"192.168.0.225\"\n    remote_dir: \"\/opt\/remote_docker_backups\"\n\n  tasks:\n    - name: Check if source directory exists\n      stat:\n        path: \"{{ source_dir }}\"\n      register: source_dir_stat\n\n    - name: Fail if source directory does not exist\n      fail:\n        msg: \"Source directory does not exist.\"\n      when: not source_dir_stat.stat.exists\n\n    - name: Check if backup directory exists\n      stat:\n        path: \"{{ backup_dir }}\"\n      register: backup_dir_stat\n\n    - name: Fail if backup directory does not exist\n      fail:\n        msg: \"Backup directory does not exist.\"\n      when: not backup_dir_stat.stat.exists\n\n    - name: Stop running Docker containers\n      command: docker stop $(docker ps -q)\n      ignore_errors: yes\n\n    - name: Create backup archive\n      command: tar -cpf \"{{ backup_dir }}\/{{ backup_filename }}\" \"{{ source_dir }}\"\n\n    - name: Start all Docker containers\n      command: docker start $(docker ps -a -q)\n      ignore_errors: yes\n\n    - name: Compress the backup archive\n      command: gzip \"{{ backup_dir }}\/{{ backup_filename }}\"\n      args:\n        chdir: \"{{ backup_dir }}\"\n\n    - name: Copy backup to remote server\n      synchronize:\n        src: \"{{ backup_dir }}\/{{ backup_filename }}.gz\"\n        dest: \"{{ remote_user }}@{{ remote_server }}:{{ remote_dir }}\"\n        mode: push\n\n    - name: Delete older backups locally\n      shell: find \"{{ backup_dir }}\" -type f -name \"*-backup.tar.gz\" -mtime +{{ keep_backups }} -exec rm {} \\;\n\n    - name: Delete older backups on remote server\n      shell: ssh \"{{ remote_user }}@{{ remote_server }}\" \"find {{ remote_dir }} -type f -name '*-backup.tar.gz' -mtime +{{ keep_backups }} -exec rm {} \\;\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Run the playbook:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ansible-playbook -i inventory.ini docker_backup.yml<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Your <code>inventory.ini<\/code> should look like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;rpidocker]\n192.168.0.224 ansible_user=root ansible_ssh_private_key_file=\/path\/to\/your\/private\/key<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You now have two methods to back up your Docker data securely to another location within your LAN. Choose the one that best fits your needs.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Prerequisites Passwordless SSH Login First, set up passwordless SSH login: Docker Volume Backup Script Create a backup script named docker_backup.sh: Run the script: Ansible Alternative Create an Ansible playbook named docker_backup.yml: Run the playbook:&#46;&#46;&#46;<\/p>\n","protected":false},"author":1,"featured_media":353,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[32,2,5],"tags":[],"class_list":["post-325","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ansible","category-docker","category-linux"],"_links":{"self":[{"href":"https:\/\/it4home.dk\/index.php\/wp-json\/wp\/v2\/posts\/325","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/it4home.dk\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/it4home.dk\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/it4home.dk\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/it4home.dk\/index.php\/wp-json\/wp\/v2\/comments?post=325"}],"version-history":[{"count":2,"href":"https:\/\/it4home.dk\/index.php\/wp-json\/wp\/v2\/posts\/325\/revisions"}],"predecessor-version":[{"id":327,"href":"https:\/\/it4home.dk\/index.php\/wp-json\/wp\/v2\/posts\/325\/revisions\/327"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/it4home.dk\/index.php\/wp-json\/wp\/v2\/media\/353"}],"wp:attachment":[{"href":"https:\/\/it4home.dk\/index.php\/wp-json\/wp\/v2\/media?parent=325"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/it4home.dk\/index.php\/wp-json\/wp\/v2\/categories?post=325"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/it4home.dk\/index.php\/wp-json\/wp\/v2\/tags?post=325"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}