Why You Need a Docker GUI
If you’ve used Docker, you’ve probably been through moments like these:
- Wanting to check a container’s logs but needing to type
docker logs -f container-name - Needing to restart a container but first finding its container ID
- Wanting to delete old images to free up space but forgetting
docker image pruneflags - Wanting to monitor resource usage, relying on
docker statsmanual refreshes
For individual developers or small teams, Portainer is the ultimate solution to告别 command-line anxiety. It’s an open-source Docker GUI management tool that can be deployed with a single command, supporting full lifecycle management of containers, images, networks, volumes, and Stacks (Compose).
Portainer Core Features
| Feature | Description |
|---|---|
| Container Management | Start/stop/restart/delete containers, view real-time logs |
| Image Management | Pull/delete/import images, build custom images |
| Network Management | Visually create and manage Docker networks |
| Volume Management | Manage data volumes, backup/restore container data |
| Stack Deployment | Deploy multi-container apps with Docker Compose YAML in one click |
| Resource Monitoring | Real-time CPU, memory, and network usage |
| Terminal Access | Access container shells directly from the browser |
| Multi-Environment | Manage local Docker and remote Swarm/K8s clusters from one interface |
Step 1: Installing Portainer
Method 1: Docker Container Deployment (Recommended)
# 1. Create a Portainer data volume
docker volume create portainer_data
# 2. Start Portainer CE (Community Edition)
docker run -d \
--name portainer \
--restart=always \
-p 9443:9443 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:latest
Tip: If you want to use HTTP (internal network only), you can additionally map port 8000 and add
--listen-port 8000.
Method 2: Using Docker Compose
version: '3.8'
services:
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
restart: always
ports:
- "9443:9443"
- "8000:8000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
volumes:
portainer_data:
docker compose up -d
Setting the Admin Password
When you first visit https://your-ip:9443, the system will ask you to set an admin password. Remember this password — Portainer provides no password recovery. Use a strong password of 16+ characters.
Step 2: Getting Familiar with the Interface
Dashboard
After logging in, you’ll see the dashboard showing:
- Server Overview: CPU, memory, and disk usage
- Container Stats: Running/stopped/total count
- Image Stats: Local image count and total size
- Quick Actions: Create container, deploy Stack, create volume
Left Navigation Bar
| Menu Item | Purpose |
|---|---|
| Containers | Manage all containers |
| Images | Manage images |
| Volumes | Manage data volumes |
| Networks | Manage networks |
| Stacks | Manage Compose Stacks |
| Registry | Image registry |
| Templates | One-click app templates |
Step 3: Hands-On — Deploying Common Services
3.1 Deploying Nextcloud Using a Stack
Click Stacks → Add stack in the left sidebar, select Web Editor, and paste the following:
version: '3.8'
services:
app:
image: nextcloud:latest
container_name: nextcloud
restart: always
ports:
- "8080:80"
volumes:
- nextcloud_data:/var/www/html
- nextcloud_config:/var/www/html/config
- nextcloud_apps:/var/www/html/apps
environment:
- MYSQL_HOST=db
- MYSQL_PASSWORD=nextcloud_pass
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
- TZ=Asia/Shanghai
db:
image: mariadb:10.6
container_name: nextcloud_db
restart: always
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
volumes:
- db_data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=rootpass
- MYSQL_PASSWORD=nextcloud_pass
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
- TZ=Asia/Shanghai
volumes:
nextcloud_data:
nextcloud_config:
nextcloud_apps:
db_data:
Click Deploy the stack, and after a few minutes Nextcloud will be accessible at http://your-ip:8080.
3.2 Deploying Home Assistant
version: '3'
services:
homeassistant:
container_name: homeassistant
restart: unless-stopped
image: ghcr.io/home-assistant/home-assistant:stable
volumes:
- ha_config:/config
- /etc/localtime:/etc/localtime:ro
environment:
- TZ=Asia/Shanghai
privileged: true
networks:
- ha_network
ports:
- "8123:8123"
volumes:
ha_config:
networks:
ha_network:
driver: bridge
3.3 Bulk Managing Existing Containers
In the Containers page, you can:
- Batch start/stop: Check multiple containers → click action buttons at the top
- One-click restart: When encountering memory leaks, select container → Restart
- View logs: Click container name → Logs tab
- Access terminal: Click container name → Console tab → Connect to enter the container Shell
- Edit configuration: Click container name → Config tab to modify port mappings, environment variables, etc.
Step 4: Advanced Tips
4.1 Adding Domain and HTTPS with Traefik
version: '3.8'
services:
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
labels:
- "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=9443"
traefik:
image: traefik:v3.0
container_name: traefik
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik.yml:/etc/traefik/traefik.yml:ro
- acme_data:/acero
labels:
- "traefik.enable=true"
volumes:
portainer_data:
acme_data:
4.2 Automatic Portainer Data Backup
Portainer’s configuration and data are stored in a Docker volume. Regular backups are essential:
#!/bin/bash
# backup-portainer.sh
BACKUP_DIR="/opt/backups/portainer"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
mkdir -p "$BACKUP_DIR"
# Backup Portainer data volume
docker run --rm \
-v portainer_data:/data:ro \
-v "$BACKUP_DIR":/backup \
alpine tar czf /backup/portainer_backup_$TIMESTAMP.tar.gz -C /data .
# Keep only the last 7 days of backups
find "$BACKUP_DIR" -name "portainer_backup_*.tar.gz" -mtime +7 -delete
echo "Backup completed: portainer_backup_$TIMESTAMP.tar.gz"
4.3 Setting Resource Limits
services:
portainer:
image: portainer/portainer-ce:latest
restart: always
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
reservations:
cpus: '0.25'
memory: 128M
Step 5: Security Hardening
5.1 Enabling Two-Factor Authentication (T2FA)
Portainer Business Edition supports TOTP two-factor authentication. Community Edition users can use Nginx/Caddy reverse proxy to implement IP whitelist access.
5.2 Restricting Access Sources
# Nginx reverse proxy config example
server {
listen 443 ssl http2;
server_name portainer.yourdomain.com;
# Allow only specific IP ranges
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
location / {
proxy_pass https://localhost:9443;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_ssl_server_name on;
}
}
5.3 Security Best Practices
- Never expose Portainer to the public internet without adequate protection measures
- Use a strong password for the admin account
- Regularly update the Portainer image to the latest version
- Enable firewall rules to only allow trusted IPs on port 9443
- Pair with Tailscale for secure remote access
Frequently Asked Questions
Q1: What’s the difference between Portainer CE and BE?
| Feature | Community Edition (CE) | Business Edition (BE) |
|---|---|---|
| Price | Free | Paid |
| Multi-environment | ✅ | ✅ |
| Two-factor auth | ❌ | ✅ |
| Audit logs | ❌ | ✅ |
| Role-based permissions | Basic | Advanced |
| Support | Community | Official |
For individual users and small teams, the CE version is more than enough.
Q2: Does Portainer affect Docker performance?
No. Portainer is just a management interface — it communicates with the Docker daemon through the Docker API and doesn’t consume extra resources. The only thing to note is that its Web UI and embedded SQLite database use a small amount of RAM, typically 100-200MB.
Q3: How do I migrate from command-line to Portainer?
You don’t need to migrate! Portainer manages the same Docker environment. Containers, images, and networks created via command-line are visible and manageable in Portainer. The reverse is also true.
Q4: Does Portainer support Kubernetes?
Yes. Portainer supports managing Docker Swarm and Kubernetes clusters. In K8s scenarios, it provides a more intuitive GUI for managing Deployments, Services, ConfigMaps, and other resources.
Summary
Portainer is one of the most popular GUI management tools in the Docker ecosystem. Its core value lies in:
- Lowering the barrier: Letting users unfamiliar with command-line manage containers
- Improving efficiency: Visual operations are much faster than typing commands
- Centralized management: One interface to manage all Docker resources
- Reducing errors: Visual confirmation prevents accidental container deletion
Whether you’re new to Docker or an experienced DevOps engineer, Portainer is worth deploying on your VPS. One command to install, a few minutes to get started — and command-line anxiety becomes a thing of the past.
Take action now: Run those three installation commands on your VPS, open your browser, and explore your Docker world visually!
