Portainer CE实战:飞牛部署、容器管理与远程访问
前言
这篇从飞牛 NAS 上部署 Portainer CE 开始,先确认 Docker 环境,再拉取portainer/portainer-ce:latest,创建portainer_data数据卷,并通过9000:9000暴露 Web 管理页面。
首次打开 Portainer 后创建管理员账号,再依次查看容器状态、容器日志、镜像、数据卷和用户管理页面,让它从“能打开”走到真正可以管理宿主机 Docker 环境。
后半部分继续把9000做成外部访问入口,并配置固定二级子域名。
整篇重点放在“飞牛—Portainer—Docker Socket—容器管理—远程访问”这条链路上,同时说明systemctl status -v写法可疑、latest不等于固定版本,以及 Docker Socket 和公网后台带来的高权限风险。
这篇也不会把Portainer写成“新手不用懂Docker”的捷径。WebUI确实降低了操作门槛,但容器、镜像、卷、端口和网络之间的关系仍然存在。真正适合长期使用的方式,是把Portainer当成可视化管理层,而不是把底层Docker概念全部跳过去。
实际使用时,我更关心的是“已有Docker环境能不能直接纳入管理”,而不是重新创建一套新环境。Portainer通过Docker Socket读取宿主机现有资源,所以部署完成后就能继续查看已经在飞牛里运行的容器、镜像和数据卷。远程部分则把问题从“容器怎么管”变成“这个高权限管理页怎么从外面安全进入”,因此文章会把公网访问和权限风险放在同一条主线里,而不是只强调方便。
1 Portainer CE解决的不是“不会Docker”,而是管理入口太分散
Docker 命令本身并不复杂。
真正麻烦的是项目多以后:
- 容器状态要看
docker ps; - 日志要看
docker logs; - 镜像、数据卷、网络又是另一套命令;
- 新建和重启服务还要来回切终端。
Portainer CE 更像是:
给 Docker 增加一层 Web 管理界面。
它不改变底层 Docker,也不会让 Docker 命令失效。
2 这类Web面板最大的价值,是把状态和操作集中起来
Portainer CE 常见能做的事情包括:
- 查看容器状态;
- 启动、停止、重启容器;
- 查看日志;
- 管理镜像;
- 管理卷;
- 管理网络;
- 创建 Stack;
- 管理用户。
真正适合的场景是:
- 家庭服务器;
- NAS;
- Home Lab;
- 小型开发环境;
- 不想频繁切终端的用户。
它更像小型 Docker 环境的可视化管理层,而不是大型集群编排平台。
3 先在飞牛开启SSH
进入飞牛设置,打开 SSH:
继续确认:
再从终端连接:
后面的镜像拉取、数据卷和容器启动都在 SSH 里完成。
4 先检查Docker是否可用
执行:
docker-vsystemctl status-v飞牛主页也能直接查看 Docker 状态:
其中:
docker -v
可以确认 Docker 命令是否存在。
但:
systemctl status -v
这个写法比较可疑。
如果执行时报参数错误,不应该直接判断 Docker 没启动,而是先确认真正要查看的服务名称和 systemctl 参数。
代码块仍按现有内容保留。
5 拉取Portainer CE镜像
执行:
dockerpull portainer/portainer-ce:latest这里使用:
portainer/portainer-ce:latest
latest表示拉取当前仓库标记为 latest 的镜像。
它的好处是省得手动写版本号,但缺点也很明显:
以后重新拉取时,拿到的具体版本可能和现在不同。
如果准备长期稳定运行,更适合显式固定版本。
6 创建持久化数据卷
执行:
dockervolume create portainer_data数据卷名称:
portainer_data
它主要保存 Portainer 自身的数据,比如:
- 用户;
- 设置;
- Endpoint / Environment信息;
- 管理配置。
这样即使 Portainer 容器本身重建,配置也可以继续保留。
7 启动Portainer容器
执行:
dockerrun-d\-p8001:8000\-p9000:9000\--name=portainer\--restart=always\-v/var/run/docker.sock:/var/run/docker.sock\-vportainer_data:/data\portainer/portainer-ce:latest这条命令里有几个关键点。
端口:
8001:80009000:9000
容器名:
portainer
重启策略:
always
Docker Socket:
/var/run/docker.sock:/var/run/docker.sock
数据卷:
portainer_data:/data
其中真正决定 Portainer 能不能管理本机 Docker 的,就是 Docker Socket。
8 Docker Socket意味着Portainer权限很高
挂载:
/var/run/docker.sock
以后,Portainer 可以和宿主机 Docker Daemon 直接通信。
这也是它能:
- 查看容器;
- 启停容器;
- 创建服务;
- 管理镜像;
- 管理卷
的原因。
但同样意味着:
Portainer管理员账号接近Docker宿主机管理入口。
所以它不是普通信息展示页。
这也是后面做公网访问时最需要注意的地方。
9 查看Portainer容器状态
执行:
dockerps可以确认 Portainer 容器是否处于运行状态。
然后看日志:
dockerlogs portainer如果容器没有正常启动,日志会比单纯看docker ps更有帮助。
10 通过9000进入Portainer WebUI
浏览器访问:
http://飞牛IP:9000
能看到页面以后,说明:
浏览器 → 飞牛9000 → Portainer
已经跑通。
这里使用9000是这篇现有部署方式的一部分。
如果后续使用不同Portainer版本或不同部署方式,实际管理端口可能需要重新确认。
11 第一次进入先创建管理员账号
初始化页面:
建议设置:
- 独立密码;
- 足够长度;
- 不和其他网站复用。
进入首页:
到这里,Portainer 才真正完成初始化。
12 先看容器列表
进入容器页面:
可以看到:
- 容器名称;
- 状态;
- 端口;
- 基础信息。
这一步最大的价值是:
不用先回忆容器名,再执行 docker ps。
13 容器日志可以直接在页面里看
进入某个容器:
继续:
日志页面:
如果服务出问题,这里可以直接看当前容器输出。
不过“能看到日志”不代表已经有长期日志留存。
Portainer这里只是把现有容器日志展示出来。
14 容器详细信息也可以直接展开
继续进入详细信息:
这里可以看到更多容器配置和运行信息。
相比命令行,WebUI最直观的优势是:
多个维度的信息不用来回切命令。
15 镜像管理
进入镜像页面:
可以查看宿主机当前已有镜像。
也可以进一步拉取 / 添加镜像:
这一层对应的仍然是 Docker Image 管理。
Portainer只是把它搬到了页面里。
16 数据卷管理
进入 Volumes:
创建数据卷:
对于数据库、配置和持久化应用来说,卷管理比容器本身更值得谨慎。
删除容器不一定丢数据。
但误删 volume 就可能直接影响业务数据。
所以可视化并不意味着操作风险变小。
17 用户管理也能在Portainer里完成
创建用户:
修改已有账号密码:
更多配置:
这类能力适合多人维护环境。
不过不同版本 / 版本类型在角色、权限和团队能力上可能存在差异。
所以长期文章更适合描述已实际看到的功能,不把所有商业版能力都默认归到 CE。
18 Portainer和Dockge的思路其实不一样
如果只是管理 Docker Compose Stack,Dockge会更贴近 Compose 工作流。
Portainer 覆盖面更广:
- 容器;
- 镜像;
- 数据卷;
- 网络;
- 用户;
- Stack。
所以两者并不是简单的“谁更好”。
更像是:
Dockge偏Compose项目管理。
Portainer偏Docker环境整体管理。
19 本地管理跑通后,再考虑远程
如果人在家里,同一局域网访问:
http://飞牛IP:9000
已经足够。
真正需要外部访问的场景通常是:
- 服务异常;
- 临时看日志;
- 容器需要重启;
- 出门后检查状态。
这时候才需要解决:
外部网络怎么进入9000。
20 安装cpolar
执行:
sudocurlhttps://get.cpolar.sh|sh安装以后检查:
sudosystemctl status cpolar然后进入:
飞牛IP:9200
后面的隧道都在这里配置。
21 给Portainer的9000创建随机公网地址
参数:
- 隧道名称:
Portainer-CE - 协议:
http - 本地地址:
9000 - 域名类型:随机域名
- 地区:
China Top
创建以后查看在线隧道:
再从外部浏览器访问:
页面可以打开以后说明:
外部浏览器 → 公网地址 → cpolar → 飞牛9000 → Portainer
网络链已经通了。
22 公网Portainer不是普通远程网页
Portainer后面连接的是 Docker Socket。
如果管理员账号被拿到,对方可能进一步:
- 停止容器;
- 删除容器;
- 修改配置;
- 拉取镜像;
- 管理数据卷;
- 创建新容器。
所以远程访问最重要的不是“地址能不能打开”。
而是:
- 管理员密码是否足够强;
- 是否只自己使用;
- 地址是否公开过;
- 是否需要额外访问控制;
- 是否有必要长期暴露。
23 cpolar负责网络入口,不负责Portainer权限
Portainer负责:
- Docker资源管理;
- 用户;
- 容器;
- 镜像;
- 卷。
cpolar负责:
- 外部浏览器怎么到达9000。
两者职责要分开。
公网地址能打开,只代表网络链已经通。
不代表 Portainer 的权限管理和 Docker Socket 风险自动解决。
24 随机地址适合临时维护
如果只是偶尔:
- 看日志;
- 重启容器;
- 检查状态;
随机地址已经够用。
先确认远程链路正常,再决定是否需要固定地址。
25 配置固定二级子域名
进入预留页面:
保留名称:
Portainer-CE
然后进入隧道列表:
修改为:
二级子域名
填写已经保留的名称:
更新后查看:
最后从外部打开:
页面可以正常访问以后,固定入口配置完成。
26 固定地址解决的是稳定,不是安全
源材料把固定地址写成:
永久不会变化。
长期文章更稳妥的写法应该是:
在账号、套餐和当前规则持续有效的情况下,固定地址不需要像随机地址那样频繁修改。
固定地址适合:
- 长期书签;
- 固定管理入口;
- 少改配置。
但它并不会给 Portainer 自动增加第二层权限保护。
27 这篇真正跑通的链路
本地:
飞牛 → Docker → Portainer → 9000
管理:
Portainer → Docker Socket → 容器 / 镜像 / 数据卷
远程:
外部浏览器 → 公网地址 → cpolar → 9000 → Portainer
实际完成:
- 飞牛 SSH;
- Docker环境确认;
- Portainer CE镜像;
portainer_data;8001:8000;9000:9000;- Docker Socket;
- 管理员初始化;
- 容器列表;
- 日志;
- 镜像;
- 数据卷;
- 用户;
- 随机公网访问;
- 固定二级子域名。
需要特别注意:
systemctl status -v写法可疑;latest不利于版本固定;- Docker Socket权限很高;
- volume误操作可能影响数据;
- 公网Portainer属于高权限管理入口;
- 固定地址不等于安全。
总结
整套流程可以拆成三层:飞牛负责Docker宿主环境,Portainer负责容器资源的Web管理,公网入口负责让外部浏览器访问9000。
本文已经完成Portainer部署、管理员初始化、容器日志、镜像、数据卷和用户管理,以及随机和固定地址访问。
需要特别注意的是,Docker Socket让Portainer具备很高权限,因此“页面能从公网打开”和“安全远程运维”不能画等号。
把账号、版本、数据卷和访问范围控制好以后,Portainer CE更适合作为Docker的可视化管理层,而不是“点几下就完全不用懂Docker”的替代品。