Răsfoiți Sursa

Feature/actions (#7)

* 添加 GitHub Actions CI/CD 配置文件,包括 PR 构建检查和版本发布工作流,更新 README.md 以说明工作流和快速开始步骤。

* fix: initialize drizzle db lazily

* build: optimize docker image with standalone output

* build: speed up multi-arch docker build

* 优化 Dockerfile,移除镜像源前缀以简化构建过程

* chore: simplify release workflow and deployment docs

* fix: ensure release buildx uses container driver

* 优化 PR 检查工作流,使用单一架构以提高构建速度,并将镜像直接加载到 Docker daemon,简化后续测试步骤。

* 优化 PR 检查和发布工作流,增强镜像验证步骤,确保 Node.js 版本和应用文件存在性检查,改进版本标签匹配规则。

* Feature/actions (#3)

* 添加 GitHub Actions CI/CD 配置文件,包括 PR 构建检查和版本发布工作流,更新 README.md 以说明工作流和快速开始步骤。

* fix: initialize drizzle db lazily

* build: optimize docker image with standalone output

* build: speed up multi-arch docker build

* 优化 Dockerfile,移除镜像源前缀以简化构建过程

* chore: simplify release workflow and deployment docs

* fix: ensure release buildx uses container driver

* 优化 PR 检查工作流,使用单一架构以提高构建速度,并将镜像直接加载到 Docker daemon,简化后续测试步骤。

* 优化 PR 检查和发布工作流,增强镜像验证步骤,确保 Node.js 版本和应用文件存在性检查,改进版本标签匹配规则。

* 删除 GitHub Actions 配置的 README.md 文件,移除不再需要的文档内容。

* 删除 action 中的 readme (#4)

* 添加 GitHub Actions CI/CD 配置文件,包括 PR 构建检查和版本发布工作流,更新 README.md 以说明工作流和快速开始步骤。

* fix: initialize drizzle db lazily

* build: optimize docker image with standalone output

* build: speed up multi-arch docker build

* 优化 Dockerfile,移除镜像源前缀以简化构建过程

* chore: simplify release workflow and deployment docs

* fix: ensure release buildx uses container driver

* 优化 PR 检查工作流,使用单一架构以提高构建速度,并将镜像直接加载到 Docker daemon,简化后续测试步骤。

* 优化 PR 检查和发布工作流,增强镜像验证步骤,确保 Node.js 版本和应用文件存在性检查,改进版本标签匹配规则。

* 删除 GitHub Actions 配置的 README.md 文件,移除不再需要的文档内容。

* 优化 PR 检查工作流,移除不必要的 Docker 镜像结构测试步骤,以简化构建过程。

* 删除 GitHub Actions 配置中的 README.md 文件,移除不再需要的文档内容。

* 更新 PR 检查工作流,仅在向 main 分支提交 PR 时触发,简化触发条件。
zsio 4 luni în urmă
părinte
comite
5eb0fa150a

+ 25 - 0
.dockerignore

@@ -0,0 +1,25 @@
+# Ignore git metadata
+.git
+.gitignore
+
+# Node modules and build artifacts
+node_modules
+.next
+out
+coverage
+dist
+
+# Local env files (will be provided via runtime)
+.env
+.env.*
+!.env.example
+
+# Editor/IDE
+.vscode
+.idea
+
+# Logs and misc
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*

+ 150 - 0
.github/CI_CD_SETUP.md

@@ -0,0 +1,150 @@
+# GitHub Actions CI/CD 配置说明
+
+## 📋 工作流概览
+
+本项目包含两个独立的 GitHub Actions 工作流:
+
+### 1. PR 构建检查 (`pr-check.yml`)
+- **触发条件**:向 `dev` 或 `main` 分支提交 Pull Request
+- **功能**:构建 Docker 镜像但不推送,用于验证代码可构建性
+- **作用**:作为合并前的质量门控
+
+### 2. 版本发布 (`release.yml`)
+- **触发条件**:在 `main` 分支上创建符合 `x.x.x` 格式的标签
+- **功能**:构建并推送 Docker 镜像到 DockerHub
+- **推送标签**:版本标签 + `latest` 标签
+
+## 🔐 必需的 GitHub Secrets
+
+在仓库设置中配置以下 Secrets:
+
+```
+DOCKERHUB_USERNAME = zsio
+DOCKERHUB_TOKEN = <your-dockerhub-access-token>
+```
+
+### 获取 DockerHub Token
+1. 登录 [Docker Hub](https://hub.docker.com)
+2. Account Settings → Security
+3. New Access Token → 创建具有 `Read & Write` 权限的 Token
+
+## 🛡️ 分支保护规则配置
+
+### 为 `dev` 分支设置保护规则
+
+1. 进入仓库 Settings → Branches
+2. Add rule → Branch name pattern: `dev`
+3. 配置以下选项:
+
+   **✅ 必选项:**
+   - [x] Require a pull request before merging
+   - [x] Require status checks to pass before merging
+     - 搜索并选择:`Docker Build Test`
+   - [x] Require branches to be up to date before merging
+
+   **可选项(根据团队需求):**
+   - [ ] Require approvals (需要审核批准)
+   - [ ] Dismiss stale pull request approvals when new commits are pushed
+   - [ ] Require review from CODEOWNERS
+
+4. Create 保存规则
+
+### 为 `main` 分支设置保护规则
+
+1. Add rule → Branch name pattern: `main`
+2. 配置以下选项:
+
+   **✅ 必选项:**
+   - [x] Require a pull request before merging
+   - [x] Require status checks to pass before merging
+     - 搜索并选择:`Docker Build Test`
+   - [x] Require branches to be up to date before merging
+   - [x] Include administrators (管理员也需要遵守规则)
+
+   **推荐选项:**
+   - [x] Require approvals (数量:1-2)
+   - [x] Require conversation resolution before merging
+   - [x] Do not allow bypassing the above settings
+
+3. Create 保存规则
+
+## 🔄 工作流程示例
+
+### 1. 功能开发流程
+```bash
+# 1. 创建功能分支
+git checkout -b feature/new-feature
+
+# 2. 开发并提交代码
+git add .
+git commit -m "feat: add new feature"
+git push origin feature/new-feature
+
+# 3. 创建 PR 到 dev 分支
+# GitHub 会自动运行构建检查
+
+# 4. 构建通过后,合并到 dev
+```
+
+### 2. 发布流程
+```bash
+# 1. 从 dev 合并到 main
+git checkout main
+git merge dev
+git push origin main
+
+# 2. 创建版本标签
+git tag 1.0.0
+git push origin 1.0.0
+
+# 3. GitHub Actions 自动:
+#    - 验证标签在 main 分支上
+#    - 构建 Docker 镜像
+#    - 推送到 DockerHub (1.0.0 + latest)
+#    - 创建 GitHub Release
+```
+
+## 🐳 Docker 镜像使用
+
+发布后,可以使用以下命令拉取镜像:
+
+```bash
+# 最新版本
+docker pull zsio/claude-code-hub:latest
+
+# 特定版本
+docker pull zsio/claude-code-hub:1.0.0
+
+# 运行容器
+docker run -d \
+  -p 3000:3000 \
+  --env-file .env \
+  zsio/claude-code-hub:latest
+```
+
+## ⚠️ 注意事项
+
+1. **版本标签格式**:必须是 `x.x.x` 格式(如 `1.0.0`),可选 `v` 前缀(如 `v1.0.0`)
+2. **分支策略**:
+   - `feature/*` → `dev` (通过 PR)
+   - `dev` → `main` (通过 PR)
+   - 标签只在 `main` 分支创建
+3. **缓存优化**:工作流使用 GitHub Actions 缓存加速构建
+4. **多平台支持**:自动构建 `linux/amd64` 和 `linux/arm64` 架构
+
+## 🚨 故障排除
+
+### PR 构建失败
+- 检查 Dockerfile 语法
+- 查看 Actions 日志中的错误信息
+- 确保所有依赖正确安装
+
+### 无法推送到 DockerHub
+- 验证 Secrets 配置正确
+- 检查 DockerHub Token 权限
+- 确认 DockerHub 仓库名称正确
+
+### 标签发布未触发
+- 确保标签格式正确(`x.x.x`)
+- 确认标签在 `main` 分支上创建
+- 检查 Actions 是否被禁用

+ 60 - 0
.github/workflows/pr-check.yml

@@ -0,0 +1,60 @@
+name: PR Build Check
+
+# 仅在向 main 分支提交 PR 时触发
+on:
+  pull_request:
+    branches:
+      - main  # 所有 PR 都合并到 main 分支
+    types: [opened, synchronize, reopened]
+
+env:
+  REGISTRY: docker.io
+  IMAGE_NAME: zsio/claude-code-hub
+
+jobs:
+  # PR 构建测试任务(不推送镜像)
+  build-check:
+    runs-on: ubuntu-latest
+    name: Docker Build Test
+
+    steps:
+    - name: 📥 Checkout repository
+      uses: actions/checkout@v4
+
+    - name: 🔧 Set up Docker Buildx
+      uses: docker/setup-buildx-action@v3
+
+    - name: 📋 Extract metadata
+      id: meta
+      uses: docker/metadata-action@v5
+      with:
+        images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+        tags: |
+          type=ref,event=pr
+          type=sha,prefix=pr-
+
+    - name: 🏗️ Build Docker image (Test Only - No Push)
+      uses: docker/build-push-action@v5
+      with:
+        context: .
+        file: ./deploy/Dockerfile
+        platforms: linux/amd64  # PR检查使用单一架构提高速度
+        push: false  # 永远不推送,仅测试构建
+        tags: ${{ steps.meta.outputs.tags }}
+        labels: ${{ steps.meta.outputs.labels }}
+        cache-from: type=gha
+        cache-to: type=gha,mode=max
+
+    - name: ✅ Build check passed
+      run: |
+        echo "✅ Docker image build successful!"
+        echo "📦 Image tags that would be used: ${{ steps.meta.outputs.tags }}"
+        echo "🔍 All checks passed - PR is ready for review"
+
+    # 如果构建失败,这个步骤会提供更详细的信息
+    - name: ❌ Build failed diagnostics
+      if: failure()
+      run: |
+        echo "❌ Build or test failed!"
+        echo "Please check the logs above for details."
+        docker images

+ 140 - 0
.github/workflows/release.yml

@@ -0,0 +1,140 @@
+name: Release Docker Image
+
+# 支持标签发布
+on:
+  push:
+    tags:
+      - '[0-9]+\.[0-9]+\.[0-9]+'  # 匹配 x.x.x 格式的版本标签(精确匹配点号)
+      - 'v[0-9]+\.[0-9]+\.[0-9]+' # 匹配 vx.x.x 格式的版本标签(精确匹配点号)
+
+env:
+  REGISTRY: docker.io
+  IMAGE_NAME: zsio/claude-code-hub
+
+jobs:
+  # 验证标签是否在 main 分支上(仅标签触发时运行)
+  verify-branch:
+    if: startsWith(github.ref, 'refs/tags/')
+    runs-on: ubuntu-latest
+    outputs:
+      is_main: ${{ steps.check.outputs.is_main }}
+
+    steps:
+    - name: 📥 Checkout repository
+      uses: actions/checkout@v4
+      with:
+        fetch-depth: 0  # 获取所有历史记录以检查分支
+
+    - name: 🔍 Check if tag is on main branch
+      id: check
+      run: |
+        # 获取包含此标签的分支
+        BRANCHES=$(git branch -r --contains ${{ github.ref_name }} | grep -E '^\s*origin/main$' || true)
+
+        if [ -n "$BRANCHES" ]; then
+          echo "✅ Tag ${{ github.ref_name }} is on main branch"
+          echo "is_main=true" >> $GITHUB_OUTPUT
+        else
+          echo "❌ Tag ${{ github.ref_name }} is NOT on main branch"
+          echo "is_main=false" >> $GITHUB_OUTPUT
+          exit 1
+        fi
+
+  # 构建并推送 Docker 镜像
+  build-and-push:
+    # 仅当标签验证通过时执行
+    needs: [verify-branch]
+    if: needs.verify-branch.outputs.is_main == 'true'
+    runs-on: ubuntu-latest
+    name: Build and Push to DockerHub
+
+    steps:
+    - name: 📥 Checkout repository
+      uses: actions/checkout@v4
+
+    - name: 🔧 Set up QEMU
+      uses: docker/setup-qemu-action@v3
+
+    - name: 🔧 Set up Docker Buildx
+      id: buildx
+      uses: docker/setup-buildx-action@v3
+      with:
+        driver: docker-container
+        install: true
+
+    - name: 🔐 Log in to Docker Hub
+      uses: docker/login-action@v3
+      with:
+        registry: ${{ env.REGISTRY }}
+        username: ${{ secrets.DOCKERHUB_USERNAME }}
+        password: ${{ secrets.DOCKERHUB_TOKEN }}
+
+    - name: 📋 Extract metadata
+      id: meta-tag
+      uses: docker/metadata-action@v5
+      with:
+        images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+        # 标签策略
+        tags: |
+          # 语义化版本
+          type=semver,pattern={{version}}
+          type=semver,pattern={{major}}.{{minor}}
+          type=semver,pattern={{major}}
+          # 手动控制 latest 标签(当推送语义化版本标签时)
+          type=raw,value=latest
+        # 标签风格配置
+        flavor: |
+          latest=false  # 禁用自动 latest(我们手动控制)
+          prefix=       # 去除 v 前缀
+          suffix=
+
+    - name: 🏗️ Build and push Docker image
+      id: build
+      uses: docker/build-push-action@v5
+      with:
+        context: .
+        file: ./deploy/Dockerfile
+        platforms: linux/amd64,linux/arm64
+        push: true
+        builder: ${{ steps.buildx.outputs.name }}
+        tags: ${{ steps.meta-tag.outputs.tags }}
+        labels: ${{ steps.meta-tag.outputs.labels }}
+        cache-from: type=gha
+        cache-to: type=gha,mode=max
+
+    - name: 📦 Image pushed successfully
+      run: |
+        echo "✅ Docker image pushed to DockerHub successfully!"
+        echo "📋 Image digest: ${{ steps.build.outputs.digest }}"
+        echo "🏷️ Image tags:"
+        echo "${{ steps.meta-tag.outputs.tags }}"
+        echo ""
+        echo "📝 Pull commands:"
+        echo "docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest"
+        echo "docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}"
+
+    - name: 🎉 Create Release Notes
+      if: startsWith(github.ref, 'refs/tags/')
+      uses: softprops/action-gh-release@v1
+      with:
+        tag_name: ${{ github.ref_name }}
+        name: Release ${{ github.ref_name }}
+        body: |
+          ## 🚀 Docker Image Released
+
+          **Version:** ${{ github.ref_name }}
+          **Image:** `${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}`
+
+          ### 📦 Available Tags
+          - `${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}`
+          - `${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest`
+
+          ### 🐳 Pull Command
+          ```bash
+          docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
+          ```
+
+          ### 📝 Changelog
+          View commits: https://github.com/${{ github.repository }}/commits/${{ github.ref_name }}
+        draft: false
+        prerelease: false

+ 67 - 25
README.md

@@ -16,49 +16,92 @@ Claude Code Hub 是一个 Claude Code API 代理中转服务平台,专为需
 
 ## 🚀 快速部署
 
-### 推荐:Docker Compose 部署
+### 推荐:官方 Docker 镜像 + Compose
 
-我们推荐使用 Docker Compose 进行一键部署,这种方式简单可靠,适合生产环境使用
+生产环境建议直接使用已经发布到 Docker Hub 的镜像 `zsio/claude-code-hub:latest`,无需进行本地构建
 
-1. **克隆项目**
+1. **准备环境变量**
 
    ```bash
-   git clone https://github.com/your-username/claude-code-hub.git
-   cd claude-code-hub
-   ```
-
-2. **配置环境变量**
-
-   ```bash
-   # 复制环境变量模板
-   cp .env.example .env
+   # 获取示例并保存为部署时使用的 .env
+   curl -fsSL https://raw.githubusercontent.com/zsio/claude-code-hub/main/.env.example -o .env
 
-   # 编辑环境变量文件
+   # 根据需求修改 .env(可使用任意编辑器)
    nano .env
    ```
 
-   主要配置项
+   关键配置示例:
 
    ```bash
-   # 管理员令牌(请设置一个强密码)
-   ADMIN_TOKEN=your-secure-admin-token-here
+   # 管理员令牌(请设置强密码)
+   ADMIN_TOKEN=your-secure-admin-token
 
-   # 数据库配置(重要,请修改)
+   # PostgreSQL 连接信息
    DB_USER=postgres
    DB_PASSWORD=postgres
    DB_NAME=claude_code_hub
    ```
 
-3. **一键启动**
+2. **创建 docker-compose.yaml**
+
+   将下方示例保存到 `.env` 同级目录;如需自定义端口或数据库,请自行调整。
+
+   <details>
+   <summary>docker-compose.yaml 示例</summary>
+
+   ```yaml
+   services:
+     postgres:
+       image: postgres:16-alpine
+       container_name: claude-code-hub-db
+       restart: unless-stopped
+       ports:
+         - "35432:5432"
+       environment:
+         POSTGRES_USER: ${DB_USER:-postgres}
+         POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres}
+         POSTGRES_DB: ${DB_NAME:-claude_code_hub}
+       volumes:
+         - postgres_data:/var/lib/postgresql/data
+       healthcheck:
+         test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-postgres} -d ${DB_NAME:-claude_code_hub}"]
+         interval: 5s
+         timeout: 5s
+         retries: 10
+         start_period: 10s
+
+     app:
+       image: zsio/claude-code-hub:latest
+       container_name: claude-code-hub-app
+       depends_on:
+         postgres:
+           condition: service_healthy
+       env_file:
+         - ./.env
+       environment:
+         NODE_ENV: production
+         PORT: 23000
+         DSN: postgresql://${DB_USER:-postgres}:${DB_PASSWORD:-postgres}@postgres:5432/${DB_NAME:-claude_code_hub}
+       ports:
+         - "23000:23000"
+       restart: unless-stopped
+
+   volumes:
+     postgres_data:
+       driver: local
+   ```
+
+   </details>
+
+3. **启动服务**
 
    ```bash
-   cd deploy
-   docker-compose up -d
+   docker compose up -d
    ```
 
 4. **访问应用**
-   - 应用地址:<http://localhost:23000>
-   - 数据库端口:localhost:35432(如需直连)
+   - Web 管理后台:<http://localhost:23000>
+   - PostgreSQL:localhost:35432(需要直连时使用
 
 ### 其他部署方式
 
@@ -132,8 +175,7 @@ docker exec claude-code-hub-db pg_dump -U postgres claude_code_hub > backup.sql
 <details>
 <summary>如何升级应用?</summary>
 
-1. 拉取最新代码:`git pull`
-2. 重新构建:`docker-compose build --no-cache`
-3. 重启服务:`docker-compose up -d`
+1. 拉取最新镜像:`docker compose pull`
+2. 重启服务:`docker compose up -d`
 
 </details>

+ 13 - 21
deploy/Dockerfile

@@ -1,40 +1,32 @@
+# syntax=docker/dockerfile:1
 
-# 使用 Node.js 22 slim 版本
-FROM docker.m.daocloud.io/library/node:22-slim
-
-# 启用 corepack 以使用 pnpm
+FROM --platform=$BUILDPLATFORM node:22-slim AS build-base
 ENV PNPM_HOME=/pnpm
 ENV PATH="$PNPM_HOME:$PATH"
 RUN corepack enable
-
-# 设置工作目录
 WORKDIR /app
 
-# 复制 package.json 和 pnpm-lock.yaml
+FROM build-base AS deps
 COPY package.json pnpm-lock.yaml ./
+RUN --mount=type=cache,target=/root/.local/share/pnpm/store pnpm install --frozen-lockfile
 
-# 安装依赖(使用 --no-frozen-lockfile 避免锁文件不同步问题)
-RUN pnpm install --no-frozen-lockfile
-
-# 复制项目文件
+FROM deps AS build
 COPY . .
-
-# 构建 Next.js 应用
+ENV NEXT_TELEMETRY_DISABLED=1
 RUN pnpm run build
 
-# 设置环境变量
+FROM node:22-slim AS runner
 ENV NODE_ENV=production
 ENV PORT=3000
 ENV HOST=0.0.0.0
+WORKDIR /app
 
-# 创建非 root 用户运行应用
-RUN chown -R node:node /app
+COPY --from=build --chown=node:node /app/public ./public
+COPY --from=build --chown=node:node /app/drizzle ./drizzle
+COPY --from=build --chown=node:node /app/.next/standalone ./
+COPY --from=build --chown=node:node /app/.next/static ./.next/static
 
-# 切换到 node 用户
 USER node
-
-# 暴露端口
 EXPOSE 3000
 
-# 启动应用(迁移将在应用启动时自动执行)
-CMD ["pnpm", "run", "start"]
+CMD ["node", "server.js"]

+ 0 - 142
deploy/README.md

@@ -1,142 +0,0 @@
-# Docker 部署指南
-
-## 快速开始
-
-### 1. 准备环境变量
-```bash
-cd deploy
-cp .env.example ../.env.local
-# 编辑 ../.env.local 设置你的数据库密码
-```
-
-### 2. 启动服务
-```bash
-# 构建并启动所有服务(仅两个容器:数据库 + 应用)
-docker-compose up -d
-
-# 查看日志
-docker-compose logs -f app
-```
-
-### 3. 验证部署
-- 应用地址:http://localhost:23000
-- 数据库端口:35432(可用于外部连接)
-
-## 架构说明
-
-### 容器结构
-1. **postgres 容器**:PostgreSQL 16 数据库
-2. **app 容器**:Next.js 应用(包含自动迁移)
-
-### 自动迁移机制
-
-**方案选择:**
-
-#### 当前方案:代码集成(推荐)
-- 在 `src/instrumentation.ts` 中实现
-- Next.js 启动时自动执行
-- 无需额外脚本文件
-- 通过 `AUTO_MIGRATE=false` 可禁用
-
-#### 备选方案:启动脚本
-- 使用 `deploy/entrypoint.sh`
-- 更传统的 Docker 方式
-- 适合需要更多控制的场景
-
-### 迁移流程
-
-1. **应用启动时**:
-   - 检查数据库连接(最多重试 30 次)
-   - 自动运行 Drizzle 迁移
-   - 迁移成功后启动 Next.js
-
-2. **失败处理**:
-   - 数据库不可用:容器退出,Docker 自动重启
-   - 迁移失败:记录错误并退出
-
-## 常用命令
-
-```bash
-# 查看服务状态
-docker-compose ps
-
-# 重新构建并启动
-docker-compose up -d --build
-
-# 停止所有服务
-docker-compose down
-
-# 清理所有数据(危险!)
-docker-compose down -v
-
-# 手动执行迁移(开发环境)
-docker-compose exec app pnpm run db:migrate
-
-# 进入应用容器
-docker-compose exec app sh
-
-# 查看数据库
-docker-compose exec postgres psql -U postgres -d claude_code_hub
-```
-
-## 环境变量
-
-| 变量 | 说明 | 默认值 |
-|------|------|--------|
-| `DB_USER` | 数据库用户名 | postgres |
-| `DB_PASSWORD` | 数据库密码 | postgres |
-| `DB_NAME` | 数据库名称 | claude_code_hub |
-| `DSN` | 数据库连接字符串 | 自动生成 |
-| `AUTO_MIGRATE` | 是否自动迁移 | true |
-| `PORT` | 应用端口 | 23000 |
-
-## 故障排查
-
-### 数据库连接失败
-```bash
-# 检查数据库容器状态
-docker-compose ps postgres
-docker-compose logs postgres
-
-# 测试数据库连接
-docker-compose exec postgres pg_isready
-```
-
-### 迁移失败
-```bash
-# 查看迁移日志
-docker-compose logs app | grep -i migration
-
-# 手动运行迁移查看详细错误
-docker-compose exec app pnpm run db:migrate
-```
-
-### 应用无法启动
-```bash
-# 查看完整日志
-docker-compose logs -f app
-
-# 检查环境变量
-docker-compose exec app env | grep -E "(DSN|DB_|NODE_ENV)"
-```
-
-## 生产部署建议
-
-1. **安全性**:
-   - 使用强密码
-   - 限制数据库端口访问
-   - 使用 Docker secrets 管理敏感信息
-
-2. **性能**:
-   - 挂载 SSD 作为数据库存储
-   - 适当调整 PostgreSQL 配置
-   - 使用 Docker Swarm 或 K8s 实现高可用
-
-3. **备份**:
-   ```bash
-   # 备份数据库
-   docker-compose exec postgres pg_dump -U postgres claude_code_hub > backup.sql
-
-   # 恢复数据库
-   docker-compose exec -T postgres psql -U postgres claude_code_hub < backup.sql
-   ```

+ 0 - 54
deploy/docker-compose.yaml

@@ -1,54 +0,0 @@
-version: '3.9'
-
-services:
-  # PostgreSQL 数据库服务
-  postgres:
-    image: postgres:16-alpine
-    container_name: claude-code-hub-db
-    restart: unless-stopped
-    ports:
-      - "35432:5432"  # 映射到主机端口,避免冲突
-    environment:
-      POSTGRES_USER: ${DB_USER:-postgres}
-      POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres}
-      POSTGRES_DB: ${DB_NAME:-claude_code_hub}
-    volumes:
-      - postgres_data:/var/lib/postgresql/data
-    healthcheck:
-      test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-postgres} -d ${DB_NAME:-claude_code_hub}"]
-      interval: 5s
-      timeout: 5s
-      retries: 10
-      start_period: 10s
-    networks:
-      - app-network
-
-  # 主应用服务(包含自动迁移)
-  app:
-    build:
-      context: ..
-      dockerfile: deploy/Dockerfile
-    container_name: claude-code-hub-app
-    depends_on:
-      postgres:
-        condition: service_healthy
-    ports:
-      - "23000:23000"
-    env_file:
-      - ../.env
-    environment:
-      NODE_ENV: production
-      PORT: 23000
-      # 使用容器网络连接数据库
-      DSN: postgresql://${DB_USER:-postgres}:${DB_PASSWORD:-postgres}@postgres:5432/${DB_NAME:-claude_code_hub}
-    restart: unless-stopped
-    networks:
-      - app-network
-
-networks:
-  app-network:
-    driver: bridge
-
-volumes:
-  postgres_data:
-    driver: local

+ 0 - 47
deploy/entrypoint.sh

@@ -1,47 +0,0 @@
-#!/bin/sh
-set -e
-
-echo "🚀 Starting Claude Code Hub..."
-echo ""
-
-# 等待数据库就绪(可选,因为 docker-compose 已有健康检查)
-echo "⏳ Checking database connection..."
-MAX_RETRIES=30
-RETRY_COUNT=0
-
-while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
-    if pnpm run db:migrate 2>&1 | grep -q "Error"; then
-        echo "   Database not ready, waiting... ($((RETRY_COUNT + 1))/$MAX_RETRIES)"
-        sleep 2
-        RETRY_COUNT=$((RETRY_COUNT + 1))
-    else
-        echo "✅ Database is ready!"
-        break
-    fi
-done
-
-if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then
-    echo "❌ Database connection timeout after $MAX_RETRIES attempts"
-    exit 1
-fi
-
-# 执行数据库迁移
-echo ""
-echo "🔄 Running database migrations..."
-pnpm run db:migrate
-
-if [ $? -eq 0 ]; then
-    echo "✅ Database migrations completed successfully!"
-else
-    echo "❌ Database migration failed!"
-    exit 1
-fi
-
-# 启动应用
-echo ""
-echo "🎯 Starting Next.js application on port ${PORT:-3000}..."
-echo "================================"
-echo ""
-
-# 使用 exec 替换当前进程,确保信号正确传递
-exec pnpm run start

+ 3 - 1
next.config.ts

@@ -1,5 +1,7 @@
 import type { NextConfig } from 'next'
 
-const nextConfig: NextConfig = {}
+const nextConfig: NextConfig = {
+  output: 'standalone',
+}
 
 export default nextConfig

+ 27 - 9
src/drizzle/db.ts

@@ -1,19 +1,37 @@
 import 'server-only';
 
-import { drizzle } from 'drizzle-orm/postgres-js';
+import { drizzle, type PostgresJsDatabase } from 'drizzle-orm/postgres-js';
 import postgres from 'postgres';
 import * as schema from './schema';
 
-const connectionString = process.env.DSN;
+let dbInstance: PostgresJsDatabase<typeof schema> | null = null;
 
-if (!connectionString) {
-  throw new Error('DSN environment variable is not set');
+function createDbInstance(): PostgresJsDatabase<typeof schema> {
+  const connectionString = process.env.DSN;
+
+  if (!connectionString) {
+    throw new Error('DSN environment variable is not set');
+  }
+
+  const client = postgres(connectionString);
+  return drizzle(client, { schema });
+}
+
+export function getDb(): PostgresJsDatabase<typeof schema> {
+  if (!dbInstance) {
+    dbInstance = createDbInstance();
+  }
+
+  return dbInstance;
 }
 
-// Create the postgres client
-const client = postgres(connectionString);
+export const db = new Proxy({} as PostgresJsDatabase<typeof schema>, {
+  get(_target, prop, receiver) {
+    const instance = getDb();
+    const value = Reflect.get(instance, prop, receiver);
 
-// Create the drizzle database instance
-export const db = drizzle(client, { schema });
+    return typeof value === 'function' ? value.bind(instance) : value;
+  },
+});
 
-export type Database = typeof db;
+export type Database = ReturnType<typeof getDb>;