本仓库用于构建并发布 1Panel 的 Docker 镜像,采用 DooD(Docker-out-of-Docker)设计,复用宿主机 Docker 引擎,使用 supervisord 管理 1Panel 进程,避免在容器内运行 systemd 或使用 --privileged。
提示:本方案适合可信、单租户环境,生产环境使用需严格控制访问并做好防护策略(建议WAF+网络防火墙)。
DooD:容器共享宿主机 Docker 引擎与缓存,构建更快、占用更小。
进程管理:容器内不运行 systemd,改用 supervisord 前台托管 1panel-core 与 1panel-agent。
版本变量注入:Dockerfile 中包含占位符,示例(ubuntu):
RUN bash /1panel/quick_start.sh v{%OnePanel_Version%}
构建时以 sed 将 {%OnePanel_Version%} 替换为具体版本(2.0.0~2.0.15)。
多架构:buildx + QEMU 生成 linux/amd64、linux/arm64 镜像;脚本会自动识别归档架构并下载对应包。
系统:ubuntu、centos、alpine
版本:2.0.0 ~ 2.0.15
架构:amd64、arm64(自动匹配下载包)
标签规范:
容器构建自动生成用户名、密码、端口,可启动后在容器内调整。这里假设面板默认端口为 8888。运行命令示例:
docker run -d --name 1panel --restart unless-stopped \
-p 8888:8888 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/lib/docker/volumes:/var/lib/docker/volumes \
-v /1panel_app/data/:/opt/ \
caijiamx/1panel:dood-2.0.15-ubuntu-cn
初始化(容器内):
重要的事情讲三遍!!!
首次部署务必修改用户名/密码/入口!
首次部署务必修改用户名/密码/入口!
首次部署务必修改用户名/密码/入口!
docker exec -it 1panel bash
# 查看安全入口与当前配置
1panel user-info
# 修改端口/用户/密码
1panel update port
1panel update username
1panel update password
仓库内提供示例 docker-compose.yml(DooD 必要挂载已包含):
services:
one_panel:
image: caijiamx/1panel:dood-2.0.15-ubuntu-cn
container_name: 1panel
restart: unless-stopped
ports:
- "8888:8888"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /var/lib/docker/volumes:/var/lib/docker/volumes
- /1panel_app/data/:/opt/
docker-compose.yml关键字段:
image:镜像标签如 caijiamx/1panel:dood-2.0.15-ubuntu-cn
ports:对外端口映射,示例 8888:8888
volumes(DooD 必要挂载):
healthcheck:简单进程检查(core/agent 是否存在)
extra_hosts:host-gateway 方便访问宿主机
networks:使用外部网络 one_panel(先创建网络)
启动服务:
docker network create one_panel
docker compose up -d
提示:
# Ubuntu
docker pull caijiamx/1panel:dood-2.0.15-ubuntu-cn
# CentOS
docker pull caijiamx/1panel:dood-2.0.15-centos-cn
# Alpine
docker pull caijiamx/1panel:dood-2.0.15-alpine-cn
将 {version} 替换为 2.0.0~2.0.15,{os} 替换为 ubuntu/centos/alpine。
alpine/ # Alpine Dockerfile 模板
centos/ # CentOS Dockerfile 模板
ubuntu/ # Ubuntu Dockerfile 模板
hack/ # 安装与 systemctl 注释脚本、supervisord 配置
hack_cn/ # 安装与 systemctl 注释脚本、supervisord 配置
.github/workflows/main.yml # GitHub Action CI 多版本/多系统/多架构构建与推送
docker-compose.yml # 容器运行配置
Makefile # 本地构建/推送/矩阵任务
20250909 由GitHub copilot 生成
根据 1Panel-dev/1Panel 仓库代码,涉及 systemctl 管理的服务主要有以下几类。如果 systemctl 不可用(如 WSL、部分容器、极简发行版等),这些服务的启动/停止/重启/状态查询都将受到影响,面板功能也会有部分不可用或异常。
| 服务名称 | 作用/描述 | systemctl不可用时影响 | 代码依据/说明 | 说明 |
|---|---|---|---|---|
| 1panel-core.service | 1Panel 核心服务 | 无法启动/重启/查询状态,面板核心功能异常 | core/app/service/setting.go, common.go、core/app/service/upgrade.go、RestartService (common.go), UpdateBindInfo/UpdatePort/UpdateSSL (setting.go), UpgradeService.Upgrade | 面板配置、端口、SSL、主控服务、升级、回滚等重启 |
| 1panel-agent.service | 1Panel Agent服务(节点服务) | 无法启动/重启/查询状态,节点管理异常 | agent/utils/common.go, common.go、core/app/service/upgrade.go、RestartService (common.go), UpgradeService.Upgrade | 节点服务重启、升级后重启、节点异常恢复 |
| docker.service, docker.socket | Docker 守护进程 | 容器管理、重启、停止等功能不可用 | agent/app/service/docker.go | 容器服务、应用容器管理、配置变更后重启 |
| fail2ban.service | 防暴力破解服务(Fail2Ban) | 防护规则无法启停、重载或查询状态 | agent/utils/toolbox/fail2ban.go | 防护规则启停、重载、状态查询 |
| clamav/clamd/freshclam | 病毒扫描服务(ClamAV) | 杀毒、病毒库更新相关功能不可用 | agent/app/service/clam.go | 杀毒服务启停、查杀操作、病毒库更新 |
| ssh/sshd.service | SSH 服务 | 远程管理、SSH配置功能异常 | agent/app/service/ssh.go | SSH服务启停、配置变更、安全加固 |
| supervisor/supervisord | 进程守护服务(Supervisor) | 守护进程管理功能不可用 | 前端文案、脚本管理相关 | 守护进程启停、自动化任务、脚本运行 |
所有涉及 systemctl 的服务都依赖 systemd
Docker、SSH、Fail2Ban、ClamAV、Supervisor 这些常用服务都通过 systemctl 集成
面板自身服务(core/agent)也通过 systemctl 管理
详细参考:服务&功能限制
/api/v1/setting/update_port —— 端口修改,涉及 RestartService 调用 systemctl 重启 core 服务/api/v1/setting/update_ssl —— SSL 配置修改后,涉及 systemctl 重启 core 服务/api/v1/upgrade/upgrade —— 升级接口,涉及 UpgradeService.Upgrade,systemctl 重启 core/agent 服务/api/v1/upgrade/rollback —— 回滚接口,涉及 UpgradeService.handleRollback,systemctl 重启 core/agent 服务/api/v1/docker/restart —— 容器管理,调用 OperateDocker,systemctl 重启 docker 服务/api/v1/agent/restart —— 节点管理,重启 agent 服务/api/v1/fail2ban/operate —— 安全防护策略启停/api/v1/clam/operate —— 病毒查杀服务启停/api/v1/ssh/operate —— SSH 服务启停与配置/api/v1/supervisor/operate —— 守护进程服务启停
Upgrade 相关 systemctl 调用补全说明
代码如 core/app/service/upgrade.go 的 UpgradeService.Upgrade 实现,升级成功后会调用:
systemctl daemon-reloadsystemctl restart 1panel-agent.servicesystemctl restart 1panel-core.service回滚也会涉及 systemctl 重启相关服务。
其他分支或历史版本中,升级、回滚等函数如 handleRollback、handleBackup 也会调用 systemctl daemon-reload && systemctl restart 1panel.service。
配置:hack/supervisord.conf(nodaemon=true 前台运行)
托管:
常用命令:
supervisorctl status
supervisorctl restart all
supervisorctl reload
运行一个 systemd ,通常需要这样设置:
docker run -d -it \
--name ubuntu2404-systemd \
--privileged \
--cgroupns=host \
--tmpfs=/run \
--tmpfs=/tmp \
--volume=/sys/fs/cgroup:/sys/fs/cgroup:rw \
trfore/docker-ubuntu2404-systemd:latest
核心风险点在于 --privileged + --cgroupns=host + --volume /sys/fs/cgroup:
宿主机隔离被打破
--privileged 让容器有所有 Linux capabilities(cap_sys_admin、cap_net_admin 等),等同 root。cgroup 控制泄露
--cgroupns=host + 挂载 /sys/fs/cgroup → 容器能操作宿主机的 cgroups,修改 CPU/内存限制、杀死其他容器的进程。宿主机提权/逃逸
--privileged 参数。参考版本库:
本指南提供一种“非官方”的 1Panel Docker 部署方案:
容器内需复用宿主机 Docker 以安装/编排应用,需挂载:
参考docker-compose.yml:
# 关键配置
volumes:
# make docker out of docker work
- /var/run/docker.sock:/var/run/docker.sock
- /var/lib/docker/volumes:/var/lib/docker/volumes
- /1panel_app/data/:/opt/
DooD(本指南采用)
DinD
Sysbox
结论:
在当前条件下选用 DooD + supervisord,明确拒绝在生产环境用 --privileged 跑 systemd。
| 特性维度 | DooD (Docker-out-of-Docker) | DinD (Docker-in-Docker) | Sysbox |
|---|---|---|---|
| 基本原理 | 容器内挂载宿主机 Docker socket,直接复用宿主机 Docker 引擎 | 在容器中运行独立的 Docker 引擎(DinD 镜像) | 使用 Sysbox 作为底层 runtime,容器内可安全运行 Docker / K8s 等系统级 workload |
| 优点 | - 共享宿主机镜像缓存,构建速度快- 节省磁盘空间 | - 简单易用,官方有现成 DinD 镜像- 容器内外引擎隔离,避免直接操作宿主机容器 | - 无需 privileged 容器- 使用 Linux user namespace 提供强隔离- 支持系统级 workload(Docker/K8s)- 与 Docker/K8s 无缝集成,使用方式类似 runc |
| 缺点 | - 安全风险极大:容器可直接控制宿主机 Docker,甚至删除宿主机所有容器- 不适合多租户环境- bind mount 限制,某些功能(如 volume 挂载)可能失效 | - 需要 privileged 权限运行,容器内 root = 宿主机 root- root 拥有全部 Linux capabilities,存在逃逸风险- 可直接访问宿主机设备和 /proc、/sys,能修改内核状态 | - 需要较新的 Linux 内核- 目前只支持部分 Linux 发行版- 仍在社区发展中,生态不如 Docker 官方成熟 |
| 安全风险 | 高:容器内用户几乎等于宿主机 root 权限 | 高:privileged 容器 = 宿主机 root + 全 capability,容易被利用 | 相对低:用户隔离(userns)、procfs/sysfs 虚拟化、syscall 拦截,避免直接 root 映射 |
| 适用场景 | - 本地开发临时测试- 单人或可信环境 | - CI/CD 流水线需要独立 Docker 环境- 简单快速的沙箱环境 | - CI/CD 多租户 runner- 安全沙箱环境- 在容器中运行系统级 workload(如 Docker/K8s) |
| 推荐程度 | ✅ 推荐(需控制访问权限) | ⚠️ 谨慎使用(非生产安全场景) | ❌ 不推荐(配置复杂) |
参考链接:
依赖:Docker Desktop(含 buildx),已登录 DockerHub(如需推送)。
列出命令:
make help
常用命令:
变量:
构建示例
# 调试单个命令
make -n build OS=ubuntu VERSION=2.0.15 ONEPANEL_TYPE=cn
# 构建单个镜像
make build OS=ubuntu VERSION=2.0.15 ONEPANEL_TYPE=cn
命名规范:caijiamx/1panel:dood-{version}-{os}-cn
工作流:.github/workflows/main.yml(“Build and Push 1Panel Images”)
触发方式:推送分支 main/dev 或手动 workflow_dispatch
构建矩阵:OS=[ubuntu, centos, alpine];VERSION=[2.0.0..2.0.15]
多架构:linux/amd64, linux/arm64(使用 setup-qemu + buildx)
版本替换:构建前用 sed 将 Dockerfile 中 v{%OnePanel_Version%} 替换为具体版本
推送目标:caijiamx/1panel:dood-{version}-{os}
凭据:需要在仓库 Secrets 配置
使用方式:Actions 页面选择 main 工作流,点 Run workflow,选择 os 与 version
从 v2.0.0 -> v2.0.11升级为例,准备工作:
开始升级步骤:
官方安装会自动维护版本号;本镜像方案需手动同步版本号(示例使用 sqlite3):
sudo apt-get update && apt-get install -y sqlite3
cp /opt/1panel/db/core.db /opt/1panel/db/core.db.bak
cp /opt/1panel/db/agent.db /opt/1panel/db/agent.db.bak
sqlite3 /opt/1panel/db/core.db "UPDATE settings SET value='v2.0.11' WHERE key='SystemVersion';"
sqlite3 /opt/1panel/db/agent.db "UPDATE settings SET value='v2.0.11' WHERE key='SystemVersion';"
更新镜像后重启容器(保留 /opt/ 数据卷)。
面板不可用功能表格如下:
| 功能 | 是否可用 | 备注 |
|---|---|---|
| 面板->立即升级(右下角) | ❌ | |
| 网站->网站->OpenResy设置->当前状态 网站->运行环境->php-fpm容器状态检查 | ❌ | |
| 工具箱->进程守护、FTP、Fail2ban、磁盘管理 | ❌ | 功能未测试 |
| 高级功能 | ❌ | 功能未测试 |
举例:
# 容器内docker-compose.yml配置
- ${WEBSITE_DIR}:/www -> /1panel_app/data/1panel/www:/www
# 容器内默认 1panel 项目目录:/opt/1panel
常用变量
# 1panel 使用变量,用于文件 docker-compose.yml
${CONTAINER_NAME} # 自定义容器名
${IMAGE_NAME} # 自定义镜像名
${PANEL_APP_PORT_HTTP} # 自定义端口
${PANEL_WEBSITE_DIR} # 默认为 /opt/1panel/www
${WEBSITE_DIR} # 默认为 /opt/1panel/www
报错信息:
服务内部错误: Get "http://127.0.0.1/nginx_status": dial tcp 127.0.0.1:80: connect: connection refused
原因:健康检查 127.0.0.1 访问失败,容器内访问 127.0.0.1 会访问 1panel 监听80端口,而 openresty 是单独的容器,1panel -> openresty 可以走 http://openresty。
处理:可为健康检查添加 host:server_name 127.0.0.1 openresty; 正确访问地址:http://openresty/nginx_status。
彻底解决问题,需要修改官方实现代码:
# 文件路径:agent/app/service/nginx.go
func (n NginxService) GetStatus() (response.NginxStatus, error) {
// bala
url := "http://127.0.0.1/nginx_status"
if httpPort != 80 {
url = fmt.Sprintf("http://127.0.0.1:%v/nginx_status", httpPort)
}
useDoodMode := true
if useDoodMode {
localServerName := "127.0.0.1"
openrestyContainerName := "openresty"
url = strings.ReplaceAll(url, localServerName, openrestyContainerName)
}
// bala
}
WebSocket/升级头
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host; # 若需要固定后端 Host,请显式设置
开启安全入口后,通过容器内命令查看:1pctl user-info
首次部署务必修改用户名/密码/入口
建议WAF+网络防火墙做好访问控制。
CPU 限额过低可能导致接口超时(偶尔 5xx/超时),建议 1.0~1.5 core。