OpenClaw Docker 部署:从开发到生产的容器化实战
目录
摘要
Docker 部署是 OpenClaw 从开发环境走向生产环境的关键一步。本文从 Docker 基础概念出发,深入讲解 OpenClaw 的 Docker 镜像构建、多阶段优化、环境变量注入、数据持久化、健康检查配置,以及 docker-compose 多服务编排。通过一个完整的实战案例——将本地 OpenClaw 项目容器化并部署到服务器,你将掌握从 Dockerfile 编写到生产运行的全流程。读完你会发现:容器化不是"加一层 Docker",而是让部署变得可重复、可移植、可扩展。
1. 引言:为什么你的 OpenClaw 需要 Docker
1.1 从"我机器上能跑"到"服务器上也能跑"
你一定遇到过这种场景:
- 本地开发环境一切正常,部署到服务器后各种报错
- “Python 版本不对”、“Node.js 版本太旧”、“系统依赖缺失”
- 换个服务器又要重新配一遍环境
- 团队新成员入职,光搭环境就要半天
Docker 解决的就是这个问题——把应用和它的所有依赖打包成一个镜像,在任何安装了 Docker 的机器上都能跑。
1.2 容器化 vs 裸机部署
| 维度 | 裸机部署 | Docker 部署 |
|---|---|---|
| 环境一致性 | ❌ 每台机器不同 | ✅ 镜像保证一致 |
| 部署速度 | 分钟级(安装依赖) | 秒级(拉镜像+启动) |
| 回滚 | 手动恢复文件 | docker run 上一版本镜像 |
| 资源隔离 | ❌ 进程级 | ✅ 容器级(CPU/内存限制) |
| 可移植性 | ❌ 绑定操作系统 | ✅ 任何支持 Docker 的系统 |
| 扩展性 | 手动配置多实例 | docker-compose / K8s 编排 |
2. Docker 基础概念速览
2.1 核心概念
在写 Dockerfile 之前,先厘清三个核心概念:
| 概念 | 说明 | 类比 |
|---|---|---|
| 镜像(Image) | 应用的只读模板,包含代码+运行时+依赖 | 安装包 ISO |
| 容器(Container) | 镜像的运行实例,有独立的文件系统和网络 | 安装后的运行程序 |
| 仓库(Registry) | 存储和分发镜像的地方 | App Store |
2.2 Dockerfile 基础指令
| 指令 | 作用 | 示例 |
|---|---|---|
FROM |
指定基础镜像 | FROM node:20-alpine |
WORKDIR |
设置工作目录 | WORKDIR /app |
COPY |
复制文件到镜像 | COPY . /app |
RUN |
在构建时执行命令 | RUN npm install |
ENV |
设置环境变量 | ENV NODE_ENV=production |
EXPOSE |
声明容器端口 | EXPOSE 18789 |
CMD |
容器启动时的默认命令 | CMD ["node", "server.js"] |
3. OpenClaw Docker 镜像构建
3.1 基础 Dockerfile
# ============================================
# OpenClaw Dockerfile - 基础版本
# 适用于开发环境和快速验证
# ============================================
FROM node:20-alpine
# 设置工作目录
WORKDIR /app
# 安装系统依赖
RUN apk add --no-cache \
python3 \
py3-pip \
git \
curl \
bash
# 安装 OpenClaw
RUN npm install -g openclaw
# 创建数据目录
RUN mkdir -p /data/openclaw /etc/openclaw
# 复制配置文件
COPY openclaw.yaml /etc/openclaw/openclaw.yaml
# 声明端口
EXPOSE 18789
# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
CMD curl -f http://localhost:18789/health || exit 1
# 启动 Gateway
CMD ["openclaw", "gateway", "start"]
构建和运行:
# 构建镜像
docker build -t openclaw:latest .
# 运行容器
docker run -d \
--name openclaw-gateway \
-p 18789:18789 \
-v /data/openclaw:/data/openclaw \
-v /etc/openclaw:/etc/openclaw \
-e OPENAI_API_KEY="sk-xxx" \
openclaw:latest
# 查看日志
docker logs -f openclaw-gateway
# 查看状态
docker ps | grep openclaw
💡 这个基础版本适合快速验证。但生产环境还需要考虑镜像体积、安全性、多阶段构建等问题。
3.2 多阶段构建优化
# ============================================
# OpenClaw Dockerfile - 多阶段构建(生产级)
# 优化点:减小镜像体积、分离构建和运行环境
# ============================================
# ===== 阶段1:构建阶段 =====
FROM node:20-alpine AS builder
WORKDIR /build
# 安装构建工具
RUN apk add --no-cache python3 py3-pip git make g++
# 安装 OpenClaw(含编译依赖)
RUN npm install -g openclaw@latest
# 安装 Python 依赖
RUN pip3 install --no-cache-dir \
requests \
aiohttp \
websockets
# ===== 阶段2:运行阶段 =====
FROM node:20-alpine AS runner
# 安装运行时依赖(不含编译工具)
RUN apk add --no-cache \
python3 \
py3-pip \
curl \
tini \
su-exec
# 创建非 root 用户
RUN addgroup -g 1000 openclaw && \
adduser -u 1000 -G openclaw -s /bin/sh -D openclaw
# 从构建阶段复制 OpenClaw
COPY --from=builder /usr/local/lib/node_modules /usr/local/lib/node_modules
COPY --from=builder /usr/local/bin/openclaw /usr/local/bin/openclaw
# 复制 Python 包
COPY --from=builder /usr/lib/python3* /usr/lib/python3*
COPY --from=builder /usr/local/lib/python3* /usr/local/lib/python3*
# 创建工作目录
WORKDIR /app
RUN mkdir -p /data/openclaw /etc/openclaw /app/workspace && \
chown -R openclaw:openclaw /data/openclaw /app/workspace
# 复制配置
COPY --chown=openclaw:openclaw openclaw.yaml /etc/openclaw/openclaw.yaml
# 切换到非 root 用户
USER openclaw
# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --start-period=15s --retries=3 \
CMD curl -sf http://localhost:18789/health || exit 1
# 暴露端口
EXPOSE 18789
# 使用 tini 作为 init 进程(处理僵尸进程和信号转发)
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["openclaw", "gateway", "start"]
多阶段构建的优势:
| 指标 | 基础版本 | 多阶段版本 | 优化幅度 |
|---|---|---|---|
| 镜像大小 | ~800MB | ~350MB | -56% |
| 构建时间 | 120s | 90s | -25% |
| 安全 | root 运行 | 非 root 用户 | 更安全 |
| 攻击面 | 含编译工具 | 仅运行时 | 更小 |
3.3 环境变量注入策略
# openclaw.yaml - 使用环境变量占位符
gateway:
port: ${GATEWAY_PORT:-18789}
auth_token: ${GATEWAY_AUTH_TOKEN}
model:
default: ${DEFAULT_MODEL:-gpt-4o-mini}
providers:
openai:
api_key: ${OPENAI_API_KEY}
base_url: ${OPENAI_BASE_URL:-https://api.openai.com/v1}
channels:
feishu:
app_id: ${FEISHU_APP_ID}
app_secret: ${FEISHU_APP_SECRET}
telegram:
bot_token: ${TELEGRAM_BOT_TOKEN}
logging:
level: ${LOG_LEVEL:-info}
file: /data/openclaw/logs/gateway.log
# 使用 env 文件启动
docker run -d \
--name openclaw-prod \
--env-file .env.production \
-p 18789:18789 \
-v openclaw-data:/data/openclaw \
openclaw:latest
# .env.production 示例
GATEWAY_PORT=18789
GATEWAY_AUTH_TOKEN=your-secure-token-here
DEFAULT_MODEL=gpt-4o
OPENAI_API_KEY=sk-prod-xxx
FEISHU_APP_ID=cli_xxx
FEISHU_APP_SECRET=xxx
TELEGRAM_BOT_TOKEN=123:abc
LOG_LEVEL=warn
4. docker-compose 多服务编排
4.1 完整编排文件
# docker-compose.yml
# OpenClaw 生产环境多服务编排
version: "3.8"
services:
# ===== OpenClaw Gateway =====
gateway:
build:
context: .
dockerfile: Dockerfile
image: openclaw:latest
container_name: openclaw-gateway
restart: unless-stopped
ports:
- "${GATEWAY_PORT:-18789}:18789"
volumes:
# 数据持久化
- openclaw_data:/data/openclaw
# 配置文件
- ./config/openclaw.yaml:/etc/openclaw/openclaw.yaml:ro
# 工作空间(Skills、插件等)
- ./workspace:/app/workspace
# 日志目录
- openclaw_logs:/data/openclaw/logs
env_file:
- .env.production
environment:
- NODE_ENV=production
- TZ=Asia/Shanghai
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:18789/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 20s
networks:
- openclaw-net
# 资源限制
deploy:
resources:
limits:
cpus: "2"
memory: "2G"
reservations:
cpus: "0.5"
memory: "512M"
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "5"
# ===== Redis(可选:会话缓存) =====
redis:
image: redis:7-alpine
container_name: openclaw-redis
restart: unless-stopped
volumes:
- redis_data:/data
command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
networks:
- openclaw-net
deploy:
resources:
limits:
cpus: "0.5"
memory: "512M"
# ===== Nginx(可选:反向代理) =====
nginx:
image: nginx:alpine
container_name: openclaw-nginx
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
depends_on:
gateway:
condition: service_healthy
networks:
- openclaw-net
deploy:
resources:
limits:
cpus: "0.5"
memory: "256M"
volumes:
openclaw_data:
driver: local
openclaw_logs:
driver: local
redis_data:
driver: local
networks:
openclaw-net:
driver: bridge
4.2 Nginx 反向代理配置
# nginx/nginx.conf
upstream openclaw_gateway {
server gateway:18789;
keepalive 32;
}
server {
listen 80;
server_name your-domain.com;
# 强制 HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# 请求体大小限制
client_max_body_size 50m;
# WebSocket 支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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_connect_timeout 60s;
proxy_send_timeout 120s;
proxy_read_timeout 120s;
location / {
proxy_pass http://openclaw_gateway;
}
# 健康检查端点
location /health {
proxy_pass http://openclaw_gateway/health;
access_log off;
}
}
4.3 启动与运维命令
# 启动所有服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看 Gateway 日志
docker-compose logs -f gateway
# 重启 Gateway(不重启 Redis/Nginx)
docker-compose restart gateway
# 更新镜像并重新部署
docker-compose pull gateway
docker-compose up -d --no-deps gateway
# 停止所有服务
docker-compose down
# 停止并删除数据卷(⚠️ 危险操作)
docker-compose down -v
5. 实战:从零容器化你的 OpenClaw
5.1 完整项目结构
openclaw-docker/
├── Dockerfile # 镜像构建文件
├── docker-compose.yml # 多服务编排
├── .env.production # 生产环境变量
├── .dockerignore # 构建排除文件
├── config/
│ └── openclaw.yaml # Gateway 配置
├── workspace/ # Skills、插件等
│ └── skills/
├── nginx/
│ ├── nginx.conf # 反向代理配置
│ └── ssl/ # SSL 证书
└── scripts/
├── deploy.sh # 部署脚本
└── backup.sh # 备份脚本
5.2 部署脚本
#!/bin/bash
# scripts/deploy.sh
# OpenClaw Docker 一键部署脚本
set -e
echo "🚀 开始部署 OpenClaw..."
# 1. 检查 Docker 环境
if ! command -v docker &> /dev/null; then
echo "❌ Docker 未安装,请先安装 Docker"
exit 1
fi
if ! command -v docker-compose &> /dev/null; then
echo "❌ docker-compose 未安装"
exit 1
fi
# 2. 检查环境变量文件
if [ ! -f .env.production ]; then
echo "❌ .env.production 文件不存在"
echo "💡 请从 .env.example 复制并填写配置"
exit 1
fi
# 3. 创建必要目录
mkdir -p workspace/skills nginx/ssl data/backups
# 4. 备份当前运行版本(如果存在)
if docker ps | grep -q openclaw-gateway; then
echo "📦 备份当前版本..."
docker commit openclaw-gateway openclaw:backup-$(date +%Y%m%d-%H%M%S)
fi
# 5. 拉取最新镜像并构建
echo "🔨 构建镜像..."
docker-compose build --pull gateway
# 6. 启动服务
echo "▶️ 启动服务..."
docker-compose up -d
# 7. 等待健康检查通过
echo "⏳ 等待服务就绪..."
for i in $(seq 1 30); do
if curl -sf http://localhost:18789/health > /dev/null 2>&1; then
echo "✅ OpenClaw Gateway 已就绪"
break
fi
sleep 2
done
# 8. 显示状态
echo ""
echo "📊 服务状态:"
docker-compose ps
echo ""
echo "✅ 部署完成!"
echo " Gateway: http://localhost:18789"
echo " 日志: docker-compose logs -f gateway"
5.3 备份脚本
#!/bin/bash
# scripts/backup.sh
# OpenClaw 数据备份脚本
BACKUP_DIR="./data/backups"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/openclaw-backup-${TIMESTAMP}.tar.gz"
mkdir -p "$BACKUP_DIR"
echo "📦 备份 OpenClaw 数据..."
# 备份数据卷
docker run --rm \
-v openclaw_data:/data:ro \
-v "$(pwd)/${BACKUP_DIR}":/backup \
alpine tar czf "/backup/openclaw-data-${TIMESTAMP}.tar.gz" -C /data .
# 备份配置文件
tar czf "${BACKUP_DIR}/openclaw-config-${TIMESTAMP}.tar.gz" \
config/ .env.production docker-compose.yml
# 清理 7 天前的备份
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +7 -delete
echo "✅ 备份完成: ${BACKUP_FILE}"
echo " 保留最近 7 天的备份"
6. 常见问题与排错
6.1 问题排查表
| 症状 | 可能原因 | 排查命令 |
|---|---|---|
| 容器启动后立即退出 | 配置文件错误 | docker logs openclaw-gateway |
| 端口无法访问 | 端口映射未生效 | docker port openclaw-gateway |
| 健康检查失败 | 服务未就绪 | docker exec openclaw-gateway curl localhost:18789/health |
| 数据丢失 | 未挂载数据卷 | docker inspect openclaw-gateway | grep Mounts -A 10 |
| 内存溢出 | 资源限制过低 | docker stats openclaw-gateway |
| 权限错误 | 文件 owner 不匹配 | docker exec openclaw-gateway ls -la /data/openclaw |
6.2 进入容器调试
# 进入容器 Shell
docker exec -it openclaw-gateway sh
# 查看进程
docker exec openclaw-gateway ps aux
# 查看资源使用
docker stats openclaw-gateway --no-stream
# 查看容器详细信息
docker inspect openclaw-gateway
7. 总结
本文从零开始,完整走通了 OpenClaw 的 Docker 容器化部署全流程:
核心要点:
-
多阶段构建:分离构建和运行环境,镜像体积减少 56%,攻击面更小
-
环境变量注入:所有敏感配置通过
.env文件注入,不硬编码在配置文件中 -
docker-compose 编排:Gateway + Redis + Nginx 三服务协同,一键启动
-
健康检查:
HEALTHCHECK指令确保服务可用,配合depends_on控制启动顺序 -
数据持久化:通过命名卷(named volume)持久化数据,容器删除数据不丢
-
一键部署脚本:
deploy.sh自动化检查、备份、构建、启动全流程
思考题:
-
你的 OpenClaw 需要支持 1000 个并发用户。单容器实例可能不够。你会如何设计多实例的负载均衡方案?
-
Docker 容器的日志默认输出到 stdout/stderr。如果日志量很大(每天 10GB),你会如何设计日志收集和轮转策略?
-
你的
.env.production包含了 API Key 等敏感信息。在团队协作中,如何安全地管理这些密钥(既要能分享给团队成员,又不能泄露到代码仓库)?
参考资料
更多推荐




所有评论(0)