D10.3 Services & Stacks 🚀

docker_swarm_service module

tasks:

  # ── Replicated service ─────────────────────
  - name: "🌐 Nginx service"
    community.docker.docker_swarm_service:
      name:           nginx
      image:          "nginx:1.25-alpine"
      state:          present
      replicas:       3             # ← 3 αντίγραφα
      publish:
        - published_port: 80
          target_port:    80
          protocol:       tcp
          mode:           ingress   # ← Swarm load balancing
      networks:
        - name: myapp_network
      placement:
        constraints:
          - "node.role == worker"   # ← μόνο σε workers
      labels:
        app:     nginx
        version: "1.25"

  # ── Global service (σε κάθε node) ─────────
  - name: "📡 Node Exporter (global)"
    community.docker.docker_swarm_service:
      name:    node_exporter
      image:   "prom/node-exporter:v1.7.0"
      state:   present
      mode:    global              # ← 1 σε ΚΑΘΕ node!
      mounts:
        - source: /
          target: /host
          type:   bind
          readonly: true
      publish:
        - published_port: 9100
          target_port:    9100
          mode:           host     # ← host mode (όχι ingress)

  # ── Constraints & Placement ────────────────
  - name: "🐘 Database service (manager only)"
    community.docker.docker_swarm_service:
      name:  postgres
      image: "postgres:15-alpine"
      state: present
      replicas: 1
      placement:
        constraints:
          - "node.role == manager"
          - "node.labels.storage == true"    # ← custom label
      env:
        POSTGRES_PASSWORD_FILE: /run/secrets/pg_pass
      secrets:
        - secret_name: pg_password
          filename:    /run/secrets/pg_pass

Overlay Network

tasks:

  - name: "🌐 Overlay network"
    community.docker.docker_network:
      name:   myapp_network
      driver: overlay    # ← multi-host network!
      state:  present
      attachable: true   # ← επιτρέπει standalone containers
      labels:
        stack: myapp

Stack deployment (Docker Compose style)

tasks:

  # ── Ανέβασμα compose file ──────────────────
  - name: Stack compose file
    ansible.builtin.template:
      src:  templates/myapp-stack.yml.j2
      dest: /opt/stacks/myapp.yml
      mode: '0640'

  # ── Deploy stack ───────────────────────────
  - name: "🚀 Deploy myapp stack"
    ansible.builtin.command:
      cmd: >
        docker stack deploy
        --compose-file /opt/stacks/myapp.yml
        --with-registry-auth
        myapp
    delegate_to: manager-01
    changed_when: true
# templates/myapp-stack.yml.j2
version: '3.8'

services:

  nginx:
    image: "nginx:1.25-alpine"
    deploy:
      replicas: 3
      update_config:
        parallelism:   1
        delay:         10s
        failure_action: rollback
      restart_policy:
        condition: on-failure
    ports:
      - "80:80"
    networks:
      - frontend

  app:
    image: "myapp:{{ app_version }}"
    deploy:
      replicas: 2
    networks:
      - frontend
      - backend
    secrets:
      - app_secret

  postgres:
    image: "postgres:15-alpine"
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == manager]
    networks:
      - backend
    secrets:
      - pg_password
    volumes:
      - postgres_data:/var/lib/postgresql/data

networks:
  frontend:
    driver: overlay
  backend:
    driver: overlay
    internal: true

secrets:
  pg_password:
    external: true
  app_secret:
    external: true

volumes:
  postgres_data:
    driver: local

Σύνοψη D10.3

Services & Stacks
│
├── docker_swarm_service:
│   ├── replicas: N → load balanced
│   ├── mode: global → 1 per node
│   ├── publish: ingress (LB) ή host
│   └── placement: constraints + preferences
│
├── Overlay network: multi-host, auto-DNS
│
└── Stack: docker stack deploy --compose-file
    └── Ολόκληρη εφαρμογή ως ένα unit