Skip to content

Deploying to Docker Swarm using Ansible

Posted on:August 1, 2023

I prefer using Ansible to manage my servers, and for my apps, I opt for Docker Swarm. To me, Docker Swarm strikes a good balance between the complexity of Kubernetes and the challenges of creating my own zero-downtime deployment script. Notably, I utilize it only on a single node, which eliminates a lot of potential complexity.

Ansible features a docker_stack module, so let’s delve into how to utilize it:

- name: Create directories if they don't exist
  file:
    path: "{{ item }}"
    state: directory
    owner: root
    group: root
    mode: 0775
  loop:
    - /opt/swarm
    - /opt/swarm/data
    - /opt/swarm/data/traefik
    - /opt/swarm/data/letsencrypt

- name: Create stack file
  ansible.builtin.template:
    src: templates/stackfile.yml.j2
    dest: "/opt/swarm/stack.yml"

- name: Pull an image
  community.docker.docker_image:
    name: ghcr.io/company/service:{{ build }}
    source: pull
    pull:
      platform: amd64

- name: Deploy stack
  docker_stack:
    state: present
    name: stack_name
    prune: true
    compose:
      - "/opt/swarm/stack.yml"

If you’re like me and utilize the GitHub Container Registry (ghcr.io) for Docker images, remember the importance of authentication prior to pulling any images. Skipping this can lead to pull failures.

- name: Log in to ghcr.io
  docker_login:
    registry: ghcr.io
    username: "{{ ghcr_username }}"
    password: "{{ ghcr_token }}"

While this Ansible deployment method for Docker Swarm offers convenience, it does come with certain drawbacks. Notably:

However, it’s worth noting that these limitations aren’t being overlooked. Docker developers are actively addressing this, with discussions and potential solutions being tracked in a dedicated issue: https://github.com/docker/cli/issues/373.

Until there’s an official fix, making your own solution is the way to go.