D7.4 docker_volume module 📦

Το module

Το community.docker.docker_volume δημιουργεί και διαχειρίζεται Docker named volumes.

# Βασική χρήση
community.docker.docker_volume:
  name:  <volume_name>
  state: present | absent

📝 Γιατί χρησιμοποιούμε το module αντί να αφήνουμε το docker_container να το φτιάξει;

Αν αφήσεις docker_container να φτιάξει το volume:
  → Φτιάχνεται με default settings (root, no labels)
  → Δύσκολο να ελέγξεις driver options

Αν χρησιμοποιείς docker_volume πρώτα:
  → Πλήρης έλεγχος settings ✅
  → Labels για οργάνωση ✅
  → Idempotent ✅

Βασική δημιουργία volumes

tasks:

  # ── Απλό volume ───────────────────────────
  - name: Δημιουργία database volume
    community.docker.docker_volume:
      name:  postgres_data
      state: present

  # ── Volume με labels ──────────────────────
  - name: Δημιουργία app data volume
    community.docker.docker_volume:
      name:  app_uploads
      state: present
      labels:
        app:         myapp
        environment: production
        managed-by:  ansible
        backup:      "true"

  # ── Πολλά volumes με loop ─────────────────
  - name: Δημιουργία volumes
    community.docker.docker_volume:
      name:  "{{ item.name }}"
      state: present
      labels:
        app:     myapp
        purpose: "{{ item.purpose }}"
    loop:
      - { name: "postgres_data", purpose: "database"  }
      - { name: "redis_data",    purpose: "cache"      }
      - { name: "app_uploads",   purpose: "media"      }
      - { name: "app_logs",      purpose: "logs"       }
    loop_control:
      label: "{{ item.name }}"

NFS Volume — Shared storage

Αν έχεις NFS server (π.χ. NAS), μπορείς να τον χρησιμοποιήσεις ως Docker volume:

tasks:

  # ── NFS volume ────────────────────────────
  - name: NFS volume για shared data
    community.docker.docker_volume:
      name:   shared_data
      state:  present
      driver: local
      driver_options:
        type:   nfs
        o:      "addr=192.168.1.5,rw,nfsvers=4"
        #         ↑ NFS server IP
        device: ":/exports/myapp"
        #         ↑ NFS export path

  # ── Container που χρησιμοποιεί NFS volume ─
  - name: Container με NFS shared storage
    community.docker.docker_container:
      name:  myapp
      image: myapp:latest
      volumes:
        - "shared_data:/app/shared:rw"    # ← NFS volume ✅

💡 Χρήση: NFS volumes χρησιμοποιούνται σε multi-host setups όπου πολλά containers σε διαφορετικά hosts πρέπει να μοιραστούν τα ίδια αρχεία.


CIFS/SMB Volume — Windows shares

tasks:

  # ── CIFS volume (Windows share) ───────────
  - name: CIFS volume
    community.docker.docker_volume:
      name:   smb_share
      state:  present
      driver: local
      driver_options:
        type:   cifs
        o:      "username={{ smb_user }},password={{ vault_smb_pass }},uid=1000"
        device: "//192.168.1.10/share"
    no_log: true    # ← credentials!

tmpfs Volume — In-memory storage

tasks:

  # ── tmpfs volume ──────────────────────────
  - name: tmpfs volume για session data
    community.docker.docker_volume:
      name:   session_tmp
      state:  present
      driver: local
      driver_options:
        type:   tmpfs
        device: tmpfs
        o:      "size=256m,uid=1000"    # ← 256MB RAM

  - name: Container με tmpfs
    community.docker.docker_container:
      name:  app_sessions
      image: myapp:latest
      volumes:
        - "session_tmp:/app/sessions"    # ← in-memory ✅

Volume Inspection

tasks:

  # ── Πληροφορίες volume ────────────────────
  - name: Volume information
    community.docker.docker_volume_info:
      name: postgres_data
    register: vol_info

  - name: Εμφάνιση volume info
    ansible.builtin.debug:
      msg:
        - "Volume  : {{ vol_info.volume.Name }}"
        - "Driver  : {{ vol_info.volume.Driver }}"
        - "Mountpoint: {{ vol_info.volume.Mountpoint }}"
        - "Created : {{ vol_info.volume.CreatedAt[:10] }}"
        - "Labels  : {{ vol_info.volume.Labels }}"
    when: vol_info.exists

  # ── Έλεγχος αν volume υπάρχει ─────────────
  - name: Δράση μόνο αν δεν υπάρχει volume
    ansible.builtin.debug:
      msg: "Volume postgres_data δεν υπάρχει  θα δημιουργηθεί"
    when: not vol_info.exists

  # ── Μέγεθος volume (από host) ─────────────
  - name: Μέγεθος volume στον host
    ansible.builtin.command:
      cmd: >
        du -sh /var/lib/docker/volumes/postgres_data/_data
    register:     vol_size
    changed_when: false
    ignore_errors: true

  - name: Volume size
    ansible.builtin.debug:
      msg: "postgres_data: {{ vol_size.stdout | default('N/A') }}"

