Skip to main content

Playbook под все хосты из твоего inventory, который установит Docker&Compose

2fbe44f0-4f9f-4b3f-81ff-3b2b08258d82.png


Что делает этот PlayBook:

  • ставит Docker CE из официального репозитория (Debian/Ubuntu и RHEL/CentOS 8/9);

  • добавляет пользователя my_user в группу docker и корректно обновляет сессию;

  • ставит Docker Compose (v2) именно из GitHub docker/compose — всегда самую последнюю стабильную (через GitHub API);

  • кросс-архитектурный: x86_64, aarch64, armv7, ppc64le, s390x;

  • аккуратно, идемпотентно, без устаревших apt_key/bionic/ручного compose v1.

Сохрани как, например, docker-install.yml и запускай:

ansible-playbook -i inventory.ini docker-install.yml

Предпосылки: на контрол-ноде установлен Ansible; на целевых — интернет к download.docker.com и github.com. Если у тебя другие sudo/SSH-настройки — поправь remote_user/инвентори.


---
- name: Install Docker CE and latest Docker Compose (GitHub)
  hosts: all
  remote_user: my_user # измени на своего SUDO USER
  become: yes
  gather_facts: yes

  vars:
    # --- Параметры, которые можно переопределить через -e ---
    compose_version: "latest"     # можно задать "v2.31.0" и т.п.
    docker_users:                 # измени на своего SUDO USER   
      - "my_user"

    # --- Маппинги архитектур ---
    # ansible_architecture -> asset suffix на GitHub
    compose_arch_map:
      x86_64:  "x86_64"
      aarch64: "aarch64"
      armv7l:  "armv7"
      ppc64le: "ppc64le"
      s390x:   "s390x"
    # ansible_architecture -> APT arch
    deb_arch_map:
      x86_64:  "amd64"
      aarch64: "arm64"
      armv7l:  "armhf"
      ppc64le: "ppc64el"
      s390x:   "s390x"

  pre_tasks:
    - name: Map architectures for Compose and APT
      set_fact:
        compose_arch: "{{ compose_arch_map[ansible_architecture] | default('') }}"
        deb_arch: "{{ deb_arch_map[ansible_architecture] | default('amd64') }}"

    - name: Fail on unsupported architecture for Compose
      fail:
        msg: "Unsupported architecture {{ ansible_architecture }} for docker-compose binary."
      when: compose_arch == ''

    # Получаем последнюю стабильную версию compose один раз (на контрол-ноде),
    # затем разносим по всем хостам.
    - name: Query latest docker/compose release tag (once)
      uri:
        url: https://api.github.com/repos/docker/compose/releases/latest
        return_content: yes
        headers:
          Accept: application/vnd.github+json
      register: compose_release_api
      when: compose_version == "latest"
      delegate_to: localhost
      run_once: true
      changed_when: false

    - name: Set global compose version (once)
      set_fact:
        compose_version_global: >-
          {{ (compose_release_api.json.tag_name | default('v2.0.0')) if compose_version == 'latest'
             else compose_version }}
      delegate_to: localhost
      run_once: true

    - name: Propagate compose version to all hosts
      set_fact:
        compose_version_final: "{{ hostvars[groups['all'][0]].compose_version_global if compose_version == 'latest' else compose_version }}"

  tasks:
    # ========================= Debian / Ubuntu =========================
    - name: Remove conflicting packages (Debian/Ubuntu)
      apt:
        name:
          - docker.io
          - docker-doc
          - docker-compose
          - podman-docker
          - containerd
          - runc
        state: absent
        purge: yes
      when: ansible_os_family == "Debian"

    - name: Ensure base packages (Debian/Ubuntu)
      apt:
        name:
          - ca-certificates
          - curl
          - gnupg
          - lsb-release
        state: present
        update_cache: yes
        cache_valid_time: 3600
      when: ansible_os_family == "Debian"

    - name: Create APT keyrings directory (Debian/Ubuntu)
      file:
        path: /etc/apt/keyrings
        state: directory
        mode: "0755"
      when: ansible_os_family == "Debian"

    - name: Add Docker GPG key to keyring (Debian/Ubuntu)
      get_url:
        url: "https://download.docker.com/linux/{{ ansible_distribution | lower }}/gpg"
        dest: /etc/apt/keyrings/docker.asc
        mode: "0644"
      when: ansible_os_family == "Debian"

    - name: Configure Docker APT repository (Debian/Ubuntu)
      copy:
        dest: /etc/apt/sources.list.d/docker.list
        mode: "0644"
        content: |
          deb [arch={{ deb_arch }} signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} stable
      when: ansible_os_family == "Debian"

    - name: Install Docker engine and plugins (Debian/Ubuntu)
      apt:
        name:
          - docker-ce
          - docker-ce-cli
          - containerd.io
          - docker-buildx-plugin
        state: present
        update_cache: yes
      when: ansible_os_family == "Debian"

    # ========================= RHEL / CentOS =========================
    - name: Remove conflicting packages (RHEL/CentOS)
      package:
        name:
          - podman-docker
        state: absent
      when: ansible_os_family == "RedHat"

    - name: Ensure prerequisites (RHEL/CentOS)
      package:
        name:
          - yum-utils
          - device-mapper-persistent-data
          - lvm2
        state: present
      when: ansible_os_family == "RedHat"

    - name: Add Docker CE YUM repo (RHEL/CentOS 8/9)
      yum_repository:
        name: docker-ce-stable
        description: Docker CE Stable - $releasever - $basearch
        baseurl: "https://download.docker.com/linux/centos/$releasever/$basearch/stable"
        gpgcheck: yes
        gpgkey: https://download.docker.com/linux/centos/gpg
        enabled: yes
      when: ansible_os_family == "RedHat"

    - name: Install Docker engine and plugins (RHEL/CentOS)
      package:
        name:
          - docker-ce
          - docker-ce-cli
          - containerd.io
          - docker-buildx-plugin
        state: present
      when: ansible_os_family == "RedHat"

    # ========================= Common =========================
    - name: Ensure docker group exists
      group:
        name: docker
        state: present

    - name: Add users to docker group
      user:
        name: "{{ item }}"
        groups: docker
        append: yes
      loop: "{{ docker_users }}"

    - name: Enable and start Docker service
      systemd:
        name: docker
        state: started
        enabled: yes
        daemon_reload: yes

    - name: Reset SSH connection to apply group changes
      meta: reset_connection

    # --- Docker Compose v2 из GitHub как CLI plugin ---
    - name: Ensure CLI plugins directory
      file:
        path: /usr/local/lib/docker/cli-plugins
        state: directory
        mode: "0755"

    - name: Download Docker Compose v2 binary (from GitHub)
      get_url:
        url: "https://github.com/docker/compose/releases/download/{{ compose_version_final }}/docker-compose-linux-{{ compose_arch }}"
        dest: /usr/local/lib/docker/cli-plugins/docker-compose
        mode: "0755"
        owner: root
        group: root

    - name: Provide docker-compose legacy symlink
      file:
        src: /usr/local/lib/docker/cli-plugins/docker-compose
        dest: /usr/local/bin/docker-compose
        state: link
        force: yes

    # --- Верификация установки ---
    - name: Show Docker version (root)
      command: docker --version
      register: docker_version
      changed_when: false

    - name: Show Docker Compose version (root)
      command: docker compose version
      register: compose_version_check
      changed_when: false

    - name: Print versions
      debug:
        msg:
          - "{{ docker_version.stdout }}"
          - "{{ compose_version_check.stdout }}"

    # Тест без коллекций: вытянет образ и отработает hello-world
    - name: Test Docker as current SSH user (my_user)
      command: docker run --rm hello-world
      register: hello_test
      changed_when: false
      failed_when: hello_test.rc != 0
      become: false

Заметки:

  • Если какой-то хост — ARM/IBM Z/PowerPC — арх маппинг уже учтён. Для экзотических платформ, которых нет в релизах compose, таск «Fail on unsupported architecture» остановит плей.

  • Проверка hello-world выполняется от лица текущего SSH-пользователя (my_user) уже после reset_connection, поэтому права группы docker применяются корректно.

  • При желании можно закрепить конкретную версию compose: -e "compose_version=v2.31.0".