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
83 changes: 82 additions & 1 deletion .env.production.example
Original file line number Diff line number Diff line change
@@ -1,28 +1,109 @@
# ============================================================================
# ============================================================================
# 生产环境配置模板
# 复制此文件到服务器 /opt/chicken-king/.env 并填入真实值
# ============================================================================

# MySQL 数据库
# MySQL root 密码
MYSQL_ROOT_PASSWORD=your_secure_root_password
# MySQL 数据库名
MYSQL_DATABASE=chicken_king
# MySQL 应用用户
MYSQL_USER=chicken
# MySQL 用户密码
MYSQL_PASSWORD=your_secure_password

# 应用密钥(用于 JWT 签名,请使用随机字符串)
SECRET_KEY=your_64_char_random_secret_key_here

# Worker 状态回写 Token(用于 Worker 回写状态接口鉴权)
WORKER_API_TOKEN=your_worker_api_token

# 作品容器资源限制(部署时由 Worker 使用)
WORKER_CONTAINER_MEMORY_LIMIT=512m
WORKER_CONTAINER_CPU_LIMIT=0.5
WORKER_CONTAINER_PIDS_LIMIT=128
WORKER_CONTAINER_LOG_MAX_SIZE=10m
WORKER_CONTAINER_LOG_MAX_FILE=3

# 是否在后端容器启动时自动执行数据库迁移(建议开启)
AUTO_MIGRATE=true
# 迁移基线版本(仅在旧库且无 schema_migrations 时使用,例如:034 或 034_contest_content)
MIGRATION_BASELINE_VERSION=

# 限流与风控
# 限流存储地址
RATE_LIMIT_STORAGE_URI=redis://redis:6379/1
# 单用户每日上传总量上限(字节)
UPLOAD_DAILY_BYTES_LIMIT=3221225472
# 触发式挑战模式:off/monitor/enforce
SECURITY_CHALLENGE_MODE=off
# 挑战提供方:pow/js/captcha/behavior
SECURITY_CHALLENGE_PROVIDER=pow
# 触发阈值(窗口内请求数)
SECURITY_CHALLENGE_THRESHOLD=20
# 统计窗口(秒)
SECURITY_CHALLENGE_WINDOW_SECONDS=60
# 挑战有效期(秒)
SECURITY_CHALLENGE_TTL_SECONDS=300
# 通过后免验证时间(秒)
SECURITY_CHALLENGE_PASS_TTL_SECONDS=1800
# PoW 难度(十六进制前导 0 个数)
SECURITY_POW_DIFFICULTY=4
# 验证码校验地址(如 Turnstile/hCaptcha)
CAPTCHA_VERIFY_URL=
# 验证码服务密钥
CAPTCHA_SECRET_KEY=
# 验证码站点 key
CAPTCHA_SITE_KEY=
# 忘记密码重置链接有效期(分钟)
PASSWORD_RESET_TOKEN_TTL_MINUTES=30
# SMTP 服务器地址
SMTP_HOST=
# SMTP 端口
SMTP_PORT=587
# SMTP 账号
SMTP_USERNAME=
# SMTP 密码
SMTP_PASSWORD=
# 是否启用 STARTTLS
SMTP_USE_TLS=true
# 是否启用 SSL(如 465 端口)
SMTP_USE_SSL=false
# 发件人邮箱
SMTP_FROM_EMAIL=
# 发件人显示名(可选)
SMTP_FROM_NAME=
# 是否启用可信代理解析(TODO: CDN/WAF 接入后开启)
TRUSTED_PROXY_ENABLED=false
# 可信代理头(优先级顺序)
TRUSTED_PROXY_HEADERS=cf-connecting-ip,x-forwarded-for,x-real-ip

# 前端 URL
FRONTEND_URL=https://pk.ikuncode.cc

# 媒体文件存储目录(容器内路径)
MEDIA_ROOT=/app/app/uploads/media

# 作品访问域名后缀(生成 project-{submission_id}.your-domain.com)
PROJECT_DOMAIN_SUFFIX=your-domain.com
# 作品访问域名模板(默认即可)
PROJECT_DOMAIN_TEMPLATE=project-{submission_id}.{suffix}

# Linux.do OAuth
# Client ID
LINUX_DO_CLIENT_ID=your_client_id
# Client Secret
LINUX_DO_CLIENT_SECRET=your_client_secret
# 回调地址
LINUX_DO_REDIRECT_URI=https://pk.ikuncode.cc/api/v1/auth/linuxdo/callback

# GitHub OAuth
# Client ID
GITHUB_CLIENT_ID=your_github_client_id
# Client Secret
GITHUB_CLIENT_SECRET=your_github_client_secret
# 回调地址
GITHUB_REDIRECT_URI=https://pk.ikuncode.cc/api/v1/auth/github/callback

