15人参与 • 2026-03-15 • Docker
这次把 openclaw 部署在一台 ubuntu 服务器上,使用 docker 运行,再通过宝塔面板中的 nginx 站点做反向代理,最后绑定域名,通过 https 访问控制界面。
最终访问链路如下:
浏览器 ↓ https://你的https域名 ↓ nginx(宝塔站点) ↓ 127.0.0.1:18789 ↓ openclaw gateway
这篇主要记录整个部署过程,以及顺手完成的几项加固:docker 端口只绑定本地、nginx 白名单限制、ufw 拒绝端口直连。目标很明确,不只是把服务跑起来,而是让它以一个更适合长期使用的方式对外提供访问。

服务器环境是 ubuntu 24,已经安装宝塔面板,并启用了 nginx。openclaw 通过 docker compose 运行,域名通过宝塔站点绑定并配置 ssl。

本次部署使用到的环境信息如下:
| 项目 | 值 |
|---|---|
| 系统 | ubuntu 24 |
| 面板 | 宝塔面板 |
| web 服务 | nginx |
| openclaw 项目目录 | /www/docker/openclaw/openclaw-main |
| openclaw 配置目录 | /root/.openclaw |
| gateway 端口 | 18789 |
| bridge 端口 | 18790 |
| 域名 | 你的https域名 |
| 允许访问的公网 ip | 自行调整 |
源码获取方式
由于服务器访问 github 不太稳定,这次没有直接拉仓库,而是先在本地下载压缩包,再上传到服务器。
压缩包路径如下:
/www/docker/openclaw/openclaw-main.zip
解压后目录如下:
/www/docker/openclaw/openclaw-main
进入项目目录后的常规操作:
cd /www/docker/openclaw/openclaw-main ls chmod +x docker-setup.sh ./docker-setup.sh
安装脚本是交互式的,这次采用的是尽量轻量的初始化方式,关键选择如下:
| 步骤 | 选择 |
|---|---|
| 初始化确认 | yes |
| 安装模式 | quickstart |
| 模型提供商 | openrouter |
| api key 提供方式 | paste api key now |
| 聊天渠道 | skip for now |
| skills | 按需选择,尽量最小化部署 |
| hooks | skip for now |
安装过程本身并不复杂,真正需要处理的重点在于,如何把 openclaw 接到一个合理、安全的公网入口上。
openclaw 配置文件位置
有一个地方比较容易找错:openclaw 的实际配置文件并不在项目目录里,而是在下面这个位置:
/root/.openclaw/openclaw.json
项目目录下的内容主要是运行环境和 compose 配置,真正控制 gateway、认证方式和 ui 来源校验的,是这个 openclaw.json。
本次用到的关键配置如下:
{
"gateway": {
"port": 18789,
"mode": "local",
"bind": "loopback",
"auth": {
"mode": "token"
},
"controlui": {
"allowedorigins": [
"https://你的https域名",
"http://你的https域名"
],
"dangerouslyallowhostheaderoriginfallback": true
}
}
}这里最重要的是两个配置项:
controlui.allowedoriginsdangerouslyallowhostheaderoriginfallback因为 openclaw 在非本地访问场景下会做来源校验。如果你是通过域名访问控制 ui,但没有把域名加入允许来源列表,网关可能直接拒绝启动,或者前端能打开但后端无法连接。
所以只要不是在本机 localhost 上使用,而是通过域名反代访问,这段配置基本都需要处理。
修改 docker compose 端口绑定
openclaw 默认的 compose 配置,会把 18789 和 18790 直接映射到公网。
默认写法如下:
ports:
- "${openclaw_gateway_port:-18789}:18789"
- "${openclaw_bridge_port:-18790}:18790"
这种方式在测试阶段没有问题,但如果直接用于公网服务器,就意味着外部可以通过 服务器ip:18789 直接访问 gateway。
更合理的做法,是只让 docker 端口绑定到本地回环地址,让外部流量统一从 nginx 入口进入。
修改后如下:
ports:
- "127.0.0.1:${openclaw_gateway_port:-18789}:18789"
- "127.0.0.1:${openclaw_bridge_port:-18790}:18790"
这样改完以后,18789 和 18790 只允许本机访问,公网无法直接连接。
实际修改命令如下:
cd /www/docker/openclaw/openclaw-main
cp docker-compose.yml docker-compose.yml.bak
sed -i 's#- "${openclaw_gateway_port:-18789}:18789"#- "127.0.0.1:${openclaw_gateway_port:-18789}:18789"#' docker-compose.yml
sed -i 's#- "${openclaw_bridge_port:-18790}:18790"#- "127.0.0.1:${openclaw_bridge_port:-18790}:18790"#' docker-compose.yml
修改完成后重启容器:
docker compose down docker compose up -d
这一步非常关键。因为如果不先把 docker 端口收口,后面即使配置了域名和 nginx 反向代理,gateway 实际上仍然是对公网暴露的。那时 nginx 只是“增加了一层入口”,不是“唯一入口”。
这次使用的是宝塔面板,所以站点直接在宝塔里创建。

