为什么需要 Portainer?
在自托管和 VPS 运维中,Docker 容器化已经是大势所趋。但命令行操作 Docker 对新手不够友好,随着容器数量增加,管理复杂度急剧上升。Portainer 提供了直观的 Web UI,让你可以:
- 可视化查看所有容器的状态、资源消耗和网络连接
- 一键部署应用:通过模板和 Stack(Compose 文件)快速部署
- 镜像和卷管理:浏览、拉取、删除镜像,管理持久化数据
- 多主机管理:一个 Portainer 实例管理多台服务器
- 权限控制:团队协作时精细控制访问权限
环境准备
假设你有一台运行 Ubuntu 22.04/24.04 或 Debian 12 的 VPS,至少 1GB 内存。
# 更新系统
sudo apt update && sudo apt upgrade -y
# 安装 Docker(如果尚未安装)
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
newgrp docker
# 验证 Docker 运行正常
docker version
docker info
方式一:Docker 容器部署 Portainer(推荐)
最简单的方式是通过 Docker 运行 Portainer Server:
# 创建 Portainer 数据卷(持久化配置)
docker volume create portainer_data
# 启动 Portainer Server
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
参数说明:
-p 9443:9443:将容器的 9443 端口映射到宿主机(HTTPS)-v /var/run/docker.sock:挂载 Docker socket,让 Portainer 能控制 Docker-v portainer_data:/data:持久化 Portainer 的配置和数据
启动后,访问 https://你的IP:9443,设置管理员密码即可进入。
⚠️ 安全提示:首次部署使用 HTTP 8000 端口进行初始设置会更简单:
docker run -d \ --name portainer \ --restart always \ -p 8000:8000 \ -p 9443:9443 \ -p 80:80 \ -v /var/run/docker.sock:/var/run/docker.sock \ -v portainer_data:/data \ portainer/portainer-ce:latest
方式二:使用 Docker Compose 部署
对于更规范的管理,推荐使用 Docker Compose:
# docker-compose.yml
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
networks:
- portainer_net
volumes:
portainer_data:
networks:
portainer_net:
driver: bridge
docker compose up -d
方式三:Traefik 反向代理集成
如果你已经在用 Traefik 作为反向代理,可以通过标签自动配置 Portainer:
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"
networks:
- proxy
volumes:
portainer_data:
networks:
proxy:
external: true
首次使用:Portainer 界面概览
登录后你会看到以下核心功能区域:
1. 环境管理
Portainer 使用"环境"概念来管理不同的 Docker 主机。首次登录会引导你选择:
- 本地环境:当前服务器上的 Docker
- 远程环境:其他服务器上的 Docker 引擎
2. 容器管理
点击"Containers"可以看到所有运行中的容器,每个容器显示:
- CPU/内存使用率
- 运行状态(运行中/已停止/重启中)
- 网络端口映射
- 启动时间
常用操作:
- Start/Stop/Restart:一键控制容器生命周期
- Logs:查看实时日志输出
- Exec:进入容器内部执行命令
- Inspect:查看容器详细配置
- Clone/Update:基于现有配置快速重建
3. 镜像管理
管理所有已下载的 Docker 镜像:
- 拉取新镜像
- 删除无用镜像释放空间
- 查看镜像详情和层信息
定期清理命令(也可通过 Portainer UI 操作):
docker system prune -a --volumes
4. Stack 部署(Compose 管理)
Portainer 最强大的功能之一是 Stack——它允许你通过 Web UI 编辑和部署 Docker Compose 文件。
以部署一个 Nextcloud 为例:
version: '3.8'
services:
nextcloud:
image: nextcloud:latest
container_name: nextcloud
restart: always
ports:
- "8080:80"
volumes:
- nextcloud_data:/var/www/html
- nextcloud_config:/var/www/html/config
environment:
- MYSQL_HOST=db
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nc_user
- MYSQL_PASSWORD=your_secure_password
networks:
- nextcloud_net
db:
image: mariadb:10.11
container_name: nextcloud_db
restart: always
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
volumes:
- db_data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=root_password
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nc_user
- MYSQL_PASSWORD=your_secure_password
networks:
- nextcloud_net
volumes:
nextcloud_data:
nextcloud_config:
db_data:
networks:
nextcloud_net:
driver: bridge
在 Portainer UI 中:
- 左侧菜单 → Stacks → Add stack
- 选择"Build"模式(从本地 docker-compose.yml 文件)
- 粘贴上面的配置
- 点击"Deploy the stack"
高级功能
多主机管理
Portainer 支持统一管理多台服务器的 Docker 引擎:
- 在被管理的服务器上启动 Portainer Agent:
docker volume create portainer_agent_data
docker run -d \
--name portainer-agent \
--restart always \
-p 9001:9001 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_agent_data:/data \
portainer/agent:latest
- 在主 Portainer 中:
- Settings → Environments → Add environment environment
- 选择"Agent"类型
- 输入远程服务器的 IP 和 9001 端口
- 输入 Agent 密钥(在 Settings → Endpoint synchronization 中查看)
安全加固
1. 启用 HTTPS
使用 Let’s Encrypt 证书:
# 安装 certbot
sudo apt install certbot -y
# 获取证书
sudo certbot certonly --standalone -d portainer.yourdomain.com
# 修改 docker-compose.yml 挂载证书
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
- /etc/letsencrypt/live/portainer.yourdomain.com/fullchain.pem:/cert/fullchain.pem
- /etc/letsencrypt/live/portainer.yourdomain.com/privkey.pem:/cert/privkey.pem
2. 配置反向代理认证
在 Nginx 前加一层 Basic Auth:
server {
listen 443 ssl;
server_name portainer.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/portainer.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/portainer.yourdomain.com/privkey.pem;
location / {
auth_basic "Portainer Admin";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass https://localhost:9443;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
生成 htpasswd 文件:
sudo apt install apache2-utils -y
sudo htpasswd -c /etc/nginx/.htpasswd admin
3. 限制网络访问
只允许特定 IP 访问 Portainer:
# 使用 UFW 防火墙
sudo ufw allow from 你的管理IP to any port 9443
sudo ufw deny 9443
备份与恢复
Portainer 的配置存储在 portainer_data 卷中,备份非常简单:
# 备份 Portainer 数据
docker run --rm \
-v portainer_data:/data \
-v $(pwd):/backup \
alpine tar czf /backup/portainer_backup_$(date +%Y%m%d).tar.gz -C /data .
# 恢复
docker run --rm \
-v portainer_data:/data \
-v $(pwd):/backup \
alpine tar xzf /backup/portainer_backup_YYYYMMDD.tar.gz -C /data
监控告警集成
Portainer 本身不提供告警功能,但可以配合外部工具:
使用 Watchtower 自动更新
version: '3.8'
services:
watchtower:
image: containrrr/watchtower
container_name: watchtower
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WATCHTOWER_POLL_INTERVAL=3600 # 每小时检查一次
- WATCHTOWER_CLEANUP=true
- WATCHTOWER_NOTIFICATIONS=shoutrrr
- WATCHTOWER_NOTIFICATION_SHOUTRRR_URLS=discord://your-webhook-url
- WATCHTOWER_NOTIFICATION_SHOUTRRR_TITLE=Portainer Update Alert
使用 Prometheus + Node Exporter
Portainer 提供 API 端点,可以集成到 Prometheus 监控栈中:
- job_name: 'portainer'
static_configs:
- targets: ['localhost:9090'] # Portainer Agent 端口
常见问题与解决
Q1: Portainer 无法连接到 Docker socket
原因:Docker socket 权限问题或容器未正确挂载。
解决:
# 检查 Docker socket 是否存在
ls -la /var/run/docker.sock
# 确认 Portainer 容器正确挂载
docker inspect portainer | grep docker.sock
Q2: 容器启动后立即退出
原因:镜像拉取失败或端口冲突。
解决:
# 查看容器日志
docker logs portainer
# 检查端口占用
ss -tlnp | grep 9443
Q3: 如何迁移 Portainer 到其他服务器?
步骤:
- 在旧服务器上备份
portainer_data卷 - 在新服务器上安装 Docker 和 Portainer
- 将备份数据恢复到新服务器的
portainer_data卷 - 启动 Portainer,导入之前的环境配置
Q4: Portainer CE vs EE 有什么区别?
| 特性 | CE (社区版) | EE (企业版) |
|---|---|---|
| 费用 | 免费 | 付费 |
| 容器管理 | ✅ | ✅ |
| Stack 部署 | ✅ | ✅ |
| 多主机管理 | ✅ | ✅ |
| RBAC 权限 | 基础 | 高级 |
| K8s 管理 | ❌ | ✅ |
| 审计日志 | ❌ | ✅ |
| 技术支持 | 社区 | 官方支持 |
对于个人和小团队,CE 版本完全够用。
最佳实践总结
- 始终使用数据卷:不要将重要数据存储在容器内部,使用命名卷或绑定挂载
- 设置重启策略:所有关键服务都配置
restart: always或restart: unless-stopped - 定期备份:至少每周备份一次 Portainer 数据和容器数据卷
- 使用网络隔离:为不同服务创建独立的 Docker 网络
- 限制暴露端口:只在必要时暴露端口,使用反向代理统一管理入口
- 保持更新:定期更新 Portainer 和所有容器镜像
- 启用日志轮转:防止日志文件占满磁盘空间
替代方案对比
| 工具 | 优点 | 缺点 |
|---|---|---|
| Portainer | 功能全面、UI 美观、社区活跃 | 需要额外资源运行 |
| Docker Compose CLI | 零额外开销、轻量 | 仅适合少量容器 |
| Rancher | 支持 K8s、企业级 | 资源消耗大、复杂度高 |
| Coolify | 类 Heroku 体验、免费 | 较新项目、生态不成熟 |
| Landoop UI | 极简、专注容器 | 功能有限 |
结语
Portainer 是 VPS 运维者的利器,它将复杂的 Docker 操作简化为可视化的点击操作。无论你是刚接触容器的新手,还是需要管理数十个服务的资深运维,Portainer 都能显著提升工作效率。
结合反向代理、自动更新和定期备份,你可以搭建一套可靠的生产级容器管理平台。
本文适用于 Ubuntu 22.04/24.04、Debian 12 及 Docker 24+ 版本。
