mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-22 16:43:35 +00:00
feat: 添加 Docker Hub 自动构建和改进部署体验
- 支持环境变量预设管理员账号密码 - 添加 docker-entrypoint.sh 自动初始化脚本 - 配置 GitHub Actions 自动构建多平台镜像(amd64, arm64) - 添加版本标签管理和自动发布流程 - 集成 Trivy 安全漏洞扫描 - 更新文档说明 Docker Hub 使用方法 - 优化 Docker 部署用户体验 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
76
.dockerignore
Normal file
76
.dockerignore
Normal file
@@ -0,0 +1,76 @@
|
||||
# Dependencies
|
||||
node_modules/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Environment files
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Logs
|
||||
logs/
|
||||
*.log
|
||||
|
||||
# Data files
|
||||
data/
|
||||
temp/
|
||||
|
||||
# Git
|
||||
.git/
|
||||
.gitignore
|
||||
.gitattributes
|
||||
|
||||
# GitHub
|
||||
.github/
|
||||
|
||||
# Documentation
|
||||
README.md
|
||||
README_EN.md
|
||||
CHANGELOG.md
|
||||
docs/
|
||||
*.md
|
||||
|
||||
# Development files
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
.DS_Store
|
||||
|
||||
# Docker files
|
||||
docker-compose.yml
|
||||
docker-compose.*.yml
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
|
||||
# Test files
|
||||
test/
|
||||
tests/
|
||||
__tests__/
|
||||
*.test.js
|
||||
*.spec.js
|
||||
coverage/
|
||||
.nyc_output/
|
||||
|
||||
# Build files
|
||||
dist/
|
||||
build/
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# CI/CD
|
||||
.travis.yml
|
||||
.gitlab-ci.yml
|
||||
azure-pipelines.yml
|
||||
|
||||
# Package manager files
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
pnpm-lock.yaml
|
||||
|
||||
# CLI
|
||||
cli/
|
||||
@@ -11,6 +11,10 @@ ADMIN_SESSION_TIMEOUT=86400000
|
||||
API_KEY_PREFIX=cr_
|
||||
ENCRYPTION_KEY=your-encryption-key-here
|
||||
|
||||
# 👤 管理员凭据(可选,不设置则自动生成)
|
||||
# ADMIN_USERNAME=cr_admin_custom
|
||||
# ADMIN_PASSWORD=your-secure-password
|
||||
|
||||
# 📊 Redis 配置
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6379
|
||||
|
||||
109
.github/DOCKER_HUB_SETUP.md
vendored
Normal file
109
.github/DOCKER_HUB_SETUP.md
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
# Docker Hub 自动发布配置指南
|
||||
|
||||
本文档说明如何配置 GitHub Actions 自动构建并发布 Docker 镜像到 Docker Hub。
|
||||
|
||||
## 📋 前置要求
|
||||
|
||||
1. Docker Hub 账号
|
||||
2. GitHub 仓库的管理员权限
|
||||
|
||||
## 🔐 配置 GitHub Secrets
|
||||
|
||||
在 GitHub 仓库中配置以下 secrets:
|
||||
|
||||
1. 进入仓库设置:`Settings` → `Secrets and variables` → `Actions`
|
||||
2. 点击 `New repository secret`
|
||||
3. 添加以下 secrets:
|
||||
|
||||
### 必需的 Secrets
|
||||
|
||||
| Secret 名称 | 说明 | 如何获取 |
|
||||
|------------|------|---------|
|
||||
| `DOCKERHUB_USERNAME` | Docker Hub 用户名 | 你的 Docker Hub 登录用户名 |
|
||||
| `DOCKERHUB_TOKEN` | Docker Hub Access Token | 见下方说明 |
|
||||
|
||||
### 获取 Docker Hub Access Token
|
||||
|
||||
1. 登录 [Docker Hub](https://hub.docker.com/)
|
||||
2. 点击右上角头像 → `Account Settings`
|
||||
3. 选择 `Security` → `Access Tokens`
|
||||
4. 点击 `New Access Token`
|
||||
5. 填写描述(如:`GitHub Actions`)
|
||||
6. 选择权限:`Read, Write, Delete`
|
||||
7. 点击 `Generate`
|
||||
8. **立即复制 token**(只显示一次)
|
||||
|
||||
## 🚀 工作流程说明
|
||||
|
||||
### 触发条件
|
||||
|
||||
- **自动触发**:推送到 `main` 分支
|
||||
- **版本发布**:创建 `v*` 格式的 tag(如 `v1.0.0`)
|
||||
- **手动触发**:在 Actions 页面手动运行
|
||||
|
||||
### 镜像标签策略
|
||||
|
||||
工作流会自动创建以下标签:
|
||||
|
||||
- `latest`:始终指向 main 分支的最新构建
|
||||
- `main`:main 分支的构建
|
||||
- `v1.0.0`:版本标签(当创建 tag 时)
|
||||
- `1.0`:主次版本标签
|
||||
- `1`:主版本标签
|
||||
- `main-sha-xxxxxxx`:包含 commit SHA 的标签
|
||||
|
||||
### 支持的平台
|
||||
|
||||
- `linux/amd64`:Intel/AMD 架构
|
||||
- `linux/arm64`:ARM64 架构(如 Apple Silicon, 树莓派等)
|
||||
|
||||
## 📦 使用发布的镜像
|
||||
|
||||
```bash
|
||||
# 拉取最新版本
|
||||
docker pull weishaw/claude-relay-service:latest
|
||||
|
||||
# 拉取特定版本
|
||||
docker pull weishaw/claude-relay-service:v1.0.0
|
||||
|
||||
# 运行容器
|
||||
docker run -d \
|
||||
--name claude-relay \
|
||||
-p 3000:3000 \
|
||||
-v ./data:/app/data \
|
||||
-v ./logs:/app/logs \
|
||||
-e ADMIN_USERNAME=my_admin \
|
||||
-e ADMIN_PASSWORD=my_password \
|
||||
weishaw/claude-relay-service:latest
|
||||
```
|
||||
|
||||
## 🔍 验证配置
|
||||
|
||||
1. 推送代码到 main 分支
|
||||
2. 在 GitHub 仓库页面点击 `Actions` 标签
|
||||
3. 查看 `Docker Build & Push` 工作流运行状态
|
||||
4. 成功后在 Docker Hub 查看镜像
|
||||
|
||||
## 🛡️ 安全功能
|
||||
|
||||
- **漏洞扫描**:使用 Trivy 自动扫描镜像漏洞
|
||||
- **扫描报告**:上传到 GitHub Security 标签页
|
||||
- **自动更新 README**:同步更新 Docker Hub 的项目描述
|
||||
|
||||
## ❓ 常见问题
|
||||
|
||||
### 构建失败
|
||||
|
||||
- 检查 secrets 是否正确配置
|
||||
- 确认 Docker Hub token 有足够权限
|
||||
- 查看 Actions 日志详细错误信息
|
||||
|
||||
### 镜像推送失败
|
||||
|
||||
- 确认 Docker Hub 用户名正确
|
||||
- 检查是否达到 Docker Hub 免费账户限制
|
||||
- Token 可能过期,需要重新生成
|
||||
|
||||
### 多平台构建慢
|
||||
|
||||
这是正常的,因为需要模拟不同架构。可以在不需要时修改 `platforms` 配置。
|
||||
114
.github/WORKFLOW_USAGE.md
vendored
Normal file
114
.github/WORKFLOW_USAGE.md
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
# GitHub Actions 工作流使用指南
|
||||
|
||||
## 📋 概述
|
||||
|
||||
本项目配置了自动化 CI/CD 流程,每次推送到 main 分支都会自动构建并发布 Docker 镜像到 Docker Hub。
|
||||
|
||||
## 🚀 工作流程
|
||||
|
||||
### 1. Docker 构建和发布 (`docker-publish.yml`)
|
||||
|
||||
**功能:**
|
||||
- 自动构建多平台 Docker 镜像(amd64, arm64)
|
||||
- 推送到 Docker Hub
|
||||
- 执行安全漏洞扫描
|
||||
- 更新 Docker Hub 描述
|
||||
|
||||
**触发条件:**
|
||||
- 推送到 `main` 分支
|
||||
- 创建版本标签(如 `v1.0.0`)
|
||||
- Pull Request(仅构建,不推送)
|
||||
- 手动触发
|
||||
|
||||
### 2. 发布管理 (`release.yml`)
|
||||
|
||||
**功能:**
|
||||
- 自动创建 GitHub Release
|
||||
- 生成更新日志
|
||||
- 关联 Docker 镜像版本
|
||||
|
||||
**触发条件:**
|
||||
- 创建版本标签(如 `v1.0.0`)
|
||||
|
||||
## 📝 版本发布流程
|
||||
|
||||
### 1. 常规更新(推送到 main)
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "fix: 修复登录问题"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
**结果:**
|
||||
- 自动构建并推送 `latest` 标签到 Docker Hub
|
||||
- 更新 `main` 标签
|
||||
|
||||
### 2. 版本发布
|
||||
|
||||
```bash
|
||||
# 创建版本标签
|
||||
git tag -a v1.0.0 -m "Release version 1.0.0"
|
||||
git push origin v1.0.0
|
||||
```
|
||||
|
||||
**结果:**
|
||||
- 构建并推送以下标签到 Docker Hub:
|
||||
- `v1.0.0`(完整版本)
|
||||
- `1.0`(主次版本)
|
||||
- `1`(主版本)
|
||||
- `latest`(最新版本)
|
||||
- 创建 GitHub Release
|
||||
- 生成更新日志
|
||||
|
||||
## 🔧 手动触发构建
|
||||
|
||||
1. 访问仓库的 Actions 页面
|
||||
2. 选择 "Docker Build & Push" 工作流
|
||||
3. 点击 "Run workflow"
|
||||
4. 选择分支并运行
|
||||
|
||||
## 📊 查看构建状态
|
||||
|
||||
- **Actions 页面**:查看所有工作流运行历史
|
||||
- **README 徽章**:实时显示构建状态
|
||||
- **Docker Hub**:查看镜像标签和拉取次数
|
||||
|
||||
## 🛡️ 安全扫描
|
||||
|
||||
每次构建都会运行 Trivy 安全扫描:
|
||||
- 扫描结果上传到 GitHub Security 标签页
|
||||
- 发现高危漏洞会在 Actions 日志中警告
|
||||
|
||||
## ❓ 常见问题
|
||||
|
||||
### Q: 如何回滚到之前的版本?
|
||||
|
||||
```bash
|
||||
# 使用特定版本标签
|
||||
docker pull weishaw/claude-relay-service:v1.0.0
|
||||
|
||||
# 或在 docker-compose.yml 中指定版本
|
||||
image: weishaw/claude-relay-service:v1.0.0
|
||||
```
|
||||
|
||||
### Q: 如何跳过自动构建?
|
||||
|
||||
在 commit 消息中添加 `[skip ci]`:
|
||||
```bash
|
||||
git commit -m "docs: 更新文档 [skip ci]"
|
||||
```
|
||||
|
||||
### Q: 构建失败如何调试?
|
||||
|
||||
1. 查看 Actions 日志详细错误信息
|
||||
2. 在本地测试 Docker 构建:
|
||||
```bash
|
||||
docker build -t test .
|
||||
```
|
||||
|
||||
## 📚 相关文档
|
||||
|
||||
- [Docker Hub 配置指南](.github/DOCKER_HUB_SETUP.md)
|
||||
- [GitHub Actions 文档](https://docs.github.com/en/actions)
|
||||
- [Docker 官方文档](https://docs.docker.com/)
|
||||
68
.github/cliff.toml
vendored
Normal file
68
.github/cliff.toml
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
# git-cliff configuration file
|
||||
# https://git-cliff.org/docs/configuration
|
||||
|
||||
[changelog]
|
||||
# changelog header
|
||||
header = """
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
"""
|
||||
# template for the changelog body
|
||||
body = """
|
||||
{% if version %}\
|
||||
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
|
||||
{% else %}\
|
||||
## [unreleased]
|
||||
{% endif %}\
|
||||
{% for group, commits in commits | group_by(attribute="group") %}
|
||||
### {{ group | upper_first }}
|
||||
{% for commit in commits %}
|
||||
- {% if commit.breaking %}[**breaking**] {% endif %}{{ commit.message | upper_first }} ([{{ commit.id | truncate(length=7, end="") }}](https://github.com/orhun/git-cliff/commit/{{ commit.id }}))
|
||||
{%- endfor %}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
footer = """
|
||||
"""
|
||||
|
||||
[git]
|
||||
# parse the commits based on https://www.conventionalcommits.org
|
||||
conventional_commits = true
|
||||
# filter out the commits that are not conventional
|
||||
filter_unconventional = true
|
||||
# process each line of a commit as an individual commit
|
||||
split_commits = false
|
||||
# regex for preprocessing the commit messages
|
||||
commit_preprocessors = [
|
||||
{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](https://github.com/orhun/git-cliff/issues/${2}))" },
|
||||
]
|
||||
# regex for parsing and grouping commits
|
||||
commit_parsers = [
|
||||
{ message = "^feat", group = "Features" },
|
||||
{ message = "^fix", group = "Bug Fixes" },
|
||||
{ message = "^docs", group = "Documentation" },
|
||||
{ message = "^perf", group = "Performance" },
|
||||
{ message = "^refactor", group = "Refactor" },
|
||||
{ message = "^style", group = "Styling" },
|
||||
{ message = "^test", group = "Testing" },
|
||||
{ message = "^chore\\(release\\): prepare for", skip = true },
|
||||
{ message = "^chore", group = "Miscellaneous Tasks" },
|
||||
{ body = ".*security", group = "Security" },
|
||||
]
|
||||
# protect breaking changes from being skipped due to matching a skipping commit_parser
|
||||
protect_breaking_commits = false
|
||||
# filter out the commits that are not matched by commit parsers
|
||||
filter_commits = false
|
||||
# glob pattern for matching git tags
|
||||
tag_pattern = "v[0-9]*"
|
||||
# regex for skipping tags
|
||||
skip_tags = "v0.1.0-beta.1"
|
||||
# regex for ignoring tags
|
||||
ignore_tags = ""
|
||||
# sort the tags topologically
|
||||
topo_order = false
|
||||
# sort the commits inside sections by oldest/newest order
|
||||
sort_commits = "oldest"
|
||||
101
.github/workflows/docker-publish.yml
vendored
Normal file
101
.github/workflows/docker-publish.yml
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
name: Docker Build & Push
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
tags:
|
||||
- 'v*'
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY: docker.io
|
||||
IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/claude-relay-service
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env.IMAGE_NAME }}
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
type=sha,prefix={{branch}}-
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
test:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name != 'pull_request'
|
||||
|
||||
steps:
|
||||
- name: Run Trivy vulnerability scanner
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
image-ref: ${{ env.IMAGE_NAME }}:latest
|
||||
format: 'sarif'
|
||||
output: 'trivy-results.sarif'
|
||||
|
||||
- name: Upload Trivy scan results to GitHub Security tab
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
if: always()
|
||||
with:
|
||||
sarif_file: 'trivy-results.sarif'
|
||||
|
||||
update-description:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Update Docker Hub Description
|
||||
uses: peter-evans/dockerhub-description@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
repository: ${{ secrets.DOCKERHUB_USERNAME }}/claude-relay-service
|
||||
readme-filepath: ./README.md
|
||||
short-description: "Claude Code API Relay Service - 多账户管理的Claude API中转服务"
|
||||
48
.github/workflows/release.yml
vendored
Normal file
48
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
name: Create Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Generate changelog
|
||||
id: changelog
|
||||
uses: orhun/git-cliff-action@v3
|
||||
with:
|
||||
config: .github/cliff.toml
|
||||
args: --latest --strip header
|
||||
|
||||
- name: Create Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
body: |
|
||||
## 🐳 Docker 镜像
|
||||
|
||||
```bash
|
||||
docker pull ${{ secrets.DOCKERHUB_USERNAME }}/claude-relay-service:${{ github.ref_name }}
|
||||
docker pull ${{ secrets.DOCKERHUB_USERNAME }}/claude-relay-service:latest
|
||||
```
|
||||
|
||||
## 📦 主要更新
|
||||
|
||||
${{ steps.changelog.outputs.content }}
|
||||
|
||||
## 📋 完整更新日志
|
||||
|
||||
查看 [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md)
|
||||
|
||||
draft: false
|
||||
prerelease: false
|
||||
generate_release_notes: true
|
||||
@@ -29,6 +29,10 @@ RUN npm ci --only=production && \
|
||||
# 📋 复制应用代码
|
||||
COPY --chown=claude:nodejs . .
|
||||
|
||||
# 🔧 复制并设置启动脚本权限
|
||||
COPY --chown=claude:nodejs docker-entrypoint.sh /usr/local/bin/
|
||||
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||
|
||||
# 📁 创建必要目录
|
||||
RUN mkdir -p logs data temp && \
|
||||
chown -R claude:nodejs logs data temp
|
||||
@@ -44,5 +48,5 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD curl -f http://localhost:3000/health || exit 1
|
||||
|
||||
# 🚀 启动应用
|
||||
ENTRYPOINT ["dumb-init", "--"]
|
||||
ENTRYPOINT ["dumb-init", "--", "/usr/local/bin/docker-entrypoint.sh"]
|
||||
CMD ["node", "src/app.js"]
|
||||
118
README.md
118
README.md
@@ -6,6 +6,8 @@
|
||||
[](https://nodejs.org/)
|
||||
[](https://redis.io/)
|
||||
[](https://www.docker.com/)
|
||||
[](https://github.com/your-repo/claude-relay-service/actions/workflows/docker-publish.yml)
|
||||
[](https://hub.docker.com/r/yourusername/claude-relay-service)
|
||||
|
||||
**🔐 自行搭建Claude API中转服务,支持多账户管理**
|
||||
|
||||
@@ -195,6 +197,9 @@ module.exports = {
|
||||
```bash
|
||||
# 初始化
|
||||
npm run setup # 会随机生成后台账号密码信息,存储在 data/init.json
|
||||
# 或者通过环境变量预设管理员凭据:
|
||||
# export ADMIN_USERNAME=cr_admin_custom
|
||||
# export ADMIN_PASSWORD=your-secure-password
|
||||
|
||||
# 启动服务
|
||||
npm run service:start:daemon # 后台运行(推荐)
|
||||
@@ -205,13 +210,124 @@ npm run service:status
|
||||
|
||||
---
|
||||
|
||||
## 🐳 Docker 部署(推荐)
|
||||
|
||||
### 使用 Docker Hub 镜像(最简单)
|
||||
|
||||
```bash
|
||||
# 拉取镜像(支持 amd64 和 arm64)
|
||||
docker pull yourusername/claude-relay-service:latest
|
||||
|
||||
# 使用 docker run 运行
|
||||
docker run -d \
|
||||
--name claude-relay \
|
||||
-p 3000:3000 \
|
||||
-v $(pwd)/data:/app/data \
|
||||
-v $(pwd)/logs:/app/logs \
|
||||
-e ADMIN_USERNAME=my_admin \
|
||||
-e ADMIN_PASSWORD=my_secure_password \
|
||||
yourusername/claude-relay-service:latest
|
||||
|
||||
# 或使用 docker-compose(推荐)
|
||||
# 创建 docker-compose.yml 文件:
|
||||
cat > docker-compose.yml << 'EOF'
|
||||
version: '3.8'
|
||||
services:
|
||||
claude-relay:
|
||||
image: yourusername/claude-relay-service:latest
|
||||
container_name: claude-relay-service
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- REDIS_HOST=redis
|
||||
- ADMIN_USERNAME=${ADMIN_USERNAME:-}
|
||||
- ADMIN_PASSWORD=${ADMIN_PASSWORD:-}
|
||||
volumes:
|
||||
- ./logs:/app/logs
|
||||
- ./data:/app/data
|
||||
depends_on:
|
||||
- redis
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: claude-relay-redis
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
|
||||
volumes:
|
||||
redis_data:
|
||||
EOF
|
||||
|
||||
# 启动服务
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### 从源码构建
|
||||
|
||||
```bash
|
||||
# 1. 克隆项目
|
||||
git clone https://github.com/your-repo/claude-relay-service.git
|
||||
cd claude-relay-service
|
||||
|
||||
# 2. 设置管理员账号密码(可选)
|
||||
# 方式一:自动生成(查看容器日志获取)
|
||||
docker-compose up -d
|
||||
|
||||
# 方式二:预设账号密码
|
||||
export ADMIN_USERNAME=cr_admin_custom
|
||||
export ADMIN_PASSWORD=your-secure-password
|
||||
docker-compose up -d
|
||||
|
||||
# 3. 查看管理员凭据
|
||||
# 自动生成的情况下:
|
||||
docker logs claude-relay-service | grep "管理员"
|
||||
|
||||
# 或者直接查看挂载的文件:
|
||||
cat ./data/init.json
|
||||
```
|
||||
|
||||
### Docker Compose 配置
|
||||
|
||||
docker-compose.yml 已包含:
|
||||
- ✅ 自动初始化管理员账号
|
||||
- ✅ 数据持久化(logs和data目录自动挂载)
|
||||
- ✅ Redis数据库
|
||||
- ✅ 健康检查
|
||||
- ✅ 自动重启
|
||||
|
||||
### 管理员凭据获取方式
|
||||
|
||||
1. **查看容器日志**(推荐)
|
||||
```bash
|
||||
docker logs claude-relay-service
|
||||
```
|
||||
|
||||
2. **查看挂载的文件**
|
||||
```bash
|
||||
cat ./data/init.json
|
||||
```
|
||||
|
||||
3. **使用环境变量预设**
|
||||
```bash
|
||||
# 在 .env 文件中设置
|
||||
ADMIN_USERNAME=cr_admin_custom
|
||||
ADMIN_PASSWORD=your-secure-password
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎮 开始使用
|
||||
|
||||
### 1. 打开管理界面
|
||||
|
||||
浏览器访问:`http://你的服务器IP:3000/web`
|
||||
|
||||
默认管理员账号:data/init.json 中寻找
|
||||
管理员账号:
|
||||
- 自动生成:查看 data/init.json
|
||||
- 环境变量预设:通过 ADMIN_USERNAME 和 ADMIN_PASSWORD 设置
|
||||
- Docker 部署:查看容器日志 `docker logs claude-relay-service`
|
||||
|
||||
### 2. 添加Claude账户
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ services:
|
||||
- PORT=3000
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
- ADMIN_USERNAME=${ADMIN_USERNAME:-} # 可选:预设管理员用户名
|
||||
- ADMIN_PASSWORD=${ADMIN_PASSWORD:-} # 可选:预设管理员密码
|
||||
volumes:
|
||||
- ./logs:/app/logs
|
||||
- ./data:/app/data
|
||||
|
||||
31
docker-entrypoint.sh
Normal file
31
docker-entrypoint.sh
Normal file
@@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
echo "🚀 Claude Relay Service 启动中..."
|
||||
|
||||
# 检查是否需要初始化
|
||||
if [ ! -f "/app/data/init.json" ]; then
|
||||
echo "📋 首次启动,执行初始化设置..."
|
||||
|
||||
# 如果设置了环境变量,显示提示
|
||||
if [ -n "$ADMIN_USERNAME" ] || [ -n "$ADMIN_PASSWORD" ]; then
|
||||
echo "📌 检测到预设的管理员凭据"
|
||||
fi
|
||||
|
||||
# 执行初始化脚本
|
||||
node /app/scripts/setup.js
|
||||
|
||||
echo "✅ 初始化完成"
|
||||
else
|
||||
echo "✅ 检测到已有配置,跳过初始化"
|
||||
|
||||
# 如果 init.json 存在但环境变量也设置了,显示警告
|
||||
if [ -n "$ADMIN_USERNAME" ] || [ -n "$ADMIN_PASSWORD" ]; then
|
||||
echo "⚠️ 警告: 检测到环境变量 ADMIN_USERNAME/ADMIN_PASSWORD,但系统已初始化"
|
||||
echo " 如需使用新凭据,请删除 data/init.json 文件后重启容器"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 启动应用
|
||||
echo "🌐 启动 Claude Relay Service..."
|
||||
exec "$@"
|
||||
@@ -42,9 +42,14 @@ async function setup() {
|
||||
fs.writeFileSync(path.join(__dirname, '..', '.env'), envContent);
|
||||
}
|
||||
|
||||
// 3. 生成随机管理员凭据
|
||||
const adminUsername = `cr_admin_${crypto.randomBytes(4).toString('hex')}`;
|
||||
const adminPassword = crypto.randomBytes(16).toString('base64').replace(/[^a-zA-Z0-9]/g, '').substring(0, 16);
|
||||
// 3. 生成或使用环境变量中的管理员凭据
|
||||
const adminUsername = process.env.ADMIN_USERNAME || `cr_admin_${crypto.randomBytes(4).toString('hex')}`;
|
||||
const adminPassword = process.env.ADMIN_PASSWORD || crypto.randomBytes(16).toString('base64').replace(/[^a-zA-Z0-9]/g, '').substring(0, 16);
|
||||
|
||||
// 如果使用了环境变量,显示提示
|
||||
if (process.env.ADMIN_USERNAME || process.env.ADMIN_PASSWORD) {
|
||||
console.log(chalk.yellow('\n📌 使用环境变量中的管理员凭据'));
|
||||
}
|
||||
|
||||
// 4. 创建初始化完成标记文件
|
||||
const initData = {
|
||||
@@ -65,7 +70,14 @@ async function setup() {
|
||||
console.log(chalk.yellow('📋 重要信息:\n'));
|
||||
console.log(` 管理员用户名: ${chalk.cyan(adminUsername)}`);
|
||||
console.log(` 管理员密码: ${chalk.cyan(adminPassword)}`);
|
||||
console.log(chalk.red('\n⚠️ 请立即保存这些凭据!首次登录后建议修改密码。\n'));
|
||||
|
||||
// 如果是自动生成的凭据,强调需要保存
|
||||
if (!process.env.ADMIN_USERNAME && !process.env.ADMIN_PASSWORD) {
|
||||
console.log(chalk.red('\n⚠️ 请立即保存这些凭据!首次登录后建议修改密码。'));
|
||||
console.log(chalk.yellow('\n💡 提示: 也可以通过环境变量 ADMIN_USERNAME 和 ADMIN_PASSWORD 预设管理员凭据。\n'));
|
||||
} else {
|
||||
console.log(chalk.green('\n✅ 已使用预设的管理员凭据。\n'));
|
||||
}
|
||||
|
||||
console.log(chalk.blue('🚀 启动服务:\n'));
|
||||
console.log(' npm start - 启动生产服务');
|
||||
|
||||
Reference in New Issue
Block a user