Docker Swarm Initial Setup

Install Docker Engine on the machine using the official installation guide at Ubuntu Install Guide for any machine that does not require the docker build features skip the docker-buildx-plugin.

Swarm Setup

Docker-Swarm-Zonal-Setup

Link to original

Always prefer to have your managers spread across all the regions so that your cluster is able to handle zone failures

Refer to Add manager nodes for fault tolerance to ensure that you have enough manager nodes as per your requirement

Try to have minimal to no load on the manager machines, since all the Traefik instances live on the Docker Swarm Manager hosts, we only have to expose them with HTTPS port on the firewall level.

The Docker Swarm is connected with Docker Swarm Manager and Docker Swarm Worker through the internally managed communication, all the traffic received on the Manager node will be redirected to the applications as necessary

For Forward and Reverse Proxy > Reverse Proxy we will be using Traefik as it is easier and handles all the SSL termination and subdomain reverse proxy management using the labels from the Docker Compose spec file for Docker Swarm

Steps

  1. Initialize the Swarm Cluster Create Swarm
  2. Ensure that the vnet or the subnet allows inter communication on ports Open protocols and ports between the hosts
  3. Add nodes to the swarm
  4. Configure Traefik for SSL & TLS Certificates and use as ReverseProxy - Follow Docker Swarm Configuration Traefik
  5. Create stacks and deploy applications

Optional Steps - Portainer

Configure Portainer and Portainer Agent on the cluster for easy mangement, ensure that Traefik and Portainer stacks are always managed through the CLI and not through the GUI.

services:
  portainer-agent:
    image: portainer/agent:2.33.6
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /var/lib/docker/volumes:/var/lib/docker/volumes
    networks:
      - agent_network
      - traefik_proxy
    ports:
      - 9001:9001
    deploy:
      labels:
        # Enable Service discovery for Traefik
        - "traefik.enable=true"
        - "traefik.http.routers.portainer-agent.rule=Host(`portainer-agent.domain.com`)"
        - "traefik.http.routers.portainer-agent.entrypoints=websecure"
        # Enable TLS
        - "traefik.http.routers.portainer-agent.tls=true"
        # Expose the portainer port number to Traefik
        - "traefik.http.services.portainer-agent.loadbalancer.server.port=9001"
      mode: global
 
  portainer:
    image: portainer/portainer-ce:2.33.6
    command: -H tcp://tasks.portainer-agent:9001 --tlsskipverify
    volumes:
      - portainer_data:/data
    networks:
      - agent_network
      - traefik_proxy
    ports:
      - 9000:9000
      - 9443:9443
      - 8000:8000
    deploy:
      labels:
        # Enable Service discovery for Traefik
        - "traefik.enable=true"
        - "traefik.http.routers.portainer.rule=Host(`portainer.domain.com`)"
        - "traefik.http.routers.portainer.entrypoints=websecure"
        # Enable TLS
        - "traefik.http.routers.portainer.tls=true"
        # Expose the portainer port number to Traefik
        - "traefik.http.services.portainer.loadbalancer.server.port=9000"
 
        - "traefik.docker.network=traefik_proxy"
        # Headers Middleware
        - "traefik.http.middlewares.portainer-headers.headers.customrequestheaders.X-Forwarded-Proto=https"
        - "traefik.http.routers.portainer.middlewares=portainer-headers"
 
        # Sticky sessions for WebSocket stability
        - "traefik.http.services.portainer.loadbalancer.sticky.cookie=true"
        - "traefik.http.services.portainer.loadbalancer.sticky.cookie.name=portainer_sticky"
      mode: replicated
      replicas: 1
      placement:
        constraints:
          - node.hostname == cluster-node-1
networks:
  agent_network:
    external: true
  traefik_proxy:
    external: true
 
volumes:
  portainer_data:

The above creates a Docker Volume on the Docker Swarm Manager node to persist the configuration files and other data, Portainer Agent is deployed as a global task, ensuring that all the nodes in the cluster are being. monitored and managed.

Setup GitOps on Portainer

If you use a VCS for your config files especially Gitlab or a similar service, you can provide a Personal Access Token to the Portainer instance and have it poll the Swarm Stack and auto update the cluster if there are any changes detected for that file GitOps