> For the complete documentation index, see [llms.txt](https://docs.helmut.de/helmut4-releases/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.helmut.de/helmut4-releases/v4.13.0/getting-started/additional-configurations/communication-ssl-proxy-and-ports/portainer-agent-for-cluster-environments.md).

# Portainer Agent for Cluster Environments

### Portainer Agent Setup for a Three-Node Docker Swarm Cluster

Using Portainer with the **Portainer Agent** in a Docker Swarm cluster is optional, but recommended for easier centralized management.

A Helmut4 cluster can also be operated with separate Portainer instances on each host. However, this has a limitation: a stack created or edited in one Portainer instance is not automatically manageable from another Portainer instance.

By deploying Portainer once as a central server and running the Portainer Agent on each Swarm node, the complete cluster can be managed from a single Portainer web interface.

This allows the complete Docker Swarm cluster to be managed from a single Portainer UI, including services, nodes, networks, volumes, and stacks.

Portainer consists of two components:

```
Portainer Server
Provides the web interface and stores the Portainer configuration.

Portainer Agent
Runs on each Swarm node and allows Portainer to communicate with the Docker environment.
```

In a Docker Swarm setup, Portainer is typically deployed as one server instance plus an agent service running globally on all nodes.

***

### Architecture Overview

A typical three-node setup looks like this:

```
Docker Swarm Cluster
├── Node 1: Manager
│   ├── Portainer Server
│   └── Portainer Agent
├── Node 2: Manager or Worker
│   └── Portainer Agent
└── Node 3: Manager or Worker
    └── Portainer Agent
```

Only one Portainer web interface is required.

The Portainer Agent is deployed as a **global service**, which means Docker automatically starts one agent container on each Swarm node.

***

### Portainer Data Volume

The Portainer Server stores its configuration, users, registry settings, environment information, and stack metadata in its `/data` directory.

For this setup, a dedicated server directory is mounted on all hosts:

```
/mnt/portainer_data
```

This directory is mounted into the Portainer Server container as:

```
/data
```

This makes the Portainer data easier to locate, back up, and restore than an unnamed Docker-managed volume.

Example mapping:

```yaml
volumes:
  - /mnt/portainer_data:/data
```

The directory must exist on every host that is allowed to run the Portainer Server.

Create the mount point on each host:

```bash
mkdir -p /mnt/portainer_data
```

Mount the shared storage to this directory on each host according to your storage configuration.

After mounting, verify that all hosts can access the same shared directory:

```bash
ls -la /mnt/portainer_data
```

Recommended permissions:

```bash
chmod 700 /mnt/portainer_data
```

Make sure the shared storage is mounted before deploying or starting the Portainer Server.

***

### Important Note About Swarm Scheduling

When using a local host directory such as:

```
/mnt/portainer_data
```

the Portainer Server should be pinned to a specific manager node.

Otherwise, Docker Swarm may reschedule the Portainer Server to another manager node where `/mnt/portainer_data` is either empty or contains different data.

For a predictable setup, use a placement constraint such as:

```yaml
placement:
  constraints:
    - node.hostname == helmut-server-01
```

Replace `helmut-server-01` with the actual hostname of the manager node that should run the Portainer Server.

If automatic failover between manager nodes is required, `/mnt/portainer_data` must be provided by shared storage that is available on all possible manager nodes.

For most standard installations, pinning Portainer to one manager node and backing up `/mnt/portainer_data` regularly is the simpler and safer option.

***

### Requirements

Before deploying Portainer, make sure the following requirements are met:

```
Docker is installed on all nodes
Docker Swarm mode is enabled
All three nodes have joined the Swarm cluster
Overlay networking is working
The deployment is executed from a Swarm manager node
Port 9001 is reachable between the nodes
The directory /mnt/portainer_data exists on the selected Portainer Server node
```

Portainer’s Swarm Agent requires communication between the nodes on port `9001`. The Portainer Server must also be able to reach the agents on this port.

***

### Recommended Portainer Deployment Method

Instead of starting Portainer individually on each host with `docker run`, deploy Portainer as a Docker Swarm stack.

This provides one central Portainer instance for the whole cluster.

Create a file called:

```
portainer-agent-stack.yml
```

Example configuration:

```yaml
version: "3.8"

services:
  agent:
    image: portainer/agent:lts
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /var/lib/docker/volumes:/var/lib/docker/volumes
    networks:
      - portainer_agent_network
    deploy:
      mode: global
      placement:
        constraints:
          - node.platform.os == linux
      resources:
        limits:
          memory: 256M

  portainer:
    image: portainer/portainer-ce:lts
    command: -H tcp://tasks.agent:9001 --tlsskipverify
    ports:
      - "9000:9000"
    volumes:
      - /mnt/portainer_data:/data
    networks:
      - portainer_agent_network
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints:
          - node.role == manager
      resources:
        limits:
          memory: 512M

networks:
  portainer_agent_network:
    driver: overlay
    attachable: true
```

***

### Deploy Portainer

Run the deployment from one of the Swarm manager nodes:

```bash
docker stack deploy -c portainer-agent-stack.yml portainer
```

Check if the services are running:

```bash
docker service ls
```

You should see two services:

```
portainer_agent
portainer_portainer
```

The agent service should run once on every Swarm node.

You can verify this with:

```bash
docker service ps portainer_agent
```

For a three-node cluster, three agent tasks should be listed.

To check where the Portainer Server is running, use:

```bash
docker service ps portainer_portainer
```

***

### Access Portainer

Open Portainer in a browser:

```
http://<manager-node-ip>:9000
```

Example:

```
http://192.168.1.10:9000
```

The first time Portainer is opened, create the initial administrator account.

Use a strong password and store it securely.

***

### Why This Setup Is Better Than Three Individual Instances

The previous setup installed a standalone Portainer instance on each host:

```
Node 1 → Portainer instance 1
Node 2 → Portainer instance 2
Node 3 → Portainer instance 3
```

This causes operational limitations because each Portainer instance manages its own local Docker endpoint. A stack created on one Portainer instance is not directly editable from another Portainer instance.

With the Swarm Agent setup, the structure changes to:

```
One Portainer Server
↓
Portainer Agents on all Swarm nodes
↓
Central management of the complete cluster
```

This means stacks and services can be managed centrally from one Portainer UI.

***

### Optional: HTTPS Port

Current Portainer installations commonly expose the web UI on port `9443` for HTTPS.

If HTTPS access to Portainer is required, the port mapping can be extended:

```yaml
ports:
  - "9000:9000"
  - "9443:9443"
```

Then access Portainer through:

```
https://<manager-node-ip>:9443
```

For environments that already use port `9000`, it is fine to keep `9000` as long as it matches the existing operational standard.

***

### Optional: Admin Password Preconfiguration

If required, the administrator password can be preconfigured by adding the `--admin-password` option to the Portainer command.

Example:

```yaml
command: >
  -H tcp://tasks.agent:9001
  --tlsskipverify
  --admin-password='$2y$05$WbcqfTqVa2T58lGrLO7Tp.30DMjKFo.6O4.XAmfBFg4a0jrVSbdW.'
```

For production environments, use a unique password hash instead of a shared default value.

***

### Configure the Docker Registry

After Portainer is running, configure the required Docker registry once in the central Portainer instance.

Please refer to the documentation: [Helmut4 Cluster System](/helmut4-releases/v4.13.0/getting-started/installation-guide/helmut4-server/helmut4-cluster-system.md#moovit-registry-for-portainer)

***

### Backup Recommendation

Because the Portainer Server configuration is stored in:

```
/mnt/portainer_data
```

this directory should be included in the regular system backup.

At minimum, back up this directory before:

```
updating Portainer
changing the Portainer deployment
moving Portainer to another node
performing major Docker or Swarm maintenance
```

***

### Important Notes

Portainer should only be deployed once for the Swarm cluster.

Do not install a separate standalone Portainer instance on each node.

The Portainer Agent must run on every node. This is handled automatically by the `global` deployment mode.

The Portainer Server should run on a defined manager node when using a local host directory for `/mnt/portainer_data`.

Make sure port `9001` is not blocked between the Swarm nodes.

Restrict access to the Portainer web interface to trusted administrators only.

Back up `/mnt/portainer_data` regularly.

***

### Summary

For a three-node Helmut4 Docker Swarm environment, the recommended Portainer setup is:

```
One Portainer Server instance
One Portainer Agent container on each Swarm node
One central Portainer web interface
Dedicated Portainer data directory on the host: /mnt/portainer_data
One shared view of the complete Swarm cluster
```

This avoids the limitations of separate Portainer installations and allows the cluster to be managed consistently from a single location.
