When managing Docker Swarm clusters, having a user-friendly control panel can simplify operations significantly. Portainer is one such solution—a feature-rich graphical interface that makes container orchestration more approachable. In a Swarm setup, Portainer utilizes a lightweight agent on each node to handle communication and coordination.
In this post, we’ll walk through a Docker Compose file that deploys both the Portainer Server (Enterprise Edition) and the Portainer Agent on a Docker Swarm cluster. We’ll break down each part of the file, focusing on how these services are configured to work together securely and efficiently.
1. Introduction to the Compose File
Below is an anonymized Docker Compose file. Notice that certain paths and IP addresses have been replaced with generic placeholders (e.g., NFS_SERVER_IP and /path/to/swarmnfs/portainer/data) to protect specific environment details.
services:
  agent:
    image: portainer/agent:2.21.5
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /var/lib/docker/volumes:/var/lib/docker/volumes
    networks:
      - agent_network
    deploy:
      mode: global
      placement:
        constraints: [node.platform.os == linux]
  
  portainer:
    image: portainer/portainer-ee:2.21.5
    command: -H tcp://tasks.agent:9001 --tlsskipverify
    ports:
      - "9443:9443"
      - "9000:9000"
      - "8000:8000"
    volumes:
      - portainer_data:/data
    networks:
      - agent_network
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints: [node.role == manager]
  
networks:
  agent_network:
    driver: overlay
    attachable: true
  
volumes:
  portainer_data:
    driver: local
    driver_opts:
      device: :/path/to/swarmnfs/portainer/data
      o: addr=NFS_SERVER_IP,nolock,soft,rw,nfsvers=4
      type: nfs
Let’s break down the significant components in detail.
2. Services
2.1 The Agent Service
services:
  agent:
    image: portainer/agent:2.21.5
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /var/lib/docker/volumes:/var/lib/docker/volumes
    networks:
      - agent_network
    deploy:
      mode: global
      placement:
        constraints: [node.platform.os == linux]
Key Points:
- Image: portainer/agent:2.21.5- The Portainer Agent is a small container that relays instructions between Portainer and each Swarm node.
 
- Volumes:- - /var/run/docker.sock:/var/run/docker.sock
 Grants the agent container direct communication with the Docker daemon on each node.
- - /var/lib/docker/volumes:/var/lib/docker/volumes
 Allows the agent to manage and inspect local Docker volumes if needed.
 
- Network:- Attached to agent_network, so it can communicate with Portainer over a secure overlay network.
 
- Attached to 
- Deployment:- mode: globalensures one container is deployed to every node in the Swarm that meets the placement constraints.
- placement.constraints: [node.platform.os == linux]ensures the agent only runs on Linux nodes.
 
With this configuration, every Linux-based node in the Swarm will host one instance of the Portainer Agent, allowing Portainer to discover and manage resources across the cluster.
2.2 The Portainer Service
  portainer:
    image: portainer/portainer-ee:2.21.5
    command: -H tcp://tasks.agent:9001 --tlsskipverify
    ports:
      - "9443:9443"
      - "9000:9000"
      - "8000:8000"
    volumes:
      - portainer_data:/data
    networks:
      - agent_network
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints: [node.role == manager]
Key Points:
- Image: portainer/portainer-ee:2.21.5- This is the Enterprise Edition of Portainer. Ensure you have the appropriate license for production environments (or use the Community Edition if that’s sufficient for your use case).
 
- Command:- -H tcp://tasks.agent:9001 --tlsskipverify
- -Hsets the agent endpoint. Using- tasks.agentlets Portainer automatically discover all containers of the- agentservice.
- 9001is the default port on which the agent listens.
- --tlsskipverifybypasses TLS verification—used commonly for internal or development setups.
 
- Ports:- 9443:9443: Exposes Portainer’s HTTPS interface.
- 9000:9000: Exposes the HTTP interface (also used for admin if HTTPS is not enforced).
- 8000:8000: Used for Edge agent features, if applicable.
 
- Volumes:- - portainer_data:/data
 Mounts the data volume, which stores Portainer’s settings, users, and other persistent data.
 
- Network:- agent_networkensures Portainer can talk to the agent containers.
 
- Deployment:- mode: replicatedwith- replicas: 1runs one instance of Portainer.
- placement.constraints: [node.role == manager]places Portainer on a manager node, which is recommended for cluster management tools.
 
3. Networks
networks:
  agent_network:
    driver: overlay
    attachable: true
- Overlay network driver allows containers across different nodes to communicate securely.
- attachable: truemakes it possible for other services or containers to attach to this network manually if required.
4. Volumes
volumes:
  portainer_data:
    driver: local
    driver_opts:
      device: :/path/to/swarmnfs/portainer/data
      o: addr=NFS_SERVER_IP,nolock,soft,rw,nfsvers=4
      type: nfs
- portainer_data is defined using the localdriver.
- driver_optsspecify NFS storage details:- device: :/path/to/swarmnfs/portainer/dataindicates the remote NFS path.
- o: addr=NFS_SERVER_IP,nolock,soft,rw,nfsvers=4mounts the volume from the NFS server.
- type: nfsexplicitly sets NFS as the filesystem type.
 
Using an NFS-based volume ensures that Portainer’s data persists externally, which is critical for high availability and backup scenarios.
5. Deploying the Stack
If you save the above YAML as portainer-stack.yml, deploy it to your Docker Swarm with:
docker stack deploy -c portainer-stack.yml portainer
Where:
- portainer-stack.ymlis the Compose file name.
- portaineris the name you assign to the stack.
6. Accessing Portainer
After your services successfully deploy:
- Open a web browser and go to https://<Swarm_Manager_IP>:9443orhttp://<Swarm_Manager_IP>:9000.
- On first use, you’ll be prompted to create an administrative user.
- Once logged in, you should see the Portainer dashboard and be able to manage your Swarm cluster.
Note: If you’re using self-signed certificates or skipped TLS verification, your browser may prompt you about an insecure connection—confirming the exception is typically required.
7. Conclusion
This Docker Compose configuration lays out a standard approach for running Portainer in Docker Swarm:
- Global Agent Deployment ensures each node is automatically managed.
- Single Portainer Server on a manager node centralizes cluster administration.
- NFS-Backed Data provides persistence and resilience for Portainer’s settings and metadata.
- Overlay Network makes inter-container communication seamless and secure within the Swarm.
 
             
         
         
        