Web-based container management UI for Docker, Docker Swarm, and Kubernetes environments with role-based access control and multi-environment support.

Table of Contents#

  1. Overview
  2. Architecture
  3. Installation
  4. Initial Configuration
  5. Multi-Environment Setup
  6. Role-Based Access Control (RBAC)
  7. Application Deployment
  8. Backup and Restore
  9. API Usage
  10. Troubleshooting

1. Overview#

Portainer is an open-source container management platform that provides a graphical interface for managing Docker, Docker Swarm, and Kubernetes environments. It abstracts away CLI complexity and provides user management, access control, and audit logging.

Editions:

EditionNodesFeatures
Community Edition (CE)Up to 5Core management, single-user RBAC, stacks, templates
Business Edition (BE)UnlimitedFull RBAC, registry management, GitOps, activity logs, OAuth/LDAP

2. Architecture#

Portainer consists of two components:

  • Portainer Server: The main application, deployed as a container. Hosts the web UI, API, and database. Only one Server instance is needed per deployment.
  • Portainer Agent: Lightweight container deployed on each remote node. Communicates with the Server over port 9001 (TLS). Required for managing remote Docker standalone hosts and Swarm clusters.

Communication flow:

Browser --> Portainer Server (:9443 HTTPS / :9000 HTTP)
                |
                +--> Local Docker socket (/var/run/docker.sock)
                +--> Remote Agent (:9001) --> Remote Docker socket
                +--> Kubernetes API (:6443)
                +--> Edge Agent (reverse tunnel)

3. Installation#

3.1 Prerequisites#

  • Docker Engine 20.10.0 or newer (CE) or any actively supported version
  • Sufficient privileges to run Docker commands (root or docker group membership)
  • Ports 9443 (HTTPS UI), 9000 (HTTP UI, optional), 8000 (Edge Agent tunnel) available

3.2 Docker Standalone#

# Create a persistent volume for Portainer data
docker volume create portainer_data

# Deploy Portainer CE with HTTPS
docker run -d \
  -p 8000:8000 \
  -p 9443:9443 \
  --name portainer \
  --restart=always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v portainer_data:/data \
  portainer/portainer-ce:lts

Access the UI at https://<host-ip>:9443.

3.3 Docker Swarm#

# Create a persistent volume
docker volume create portainer_data

# Deploy as a Swarm service (manager node only)
docker service create \
  --name portainer \
  --publish 9443:9443 \
  --publish 8000:8000 \
  --replicas=1 \
  --constraint 'node.role == manager' \
  --mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
  --mount type=volume,src=portainer_data,dst=/data \
  portainer/portainer-ce:lts

3.4 Kubernetes#

# Using Helm
helm repo add portainer https://portainer.github.io/k8s/
helm repo update
helm upgrade --install portainer portainer/portainer \
  --namespace portainer --create-namespace \
  --set tls.force=true

3.5 Portainer Agent#

Deploy the agent on remote nodes that the Portainer Server will manage:

# Docker standalone agent
docker run -d \
  -p 9001:9001 \
  --name portainer_agent \
  --restart=always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /var/lib/docker/volumes:/var/lib/docker/volumes \
  portainer/agent:lts

# Swarm agent (deployed as a global service across all nodes)
docker service create \
  --name portainer_agent \
  --publish mode=host,target=9001,published=9001 \
  --mode global \
  --constraint 'node.platform.os == linux' \
  --mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
  --mount type=bind,src=/var/lib/docker/volumes,dst=/var/lib/docker/volumes \
  portainer/agent:lts

4. Initial Configuration#

On first access, Portainer prompts you to:

  1. Create an admin account - set a strong password (minimum 12 characters)
  2. Connect to the local environment - automatically detected if the Docker socket is mounted
  3. Set environment URL - the public URL users will access (important for Edge Agent connections)

After setup, the local Docker environment appears in the dashboard immediately.

5. Multi-Environment Setup#

5.1 Adding Docker Environments#

Navigate to Environments > Add environment > Docker:

MethodWhen to Use
AgentRemote Docker host with the Portainer Agent running
Docker APIDirect TCP connection (requires TLS configuration)
SocketLocal Unix socket (usually the initial environment)
Edge AgentRemote host behind NAT/firewall without inbound connectivity

For Agent connections, enter <remote-ip>:9001 and the environment name.

5.2 Adding Kubernetes Environments#

Navigate to Environments > Add environment > Kubernetes:

  • Agent: Deploy the agent as a DaemonSet, then connect
  • Edge Agent: For clusters behind firewalls
  • kubeconfig import: Provide a kubeconfig file directly

5.3 Edge Agent#

The Edge Agent establishes an outbound tunnel from the remote host to the Portainer Server, requiring no inbound ports:

  1. In Portainer, go to Environments > Add environment > Docker/Kubernetes > Edge Agent
  2. Copy the generated docker run command
  3. Run it on the remote host
  4. The environment appears automatically after the agent connects

Edge Agent uses port 8000 on the Portainer Server for the tunnel.

6. Role-Based Access Control (RBAC)#

6.1 Roles#

