D1.4 Προετοιμασία Περιβάλλοντος 🛠️
Τι χρειαζόμαστε
┌─────────────────────────────────────────────────────────┐
│ Controller (bananapim4berry) │
│ ✅ Ansible 2.20.4 │
│ ✅ community.docker collection │
│ ⬜ docker Python library (στον controller) │
│ │
│ Managed Server (nextcloud) │
│ ⬜ Docker Engine │
│ ⬜ docker Python library (στον server) │
│ ⬜ docker-compose plugin │
└─────────────────────────────────────────────────────────┘
Βήμα 1: Έλεγχος Controller
# Ως ansible user στο Armbian
cd ~/ansible
# ── Έλεγχος collection ────────────────────────
ansible-galaxy collection list | grep docker
# ── Έλεγχος Python docker library ────────────
python3 -c "import docker; print(docker.__version__)"
# Αν βγάλει error → χρειάζεται εγκατάσταση
# ── Εγκατάσταση docker Python library ─────────
pip install docker docker-compose
# ── Επαλήθευση ────────────────────────────────
python3 -c "import docker; print('docker SDK:', docker.__version__)"
Βήμα 2: Έλεγχος Managed Server
# Έλεγχος αν υπάρχει Docker
ansible nextcloud -m ansible.builtin.command \
-a "docker --version" \
--become
# Έλεγχος Python docker library στον server
ansible nextcloud -m ansible.builtin.command \
-a "python3 -c 'import docker; print(docker.__version__)'" \
--become
# Έλεγχος Docker service
ansible nextcloud -m ansible.builtin.service_facts \
--become | grep -i docker
Βήμα 3: Ενημέρωση requirements.yml
cat > ~/ansible/requirements.yml << 'EOF'
---
roles:
- name: geerlingguy.nginx
version: "3.2.0"
collections:
- name: community.general
version: ">=7.0.0"
- name: ansible.posix
version: ">=1.5.0"
- name: community.docker
version: ">=3.0.0" # ← για Docker automation
EOF
# Εγκατάσταση
ansible-galaxy collection install -r requirements.yml
Βήμα 4: Ενημέρωση group_vars
# Προσθήκη Docker variables στο group_vars
cat >> ~/ansible/inventory/group_vars/all/vars.yml << 'EOF'
# ── Docker Settings ───────────────────────────
docker_edition: ce # community edition
docker_install_compose: true
docker_compose_version: "v2.24.0"
docker_users:
- ansible # ← ποιοι users μπορούν να τρέχουν docker
# ── Docker Registry ───────────────────────────
docker_registry_url: "https://index.docker.io/v1/"
# ── Container defaults ────────────────────────
container_restart_policy: unless-stopped
container_log_driver: json-file
container_log_max_size: "10m"
container_log_max_file: "3"
EOF
Βήμα 5: Δημιουργία Docker Role Structure
# Δημιουργία Docker installation role
cd ~/ansible/roles
ansible-galaxy role init docker
# Δομή που θα φτιάξουμε:
tree ~/ansible/roles/docker/
# docker/
# ├── defaults/
# │ └── main.yml
# ├── handlers/
# │ └── main.yml
# ├── tasks/
# │ ├── main.yml
# │ ├── install.yml
# │ ├── configure.yml
# │ └── users.yml
# └── meta/
# └── main.yml
Βήμα 6: Docker Role — defaults/main.yml
cat > ~/ansible/roles/docker/defaults/main.yml << 'EOF'
---
# ============================================================
# Docker Role Defaults
# ============================================================
# ── Edition ───────────────────────────────────
docker_edition: ce # ce = Community Edition
# ── Packages ──────────────────────────────────
docker_packages_debian:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-buildx-plugin
- docker-compose-plugin
docker_packages_redhat:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-buildx-plugin
- docker-compose-plugin
docker_packages_suse:
- docker
- docker-compose
# ── Service ───────────────────────────────────
docker_service_enabled: true
docker_service_state: started
# ── Users ─────────────────────────────────────
docker_users: [] # ← users που θα μπουν στο docker group
# ── Daemon config ─────────────────────────────
docker_daemon_options:
log-driver: json-file
log-opts:
max-size: "10m"
max-file: "3"
storage-driver: overlay2
# ── Compose ───────────────────────────────────
docker_install_compose: true
EOF
Βήμα 7: Docker Role — tasks/main.yml
cat > ~/ansible/roles/docker/tasks/main.yml << 'EOF'
---
# ============================================================
# Docker Role — Main Entry Point
# ============================================================
- name: Install Docker
ansible.builtin.import_tasks:
file: install.yml
tags: [install, docker]
- name: Configure Docker
ansible.builtin.import_tasks:
file: configure.yml
tags: [config, docker]
- name: Configure Docker users
ansible.builtin.import_tasks:
file: users.yml
tags: [users, docker]
when: docker_users | length > 0
EOF
Βήμα 8: Docker Role — tasks/install.yml
cat > ~/ansible/roles/docker/tasks/install.yml << 'EOF'
---
# ============================================================
# Docker Installation — Και στις 3 διανομές
# ============================================================
# ══════════════════════════════════════════
# DEBIAN / UBUNTU
# ══════════════════════════════════════════
- name: Install prerequisites (Debian)
ansible.builtin.apt:
name:
- ca-certificates
- curl
- gnupg
- lsb-release
state: present
update_cache: true
when: ansible_facts['os_family'] == "Debian"
- name: Add Docker GPG key (Debian)
ansible.builtin.apt_key:
url: "https://download.docker.com/linux/{{ ansible_facts['distribution'] | lower }}/gpg"
state: present
when: ansible_facts['os_family'] == "Debian"
- name: Add Docker repository (Debian)
ansible.builtin.apt_repository:
repo: >-
deb [arch={{ ansible_facts['architecture'] | replace('x86_64', 'amd64') | replace('aarch64', 'arm64') }}]
https://download.docker.com/linux/{{ ansible_facts['distribution'] | lower }}
{{ ansible_facts['distribution_release'] }}
stable
state: present
filename: docker
when: ansible_facts['os_family'] == "Debian"
- name: Install Docker packages (Debian)
ansible.builtin.apt:
name: "{{ docker_packages_debian }}"
state: present
update_cache: true
when: ansible_facts['os_family'] == "Debian"
notify: Restart Docker
# ══════════════════════════════════════════
# REDHAT / FEDORA
# ══════════════════════════════════════════
- name: Add Docker repository (RedHat)
ansible.builtin.yum_repository:
name: docker-ce
description: Docker CE Stable
baseurl: "https://download.docker.com/linux/centos/$releasever/$basearch/stable"
gpgcheck: true
gpgkey: "https://download.docker.com/linux/centos/gpg"
enabled: true
when: ansible_facts['os_family'] == "RedHat"
- name: Install Docker packages (RedHat)
ansible.builtin.dnf:
name: "{{ docker_packages_redhat }}"
state: present
when: ansible_facts['os_family'] == "RedHat"
notify: Restart Docker
# ══════════════════════════════════════════
# OPENSUSE
# ══════════════════════════════════════════
- name: Install Docker packages (openSUSE)
community.general.zypper:
name: "{{ docker_packages_suse }}"
state: present
when: ansible_facts['os_family'] == "Suse"
notify: Restart Docker
# ══════════════════════════════════════════
# ΚΟΙΝΟ ΓΙΑ ΟΛΕΣ ΤΙΣ ΔΙΑΝΟΜΕΣ
# ══════════════════════════════════════════
- name: Enable and start Docker
ansible.builtin.service:
name: docker
state: "{{ docker_service_state }}"
enabled: "{{ docker_service_enabled }}"
- name: Install Python Docker SDK
ansible.builtin.pip:
name:
- docker
- docker-compose
state: present
virtualenv: "{{ ansible_env.VIRTUAL_ENV | default(omit) }}"
- name: Verify Docker installation
ansible.builtin.command:
cmd: docker --version
register: docker_version
changed_when: false
- name: Show Docker version
ansible.builtin.debug:
msg: "✅ {{ docker_version.stdout }}"
EOF
Βήμα 9: Docker Role — tasks/configure.yml
cat > ~/ansible/roles/docker/tasks/configure.yml << 'EOF'
---
# ============================================================
# Docker Daemon Configuration
# ============================================================
- name: Create Docker config directory
ansible.builtin.file:
path: /etc/docker
state: directory
owner: root
group: root
mode: '0755'
- name: Deploy Docker daemon config
ansible.builtin.copy:
dest: /etc/docker/daemon.json
owner: root
group: root
mode: '0644'
content: "{{ docker_daemon_options | to_nice_json }}"
notify: Restart Docker
- name: Create Docker systemd override directory
ansible.builtin.file:
path: /etc/systemd/system/docker.service.d
state: directory
mode: '0755'
- name: Verify Docker daemon config
ansible.builtin.command:
cmd: docker info
register: docker_info
changed_when: false
ignore_errors: true
- name: Docker info summary
ansible.builtin.debug:
msg:
- "Docker Storage Driver: {{ docker_info.stdout | regex_search('Storage Driver: (.+)', '\\1') | first | default('N/A') }}"
- "Docker Logging Driver: {{ docker_info.stdout | regex_search('Logging Driver: (.+)', '\\1') | first | default('N/A') }}"
when: not docker_info.failed
EOF
Βήμα 10: Docker Role — tasks/users.yml
cat > ~/ansible/roles/docker/tasks/users.yml << 'EOF'
---
# ============================================================
# Docker User Configuration
# ============================================================
- name: Add users to docker group
ansible.builtin.user:
name: "{{ item }}"
groups: docker
append: true
loop: "{{ docker_users }}"
loop_control:
label: "{{ item }}"
- name: Verify docker group membership
ansible.builtin.command:
cmd: "id {{ item }}"
register: user_groups
changed_when: false
loop: "{{ docker_users }}"
loop_control:
label: "{{ item }}"
- name: Show user group info
ansible.builtin.debug:
msg: "{{ item.stdout }}"
loop: "{{ user_groups.results }}"
loop_control:
label: "{{ item.item }}"
EOF
Βήμα 11: Docker Role — handlers/main.yml
cat > ~/ansible/roles/docker/handlers/main.yml << 'EOF'
---
- name: Restart Docker
ansible.builtin.service:
name: docker
state: restarted
ignore_errors: "{{ ansible_check_mode }}"
- name: Reload Docker
ansible.builtin.service:
name: docker
state: reloaded
ignore_errors: "{{ ansible_check_mode }}"
EOF
Βήμα 12: Docker Install Playbook
cat > ~/ansible/playbooks/docker-install.yml << 'EOF'
---
# ============================================================
# Docker Installation Playbook
# ============================================================
- name: Install Docker
hosts: "{{ target | default('all_managed') }}"
become: true
gather_facts: true
pre_tasks:
- name: Pre-install info
ansible.builtin.debug:
msg:
- "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
- "Installing Docker"
- "Host: {{ inventory_hostname }}"
- "OS : {{ ansible_facts['distribution'] }} {{ ansible_facts['distribution_version'] }}"
- "Arch: {{ ansible_facts['architecture'] }}"
- "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
tags: always
roles:
- role: docker
vars:
docker_users:
- ansible
- "{{ ansible_user }}"
tags: docker
post_tasks:
- name: Test Docker
ansible.builtin.command:
cmd: docker run --rm hello-world
register: hello_world
changed_when: false
ignore_errors: true
tags: verify
- name: Test Docker Compose
ansible.builtin.command:
cmd: docker compose version
register: compose_version
changed_when: false
ignore_errors: true
tags: verify
- name: Installation Report
ansible.builtin.debug:
msg:
- "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
- "✅ DOCKER INSTALLATION COMPLETE"
- "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
- "Docker : {{ '✅ OK' if not hello_world.failed else '❌ Check manually' }}"
- "Compose : {{ compose_version.stdout | default('❌ Not found') }}"
- "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
tags: always
EOF
Βήμα 13: Εκτέλεση
# ── Syntax check ──────────────────────────────
ansible-playbook playbooks/docker-install.yml \
--syntax-check
# ── Dry run ───────────────────────────────────
ansible-playbook playbooks/docker-install.yml \
--check \
--limit nextcloud
# ── Εκτέλεση ──────────────────────────────────
ansible-playbook playbooks/docker-install.yml \
--limit nextcloud \
-v
# ── Επαλήθευση ────────────────────────────────
ansible nextcloud -m ansible.builtin.command \
-a "docker --version" --become
ansible nextcloud -m ansible.builtin.command \
-a "docker compose version" --become
ansible nextcloud -m ansible.builtin.command \
-a "docker run --rm hello-world" --become
Σύνοψη D1.4
Προετοιμασία Περιβάλλοντος
├── Controller:
│ ├── community.docker collection ✅
│ └── pip install docker
│
├── Docker Role:
│ ├── defaults/main.yml → packages, daemon config
│ ├── tasks/install.yml → Debian/RedHat/openSUSE
│ ├── tasks/configure.yml→ daemon.json
│ ├── tasks/users.yml → docker group
│ └── handlers/main.yml → restart docker
│
├── Playbook:
│ └── docker-install.yml → full installation
│
└── Verify:
├── docker --version
├── docker compose version
└── docker run hello-world