部署AI智能体,本该是一件让人兴奋的事,结果很多人的第一次体验都毁在了环境配置上:Python 版本莫名其妙不兼容、pip 装包装到系统路径里、一个依赖升级把另一个服务搞挂;更别提给智能体加记忆、接数据库、换模型时那种牵一发动全身的恐惧感。我自己早期裸机跑过不少智能体项目,折腾下来发现,真正能一劳永逸的解法还是容器化。Docker + OpenClaw 这套组合,把 AI 智能体从运行环境到依赖、从配置到数据全部装进容器,一条 compose 命令拉起来,换机器迁移也就是拷个目录的事。这篇教程我会从零开始,完整走一遍一体化部署流程,把每一步的原理和避坑点都讲透,适合有点 Docker 基础但没正式部署过智能体的开发者收藏参考。
1. 先搞清楚 OpenClaw 能干什么,再决定要不要上车
1.1 为什么选 OpenClaw,而不是自己写脚本或套别的框架
OpenClaw 本质上是一个开源的 AI 智能体框架,核心能力是让大模型具备"拆解任务-调用工具-执行动作-返回结果"的闭环能力。跟普通聊天机器人最大的区别在于,聊天机器人是"你问一句,它答一句",而 OpenClaw 是你把一个目标丢给它,比如"帮我整理这周的电商销售数据并生成周报",它会自己去规划步骤、决定调数据库还是调表格工具、按顺序执行,最后把成品交给你。
那为什么不自己从头写一套脚本?说实话,自己搭一套智能体跑起来并不难,难的是把"规划-执行-记忆-工具调用"这些环节串成稳定系统。OpenClaw 这类框架的价值在于,它把智能体共用的骨架建好了:任务规划器负责拆解目标,工具调用层负责对接外部 API,记忆模块负责把历史对话和结果存起来,你再往上填自己的业务逻辑就行了。开源框架的好处是生态现成,遇到问题能翻别人踩过的坑,不用自己从零发明轮子。
对比其他成熟 Agent 框架,OpenClaw 在部署这件事上有一个很突出的优点:它对容器化的支持做得相当完整,官方镜像自带运行时环境和默认配置,Compose 编排也是开箱即用。这意味着你不用关心底层依赖是用什么版本编译的,镜像里已经全给你准备好了。
1.2 为什么非要用 Docker:隔离、可移植、可回滚
说句实话,智能体这个东西对运行环境的挑剔程度,比我见过的大部分 Web 服务都要高。它要装 Python 库、要调用系统命令、可能要连数据库、可能要跑浏览器自动化,任何一个依赖装错版本都会演变成玄学问题。Docker 解决这个问题的方式很粗暴:把整个运行环境连同应用一起打包成镜像,镜像里有特定版本的 Python、系统库、预装依赖,宿主机上有什么根本不影响。
除了环境隔离,Docker 带来的另外两个隐含收益在真刀真枪部署时非常关键。第一个是可移植性:同一份 Compose 文件,在开发机上能跑,在服务器上也能跑,在朋友的机器上同样能跑,不再有"在我电脑上明明好好的"这种尴尬。第二个是可回滚:镜像的 tag 就是版本号,新版本升级失败,一条命令切回旧 tag 再启动,连代码都不用动。这种安全感在裸机时代是奢侈品。
还有一个日常不太会注意但很实际的点:Docker 对资源限制非常方便。AI 智能体跑起来之后,如果你不做限制,它发起狂来可能把一块 8G 内存全吃掉。我习惯在 Compose 里给智能体容器配好mem_limit,省得它跟别的服务抢资源。
1.3 一体化部署完成后,你手里会有什么
按这套教程走完,你的 Docker 环境里会出现这么几个协作工作的容器:
| 容器 | 职责 | 是否必选 |
|---|---|---|
| OpenClaw 主进程 | 智能体核心引擎,负责任务规划、工具调度和模型对话 | 必选 |
| PostgreSQL | 存储智能体的记忆、会话状态和任务中间结果 | 强烈建议 |
| Ollama(可选) | 本地大模型推理引擎,让智能体不依赖外部 API | 按需 |
| Redis(可选) | 缓存和任务队列,高并发场景下用 | 按需 |
主进程加数据库,这是一体化部署的最小底座。记忆和状态存外部数据库而不是塞在本地文件里,是我强烈推荐的做法,因为容器一旦重建,本地文件就全没了,数据放 Postgres 里用 Volume 挂载,容器随便删,数据丢不了。
2. 部署前的准备工作:硬件、Docker、模型接口一个都不能少
2.1 硬件配置要求:先看看自己的机器行不行
OpenClaw 本身是个 Python 服务,对 CPU 要求不算夸张,但 AI 智能体跑起来之后,上下文窗口、任务规划、工具返回结果都会占内存。直接给一套我在实际部署中总结出来的硬指标:
| 配置项 | 最低要求 | 推荐配置 | 备注 |
|---|---|---|---|
| CPU | 2 核 | 4 核以上 | 多核能加快任务调度和并发工具调用 |
| 内存 | 4 GB | 8 GB 以上 | 4G 只够跑主进程和数据库,再多开一个本地模型就吃力 |
| 磁盘 | 10 GB 可用 | 20 GB 以上 SSD | 容器镜像、日志、数据库文件都会慢慢吃空间 |
| 操作系统 | Linux / macOS / Windows (WSL2) | Ubuntu 22.04 LTS | 服务器上跑强烈建议 Linux |
| 网络 | 能访问模型服务的公网接口 | 对延迟和稳定性有要求 | 如果走本地模型,网络要求大幅降低 |
我早期在一台 2 核 4G 的旧笔记本上试过,主进程加 Postgres 跑起来之后内存基本见底,智能体稍微干点复杂任务就开始卡。后来换到 4 核 8G 的云主机,体感是质的飞跃。如果你想在同一台机器上再跑 Ollama 本地模型,那内存最好直接上 16G,否则推理速度会让你怀疑人生。
2.2 安装 Docker:Ubuntu 服务器和 Windows 笔记本两条路线
部署的起点是装好 Docker 引擎。以我最常用的 Ubuntu 22.04 为例,装 Docker 其实不用走网络上传的神奇脚本,官方仓库安装最稳妥。先把系统包索引刷新,装上前置依赖:
sudo apt update sudo apt install -y ca-certificates curl gnupg lsb-release然后添加 Docker 官方的 GPG 密钥和软件源。这里提醒一下,不同版本的 Ubuntu 对应不同的下载通道,官方源会自动根据你系统的代号匹配,所以不用手动指定版本号。
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null接着安装,并顺手把 Docker 服务设置成开机自启:
sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin sudo systemctl enable --now docker装完之后跑docker --version和docker compose version验证一下。这里有个新手很容易踩的坑:在 Linux 上装完 Docker,直接跑docker ps大概率报permission denied while trying to connect to the Docker daemon socket。原因是当前用户不在docker用户组里。解决办法很直接:
sudo usermod -aG docker $USER newgrp docker如果你用的是 Windows 笔记本,那走 Docker Desktop 路线。安装包里会自带 WSL2 后端,装完之后去设置里确认一下"Use WSL 2 based engine"是打开的。Windows 上最容易翻车的点是 BIOS 里的虚拟化没开启,Docker Desktop 会直接提示virtualization support wasn't detected,这个时候需要进 BIOS 把 Intel VT-x 或 AMD-V 打开,没有捷径。
2.3 准备模型服务的访问凭证
OpenClaw 本身不带推理能力,它的大脑来自大模型服务。所以在部署之前,你得先有一个能用的模型 API,也就是 API Key。申请流程各家大同小异:注册账号、创建密钥、给账户充值,然后把密钥保存好。别把它写在 Compose 文件里或者提交到代码仓库,这是我见过的最常见安全事故。
密钥管理的小技巧是建一个.env文件放在项目根目录,然后在 Compose 里用${MODEL_API_KEY}这种变量引用。.env放进.gitignore,这样就算项目目录被同步到公共仓库,密钥也不会泄露。
如果你不想用外部模型服务,也可以等部署完成之后再接本地模型,这块我放到第 4 节详细讲,先不在准备阶段卡住你。
3. 上手实操:写 Compose 文件,一键拉起整套智能体服务
3.1 先规划好项目目录结构
我每次部署新环境,都会把项目目录建得很规矩。目录结构清晰的好处是,几个月后再回来维护,你还能一眼看出什么东西放在哪里。建议按下面这种结构来:
~/openclaw/ ├── data/ │ ├── postgres/ # 数据库数据持久化目录 │ └── openclaw/ # 智能体运行数据、日志 ├── skills/ # 自定义技能目录 ├── .env # 环境变量文件 └── docker-compose.yml # 服务编排文件先创建目录,把.env和docker-compose.yml放进去。我第一次跑的时候图省事,把所有数据都怼在容器里,后来升级镜像一重建容器,记忆全部清空,那叫一个后悔。现在这套data目录挂载方式,已经是我所有部署的默认模板了。
3.2 编写 docker-compose.yml:核心配置逐行解析
先用可视化的方式列出整个 Compose 文件的结构,再解释每个关键配置项的含义。我实际使用的 Compose 大致长这样:
version: "3.8" services: openclaw: image: openclaw/openclaw:latest container_name: openclaw restart: unless-stopped ports: - "2882:2882" env_file: - .env environment: - OPENCLAW_DATABASE_URL=postgresql://openclaw:openclaw@postgres:5432/openclaw volumes: - ./data/openclaw:/app/data - ./skills:/app/skills depends_on: - postgres mem_limit: 4g postgres: image: postgres:16-alpine container_name: openclaw-db restart: unless-stopped environment: - POSTGRES_USER=openclaw - POSTGRES_PASSWORD=openclaw - POSTGRES_DB=openclaw volumes: - ./data/postgres:/var/lib/postgresql/data mem_limit: 1g这段配置看着简单,里面有几个点值得展开说一下。
ports里的2882:2882是 OpenClaw 的默认管理端口。左边是宿主机端口,右边是容器内端口。如果你本机 2882 已经被占用,可以改成2883:2882,这样外部访问就用 2883。容器内部端口最好不要改,因为镜像里的默认配置是按 2882 工作的,改了镜像内配置,这多出来的工作量没意义。
env_file指向.env文件,模型密钥、各种 Token 都从这个文件注入,而不是硬编码在 Compose 里。这么做的好处有两个:一是不同环境切换只需换.env,二是 Compose 文件本身可以放心提交到仓库。
depends_on表示 OpenClaw 依赖 Postgres 先启动。但这里有个细节,depends_on只保证容器启动顺序,不保证数据库服务已经就绪。也就是说,Postgres 容器启动了,但 PostgreSQL 进程可能还没准备好接受连接,OpenClaw 启动时如果连不上数据库,可能会直接退出。所以要在 OpenClaw 的启动脚本里加重试逻辑,或者用好restart: unless-stopped让 Docker 在容器退出后自动重启它。实际部署中,往往一次重启之后数据库就绪了,服务就能正常起来。
3.3 环境变量逐一说明:每个 Key 是干什么的
.env文件是我这套部署方案的中枢。我把自己用的典型配置贴出来,并解释每个变量的作用:
# 模型服务配置 MODEL_PROVIDER=openai-compatible MODEL_NAME=gpt-4o-mini MODEL_API_KEY=sk-xxxxxxxxxxxxxxxx MODEL_API_BASE= # OpenClaw 基础配置 OPENCLAW_MASTER_KEY=change-me-to-a-long-random-string OPENCLAW_LOG_LEVEL=info # 管理面板 ENABLE_DASHBOARD=true DASHBOARD_PORT=2882MODEL_PROVIDER声明模型服务的类型。OpenClaw 兼容 OpenAI 的接口格式,所以任何提供 OpenAI 兼容接口的模型服务都可以填openai-compatible。MODEL_NAME是具体的模型名,注意它必须和服务商侧实际的模型标识一致,否则请求会直接 404。MODEL_API_KEY就是前面准备好的密钥。
MODEL_API_BASE默认留空,走官方默认地址。如果你用的是第三方兼容网关,就得把这个地址填上,OpenClaw 会把它作为所有模型请求的基础 URL。这也是接入本地模型时待会要重点用到的变量。
OPENCLAW_MASTER_KEY是管理密钥,控制管理面板和 API 访问,生产环境务必换成一个足够长的随机字符串。生成方法很简单,Linux 下直接跑openssl rand -hex 32。
3.4 启动服务并完成基础验证
配置写完之后,进入项目目录,执行:
docker compose up -d-d是后台运行,否则日志会直接铺满终端。第一次启动要拉镜像,如果镜像比较大,耐心等一会。启动之后用下面几个命令验证状态:
docker compose ps docker compose logs -f openclawcompose ps会列出两个容器的运行状态。如果STATUS这一列是Up并且没有频繁重启,说明至少进程起来了。然后看日志,重点观察几类日志:数据库连接是否成功、模型配置是否被正确加载、管理面板是否监听端口。日志里没有红字 ERROR 之后,打开浏览器访问http://服务器IP:2882,应该能看到管理面板的登录页。
注意:如果你是在云服务器上部署,记得在安全组/防火墙里放行 2882 端口。我遇到过一次容器内部一切正常、面板死活打不开的情况,排查半天发现是云安全组把端口给拦了。
4. 让智能体真正干活:模型接入、技能挂载与数据持久化
4.1 接入云端模型:改一行配置就能切换
OpenClaw 启动时默认从.env里读模型配置。想切换云端模型,只需要改MODEL_NAME和对应的MODEL_API_KEY,然后重启容器:
docker compose restart openclaw这里有三个实操细节值得记一下。第一,改完配置后必须重启,智能体进程不会热加载.env,不重启等于白改。第二,不同模型的能力差异很大,我踩过的坑是:小模型面对复杂任务会频繁"偷懒",明明需要调用工具,它直接编一个假结果给你。所以如果是跑正经业务,别贪便宜用太迷你的模型。第三,如果服务商有多个模型可用,建议在同一个MODEL_NAME里填写业务模型,不要七个八个模型来回切换,智能体会精神分裂。
模型接入完成之后的验证方式很简单:在管理面板里新建一个会话,给智能体发一条指令,比如"请总结你当前使用的模型和运行环境"。如果它能准确回答出模型名称和配置详情,就说明模型链路已经打通。
4.2 接入本地模型:断网也能跑,但先想清楚值不值
如果你对数据隐私很敏感,或者不想让智能体每次请求都走公网,可以考虑接入本地模型。OpenClaw 支持通过 Ollama 在本地跑推理,部署方式是在 Compose 里再加一个服务:
ollama: image: ollama/ollama:latest container_name: ollama restart: unless-stopped volumes: - ./data/ollama:/root/.ollama ports: - "11434:11434" mem_limit: 8g然后进入 Ollama 容器拉取模型:
docker exec -it ollama ollama pull qwen2.5:7b拉完之后,把.env改成:
MODEL_PROVIDER=ollama MODEL_NAME=qwen2.5:7b MODEL_API_BASE=http://ollama:11434/v1注意这个MODEL_API_BASE写的是http://ollama:11434/v1,不是localhost。在 Docker 网络里,容器之间的通信要通过服务名,而不是localhost。这是新手最容易搞混的一个点,localhost在容器里指向的是容器自己,不是宿主机,更不是别的容器。
本地模型的好处是私密性和零 API 费用,代价是推理速度和生成质量通常比不过云端大模型。我个人建议:如果只是开发调试,可以直接用云端小模型,便宜又快;如果要跑敏感数据处理,或者要做离线演示,那本地模型才是唯一正解。
4.3 挂载技能:把 OpenClaw 从聊天机器人变成干活机器人
OpenClaw 真正的威力在于工具调用,也就是所谓的"技能"。一个技能就是一个工具包,智能体可以在任务规划时动态决定调用哪个技能来完成子任务。技能文件的存放位置就是我们在 Compose 里挂载的./skills目录。
技能目录的典型结构大致如下:
skills/ └── my-skill/ ├── manifest.yaml # 技能描述文件 ├── script.py # 实现工具逻辑 └── requirements.txt # 额外依赖其中manifest.yaml是这个技能的说明书,告诉智能体这个技能是干什么的、有哪些参数、什么时候该调用它。智能体在规划任务时,会读取这个描述来决定要不要调用。所以技能的描述写得越清楚,智能体就越会正确地使用它,否则就算有技能它也只会干瞪眼。
把一个新技能放入skills目录之后,同样需要重启容器让它生效:
docker compose restart openclaw重启之后在管理面板的日志里确认技能被加载成功。如果依赖里包含系统底层库,可能会遇到镜像里没有预装的问题,这时就得偏偏在技能目录里放一个构建脚本,或者在 Compose 中单独为 OpenClaw 扩展一个自定义镜像。这一步属于进阶玩法,用到时再深入研究即可。
4.4 数据持久化:让智能体拥有跨会话的记忆
智能体的记忆是它的核心竞争力之一。这里说的记忆不只是聊天记录的存储,还包括任务执行的历史、工具调用的结果、用户偏好等等。OpenClaw 把这些数据统一存在 PostgreSQL 中,而 Postgres 的数据目录通过./data/postgres挂载在宿主机上。
为什么这一层如此重要?因为容器本质上是"一次性"的。docker compose down会销毁容器,但不会销毁挂载在宿主机上的数据目录。下次up启动时,Postgres 读到旧数据,智能体的记忆就还在。如果没有挂载卷,down之后数据库文件跟着容器一起消失,一切归零。
备份也很简单,直接用 PostgreSQL 标准工具做逻辑备份或者直接打包宿主机上的数据目录:
docker compose exec postgres pg_dump -U openclaw openclaw > backup.sql恢复时只要在空库上执行这个 SQL 文件即可。我在实际生产里用的策略是:每天凌晨用 cron 自动备份backup.sql到独立磁盘,每周做一次全量快照。做数据恢复演练时能让你心里有底,数据无价。
5. 常见问题与排查技巧实录:把这些坑提前帮你踩了
5.1 Docker 本身的问题:权限、虚拟化、镜像拉取
这套部署方案 90% 的报错其实发生在 Docker 层,而不是 OpenClaw 层。最常见的三个问题我整理成速查表:
| 现象 | 原因 | 解决方案 |
|---|---|---|
permission denied while trying to connect to the Docker daemon socket | 当前用户不在 docker 用户组 | sudo usermod -aG docker $USER后重新登录 |
| Docker Desktop 报虚拟化未开启 | BIOS 中 CPU 虚拟化被禁用 | 进 BIOS 开启 Intel VT-x / AMD-V |
| 镜像拉取速度很慢或超时 | Docker Hub 连接不畅 | 配置公共镜像加速地址,重启 Docker 生效 |
镜像拉取慢这个问题,我自己的处理方式是在/etc/docker/daemon.json里配置镜像加速地址,然后sudo systemctl restart docker。需要留意的是,加速配置只对新拉取的镜像生效,已经存在的镜像不用重复处理。
5.2 OpenClaw 启动失败:数据库、密钥、端口三板斧
如果docker compose logs openclaw里出现数据库连接错误,比如could not connect to server,十有八九是 Postgres 还没就绪,或者密码和DATABASE_URL里的对不上。检查顺序是:先确认 Postgres 容器状态正常,再确认.env中的数据库密码和 Compose 中POSTGRES_PASSWORD一致,最后确认连接串里写的主机名是postgres而不是localhost。
密钥类报错更容易辨认。日志里若出现认证失败或 401,直接检查MODEL_API_KEY是不是复制完整了。这里有个隐藏的坑:.env文件里的值如果带特殊字符,比如+、/、=,不需要手动转义,但如果你的 Key 不小心带了空格,那就完蛋了。粘贴密钥前后注意别带上多余空格。
端口类问题主要表现是容器显示 Up,但管理面板打不开。建议先确认容器内进程是否真的在监听 2882:
docker exec openclaw ss -tlnp | grep 2882这一步能区分到底是应用没起来,还是防火墙/安全组挡了外部访问,排查思路会清晰很多。
5.3 模型调用超时与限流:别让智能体被 A 服务卡死
还有一个非常常见的问题:任务一复杂,模型调用就超时,日志里全是timeout或rate limit exceeded。这通常不是 OpenClaw 的问题,而是模型服务商的接口超时设定或者限流策略导致的。解决思路有几个。
看是否是并发太高。智能体在规划复杂任务时,可能会在短时间内发起大量模型请求,超出服务商的速率限制。这种情况可以在管理面板把并发数调低,或者给任务加排队机制。如果是单请求执行时间太长,检查模型服务商的超时上限,有的服务默认 60 秒,大任务很容易超。OpenClaw 侧也可以调大 HTTP 请求超时参数。如果是自建模型,那就是硬件算力不够,只能靠降模型规模、加显存或者换更快的推理引擎来解。
5.4 换个思路排查:看日志时要找上下文,别只看最后一行
排查问题这件事,我没少熬过夜,最深刻的体会是:日志一定要看上下文,不要只看最后一行。很多报错表面上是 A,实际原因是 B。比如一个模型 500 报错,后面跟着的大串堆栈,真正的错误原因可能早在前 50 行标注了Input data format不对劲。养成习惯,出问题先docker compose logs --tail 200而不是--tail 20,能少踩很多坑。
另外强烈建议把 OpenClaw 的日志级别调成info以上,不要觉得debug更高级就一直开 debug,日志量太大了反而淹没了关键信息。我在生产环境坚持用info,需要深挖的时候临时切一次debug,用完了再切回来,这个习惯帮我节省了大量读日志的时间。
内容写到这里,整个一体化部署的闭环已经打通了。我再多说一句真心话,这套方案最值钱的地方不是某个炫技操作,而是它把 AI 智能体从一个"脆弱的本地程序"变成了"可复制、可迁移、可恢复的基础设施"。第一次部署的时候,耐心看完每一个日志的输出,跑通之后再回过头来整理自己的.env模板和技能包,你会发现后续每次上新场景,从零到一的时间会从一下午压缩到十分钟。这就是容器化部署应该有的样子。