# 前端 API URL(生产环境使用相对路径)
Expand Down
15 changes: 15 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,21 @@ venv/
.env.prod
*.env

# 本地临时与密钥
.ssh/
.tmp/
.sync.tar.gz
.spec-workflow/

# 媒体上传目录
backend/app/uploads/

# 本地文档
docs/进度与待办.md
待办清单.md
readme2.md
CODE_REVIEW_REPORT.md

# Build
dist/
build/
Expand Down
52 changes: 34 additions & 18 deletions DEPLOY.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@
```
鸡王争霸赛/
├── docker-compose.prod.yml # 生产环境编排
├── .env.production.example # 环境变量模板
├── .env.production.example # 环境变量模板(复制为 .env)
├── deploy/
│ └── webhook/ # GitHub Webhook 自动部署
├── nginx/
│ ├── nginx.prod.conf # Nginx 反向代理配置
│ ├── ssl/ # SSL 证书目录
│ └── logs/ # Nginx 日志
├── backend/
│ ├── Dockerfile.prod # 后端生产镜像
│ └── sql/init/ # 数据库初始化脚本
│ └── sql/ # 数据库迁移脚本
└── frontend/
├── Dockerfile.prod # 前端生产镜像
└── nginx.conf # 前端容器 Nginx 配置
Expand Down Expand Up @@ -43,10 +45,10 @@ cd chicken-king

```bash
# 复制模板
cp .env.production.example .env.production
cp .env.production.example .env

# 编辑配置(重要!)
nano .env.production
nano .env
```

**必须修改的配置项:**
Expand All @@ -61,6 +63,20 @@ nano .env.production
| `LINUX_DO_CLIENT_SECRET` | Linux.do OAuth | 从 connect.linux.do 获取 |
| `LINUX_DO_REDIRECT_URI` | OAuth 回调地址 | `https://your-domain.com/api/v1/auth/linuxdo/callback` |

### 3.5 数据库迁移(自动)

生产环境默认启用自动迁移(`AUTO_MIGRATE=true`),后端容器启动时会:
- 空库导入 `backend/sql/production_clean_db.sql`(或回退 `schema.sql` + `seed_production_config.sql`)
- 旧库按 `backend/sql/NNN_*.sql` 增量执行

如旧库已存在历史迁移但无 `schema_migrations`,可在 `.env` 设置 `MIGRATION_BASELINE_VERSION=XXX` 作为基线。

### 3.6 部署前检查清单

- `.env` 已更新必要配置
- Nginx 证书与域名解析已准备
- 数据库迁移脚本已执行或初始化脚本已替换

### 4. 配置域名和 SSL