Αφαίρεση volumes

tasks:

  # ── Αφαίρεση συγκεκριμένου volume ─────────
  - name: Αφαίρεση παλιού volume
    community.docker.docker_volume:
      name:  old_data
      state: absent
    # ← αποτυγχάνει αν container ακόμα το χρησιμοποιεί!

  # ── Prune unused volumes (ΠΡΟΣΟΧΗ!) ────────
  - name: Prune unused volumes
    community.docker.docker_prune:
      volumes: true
    when: docker_prune_volumes | default(false)
    # ← ΠΑΝΤΑ με when: + variable!
    # ← Διαγράφει ό,τι δεν χρησιμοποιείται!

⚠️ ΚΡΙΣΙΜΟ: docker_prune: volumes: true διαγράφει οριστικά όλα τα anonymous volumes. Ποτέ μην το τρέχεις χωρίς explicit variable confirmation.


Πρακτικό playbook — Volume Management

---
# docker-volumes-setup.yml

- name: Docker Volumes Setup
  hosts: "{{ target | default('all_managed') }}"
  become: true
  gather_facts: true

  vars:
    app_name: myapp
    app_volumes:
      - name:    "{{ app_name }}_postgres"
        purpose: database
        backup:  "true"
      - name:    "{{ app_name }}_redis"
        purpose: cache
        backup:  "false"
      - name:    "{{ app_name }}_uploads"
        purpose: media
        backup:  "true"
      - name:    "{{ app_name }}_logs"
        purpose: logs
        backup:  "false"

  tasks:

    # ── Δημιουργία volumes ────────────────────
    - name: "💾 Δημιουργία volumes ({{ app_name }})"
      community.docker.docker_volume:
        name:  "{{ item.name }}"
        state: present
        labels:
          app:         "{{ app_name }}"
          purpose:     "{{ item.purpose }}"
          backup:      "{{ item.backup }}"
          environment: "{{ app_env | default('production') }}"
          managed-by:  ansible
      loop: "{{ app_volumes }}"
      loop_control:
        label: "{{ item.name }}"

    # ── Inspection ────────────────────────────
    - name: "🔍 Inspection volumes"
      community.docker.docker_volume_info:
        name: "{{ item.name }}"
      register: vol_check
      loop:     "{{ app_volumes }}"
      loop_control:
        label: "{{ item.name }}"

    # ── Report ────────────────────────────────
    - name: "📊 Volume Report"
      ansible.builtin.debug:
        msg:
          - "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
          - "  Docker Volumes ({{ app_name }})"
          - "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
          - "{% for v in vol_check.results %}\
             {{ '  ✅' if v.exists else '  ❌' }} {{ v.item.name }}\
             ({{ v.item.purpose }}){% if v.item.backup == 'true' %} 🔄{% endif %}\
             {% endfor %}"
          - "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
          - "  🔄 = backup enabled"
      run_once: true
# Εκτέλεση
ansible-playbook playbooks/docker-volumes-setup.yml \
    --limit nextcloud -v

# Λίστα volumes στον host
ansible nextcloud -m ansible.builtin.command \
    -a "docker volume ls --format '{{.Name}}\t{{.Driver}}'" \
    --become

Σύνοψη D7.4

docker_volume module
│
├── Βασική χρήση:
│   ├── name:  volume_name
│   └── state: present | absent
│
├── Labels:
│   └── Οργάνωση + αναγνώριση volumes
│
├── Drivers:
│   ├── local (default) → local filesystem
│   ├── NFS             → Network filesystem
│   ├── CIFS            → Windows shares
│   └── tmpfs           → In-memory
│
├── Inspection:
│   └── docker_volume_info → name, driver, mountpoint
│
└── Cleanup:
    ├── state: absent     → αφαίρεση συγκεκριμένου
    └── docker_prune      → ΠΡΟΣΟΧΗ! Μόνο με explicit flag