需要注意的是,站点目录本身并不是重点。它不会直接渲染 openclaw 页面,更像是一个 nginx 入口,用于完成三件事:
站点目录给一个普通路径即可,例如:
/www/wwwroot/你的https域名
最终使用的核心 nginx 配置如下:
location / {
allow 127.0.0.1;
deny all;
proxy_pass http://127.0.0.1:18789;
proxy_http_version 1.1;
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_set_header x-forwarded-proto $scheme;
proxy_set_header upgrade $http_upgrade;
proxy_set_header connection "upgrade";
proxy_read_timeout 86400;
proxy_send_timeout 86400;
proxy_connect_timeout 60s;
proxy_buffering off;
proxy_request_buffering off;
}这段配置主要完成了三件事。
首先是 ip 白名单控制,只允许服务器本机和指定公网 ip 访问,其它请求直接返回 403。
其次是补齐 websocket 所需代理头,因为 openclaw 控制界面依赖 websocket 与后端通信。
最后才是将流量转发到 127.0.0.1:18789。
修改完成后,先检查配置:
nginx -t
确认没有问题后再重载:
nginx -s reload
虽然前面已经把 docker 端口绑定到了 127.0.0.1,理论上公网已经无法直接访问 18789 和 18790,但这里我还是补了一层 ufw。
执行规则如下:
ufw deny 18789 ufw deny 18790 ufw enable
这样做的目的就是多一层保险。即使后续某次改动误把 docker 端口重新暴露出来,防火墙层面仍然可以拦住这两个端口,避免被直接访问。
对外开放端口建议只保留:
| 端口 | 用途 |
|---|---|
| 22 | ssh 登录 |
| 80 | http |
| 443 | https |
如果服务器在腾讯云、阿里云等云平台上,安全组也建议同步关闭 18789 和 18790,只保留 22、80、443。
openclaw 的认证机制
openclaw 默认并不是传统的账号密码登录系统,而是采用 gateway token 模式。
也就是说,用户可以看到前端页面,但如果没有正确的 token,就无法真正连接后端。这时前端通常会提示:
unauthorized: gateway token missing
token 存放在:
/root/.openclaw/openclaw.json
结构大概如下:
"auth": {
"mode": "token",
"token": "xxxxxxxxxxxxxxxx"
}这意味着它的访问控制实际上分成两层:
第一层是外层访问控制,也就是能不能先打开这个页面。这部分由 nginx 白名单、域名入口和 https 决定。
第二层是内部操作控制,也就是能不能真正控制 agent。这部分由 gateway token 决定。
所以这次的思路很简单,外层用 nginx 白名单限制访问范围, 内层保留 openclaw 自己的 gateway token 作为实际控制权限。
如果后续还想进一步强化,也可以在 nginx 层再加 basicauth,让浏览器先弹账号密码框。
当前这套结构的最终效果
到这里,这次部署的整体安全边界就比较清楚了。
当前已经完成的控制如下:
| 层级 | 作用 |
|---|---|
docker 只绑定 127.0.0.1 | 阻止公网直接访问 18789/18790 |
| ufw 拒绝 18789/18790 | 防止端口直连 |
| nginx 白名单 | 只允许指定来源访问 |
| https 域名访问 | 满足安全上下文要求 |
| gateway token | 控制真正的 agent 连接权限 |
最终访问表现应该如下:
| 访问方式 | 结果 |
|---|---|
https://你的https域名,且来源 ip 为允许 ip | 正常访问 |
https://你的https域名,但来源为其他 ip | 403 forbidden |
http://服务器ip:18789 | 无法访问 |
| 页面打开但没填 gateway token | 页面可见但无法操作 |
| 正确填写 gateway token | 可正常控制 openclaw |
到这一步,至少入口是统一的,权限是分层的,公网也没有留下多余暴露面。
先看 dns,再查服务
这次排查过程中,还有一个很典型的问题。
一开始域名访问不上,最先怀疑的是 docker、nginx 或者 openclaw 配置本身,结果最后发现问题根本不在服务层,而是在 dns。
你的https域名 这个子域名,必须先在 dns 控制台中添加 a 记录,例如:
| 类型 | 主机记录 | 记录值 |
|---|---|---|
| a | openclaw | xxx.xxx.xxx.xxx |
只有解析生效之后,请求才会真正打到当前服务器。
可以通过以下命令验证:
ping -c 2 你的https域名 curl -i http://你的https域名 curl -ik https://你的https域名
如果 dns 尚未生效,通常看到的报错会是:
could not resolve host name or service not known
所以如果遇到域名无法访问的问题,建议先确认 dns 解析是否正确,再去检查 docker、nginx 或 openclaw 本身。
常用运维命令整理
下面把部署和排查时比较常用的命令一起记下来,后面复用会比较方便。
查看容器状态:
cd /www/docker/openclaw/openclaw-main docker ps docker compose ps
查看网关日志:
docker logs --tail 100 openclaw-main-openclaw-gateway-1
重启 openclaw:
cd /www/docker/openclaw/openclaw-main docker compose down docker compose up -d
检查 nginx 配置:
nginx -t nginx -s reload
检查 80 和 443 是否监听:
ss -lntp | grep -e ':80|:443'
检查 openclaw 本机端口:
curl -i http://127.0.0.1:18789 curl -i http://127.0.0.1:18789/__openclaw__/canvas/
检查 nginx 到 openclaw 的反代链路:
curl -i http://127.0.0.1 -h "host: 你的https域名" curl -ik https://127.0.0.1 -h "host: 你的https域名"
这些命令都比较基础,但在排查时很高频。尤其是本机端口和反代链路测试,通常能很快判断问题到底出在 openclaw、docker、nginx,还是域名解析层。
后续还能继续增强的方向
目前这套结构已经可以稳定使用,但如果后续想继续往更完整的生产环境演进,还可以继续补几项:
| 方向 | 说明 |
|---|---|
| 增加 nginx basicauth | 再加一层浏览器级账号密码认证 |
| 接入 cloudflare access / oauth | 做更标准的统一身份认证 |
| 隐藏默认控制路径 | 降低被扫描器直接探测到的概率 |
| 固定允许来源域名 | 进一步减少 host header 风险 |
| 细化模型调用策略 | 按 openrouter / deepseek 做权限隔离 |
| 记录访问日志和异常日志 | 方便后续审计和问题回溯 |
这些都不是这次部署的必需项,但如果后面要从“自己用”逐步走向“长期用”或者“多人用”,基本都会慢慢补上。
这次部署完成后,openclaw 已经可以通过 https 域名正常访问,gateway 端口也不再直接暴露到公网。
目前这套结构的核心有三点:
对个人长期使用来说,这样的结构已经比较稳,也方便后续继续叠加认证或访问控制。
以上就是openclaw在ubuntu服务器上的完整部署流程的详细内容,更多关于openclaw在ubuntu上的部署的资料请关注代码网其它相关文章!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论