Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
node_modules
npm-debug.log
.next
out
dist
.git
.gitignore
README.md
.env
.env.local
.env.development
.env.production
Dockerfile
docker-compose.yml
.dockerignore
221 changes: 221 additions & 0 deletions DOCKER-README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
# 🐳 OpenClaw101 容器化部署指南

## 🚀 快速部署

使用 `build-docker-run.sh` 脚本可以一键构建和运行 OpenClaw101 容器:

```bash
# 1. 进入项目目录
cd ~/openclaw101/

# 2. 运行部署脚本
chmod +x build-docker-run.sh
sudo ./build-docker-run.sh
```

脚本会自动:
- ✅ 检查 Docker 服务状态
- ✅ 清理旧的构建缓存
- ✅ 构建 Docker 镜像
- ✅ 显示运行命令和访问地址

## 📋 脚本详解

### 脚本功能
`build-docker-run.sh` 是一个自动化部署脚本,简化了 OpenClaw101 的容器化部署流程。

### 可配置参数

#### 1. 镜像标签(可选参数)
```bash
# 使用默认标签(openclaw101:latest)
./build-docker-run.sh

# 使用自定义标签
./build-docker-run.sh openclaw101:v1.0
./build-docker-run.sh myregistry.com/openclaw101:production
```

#### 2. 容器名称和端口(在脚本中修改)
脚本默认使用以下配置:
```bash
容器名称:openclaw101
主机端口:3000
容器端口:80
```

如果需要修改这些配置,可以编辑脚本中的运行命令部分:
```bash
# 在脚本中找到这一行(约第24行)
echo " docker run -d -p 3000:80 --name openclaw101 $TAG"

# 修改为:
# docker run -d -p 8080:80 --name my-openclaw101 $TAG
```

### 配置示例

#### 示例1:使用不同端口
```bash
# 修改脚本中的端口映射
# 原配置:-p 3000:80
# 新配置:-p 8080:80

# 然后运行脚本
./build-docker-run.sh
```

#### 示例2:使用不同容器名称
```bash
# 修改脚本中的容器名称
# 原配置:--name openclaw101
# 新配置:--name my-openclaw-app

# 然后运行脚本
./build-docker-run.sh
```

#### 示例3:同时修改端口和名称
```bash
# 修改脚本中的运行命令
# 原配置:docker run -d -p 3000:80 --name openclaw101 $TAG
# 新配置:docker run -d -p 9090:80 --name openclaw-prod $TAG

# 然后运行脚本
./build-docker-run.sh openclaw101:production
```

## 🔧 手动运行命令

如果你需要更多控制,也可以直接使用 Docker 命令:

### 1. 构建镜像
```bash
# 使用默认标签
docker build -t openclaw101:latest .

# 使用自定义标签
docker build -t myregistry.com/openclaw101:v1.0 .
```

### 2. 运行容器
```bash
# 基本运行(使用脚本默认配置)
docker run -d -p 3000:80 --name openclaw101 openclaw101:latest

# 自定义端口
docker run -d -p 8080:80 --name openclaw101 openclaw101:latest

# 自定义容器名称
docker run -d -p 3000:80 --name my-openclaw-app openclaw101:latest

# 后台运行并自动重启
docker run -d -p 3000:80 --name openclaw101 --restart unless-stopped openclaw101:latest
```

### 3. 查看运行状态
```bash
# 查看容器状态
docker ps | grep openclaw101

# 查看日志
docker logs -f openclaw101

# 查看资源使用
docker stats openclaw101
```

## 🌐 访问应用

部署完成后,通过以下地址访问:

```
http://localhost:3000
```

如果修改了端口,请使用对应的端口号:
```
http://localhost:8080 # 如果修改为8080端口
```

## 🛠️ 管理容器

### 停止容器
```bash
docker stop openclaw101
```

### 启动容器
```bash
docker start openclaw101
```

### 重启容器
```bash
docker restart openclaw101
```

### 删除容器
```bash
# 停止并删除容器
docker stop openclaw101 && docker rm openclaw101

# 删除镜像
docker rmi openclaw101:latest
```

### 进入容器
```bash
# 进入容器shell
docker exec -it openclaw101 sh
```

## 📊 脚本输出示例

运行 `./build-docker-run.sh` 会显示以下信息:

```
🔨 开始构建 OpenClaw101 Docker 镜像(修复版)...
📦 镜像标签: openclaw101:latest
🧹 清理旧的构建缓存...
📦 构建 Docker 镜像...

✅ 构建完成!
📊 镜像信息:
openclaw101 latest abc123def456 35MB 2 minutes ago

🚀 运行命令:
docker run -d -p 3000:80 --name openclaw101 openclaw101:latest

🔍 查看日志:
docker logs -f openclaw101

🌐 访问地址: http://localhost:3000
```

