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: global
ensures 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
-H
sets the agent endpoint. Usingtasks.agent
lets Portainer automatically discover all containers of theagent
service.9001
is the default port on which the agent listens.--tlsskipverify
bypasses 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_network
ensures Portainer can talk to the agent containers.
- Deployment:
mode: replicated
withreplicas: 1
runs 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: true
makes 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
local
driver. driver_opts
specify NFS storage details:device: :/path/to/swarmnfs/portainer/data
indicates the remote NFS path.o: addr=NFS_SERVER_IP,nolock,soft,rw,nfsvers=4
mounts the volume from the NFS server.type: nfs
explicitly 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.yml
is the Compose file name.portainer
is 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>:9443
orhttp://<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.