资讯中心

Docker安装OpenClaw全攻略:容器化部署智能体与避坑指南

📅 2026/9/29 16:05:20
Docker安装OpenClaw全攻略:容器化部署智能体与避坑指南
简介面向需要在容器环境中快速部署OpenClaw的开发者与运维人员这份代码包提供了从基础镜像手动安装到Dockerfile构建镜像的完整实现方案覆盖拉取镜像、启动容器、依赖安装、网关配置、插件冲突规避与网络设置等关键步骤既适合测试开发阶段的灵活调试也能满足生产环境下的可重复部署与版本回退需求。包内共8个文件以shell安装脚本、Dockerfile、docker-compose编排文件、JSON配置样例及Markdown说明文档为主同时包含HTML展示页与项目辅助标记文件全套仅12KB轻量且结构清晰便于按需拆分或直接复用。已有1358人学习使用尤其适合需要快速迭代AI系统、维护多版本环境的团队。借助其中的自动化脚本与配置模板可显著降低环境搭建复杂度同时通过容器隔离减少依赖冲突提升部署稳定性与可控性。1. 用 Docker 装 OpenClaw把智能体跑起来比想象中省事把服务装进容器这件事做一次就觉得值OpenClaw 这类智能体不光要跑核心进程还要接 channel、挂会话、配置模型环境一乱就全乱。用 Docker 安装 OpenClaw你只需要保证宿主机有 Docker剩下的依赖、Python 运行时、会话文件路径都由镜像固化管理。这篇面向两类人一是本地开发想在 Windows 或 Mac 上用 Docker Desktop 快速起一个 OpenClaw 实例二是服务器部署想在 Linux 上无头跑通并接入 Microsoft Teams 等外部 channel。全文会把可以直接抄的 docker run 命令、docker-compose.yml 和一组配置参数都放出来也会把 session file locked、容器重启丢数据这类高频坑提前排掉。2. 装前准备宿主环境、Docker 选型和最小启动命令2.1 宿主机环境检查从 Docker Desktop 到 Linux 无头服务器先别急着拉镜像宿主机环境决定了后面 80% 的坑。我第一次在 Windows 上装 Docker Desktop 就翻过车双击安装包后一切正常启动却弹了句 Virtualization support not detectedDocker Desktop failed to start后来才发现是 BIOS 里 Virtualization Technology 没开启。这个错在热搜词里被反复搜说明踩的人不少解决方式也很简单进 BIOS 开启虚拟化选项重启后再启动 Docker Desktop。Linux 服务器上没这么多图形界面的事。你只需要确认内核里没有旧版 iptables 干扰、Docker 服务在跑以及当前用户有操作 Docker 的权限。我一般用下面三组命令做一次快速体检# 检查 Docker 引擎版本与 Compose 插件 docker version docker compose version # 检查 Docker 服务是否在运行systemd 系 systemctl status docker # 把当前用户加进 docker 组避免每条命令都带 sudo sudo usermod -aG docker $USER newgrp docker逻辑说明第一条命令同时打印 Client 和 Server 两个区块Server 区块能正常显示 Engine 版本说明 Docker 守护进程起来了如果卡在Cannot connect to the Docker daemon优先看 systemctl。第二条命令能看到服务运行状态和最近日志。第三条命令是为了省去之后所有 docker 命令前加 sudo 的麻烦执行完需要重新登录会话才生效。参数说明-aG里的a是追加G是指定用户组加完组后务必重新 ssh 或注销重登否则权限不会立刻刷新。如果你用的是 Docker Desktop 而非纯引擎Windows 下还要确认 WSL 2 已启用wsl --status能看到默认版本若不是 2执行wsl --set-default-version 2。2.2 一层镜像拉起 OpenClawdocker run 最小命令环境就绪后可以用最精简的方式先验证镜像能跑起来。我不建议第一分钟就上 docker-compose 编排先用一条docker run把 OpenClaw 跑通再考虑目录挂载和渠道接入。这里给出一个最小可用的启动命令# 启动 OpenClaw 容器映射配置与数据目录暴露交互端口 docker run -d \ --name openclaw \ -p 1860:1860 \ -v ./openclaw/config:/app/config \ -v ./openclaw/sessions:/app/sessions \ -v ./openclaw/logs:/app/logs \ 镜像仓库中的 openclaw 镜像名:latest逻辑说明-d表示后台运行容器终端退出后进程不停--name openclaw给容器固定名字后续docker logs openclaw、docker restart openclaw都不用查容器 ID。-p 1860:1860把容器内 1860 端口映射到宿主机这是 OpenClaw 默认的 Web 管理与交互端口具体端口号以你用的镜像说明为准我习惯先在宿主机上用相同端口避免二次映射导致环境变量混乱。三个-v挂载分别是配置、会话和日志目录这一步是必须的哪怕现在只做验证不挂载的话容器销毁后所有会话就归零了。参数说明冒号前是宿主机路径冒号后是容器内路径。./openclaw/config这种相对路径写法适合第一次快速验证生产环境建议全部改成绝对路径比如/opt/openclaw/config避免 cd 到别的目录后路径失效。镜像名部分我用尖括号占位是因为不同团队发布的 OpenClaw 镜像标签规则不一致拉取前先确认镜像仓库地址和版本标签别默认 latest 就是最新的稳定版。容器起来后用两句话确认状态docker ps --filter nameopenclaw docker logs --tail 50 openclaw逻辑说明docker ps看容器是否处于 Up 状态如果看到 Exited说明容器启动后立刻退出了这时候docker logs是唯一有效的黑匣子把报错堆栈贴进搜索引擎基本能定位。OpenClaw 首次启动会在挂载目录里生成默认配置文件看到类似配置文件生成、session 目录初始化之类的日志就算起点跑通了。之后你可以打开浏览器访问http://localhost:1860如果页面能正常返回说明最小部署成立可以进入下一章。3. 把配置做厚目录挂载、channel 接入与模型接入3.1 数据目录挂载config、sessions、attachments 各归其位很多 OpenClaw 部署完用了一周容器一升级就变“失忆”根因几乎都是没有坚持挂载目录。容器的文件系统是临时的镜像重建后原来写在容器层里的数据全部消失这就是“后悔药”的唯一解法挂载。OpenClaw 官方镜像默认把数据写在/app下但不同镜像版本对子目录命名有差异最常见的三个目录是config、sessions和attachments。我在生产服务器上的挂载结构长这样/opt/openclaw/ ├── config/ # OpenClaw 主配置文件含 channel 与模型参数 ├── sessions/ # 每个会话一个独立文件以 session_id 命名 ├── attachments/ # 对话中产生的图片、文件等附件 └── logs/ # 运行日志与 channel 调用日志目录拆分的逻辑很直接config 是唯一需要人工编辑的目录单独挂出来方便修改和备份sessions 是运行时频繁读写的区域容器重启后要保证不丢attachments 是附件缓存挂出来可以把容量风险转交给宿主机磁盘。有些版本还会用到/app/data我建议先启动一次容器看日志里初始化输出写了哪些路径再按实际路径对照挂载。挂载时有一个权限坑尤其现在部署的 OpenClaw 大多是 rootless 容器进程以非 root 用户运行宿主机目录属主不一致会导致写入 502。常见做法是在宿主机上把目录属主改成容器内用户的 UID比如容器以 uid 1000 运行就执行# 将宿主机目录属主调整为容器内运行用户的 UID/GID sudo mkdir -p /opt/openclaw/{config,sessions,attachments,logs} sudo chown -R 1000:1000 /opt/openclaw然后重新挂载启动。如果你偷懒用-v挂载了宿主机一个权限过严的目录容器启动时大概率会报Permission denied这时候不要对着容器里 chmod直接改宿主机目录属主才有效。3.2 接入 Microsoft Teamschannel 选择与连接器配置OpenClaw 的核心价值之一是能接入多种即时通讯渠道国内叫 channel国外叫 connector。据我目前的经验最常用的 channel 是 Microsoft Teams、飞书和自定义 Webhook其中 Teams 的接入流程最有代表性热搜词里也是高频查询。OpenClaw 在配置里用channels字段定义所有通信渠道你可以把 agents 绑定到任意 channel 上也可以让多个 channel 共用一个 agent。先看一眼配置文件里的结构通常长这样{ channels: { teams: { enabled: true, app_id: 你的应用注册ID, app_secret: 你的应用密码, tenant_id: 你的租户ID, port: 1861 }, webhook: { enabled: true, path: /hook/default } }, agents: { main: { channels: [teams, webhook], model: qwen-plus, system_prompt: 你是 OpenClaw 助手... } } }逻辑说明channels.teams段存放 Teams 应用接入所需的三项核心凭据应用注册 ID、应用密码和租户 ID。这三样东西在 Azure Portal 的应用注册页里生成Teams 机器人接入本质上就是一个 OAuth 2.0 客户端OpenClaw 启动后拿这个凭据向微软的 Bot Framework 注册活动之后 Teams 里私聊或群聊 机器人消息就会推送到容器的 1861 端口上。agents.main.channels这个数组决定 agent 绑定哪些 channel我现在就让同一个 agent 同时服务 Teams 和 Webhook两边不要重复建 agent节省 token 也节省排查成本。参数说明port字段要和容器端口映射对齐如果容器里监听 1861外部访问也要映射 1861映射错位后常见的表象是 Teams 那边报“Bot 不响应”OpenClaw 日志里却什么都没有因为消息根本没进容器。webhook.channel的path是自定义入口路径可以配到企业微信或飞书的自定义事件回调里这一类不需要 app_id只要对外地址能到达即可。如果你要用 HTTPS 回调到 Teams容器和前级 Nginx 的代理配置也要一起改这一节先不展开到第 4 章讲 compose 编排时再补。3.3 模型接入给 OpenClaw 配上千问等 OpenAI 兼容接口模型配置是另一个高频热搜点尤其搜索词里“openclaw 配置千问”出现了多次。原因不难理解OpenClaw 本身不内置大模型它只做会话编排所有推理都要发给后端模型服务。模型接入的风格目前已经演进到高度统一OpenAI 兼容接口成了事实标准不管是通义千问、DeepSeek 还是智谱基本都提供了 OpenAI 格式的接口地址和 key。# config/models.yaml models: qwen-plus: provider: openai-compatible base_url: https://dashscope.aliyuncs.com/compatible-mode/v1 api_key: ${QWEN_API_KEY} model_name: qwen-plus max_tokens: 4096 qwen-max: provider: openai-compatible base_url: https://dashscope.aliyuncs.com/compatible-mode/v1 api_key: ${QWEN_API_KEY} model_name: qwen-max max_tokens: 8192逻辑说明base_url指向千问的 OpenAI 兼容端点model_name决定实际调用哪个规格的千问模型qwen-plus和qwen-max是速度和质量的两种取舍。api_key没有硬编码用${QWEN_API_KEY}引用环境变量OpenClaw 进程从宿主机环境里读取这样配置文件即使被提交到 Git 仓库也不会泄露密钥。max_tokens限制单次返回的最大 token 数我一般给 qwen-max 放 8192因为复杂任务需要长输出但要注意模型侧的上下文窗口上限配得比窗口还大会直接报错。参数说明provider: openai-compatible是几乎所有模型的统一入口OpenClaw 内部用 OpenAI SDK 协议去适配各家接口所以只要是 OpenAI 兼容的模型服务都能用同样结构接入。如果你用本地推理引擎如 Ollama、vLLM把base_url换成它们的地址和端口即可其余字段不用动。换模型时不需要改 channel 配置只要在 agent 的model字段里改名字然后重启容器让配置生效。每次改配置后的重启动作我现在已经形成肌肉记忆先docker exec -it openclaw openclaw config validate校验一遍再docker restart openclaw避免配置写错后带着错误配置直接上线让 agent 在 Teams 里给人一种“人工智障”的印象。4. 上生产的编排用 docker compose 管理 OpenClaw4.1 docker-compose.yml 完整清单与逐项注释当你把 OpenClaw 从“能跑”推向“能一直跑”docker run 就没法满足需求了你需要把启动参数、挂载、环境变量、网络、重启策略都声明进 docker-compose.yml。这个文件就是 OpenClaw 部署的“代码”别人拿到它就能完整复现一套配置这才是标题里“代码”二字的深意。# docker-compose.yml services: openclaw: image: openclaw-image:latest container_name: openclaw restart: unless-stopped ports: - 1860:1860 # Web 管理界面 - 1861:1861 # Teams channel 回调端口 volumes: - ./config:/app/config - ./sessions:/app/sessions - ./attachments:/app/attachments - ./logs:/app/logs environment: - QWEN_API_KEY${QWEN_API_KEY} - TZAsia/Shanghai - LOG_LEVELinfo healthcheck: test: [CMD, curl, -f, http://localhost:1860/health] interval: 30s timeout: 10s retries: 3 start_period: 40s logging: driver: json-file options: max-size: 20m max-file: 5逻辑说明restart: unless-stopped是生产部署里的关键设置宿主机重启、Docker 服务重启后容器都会自动拉起只有你手动 stop 的容器它才不复活这个策略比always更克制适合常驻服务。ports段把两个端口都露出来1860 留给管理界面1861 留给 Teams 回调如果将来要加飞书 Webhook再补一个端口。volumes段把第 3 章梳理的四个目录全部映射到宿主机./下注意这里的相对路径是相对于 docker-compose.yml 所在目录别再当 shell 相对路径理解。environment段里只放了运行时需要的变量QWEN_API_KEY通过${QWEN_API_KEY}从宿主机环境变量注入yml 文件本身不存密钥TZAsia/Shanghai统一容器和宿主机的时区避免日志时间与告警时间对不上LOG_LEVELinfo是 OpenClaw 的日志级别默认可能是 debug生产环境关到 info 能省大量磁盘。healthcheck是 OpenClaw 容器化部署容易忽略但非常实用的一节每 30 秒用 curl 探测一次健康端点连续 3 次失败 Docker 会标记容器 unhealthy配合监控系统可以及时告警。4.2 healthcheck、日志轮转与资源限额三个让人少熬夜的参数在 docker run 模式下日志和资源限制通常没人管跑几天后/var/lib/docker/containers能占几十 GB这在 OpenClaw 这类长连接智能体上格外明显。compose 文件里的logging段就是干这个的logging: driver: json-file options: max-size: 20m max-file: 5max-size: 20m表示单个日志文件最大 20MBmax-file: 5表示最多保留 5 份超出的日志自动轮转删除。这样 Log 目录大小上限被锁在一百 MB 左右不会出现磁盘被日志写满导致容器假死的惨状。更稳妥的做法是搭一套 Loki 或 ELK 把日志收到中心化平台但对单机部署 OpenClaw 来说这个配置已经够挡住 90% 的磁盘告警。资源限额同样值得配。OpenClaw 在跑长上下文时内存会涨不限制的话可能把宿主机拖垮deploy: resources: limits: memory: 2g cpus: 1.0含义是容器最多使用 2GB 内存和 1 个 CPU 核超过后容器会被 OOM killer 杀掉而不是拖死宿主机上其他服务。如果你的 OpenClaw 要处理大附件、频繁调用多模态模型建议把 memory 调到 4g。这里不用mem_limit和cpu_limit的旧写法compose 新版本全部走deploy.resources兼容性最好。4.3 镜像升级与平滑重启别再用 docker stop 硬来了OpenClaw 新版本发布后你想升级镜像常见做法是先拉新镜像——但 restart 策略会立刻把旧容器拉起来新镜像根本没进去。正确流程是先停止旧容器再拉镜像然后启动# 进入项目目录关闭旧容器但不删卷 docker compose down # 拉取新镜像 docker compose pull # 校验最新配置后启动并实时看日志 docker compose up -d docker compose logs -f openclaw逻辑说明docker compose down只删除容器和默认网络volumes里声明的数据卷不受影响所以会话和配置都还在。pull之后 compose 会用新镜像重建容器up -d启动后建议立刻看前 60 行日志确认配置加载成功且 channel 都注册上了。如果不放心可以先把镜像标签从版本 A 切到比 latest 更明确的版本号升级失败时直接改回旧版本再 up这就是容器给的“后悔药”回滚只改一个标签宿主机不用动。有个细节docker compose down不会删除restart: unless-stopped的容器为你保留的数据但如果你用了-v全局变量或者把数据卷声明在了 compose 顶层没有绑定宿主机目录那 down 的时候一定要看清提示是否有删除 volume 的字样。建议所有数据都用宿主机目录挂载而不是命名卷这样即使 compose 文件误删数据仍在磁盘上。5. 避坑OpenClaw 容器化部署的 4 个高频故障5.1 agent failed before reply: session file locked (timeout 60000ms)这个报错在搜索词里几乎原样出现agent failed before reply: session file locked (timeout 60000ms) openclaw。现象是 OpenClaw 收到消息后迟迟不回复日志里打出一行警告说 session 文件被锁住了等待超时 60 秒。原因OpenClaw 的会话状态以文件形式保存在 sessions 目录每个会话一个文件默认实现为单进程内读写锁。当两个任务同时命中同一个会话或上一次任务异常退出后锁没有释放就会触发超时。容器持久化挂载的一个隐藏副作用是会话文件被多个 OpenClaw 实例共享——如果你起了两个容器挂载同一个 sessions 目录也容易出现这个错。解决先确认是不是多容器共用目录是的话拆开目录或在业务侧分 agent。单容器场景下找到对应 session 文件删除锁标记常见做法是删除该 session 文件让 OpenClaw 重建会话或者调用管理接口清空会话。如果频繁出现最稳妥的解法是给每个 channel 配一个独立 agent 文件避免消息洪峰争抢同一会话锁。我用一句经验总结OpenClaw 的 session 锁设计是单机单实例优先硬上多副本前务必先搞清锁的存储位置。5.2 容器一重启会话与配置全没了现象明明日常对话都正常升级镜像或docker compose down up -d后所有历史会话消失配置回到初始状态像是刚装完一样。原因容器内/app下的数据没有挂载到宿主机容器重建时写进容器层的数据被整体清空。很多第一次用 Docker 的开发者会犯这个错以为-v只要在 run 命令里出现就是挂载了实际上挂载点没对齐容器实际写入路径等于白挂。解决启动后用docker exec进容器确认实际数据写入路径把路径和docker inspect里的 Mounts 字段对照一遍。例如# 查看容器的实际挂载表确认宿主机目录绑定到了哪个容器目录 docker inspect openclaw --format {{json .Mounts}} | python3 -m json.tool然后按第 3 章目录结构把 config、sessions、attachments 一一挂到正确路径。修改挂载必须重建容器restart不会应用新的挂载参数这也是新手对着docker restart挠头的常见原因。5.3 容器能起来但 Teams 等 channel 一直连不上现象容器状态健康1860 管理界面能打开Teams 里 机器人却石沉大海看日志没有任何来自 Teams 的事件。原因大多数情况不是 OpenClaw 的问题而是回调地址不通。 Teams 的 Bot Framework 需要一个可通过公网访问的 HTTPS 回调端点本地 Docker 部署的 1861 端口若没有域名和反向代理Teams 根本推不进来。另一种情况是 Azure 应用注册里的“消息端点”填错了路径或者容器端口映射到的是 1860 而不是 1861。解决先分两步走。第一步确认容器端口确实对外可访问如用curl http://localhost:1861看响应第二步检查 Teams 后台配置的端点 URL它必须指向https://你的域名/api/messages这一类的完整路径域名背后用 Nginx 反代到宿主机 1861 端口。Nginx 配置里记得加大client_max_body_size和处理 WebSocket 升级的Upgrade头。还有一条来自实际部署的提醒Teams 对 SSL 证书要求严格自签名证书会直接拒连上正式环境前先把证书换成受信任证书。5.4 内存慢慢涨容器莫名被杀 Restarting现象容器运行三五天后docker ps看到 STATUS 一直是 Restarting日志末尾出现Killed或退出码 137。原因退出码 137 几乎都是 OOM 杀进程OpenClaw 持有长会话上下文内存在高并发或大上下文下逐渐累积触发内核 OOM killer。另外容器内没有设置--memory限制时Docker 默认允许容器无限吃内存宿主机内存紧张后反而更容易殃及池鱼。解决给容器加上内存和 CPU 限制见 4.2 节配置。同时检查 OpenClaw 有没有会话过期淘汰策略把不活跃会话设了自动清理减少常驻上下文数量。长期观察后你会发现内存曲线趋于平稳而不是线性往上爬到被 OOM 杀死——平稳是健康部署的指标。如果容器日志还出现msvcp140.dll这类 Win 下才有的加载错误说明你拿错了镜像Windows 宿主机上也别直接跑 Windows 容器版Docker Desktop 默认 Linux 容器即可。6. 用一条真实 agent 对话验证部署日志链路与自查口诀部署完别急着写“接入了千行代码”先用一次最小对话做端到端验证。我的做法是从 Web 管理界面或 Webhook 发一条简单消息比如“你好请回复 OK”然后看 OpenClaw 日志的完整链路。以下是一条健康链路的标志性输出[INFO] channelteams eventmessage_received session_id0a3f... [INFO] agentmain modelqwen-plus request_idreq_9e2... [INFO] llm_response modelqwen-plus tokens_in128 tokens_out32 [INFO] session_saved path/app/sessions/0a3f...elapsed2140ms逻辑说明第一行表示 Teams 消息进到了 OpenClaw 的 channel 层session_id 是会话文件的文件名第二行表示 agent 收到消息并选择模型 qwen-plus第三行是模型调用的返回信息tokens 数字能帮你估算单次对话的模型成本第四行表示会话已写回磁盘。四行日志顺序出现说明 channel、agent、模型、会话存储四个环节都通了这个部署就算真正跑通了。验证完成后我建议再检查一次会话文件是否真的落盘尤其是容器重建后测试过一遍才能把持久化这件事落实# 查看 sessions 目录是否生成了对应的 session 文件 ls -la /opt/openclaw/sessions/ | tail -5最后送你一个永远有效的自查口诀先看日志、再看会话、最后看版本。遇到任何部署异常第一反应不是改配置而是docker logs --tail 200把最近的日志拉出来绝大部分问题在日志里都有明确线索确认日志没有异常报错后再检查会话文件是否正常读写最后确认当前镜像版本和文档是否对齐。我自己的教训是曾经在某次排查中忽略了镜像版本对着一个已废弃的配置格式排查了整整三个小时后来发现只是 old version 的兼容性问题升级就好了。格式化排错顺序能省掉大半无头绪的“玄学”定位。希望这条 Docker 安装 OpenClaw 的路线和这些坑能帮到你照着跑通一次以后升级和扩展都有底。本文还有配套的精品资源点击获取

看完文章,想为自己的企业也做一次专业网站诊断?

尧图顾问免费为您评估现有网站,并给出建站/改版建议与报价方案。

免费获取方案