RolePermissions
AdministratorFull access to all environments and settings
Helpdesk (BE)Read-only access to all environments
Standard UserAccess only to assigned environments and resources
Read-only UserView-only access to assigned environments

In CE, there are two effective levels: administrator and standard user. Full RBAC requires BE.

6.2 Teams#

Teams group users for easier access management:

  1. Navigate to Users > Teams > Add team
  2. Add users to the team
  3. Assign the team to environments with specific access levels

6.3 Environment Access#

Control which users and teams can access each environment:

  1. Go to Environments > select environment > Access management
  2. Add users or teams
  3. Set the access level (Environment administrator, Operator, Helpdesk, Standard user, Read-only)

7. Application Deployment#

7.1 Containers#

Deploy individual containers through the UI:

  1. Select an environment
  2. Go to Containers > Add container
  3. Configure image, ports, volumes, environment variables, restart policy, resource limits
  4. Click Deploy the container

7.2 Stacks (Compose)#

Stacks are Docker Compose deployments managed through Portainer:

  1. Go to Stacks > Add stack
  2. Choose input method:
    • Web editor - paste or write Compose YAML directly
    • Upload - upload a compose.yaml file
    • Repository - pull from a Git repository (GitOps, auto-redeploy supported in BE)
    • Custom template - use a previously saved template
  3. Add environment variables if needed
  4. Click Deploy the stack

7.3 App Templates#

Templates provide one-click deployment of common applications:

  • Portainer ships with built-in templates (NGINX, MySQL, Redis, WordPress, etc.)
  • Custom templates: App Templates > Custom Templates > Add Custom Template
  • External template definitions: set a URL in Settings > App Templates > URL

8. Backup and Restore#

Manual Backup#

Portainer stores all configuration in the portainer_data volume:

# Stop Portainer
docker stop portainer

# Backup the volume
docker run --rm \
  -v portainer_data:/data \
  -v $(pwd):/backup \
  busybox tar czf /backup/portainer-backup.tar.gz -C /data .

# Restart Portainer
docker start portainer

Automated Backup (BE)#

Business Edition provides built-in backup scheduling via Settings > Backup configuration.

Restore#

# Stop Portainer
docker stop portainer

# Restore the volume
docker run --rm \
  -v portainer_data:/data \
  -v $(pwd):/backup \
  busybox sh -c "cd /data && tar xzf /backup/portainer-backup.tar.gz"

# Start Portainer
docker start portainer

Resetting the Admin Password#

If you lose access to the admin account:

docker stop portainer

# Generate a new bcrypt hash
docker run --rm httpd:2.4-alpine htpasswd -nbB admin <new-password> | cut -d ":" -f 2

# Reset the password
docker run --rm -v portainer_data:/data portainer/helper-reset-password
# Follow the prompts

docker start portainer

9. API Usage#

Portainer exposes a REST API on the same port as the web UI.

Authentication#

# Get a JWT token
TOKEN=$(curl -sk -X POST "https://<portainer-url>:9443/api/auth" \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"<password>"}' | jq -r '.jwt')

# Use the token in subsequent requests
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://<portainer-url>:9443/api/endpoints"

Common API Endpoints#

EndpointMethodDescription
/api/authPOSTAuthenticate and get JWT
/api/endpointsGETList all environments
/api/endpoints/<id>/docker/containers/jsonGETList containers in an environment
/api/stacksGETList all stacks
/api/stacksPOSTCreate a new stack
/api/usersGETList all users
/api/teamsGETList all teams
/api/templatesGETList app templates
/api/backupPOSTTrigger a backup (BE)
/api/statusGETGet Portainer status and version

API Example: Deploy a Stack#

curl -sk -X POST "https://<portainer-url>:9443/api/stacks/create/standalone/string?endpointId=1" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-stack",
    "stackFileContent": "services:\n  web:\n    image: nginx:alpine\n    ports:\n      - \"8080:80\""
  }'

Full API documentation is available as Swagger/OpenAPI at https://<portainer-url>:9443/api/docs.

Troubleshooting#

IssueCauseSolution
Cannot access UI after installationWrong port or firewall blockingVerify port 9443 is open; check docker logs portainer
Unauthorized when adding AgentAgent and Server version mismatchEnsure Agent and Server use the same major version
Agent environment shows as DownNetwork connectivity or firewallVerify port 9001 is reachable between Server and Agent
Edge Agent not connectingPort 8000 blocked or wrong Server URLEnsure port 8000 is accessible and the Portainer URL is correct in Edge Agent config
Stack deployment failsInvalid Compose syntax or image pull errorCheck the stack logs; validate YAML with docker compose config
Admin password lostNo password reset option in UIUse the helper-reset-password container (see Backup section)
Docker socket permission deniedPortainer container cannot access socketEnsure -v /var/run/docker.sock:/var/run/docker.sock is set and the socket has correct permissions
Slow UI with many containersLarge number of containers or frequent pollingAdjust polling interval in Settings, or reduce container count
TLS certificate errorSelf-signed cert on PortainerImport a valid cert via --sslcert and --sslkey flags, or trust the self-signed cert
Upgrade breaks configurationDatabase schema changeAlways backup portainer_data before upgrading; check release notes

See Also#

Sources#