#### 方式一:使用 Let's Encrypt(推荐)
Expand Down Expand Up @@ -114,13 +130,13 @@ server {

```bash
# 构建并启动所有服务
docker-compose -f docker-compose.prod.yml --env-file .env.production up -d --build
docker compose -f docker-compose.prod.yml up -d --build

# 查看服务状态
docker-compose -f docker-compose.prod.yml ps
docker compose -f docker-compose.prod.yml ps

# 查看日志
docker-compose -f docker-compose.prod.yml logs -f
docker compose -f docker-compose.prod.yml logs -f
```

### 6. 验证部署
Expand All @@ -130,11 +146,11 @@ docker-compose -f docker-compose.prod.yml logs -f
curl http://localhost/health

# 检查 API
curl http://localhost/api/v1/health
curl http://localhost/api/v1/contests/

# 查看各服务日志
docker-compose -f docker-compose.prod.yml logs backend
docker-compose -f docker-compose.prod.yml logs nginx
docker compose -f docker-compose.prod.yml logs backend
docker compose -f docker-compose.prod.yml logs nginx
```

## 常用运维命令
Expand All @@ -143,14 +159,14 @@ docker-compose -f docker-compose.prod.yml logs nginx

```bash
# 停止服务
docker-compose -f docker-compose.prod.yml down
docker compose -f docker-compose.prod.yml down

# 重启单个服务
docker-compose -f docker-compose.prod.yml restart backend
docker compose -f docker-compose.prod.yml restart backend

# 更新部署
git pull
docker-compose -f docker-compose.prod.yml up -d --build
docker compose -f docker-compose.prod.yml up -d --build

# 查看资源使用
docker stats
Expand Down Expand Up @@ -186,7 +202,7 @@ tail -f nginx/logs/error.log

```bash
# 使用 analytics profile 启动
docker-compose -f docker-compose.prod.yml --env-file .env.production --profile analytics up -d
docker compose -f docker-compose.prod.yml --profile analytics up -d

# Umami 默认访问地址
# http://your-domain.com:3001
Expand All @@ -210,8 +226,8 @@ docker-compose -f docker-compose.prod.yml --env-file .env.production --profile a
sudo apt update && sudo apt upgrade -y

# 更新 Docker 镜像
docker-compose -f docker-compose.prod.yml pull
docker-compose -f docker-compose.prod.yml up -d
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d
```

3. **数据备份**
Expand All @@ -228,7 +244,7 @@ docker-compose -f docker-compose.prod.yml --env-file .env.production --profile a

# 复制新证书
sudo cp /etc/letsencrypt/live/your-domain.com/*.pem nginx/ssl/
docker-compose -f docker-compose.prod.yml restart nginx
docker compose -f docker-compose.prod.yml restart nginx
```

## 故障排除
Expand All @@ -240,7 +256,7 @@ docker-compose -f docker-compose.prod.yml --env-file .env.production --profile a
sudo netstat -tlnp | grep -E '80|443|8000|3306'

# 检查 Docker 日志
docker-compose -f docker-compose.prod.yml logs --tail=100
docker compose -f docker-compose.prod.yml logs --tail=100
```

### 数据库连接失败
Expand Down
41 changes: 38 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

## 功能特性

- **Linux.do OAuth 登录** - 一键授权登录
- **本地账号** - 注册/登录/找回密码
- **第三方登录/绑定** - Linux.do / GitHub OAuth
- **账号安全** - 修改/设置密码、绑定冲突提示
- **比赛报名** - 选手报名与审核
- **作品提交** - 支持附件上传
- **投票系统** - 为喜欢的作品投票
Expand Down Expand Up @@ -44,7 +46,13 @@
│ ├── sql/ # 数据库迁移脚本
│ └── requirements.txt
└── docker-compose.yml # Docker 编排(含 Umami)
├── deploy/ # 部署脚本与 Webhook 服务
│ └── webhook/ # GitHub Webhook 自动部署
├── nginx/ # Nginx 生产反代
├── docs/ # 项目文档
├── docker-compose.yml # 本地开发编排
├── docker-compose.prod.yml # 生产环境编排
└── .env.production.example # 生产环境变量模板
```

## 技术栈
Expand Down Expand Up @@ -136,9 +144,25 @@ npm run dev
### 4. Docker 一键启动

```bash
# 复制环境变量模板到项目根目录(Docker Compose 会读取此 .env)
cp .env.production.example .env
# 编辑 .env 填写真实配置(如 MySQL/SECRET_KEY/OAuth 等)

docker-compose up -d
```

生产环境可使用(与自动部署保持一致):

```bash
docker compose -f docker-compose.prod.yml up -d --build
```

> 说明:生产环境只使用 `docker-compose.prod.yml`,避免与开发配置互相覆盖。
> `.env` 由 Compose 自动读取并注入到容器中,`DATABASE_URL/REDIS_URL` 由 Compose 组合生成,无需在 `.env` 中重复填写。
> 后端容器启动时会自动执行迁移(`AUTO_MIGRATE=true`)。

> 生产环境建议使用 GitHub Webhook 自动部署,详见 `docs/AUTO_DEPLOY.md`。

## 网站统计(Umami)

### 部署 Umami
Expand Down Expand Up @@ -180,8 +204,17 @@ VITE_UMAMI_WEBSITE_ID=你的网站ID

## 环境变量

### Docker Compose(项目根目录 `.env`)

- 适用于 `docker-compose.yml` / `docker-compose.prod.yml`
- 入口文件:项目根目录 `.env`(可从 `.env.production.example` 复制并填写)
- 由 Compose 注入到 backend/worker 容器
- `DATABASE_URL/REDIS_URL` 已在 Compose 中拼接,无需在 `.env` 里写

### 后端 (`backend/.env`)

> 仅用于本地非 Docker 启动(如 `uvicorn` 直接运行)

```bash
DEBUG=true
SECRET_KEY=your-secret-key
Expand All @@ -200,6 +233,8 @@ GITHUB_CLIENT_SECRET=xxx
GITHUB_TOKEN=xxx
```

> 其他配置项(如 SMTP、触发式安全挑战、上传配额、Worker 等)详见 `backend/.env.example`。

### 前端 (`frontend/.env`)

```bash
Expand Down Expand Up @@ -234,7 +269,7 @@ docker-compose down # 停止所有服务

| 模块 | 前缀 | 功能 |
|------|------|------|
| auth | `/auth` | Linux.do/GitHub OAuth |
| auth | `/auth` | 本地注册/登录/刷新/找回密码 + Linux.do/GitHub OAuth 绑定 |
| users | `/users` | 用户信息、成就 |
| contests | `/contests` | 比赛管理 |
| submissions | `/submissions` | 作品提交 |
Expand Down
Loading