OpenClaw Docker部署实战:避坑指南与生产级docker-compose配置
1. 项目概述:为什么OpenClaw值得用Docker部署,而不是手动装一地依赖
OpenClaw不是个玩具项目,它是个正经的、面向生产环境设计的开源智能体工作流引擎——你可以把它理解成一个“可编程的AI调度中心”,核心能力是把大模型调用、工具执行、状态管理、多步骤决策这些事,用代码逻辑串起来,跑得稳、看得清、改得快。最近半年,我帮七八个团队落地过OpenClaw,从初创公司做客服自动归因,到传统企业搭内部知识助手,再到高校实验室跑实验流程编排,发现一个铁律: 凡是没用Docker部署的,后期90%都卡在环境不一致上 。有人在Mac上跑得好好的,扔到Ubuntu服务器就报 ModuleNotFoundError: No module named 'pydantic.v1' ;有人本地调试时响应200ms,一上测试机直接超时5秒,查半天发现是MySQL连接池配置和Python异步事件循环打架。这不是OpenClaw的锅,是环境变量、Python版本、系统库、时区、甚至glibc小版本差异埋下的雷。
Docker在这里干的活,远不止“打包运行”这么简单。它本质是给你划出一块干净的、可复现的“数字沙盒”:里面Python是3.11.9,Pydantic是2.7.1,MySQL是8.0.34,Redis是7.2.4,连时区都锁死在UTC+0——所有组件的版本、启动顺序、网络互通方式、数据落盘路径,全由 docker-compose.yml 这一份文件定义。你今天在笔记本上 docker-compose up -d 起一套,明天在阿里云ECS、腾讯云CVM、甚至树莓派4B上,只要装了Docker Engine,执行同一份命令,出来的就是一模一样的服务拓扑。这背后省掉的是什么?是运维同学半夜被call醒查 pip list 输出里混着三个不同版本的 httpx ,是开发同学反复重装 mysql-client 头文件,是测试同学对着“本地OK线上炸”截图发呆两小时。OpenClaw官方文档里那句“推荐使用Docker部署”,不是客套话,是踩过坑的人用时间换来的结论。
这个教程要解决的,就是把“推荐”变成“照着做就能跑通”。不讲虚的Docker原理,不堆概念,只聚焦三件事:第一, docker-compose.yml 里每个字段为什么这么写(比如 restart: unless-stopped 不是随便加的,是防宿主机重启后服务静默死亡);第二,MySQL和Redis的初始化脚本怎么写才不会让OpenClaw启动时卡在“等待数据库连接”;第三,最常被忽略的 .env 文件里,哪些环境变量改错一个,整个工作流就永远处于 pending 状态。我会把第一次部署时遇到的6个典型报错——从 docker-compose up 卡在 pulling image ,到OpenClaw UI显示 Connection refused ,再到技能节点执行时报 No module named 'openclaw.skill' ——全部还原当时的终端日志、排查路径和最终修复动作。你不需要懂Docker底层cgroups怎么调度,但得知道 docker-compose logs -f openclaw 这条命令能救你命。
2. 整体架构设计与关键组件选型逻辑
2.1 为什么必须用docker-compose,而不是单个docker run?
OpenClaw不是单进程应用,它天然依赖至少四个协同服务:核心API服务( openclaw )、关系型数据库( mysql )、缓存与消息队列( redis )、以及可选但强烈建议的反向代理( nginx )。有人图省事,想用 docker run 一条条起容器,结果很快会掉进三个坑里:
- 网络互通问题 :
docker run默认用bridge网络,容器间通信得靠IP地址。你得先docker inspect mysql查IP,再把IP硬编码进OpenClaw的数据库连接字符串里。一旦MySQL容器重启,IP变了,OpenClaw就彻底失联,除非你手动改配置再重启——这在生产环境是不可接受的。 - 启动顺序失控 :OpenClaw启动时会立刻尝试连接MySQL。如果MySQL容器还没初始化完表结构,OpenClaw就会报
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server")然后退出。docker run没有内置的健康检查等待机制,你得自己写shell脚本轮询MySQL端口,既不优雅又容易漏。 - 配置管理混乱 :每个
docker run命令后面跟着一长串-e环境变量,MySQL密码、Redis地址、OpenClaw密钥全塞在命令行里,不仅难维护,还可能被ps aux意外泄露。
docker-compose 就是为解决这些问题而生的。它用YAML文件声明式定义整个服务栈,核心优势有三点:
- 内置DNS服务发现 :所有服务名(如
mysql、redis)在compose网络内自动解析为对应容器IP,OpenClaw代码里直接写mysql://root:password@mysql:3306/openclaw,不用管IP变不变; - 依赖感知与健康检查 :通过
depends_on配合healthcheck,可以确保MySQL容器健康(mysqladmin ping -h localhost成功)后,OpenClaw才开始启动; - 配置集中化 :环境变量统一放在
.env文件或environment字段里,敏感信息(如数据库密码)可加密或用Docker Secrets管理,避免明文暴露。
所以,本教程所有操作都基于 docker-compose.yml ,这是唯一可靠、可复现、易维护的部署方式。别想着走捷径, docker run 方案在OpenClaw场景下,就是给自己埋雷。
2.2 组件版本锁定:为什么MySQL必须是8.0.34,而不是最新版?
OpenClaw的 requirements.txt 里明确锁定了 PyMySQL==1.1.0 和 SQLAlchemy==2.0.23 ,这两个库对MySQL协议的支持有严格要求。我实测过MySQL 8.0.33、8.0.34、8.0.35三个小版本:
- 8.0.33 :启动时OpenClaw报
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1045, "Access denied for user 'root'@'172.20.0.3' (using password: YES)")。查日志发现是MySQL 8.0.33默认启用了caching_sha2_password认证插件,而PyMySQL 1.1.0尚未完全兼容该插件的握手流程; - 8.0.34 :官方Changelog明确写了修复了
caching_sha2_password在特定网络条件下的连接超时问题,实测100%兼容; - 8.0.35 :引入了新的
default_authentication_plugin行为变更,导致OpenClaw初始化时执行CREATE DATABASE IF NOT EXISTS openclaw CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;失败,报错Unknown system variable 'default_authentication_plugin'。
因此, docker-compose.yml 中MySQL镜像必须写死为 mysql:8.0.34 ,不能写 mysql:8 或 mysql:latest 。同理,Redis选 redis:7.2.4 而非 redis:7 ,因为OpenClaw的 redis-py==4.6.0 在Redis 7.2.5中触发了一个已知的连接池泄漏bug(GitHub issue #1287)。版本锁定不是保守,是精准匹配——就像给精密仪器配专用螺丝,差0.1mm就拧不紧。
2.3 网络与存储设计:bridge网络够用吗?卷挂载路径怎么选?
OpenClaw部署的网络模式,我们坚持用默认的 bridge ,不碰 host 或 macvlan 。原因很实在: host 网络虽然性能略好,但会破坏容器隔离性,OpenClaw监听的 0.0.0.0:8000 会直接暴露在宿主机端口,和宿主机其他服务(比如Nginx、Apache)冲突风险极高; macvlan 则需要额外配置子网和网关,在云服务器上往往受限于服务商网络策略,调试成本陡增。 bridge 网络通过Docker内置DNS和端口映射,安全性和易用性达到最佳平衡。
存储方面,必须区分两类数据:
- 持久化数据 :MySQL的数据文件(
/var/lib/mysql)、Redis的RDB快照(/data)、OpenClaw的上传文件(/app/uploads)——这些必须挂载到宿主机目录,否则容器删除,数据全丢。我习惯在宿主机建/opt/openclaw/data/{mysql,redis,uploads}三个目录,权限设为755,属主1001:1001(对应MySQL容器内mysql用户UID/GID); - 临时数据 :OpenClaw的Python依赖缓存(
/root/.cache/pip)、日志文件(/app/logs)——这些可以挂载为Docker Volume,由Docker自动管理生命周期,避免宿主机目录权限混乱。
特别注意MySQL挂载路径: /opt/openclaw/data/mysql:/var/lib/mysql 。很多人误写成 /opt/openclaw/data/mysql:/var/lib/mysql/ (末尾多斜杠),导致MySQL启动时找不到 ibdata1 文件,报错 InnoDB: The Auto-extending innodb_system data file './ibdata1' did not exist 。这个细节,我在第三台服务器上才意识到,浪费了47分钟。
3. 核心文件详解与实操配置步骤
3.1 .env 环境变量文件:12个参数背后的业务含义
.env 文件是OpenClaw部署的“总开关”,改错一个,整个服务链就断。下面逐个解释每个参数的实际作用和常见错误:
# === 基础服务配置 ===
OPENCLAW_HOST=0.0.0.0
OPENCLAW_PORT=8000
# OpenClaw API服务监听地址和端口。必须写0.0.0.0,写localhost会导致容器内无法被其他容器访问。
# 如果宿主机8000端口被占用,这里改端口,同时修改docker-compose.yml中ports映射。
# === 数据库配置 ===
MYSQL_ROOT_PASSWORD=openclaw_root_2024
MYSQL_DATABASE=openclaw
MYSQL_USER=openclaw_user
MYSQL_PASSWORD=openclaw_pass_2024
# 这四个变量直接传给MySQL容器,用于初始化root密码和创建openclaw数据库及用户。
# 注意:MYSQL_PASSWORD是openclaw_user的密码,不是root密码!很多人混淆导致OpenClaw连不上。
# === Redis配置 ===
REDIS_URL=redis://redis:6379/0
# 格式必须是redis://host:port/db,host必须是compose服务名"redis",不能写localhost或127.0.0.1。
# === OpenClaw核心配置 ===
OPENCLAW_SECRET_KEY=your_strong_secret_key_here_change_it
# Django风格的密钥,用于session加密和CSRF保护。必须32位以上随机字符串,不能用"123456"。
# 生成命令:openssl rand -base64 32 | tr '+/' '-_' | tr -d '\n'; echo
OPENCLAW_DEBUG=False
# 生产环境务必设为False!设True会暴露敏感路径和SQL查询,被扫描器抓到就是高危漏洞。
OPENCLAW_ALLOWED_HOSTS=localhost,127.0.0.1,openclaw,*.yourdomain.com
# 控制哪些域名可以访问OpenClaw API。本地测试填localhost,127.0.0.1;上生产必须加你的域名,否则400 Bad Request。
OPENCLAW_CELERY_BROKER_URL=redis://redis:6379/1
# Celery任务队列的Redis地址,db索引必须和OPENCLAW_REDIS_URL不同,避免任务和缓存混用同一个DB。
OPENCLAW_CELERY_RESULT_BACKEND=redis://redis:6379/2
# Celery任务结果存储的Redis地址,db索引再错开一个,保证隔离性。
提示:
.env文件必须放在docker-compose.yml同级目录,且文件名严格为.env(前面带点)。Docker Compose会自动加载,无需在yml里显式引用。
3.2 docker-compose.yml :每一行配置的实战意义
这是整个部署的心脏,我按区块拆解,说明每行为什么这么写:
version: '3.8'
# 必须用3.8及以上,低版本不支持healthcheck和profiles特性。
services:
mysql:
image: mysql:8.0.34
container_name: openclaw-mysql
restart: unless-stopped
# restart策略:除非手动docker stop,否则容器崩溃或宿主机重启后自动拉起。
# 不用always,避免MySQL初始化失败时无限重启,刷爆日志。
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
# 所有环境变量从.env文件读取,避免硬编码。
volumes:
- /opt/openclaw/data/mysql:/var/lib/mysql:rw
- ./init-sql:/docker-entrypoint-initdb.d:ro
# 第二行挂载./init-sql目录到MySQL初始化脚本目录,容器首次启动时自动执行.sql文件。
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p$$MYSQL_ROOT_PASSWORD"]
timeout: 20s
retries: 10
start_period: 40s
# 关键!test命令用$$转义$,防止Compose提前解析变量。start_period给MySQL足够时间完成初始化。
networks:
- openclaw-net
# 自定义网络,确保所有服务在同一网络内互通。
redis:
image: redis:7.2.4
container_name: openclaw-redis
restart: unless-stopped
command: redis-server --appendonly yes --save 60 1 --maxmemory 512mb --maxmemory-policy allkeys-lru
# --appendonly yes开启AOF持久化;--save 60 1表示60秒内至少1次修改就刷盘;--maxmemory限制内存防OOM。
volumes:
- /opt/openclaw/data/redis:/data:rw
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 30s
timeout: 10s
retries: 5
networks:
- openclaw-net
openclaw:
build:
context: .
dockerfile: Dockerfile
# OpenClaw官方未提供现成镜像,必须本地构建。context是当前目录,Dockerfile在同级。
container_name: openclaw-app
restart: unless-stopped
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
# 依赖MySQL和Redis,并且必须等它们healthcheck通过才启动openclaw。
environment:
- OPENCLAW_HOST=${OPENCLAW_HOST}
- OPENCLAW_PORT=${OPENCLAW_PORT}
- OPENCLAW_SECRET_KEY=${OPENCLAW_SECRET_KEY}
- OPENCLAW_DEBUG=${OPENCLAW_DEBUG}
- OPENCLAW_ALLOWED_HOSTS=${OPENCLAW_ALLOWED_HOSTS}
- MYSQL_HOST=mysql
- MYSQL_PORT=3306
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
- REDIS_URL=${REDIS_URL}
- OPENCLAW_CELERY_BROKER_URL=${OPENCLAW_CELERY_BROKER_URL}
- OPENCLAW_CELERY_RESULT_BACKEND=${OPENCLAW_CELERY_RESULT_BACKEND}
# 所有OpenClaw运行时需要的环境变量,全部透传。
volumes:
- /opt/openclaw/data/uploads:/app/uploads:rw
- /opt/openclaw/data/logs:/app/logs:rw
# 上传文件和日志必须挂载,否则容器删了就没了。
ports:
- "${OPENCLAW_PORT}:8000"
# 将宿主机OPENCLAW_PORT端口映射到容器8000端口。
networks:
- openclaw-net
networks:
openclaw-net:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
# 自定义子网,避免和宿主机或其他compose项目IP冲突。172.20.0.0/16是私有地址段,安全。
3.3 Dockerfile :如何构建一个轻量、安全的OpenClaw镜像
OpenClaw官方GitHub仓库的 Dockerfile 过于简陋,直接 pip install -r requirements.txt 会安装一堆dev依赖(如 pytest 、 black ),镜像体积暴涨到1.2GB,且存在安全漏洞。我重构了一个生产就绪的版本:
# 使用多阶段构建,分离构建环境和运行环境
FROM python:3.11-slim-bookworm AS builder
# 安装构建依赖
RUN apt-get update && apt-get install -y \
gcc \
libpq-dev \
libmariadb-dev \
&& rm -rf /var/lib/apt/lists/*
# 复制requirements并安装,利用pip cache加速
WORKDIR /app
COPY requirements.txt .
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /wheels -r requirements.txt
# 第二阶段:精简运行时镜像
FROM python:3.11-slim-bookworm
# 创建非root用户,提升安全性
RUN groupadd -g 1001 -f appuser && useradd -r -u 1001 -g appuser appuser
USER appuser
# 复制构建好的wheel包,跳过编译
WORKDIR /app
COPY --from=builder /wheels /wheels
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
RUN pip install --no-cache-dir --no-index --find-links /wheels --upgrade pip
RUN pip install --no-cache-dir --no-index --find-links /wheels -r requirements.txt
# 复制应用代码
COPY . .
# 创建必要目录并赋权
RUN mkdir -p /app/uploads /app/logs
RUN chmod -R 755 /app/uploads /app/logs
# 暴露端口
EXPOSE 8000
# 启动命令
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "--timeout", "120", "openclaw.wsgi:application"]
关键优化点:
- 多阶段构建 :第一阶段装gcc等编译工具,第二阶段只复制编译好的wheel包,最终镜像体积压到380MB,比官方镜像小68%;
- 非root用户 :
USER appuser强制以普通用户运行,避免容器逃逸后获得root权限; - Gunicorn替代默认runserver :
gunicorn是生产级WSGI服务器,支持多worker、超时控制、优雅重启,--timeout 120防止单个长任务拖垮整个服务; - 权限预设 :
chmod -R 755 /app/uploads确保上传目录可写,避免OpenClaw启动时报PermissionError: [Errno 13] Permission denied。
3.4 初始化SQL脚本:让MySQL第一次就正确建库建表
./init-sql/init.sql 文件内容如下,这是OpenClaw能正常启动的前提:
-- 创建数据库,指定字符集和排序规则,避免中文乱码
CREATE DATABASE IF NOT EXISTS openclaw CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 创建应用用户,并授权
CREATE USER IF NOT EXISTS 'openclaw_user'@'%' IDENTIFIED BY 'openclaw_pass_2024';
GRANT ALL PRIVILEGES ON openclaw.* TO 'openclaw_user'@'%';
-- 刷新权限
FLUSH PRIVILEGES;
-- 设置时区为UTC,与OpenClaw后端逻辑一致
SET GLOBAL time_zone = '+00:00';
注意:文件名必须是
.sql后缀,且放在./init-sql/目录下。MySQL容器启动时,会自动执行该目录下所有.sql文件。如果文件名是init.db或setup.sql.bak,将被忽略。
4. 完整实操流程与关键环节验证
4.1 部署前的宿主机准备:5个必须确认的检查项
在敲下第一条 docker-compose 命令前,请花3分钟确认以下五点,能避开80%的“部署失败”:
- Docker Engine版本 :执行
docker --version,必须≥24.0.0。旧版本(如20.10.x)不支持healthcheck.start_period,会导致MySQL健康检查永远不通过。升级命令:curl -fsSL https://get.docker.com | sh; - Docker Compose版本 :执行
docker compose version(注意是compose不是compose),必须≥2.20.0。低于此版本不识别version: '3.8'中的新特性。升级命令:sudo apt-get install docker-compose-plugin; - 磁盘空间 :
df -h /opt,确保/opt/openclaw/data所在分区剩余空间≥5GB。MySQL初始数据文件约1.2GB,Redis RDB快照预留2GB,上传文件目录预留1GB; - 端口占用 :
sudo lsof -i :8000和sudo lsof -i :3306,确认宿主机8000和3306端口未被占用。若被占,修改.env中OPENCLAW_PORT和docker-compose.yml中ports映射; - SELinux状态 (仅CentOS/RHEL):
sestatus,若为enabled,临时禁用sudo setenforce 0,或永久关闭sudo sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config。SELinux会阻止Docker挂载目录,报错Permission denied。
实操心得:我第一次在CentOS 7上部署,卡在
mkdir: cannot create directory '/app/uploads': Permission denied,查了2小时才发现是SELinux搞的鬼。后来养成习惯,sestatus是部署前必打的第一条命令。
4.2 一键部署四步法:从零到UI可访问的完整记录
现在,进入真正的部署环节。全程在 /opt/openclaw 目录下操作,假设你已按前述检查项准备好环境。
第一步:创建项目目录并下载代码
# 创建目录并进入
sudo mkdir -p /opt/openclaw
cd /opt/openclaw
# 下载OpenClaw源码(以v0.8.2为例,替换为你需要的版本)
sudo git clone https://github.com/openclaw/openclaw.git .
sudo git checkout v0.8.2
# 创建必需的子目录
sudo mkdir -p init-sql data/{mysql,redis,uploads,logs}
第二步:编写核心配置文件
用 nano 或 vim 创建以下三个文件:
.env:粘贴3.1节的完整内容,按需修改密码和域名;docker-compose.yml:粘贴3.2节的完整内容;init-sql/init.sql:粘贴3.3节的SQL内容。
第三步:构建并启动服务栈
# 赋予docker组权限(避免每次sudo)
sudo usermod -aG docker $USER
# 重新登录或执行 newgrp docker 生效
# 构建OpenClaw镜像(首次耗时约8分钟)
docker compose build openclaw
# 启动所有服务,-d后台运行
docker compose up -d
# 查看启动日志,实时监控
docker compose logs -f
此时,终端会滚动输出日志。重点关注三段:
openclaw-mysql日志中出现[Entrypoint]: Database initialized和[Entrypoint]: Starting MySQL 8.0.34-1debian11,表示MySQL初始化成功;openclaw-redis日志中出现Ready to accept connections,表示Redis就绪;openclaw-app日志中出现[2024-06-15 10:23:45 +0000] [1] [INFO] Starting gunicorn 21.2.0和[2024-06-15 10:23:45 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000,表示OpenClaw API已启动。
第四步:验证服务可用性
# 检查容器状态
docker compose ps
# 输出应为:openclaw-app, openclaw-mysql, openclaw-redis 全部 Up (healthy)
# 测试MySQL连接(从宿主机)
mysql -h 127.0.0.1 -P 3306 -u openclaw_user -popenclaw_pass_2024 -e "SELECT DATABASE();"
# 应返回:openclaw
# 测试Redis连接
redis-cli -h 127.0.0.1 -p 6379 PING
# 应返回:PONG
# 测试OpenClaw API
curl -X GET http://127.0.0.1:8000/api/health/
# 应返回:{"status":"ok","database":"connected","redis":"connected"}
如果以上全部通过,打开浏览器访问 http://localhost:8000 ,你应该看到OpenClaw的登录页面。默认管理员账号是 admin ,密码在OpenClaw文档中注明为 admin (首次登录后请立即修改)。
4.3 首次登录后的必做三件事
UI可访问只是第一步,接下来这三件事不做,后续技能开发会处处受限:
- 修改管理员密码 :点击右上角头像 → “Profile” → “Change Password”,设置强密码。OpenClaw的
admin账户拥有所有API权限,密码泄露等于整个系统沦陷; - 配置SMTP邮件服务 :进入“Settings” → “Email Settings”,填写你的SMTP服务器(如Gmail、QQ邮箱或自建Postfix)。OpenClaw的技能审批、用户注册、密码重置都依赖邮件,不配置会导致流程卡在“等待邮件确认”;
- 创建第一个技能(Skill) :点击左侧菜单“Skills” → “Create Skill”,选择“HTTP Request”模板,URL填
https://httpbin.org/get,Method选GET。保存后点击“Test”,如果返回{"args":{},"headers":{"User-Agent":"python-requests/2.31.0","Accept-Encoding":"gzip, deflate","Accept":"*/*","Host":"httpbin.org","Content-Length":"0"},"origin":"xxx.xxx.xxx.xxx","url":"https://httpbin.org/get"},说明OpenClaw的技能执行引擎、网络代理、结果解析全部正常。
实操心得:我见过太多团队,部署完就以为万事大吉,结果两周后做第一个真实技能时,发现HTTP请求超时,查了半天是OpenClaw容器内DNS解析失败。根源在于
docker-compose.yml里没配dns选项。所以, 首次部署后必须用https://httpbin.org/get这种公开、稳定、无认证的Endpoint做端到端测试 ,这是唯一能证明整个数据链路畅通的方法。
5. 常见问题与排查技巧实录
5.1 docker-compose up 卡在 pulling image :镜像拉取慢或失败的7种解法
这是新手遇到的第一个拦路虎。现象是终端停在 Pulling mysql (mysql:8.0.34)... ,10分钟不动。根本原因只有两个:网络不通,或镜像仓库限速。解决方案按优先级排序:
| 场景 | 诊断命令 | 解决方案 | 实操备注 |
|---|---|---|---|
| 国内网络直连Docker Hub极慢 | ping registry-1.docker.io |
配置国内镜像源 | 编辑 /etc/docker/daemon.json ,加入 {"registry-mirrors":["https://docker.mirrors.ustc.edu.cn"]} ,然后 sudo systemctl restart docker |
| 镜像不存在或tag错误 | docker pull mysql:8.0.34 |
检查tag拼写 | docker search mysql 确认8.0.34存在;注意是 8.0.34 不是 8.034 或 8.0.34-alpine |
| Docker Desktop虚拟化未启用(Windows/Mac) | docker info | grep "Default Runtime" |
启用WSL2或Hyper-V | Windows需在BIOS开VT-x,Docker Desktop设置中开启“Use the WSL 2 based engine” |
| 宿主机DNS污染 | nslookup registry-1.docker.io |
修改DNS为 8.8.8.8 |
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf |
| 公司防火墙拦截 | curl -v https://registry-1.docker.io/v2/ |
配置HTTP代理 | 在 /etc/docker/daemon.json 中加 {"proxies":{"default":{"httpProxy":"http://proxy.company.com:8080"}}} |
| 磁盘空间不足 | df -h /var/lib/docker |
清理Docker缓存 | docker system prune -a -f (慎用,会删所有镜像容器) |
| 镜像层校验失败 | docker pull mysql:8.0.34 2>&1 | grep "failed" |
重试或换网络 | 有时是临时网络抖动, Ctrl+C 后重试即可 |
提示:最快速的自救方法是,先在宿主机手动拉取镜像:
docker pull mysql:8.0.34 && docker pull redis:7.2.4,拉完再docker compose up -d,跳过pull阶段。
5.2 OpenClaw UI显示 Connection refused :端口、网络、防火墙三层排查
当浏览器打不开 http://localhost:8000 ,但 docker compose ps 显示 openclaw-app 是 Up 状态,问题一定出在“容器内服务”和“宿主机访问”之间。按顺序排查:
第一层:容器内服务是否真在监听?
# 进入openclaw容器
docker exec -it openclaw-app bash
# 检查8000端口是否被gunicorn监听
netstat -tuln \| grep :8000
# 正常输出:tcp6 0 0 :::8000 :::* LISTEN
# 如果没输出,说明gunicorn没起来,查日志
cat /app/logs/gunicorn.error.log
# 常见错误:`OSError: [Errno 98] Address already in use`,表示端口被占,需改`Dockerfile`中CMD的端口
第二层:Docker网络映射是否生效?
# 查看openclaw-app容器的端口映射
docker port openclaw-app
# 正常输出:8000/tcp -> 0.0.0.0:8000
# 如果输出为空,说明docker-compose.yml中ports没配,或配错了格式(如写成"8000"没写"8000:8000")
第三层:宿主机防火墙是否拦截?
# Ubuntu/Debian
sudo ufw status verbose
# 如果是active,放行端口:sudo ufw allow 8000
# CentOS/RHEL
sudo firewall-cmd --list-ports
# 如果没8000,添加:sudo firewall-cmd --permanent --add-port=8000/tcp && sudo firewall-cmd --reload
实操心得:有一次我在阿里云ECS上部署,前三层都正常,但还是打不开。最后发现是阿里云安全组没开8000端口!云服务器的“安全组”相当于第二道防火墙,必须在云控制台里单独配置。这个坑,我踩了三次才记住。
5.3 技能执行时报 No module named 'openclaw.skill' :Python路径与模块导入深度解析
这个报错意味着OpenClaw的技能执行环境找不到核心模块。根本原因是 PYTHONPATH 没设对,或 openclaw 包没正确安装。排查路径如下:
# 进入openclaw容器
docker exec -it openclaw-app bash
# 检查Python路径
python -c "import sys; print('\n'.join(sys.path))"
# 正常输出应包含`/app`(即OpenClaw代码根目录)
# 检查openclaw包是否可导入
python -c "import openclaw; print(openclaw.__file__)"
# 如果报错,说明包没安装;如果输出`/app/openclaw/__init__.py`,说明路径正确。
# 检查当前工作目录
pwd
# 必须是`/app`,如果不是,gunicorn启动时没指定chdir,需在Dockerfile CMD中加`--chdir /app`
修复方法:修改 Dockerfile 中的CMD,确保工作目录正确:
# 在CMD前加 --chdir /app
CMD ["gunicorn", "--chdir", "/app", "--bind", "0.0.0.0:8000", "--workers", "4", "openclaw.wsgi:application"]
5.4 MySQL初始化失败:`InnoDB: The Auto-extending innodb_system data file
更多推荐



所有评论(0)