Skip to main content

Deploy Portainer Management

Portainer is a lightweight management UI that allows you to easily manage your different Docker environments (Docker hosts or Swarm clusters).

Architecture

In a Docker Swarm cluster, Portainer is deployed as a two-part stack:

  1. Portainer Server: The web UI and central database, running exclusively on a manager Instance.
  2. Portainer Agent: A global service running on every Instance in the cluster (managers and workers), collecting data and sending it back to the server.

Deployment Configuration

Create a docker-compose.yml to deploy Portainer using the following boilerplate, which is optimized for Traefik ingress:

version: '3.8'

services:
agent:
image: portainer/agent:2.40.0
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /var/lib/docker/volumes:/var/lib/docker/volumes
networks:
- portainer-agent
deploy:
mode: global
placement:
constraints:
- node.platform.os == linux

server:
image: portainer/portainer-ce:2.21.0
command: -H tcp://tasks.agent:9001 --tlsskipverify
volumes:
- portainer-data:/data
networks:
- portainer-agent
- traefik-public
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- node.role == manager

restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3

resources:
limits:
cpus: '1'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M

labels:
# Traefik routing configuration
- "traefik.enable=true"
- "traefik.http.routers.portainer.rule=Host(`portainer.<yourdomain>.com`)"
- "traefik.http.routers.portainer.entrypoints=websecure"
- "traefik.http.routers.portainer.tls.certresolver=letsencrypt"
- "traefik.http.services.portainer.loadbalancer.server.port=9000"
- "traefik.docker.network=traefik-public"

networks:
portainer-agent:
driver: overlay
name: portainer-agent
attachable: false

traefik-public:
external: true

volumes:
portainer-data:
name: portainer-data

Best Practices

  1. Agent Security: The portainer-agent network is marked as attachable: false so that rogue containers cannot connect to the agent network to execute arbitrary commands on other nodes.
  2. Resource Constraints: Limits (limits) and reservations (reservations) ensure Portainer runs reliably without starving other mission-critical services of CPU and Memory.
  3. Manager Constraint: The server component is strictly constrained to node.role == manager. Since it interacts heavily with the Swarm control plane, this minimizes latency and avoids security risks associated with running management plane tasks on worker nodes.
  4. Data Persistence: Using a named volume (portainer-data) ensures your configurations, user accounts, and endpoints remain intact across updates or node reboots.