Web-based container management UI for Docker, Docker Swarm, and Kubernetes environments with role-based access control and multi-environment support.
Table of Contents#
- Overview
- Architecture
- Installation
- 3.1 Prerequisites
- 3.2 Docker Standalone
- 3.3 Docker Swarm
- 3.4 Kubernetes
- 3.5 Portainer Agent
- Initial Configuration
- Multi-Environment Setup
- Role-Based Access Control (RBAC)
- 6.1 Roles
- 6.2 Teams
- 6.3 Environment Access
- Application Deployment
- 7.1 Containers
- 7.2 Stacks (Compose)
- 7.3 App Templates
- Backup and Restore
- API Usage
- 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.
- Project Homepage: portainer.io
- Documentation: docs.portainer.io
- License: Zlib (Community Edition), Commercial (Business Edition)
Editions:
| Edition | Nodes | Features |
|---|---|---|
| Community Edition (CE) | Up to 5 | Core management, single-user RBAC, stacks, templates |
| Business Edition (BE) | Unlimited | Full 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:ltsAccess 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:lts3.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=true3.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:lts4. Initial Configuration#
On first access, Portainer prompts you to:
- Create an admin account - set a strong password (minimum 12 characters)
- Connect to the local environment - automatically detected if the Docker socket is mounted
- 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:
| Method | When to Use |
|---|---|
| Agent | Remote Docker host with the Portainer Agent running |
| Docker API | Direct TCP connection (requires TLS configuration) |
| Socket | Local Unix socket (usually the initial environment) |
| Edge Agent | Remote 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:
- In Portainer, go to Environments > Add environment > Docker/Kubernetes > Edge Agent
- Copy the generated
docker runcommand - Run it on the remote host
- 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#
| Role | Permissions |
|---|---|
| Administrator | Full access to all environments and settings |
| Helpdesk (BE) | Read-only access to all environments |
| Standard User | Access only to assigned environments and resources |
| Read-only User | View-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:
- Navigate to Users > Teams > Add team
- Add users to the team
- Assign the team to environments with specific access levels
6.3 Environment Access#
Control which users and teams can access each environment:
- Go to Environments > select environment > Access management
- Add users or teams
- Set the access level (Environment administrator, Operator, Helpdesk, Standard user, Read-only)
7. Application Deployment#
7.1 Containers#
Deploy individual containers through the UI:
- Select an environment
- Go to Containers > Add container
- Configure image, ports, volumes, environment variables, restart policy, resource limits
- Click Deploy the container
7.2 Stacks (Compose)#
Stacks are Docker Compose deployments managed through Portainer:
- Go to Stacks > Add stack
- Choose input method:
- Web editor - paste or write Compose YAML directly
- Upload - upload a
compose.yamlfile - Repository - pull from a Git repository (GitOps, auto-redeploy supported in BE)
- Custom template - use a previously saved template
- Add environment variables if needed
- 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 portainerAutomated 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 portainerResetting 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 portainer9. 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#
| Endpoint | Method | Description |
|---|---|---|
/api/auth | POST | Authenticate and get JWT |
/api/endpoints | GET | List all environments |
/api/endpoints/<id>/docker/containers/json | GET | List containers in an environment |
/api/stacks | GET | List all stacks |
/api/stacks | POST | Create a new stack |
/api/users | GET | List all users |
/api/teams | GET | List all teams |
/api/templates | GET | List app templates |
/api/backup | POST | Trigger a backup (BE) |
/api/status | GET | Get 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#
| Issue | Cause | Solution |
|---|---|---|
| Cannot access UI after installation | Wrong port or firewall blocking | Verify port 9443 is open; check docker logs portainer |
Unauthorized when adding Agent | Agent and Server version mismatch | Ensure Agent and Server use the same major version |
Agent environment shows as Down | Network connectivity or firewall | Verify port 9001 is reachable between Server and Agent |
| Edge Agent not connecting | Port 8000 blocked or wrong Server URL | Ensure port 8000 is accessible and the Portainer URL is correct in Edge Agent config |
| Stack deployment fails | Invalid Compose syntax or image pull error | Check the stack logs; validate YAML with docker compose config |
| Admin password lost | No password reset option in UI | Use the helper-reset-password container (see Backup section) |
| Docker socket permission denied | Portainer container cannot access socket | Ensure -v /var/run/docker.sock:/var/run/docker.sock is set and the socket has correct permissions |
| Slow UI with many containers | Large number of containers or frequent polling | Adjust polling interval in Settings, or reduce container count |
| TLS certificate error | Self-signed cert on Portainer | Import a valid cert via --sslcert and --sslkey flags, or trust the self-signed cert |
| Upgrade breaks configuration | Database schema change | Always backup portainer_data before upgrading; check release notes |