## ⚠️ 注意事项

1. **Docker 服务**:确保 Docker 服务正在运行
2. **端口冲突**:如果 3000 端口被占用,请修改脚本中的端口配置
3. **容器名称冲突**:如果已存在名为 `openclaw101` 的容器,请修改容器名称
4. **权限问题**:通常不需要 `sudo`,除非 Docker 安装配置需要
5. **构建缓存**:脚本会自动清理旧的构建缓存,但不会影响现有容器

## 🔄 更新部署

如果需要更新应用:

```bash
# 1. 停止并删除旧容器
docker stop openclaw101 && docker rm openclaw101

# 2. 重新构建和运行
./build-docker-run.sh
```

## 📞 支持

如有问题,请参考:
- [Docker 官方文档](https://docs.docker.com/)
- [脚本源代码](./build-docker-run.sh)
- [项目主文档](./README.md)
48 changes: 48 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# ==========================================
# 阶段 1: 构建阶段
# ==========================================
FROM node:20-alpine AS builder

# 设置工作目录
WORKDIR /app

# 安装必要的构建工具(Alpine环境需要)
RUN apk add --no-cache libc6-compat

# 先复制package文件(利用Docker缓存层)
COPY package*.json ./

# 安装所有依赖(包括开发依赖,构建需要TypeScript等)
RUN npm ci && npm cache clean --force

# 复制源代码
COPY . .

# 验证 TypeScript 配置和路径别名
# 如果这一步失败,会提前发现问题
RUN echo "=== 验证 TypeScript 路径别名 ===" && \
node -e "const ts = require('typescript'); const cfg = require('./tsconfig.json'); console.log('tsconfig paths:', JSON.stringify(cfg.compilerOptions?.paths, null, 2))"

# 构建静态站点
ENV NODE_ENV=production
RUN npm run build

# ==========================================
# 阶段 2: 运行阶段(Nginx 托管)
# ==========================================
FROM nginx:1.25-alpine-slim AS runtime

# 复制构建产物到 Nginx
COPY --from=builder /app/out /usr/share/nginx/html

# 复制自定义 Nginx 配置
COPY nginx.conf /etc/nginx/conf.d/default.conf

# 暴露端口
EXPOSE 80

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --quiet --tries=1 --spider http://localhost/ || exit 1

CMD ["nginx", "-g", "daemon off;"]
41 changes: 41 additions & 0 deletions build-docker-run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/bash

# OpenClaw101 Docker 构建脚本
# 用法: ./build-docker-run.sh [tag]

set -e

# 默认标签
TAG=${1:-"openclaw101:latest"}

echo "🔨 开始构建 OpenClaw101 Docker 镜像..."
echo "📦 镜像标签: $TAG"

# 检查 Docker 是否运行
if ! docker info > /dev/null 2>&1; then
echo "❌ Docker 未运行,请启动 Docker 服务"
exit 1
fi

# 清理旧的构建缓存(可选)
echo "🧹 清理旧的构建缓存..."
docker builder prune -f

# 构建镜像
echo "📦 构建 Docker 镜像..."
docker build -t "$TAG" .

# 显示构建结果
echo ""
echo "✅ 构建完成!"
echo "📊 镜像信息:"
docker images | grep openclaw101

echo ""
echo "🚀 运行命令:"
echo " docker run -d -p 3000:80 --name openclaw101 $TAG"
echo ""
echo "🔍 查看日志:"
echo " docker logs -f openclaw101"
echo ""
echo "🌐 访问地址: http://localhost:3000"
26 changes: 26 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const path = require('path');
const withMDX = require('@next/mdx')({
extension: /\.mdx?$/,
options: {
Expand All @@ -13,6 +14,31 @@ const nextConfig = {
unoptimized: true,
},
pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'],

// ==========================================
// 关键修复:配置 webpack 路径别名
// 确保 @/* 路径在 Docker 环境中正确解析
// ==========================================
webpack: (config) => {
// 确保 resolve 和 alias 对象存在
if (!config.resolve) {
config.resolve = {};
}
if (!config.resolve.alias) {
config.resolve.alias = {};
}

// 添加 @ 路径别名指向 src 目录
config.resolve.alias['@'] = path.resolve(__dirname, 'src');

return config;
},

// 确保 TypeScript 路径别名也能被正确解析
experimental: {
// 禁用某些可能导致问题的实验性功能
turboMode: false,
},
};

module.exports = withMDX(nextConfig);
26 changes: 26 additions & 0 deletions nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;

# Gzip 压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;

# 缓存静态资源
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}

# Next.js 静态导出路由处理
location / {
try_files $uri $uri.html $uri/ =404;
}

# 404 页面
error_page 404 /404.html;
}
Loading