将仓储层/基础设施改为 Ent + 原生 SQL 执行路径,并移除 AutoMigrate 与 GORM 依赖。 重构内容包括: - 仓储层改用 Ent/SQL(含 usage_log/account 等复杂查询),统一错误映射 - 基础设施与 setup 初始化切换为 Ent + SQL migrations - 集成测试与 fixtures 迁移到 Ent 事务模型 - 清理遗留 GORM 模型/依赖,补充迁移与文档说明 - 增加根目录 Makefile 便于前后端编译 测试: - go test -tags unit ./... - go test -tags integration ./...
403 lines
12 KiB
Markdown
403 lines
12 KiB
Markdown
# Sub2API Deployment Files
|
|
|
|
This directory contains files for deploying Sub2API on Linux servers.
|
|
|
|
## Deployment Methods
|
|
|
|
| Method | Best For | Setup Wizard |
|
|
|--------|----------|--------------|
|
|
| **Docker Compose** | Quick setup, all-in-one | Not needed (auto-setup) |
|
|
| **Binary Install** | Production servers, systemd | Web-based wizard |
|
|
|
|
## Files
|
|
|
|
| File | Description |
|
|
|------|-------------|
|
|
| `docker-compose.yml` | Docker Compose configuration |
|
|
| `.env.example` | Docker environment variables template |
|
|
| `DOCKER.md` | Docker Hub documentation |
|
|
| `install.sh` | One-click binary installation script |
|
|
| `sub2api.service` | Systemd service unit file |
|
|
| `config.example.yaml` | Example configuration file |
|
|
|
|
---
|
|
|
|
## Docker Deployment (Recommended)
|
|
|
|
### Quick Start
|
|
|
|
```bash
|
|
# Clone repository
|
|
git clone https://github.com/Wei-Shaw/sub2api.git
|
|
cd sub2api/deploy
|
|
|
|
# Configure environment
|
|
cp .env.example .env
|
|
nano .env # Set POSTGRES_PASSWORD (required)
|
|
|
|
# Start all services
|
|
docker-compose up -d
|
|
|
|
# View logs (check for auto-generated admin password)
|
|
docker-compose logs -f sub2api
|
|
|
|
# Access Web UI
|
|
# http://localhost:8080
|
|
```
|
|
|
|
### How Auto-Setup Works
|
|
|
|
When using Docker Compose with `AUTO_SETUP=true`:
|
|
|
|
1. On first run, the system automatically:
|
|
- Connects to PostgreSQL and Redis
|
|
- Applies database migrations (SQL files in `backend/migrations/*.sql`) and records them in `schema_migrations`
|
|
- Generates JWT secret (if not provided)
|
|
- Creates admin account (password auto-generated if not provided)
|
|
- Writes config.yaml
|
|
|
|
2. No manual Setup Wizard needed - just configure `.env` and start
|
|
|
|
3. If `ADMIN_PASSWORD` is not set, check logs for the generated password:
|
|
```bash
|
|
docker-compose logs sub2api | grep "admin password"
|
|
```
|
|
|
|
### Database Migration Notes (PostgreSQL)
|
|
|
|
- Migrations are applied in lexicographic order (e.g. `001_...sql`, `002_...sql`).
|
|
- `schema_migrations` tracks applied migrations (filename + checksum).
|
|
- Migrations are forward-only; rollback requires a DB backup restore or a manual compensating SQL script.
|
|
|
|
**Verify `users.allowed_groups` → `user_allowed_groups` backfill**
|
|
|
|
During the incremental GORM→Ent migration, `users.allowed_groups` (legacy `BIGINT[]`) is being replaced by a normalized join table `user_allowed_groups(user_id, group_id)`.
|
|
|
|
Run this query to compare the legacy data vs the join table:
|
|
|
|
```sql
|
|
WITH old_pairs AS (
|
|
SELECT DISTINCT u.id AS user_id, x.group_id
|
|
FROM users u
|
|
CROSS JOIN LATERAL unnest(u.allowed_groups) AS x(group_id)
|
|
WHERE u.allowed_groups IS NOT NULL
|
|
)
|
|
SELECT
|
|
(SELECT COUNT(*) FROM old_pairs) AS old_pair_count,
|
|
(SELECT COUNT(*) FROM user_allowed_groups) AS new_pair_count;
|
|
```
|
|
|
|
### Commands
|
|
|
|
```bash
|
|
# Start services
|
|
docker-compose up -d
|
|
|
|
# Stop services
|
|
docker-compose down
|
|
|
|
# View logs
|
|
docker-compose logs -f sub2api
|
|
|
|
# Restart Sub2API only
|
|
docker-compose restart sub2api
|
|
|
|
# Update to latest version
|
|
docker-compose pull
|
|
docker-compose up -d
|
|
|
|
# Remove all data (caution!)
|
|
docker-compose down -v
|
|
```
|
|
|
|
### Environment Variables
|
|
|
|
| Variable | Required | Default | Description |
|
|
|----------|----------|---------|-------------|
|
|
| `POSTGRES_PASSWORD` | **Yes** | - | PostgreSQL password |
|
|
| `SERVER_PORT` | No | `8080` | Server port |
|
|
| `ADMIN_EMAIL` | No | `admin@sub2api.local` | Admin email |
|
|
| `ADMIN_PASSWORD` | No | *(auto-generated)* | Admin password |
|
|
| `JWT_SECRET` | No | *(auto-generated)* | JWT secret |
|
|
| `TZ` | No | `Asia/Shanghai` | Timezone |
|
|
| `GEMINI_OAUTH_CLIENT_ID` | No | *(builtin)* | Google OAuth client ID (Gemini OAuth). Leave empty to use the built-in Gemini CLI client. |
|
|
| `GEMINI_OAUTH_CLIENT_SECRET` | No | *(builtin)* | Google OAuth client secret (Gemini OAuth). Leave empty to use the built-in Gemini CLI client. |
|
|
| `GEMINI_OAUTH_SCOPES` | No | *(default)* | OAuth scopes (Gemini OAuth) |
|
|
|
|
See `.env.example` for all available options.
|
|
|
|
---
|
|
|
|
## Gemini OAuth Configuration
|
|
|
|
Sub2API supports three methods to connect to Gemini:
|
|
|
|
### Method 1: Code Assist OAuth (Recommended for GCP Users)
|
|
|
|
**No configuration needed** - always uses the built-in Gemini CLI OAuth client (public).
|
|
|
|
1. Leave `GEMINI_OAUTH_CLIENT_ID` and `GEMINI_OAUTH_CLIENT_SECRET` empty
|
|
2. In the Admin UI, create a Gemini OAuth account and select **"Code Assist"** type
|
|
3. Complete the OAuth flow in your browser
|
|
|
|
> Note: Even if you configure `GEMINI_OAUTH_CLIENT_ID` / `GEMINI_OAUTH_CLIENT_SECRET` for AI Studio OAuth,
|
|
> Code Assist OAuth will still use the built-in Gemini CLI client.
|
|
|
|
**Requirements:**
|
|
- Google account with access to Google Cloud Platform
|
|
- A GCP project (auto-detected or manually specified)
|
|
|
|
**How to get Project ID (if auto-detection fails):**
|
|
1. Go to [Google Cloud Console](https://console.cloud.google.com/)
|
|
2. Click the project dropdown at the top of the page
|
|
3. Copy the Project ID (not the project name) from the list
|
|
4. Common formats: `my-project-123456` or `cloud-ai-companion-xxxxx`
|
|
|
|
### Method 2: AI Studio OAuth (For Regular Google Accounts)
|
|
|
|
Requires your own OAuth client credentials.
|
|
|
|
**Step 1: Create OAuth Client in Google Cloud Console**
|
|
|
|
1. Go to [Google Cloud Console - Credentials](https://console.cloud.google.com/apis/credentials)
|
|
2. Create a new project or select an existing one
|
|
3. **Enable the Generative Language API:**
|
|
- Go to "APIs & Services" → "Library"
|
|
- Search for "Generative Language API"
|
|
- Click "Enable"
|
|
4. **Configure OAuth Consent Screen** (if not done):
|
|
- Go to "APIs & Services" → "OAuth consent screen"
|
|
- Choose "External" user type
|
|
- Fill in app name, user support email, developer contact
|
|
- Add scopes: `https://www.googleapis.com/auth/generative-language.retriever` (and optionally `https://www.googleapis.com/auth/cloud-platform`)
|
|
- Add test users (your Google account email)
|
|
5. **Create OAuth 2.0 credentials:**
|
|
- Go to "APIs & Services" → "Credentials"
|
|
- Click "Create Credentials" → "OAuth client ID"
|
|
- Application type: **Web application** (or **Desktop app**)
|
|
- Name: e.g., "Sub2API Gemini"
|
|
- Authorized redirect URIs: Add `http://localhost:1455/auth/callback`
|
|
6. Copy the **Client ID** and **Client Secret**
|
|
7. **⚠️ Publish to Production (IMPORTANT):**
|
|
- Go to "APIs & Services" → "OAuth consent screen"
|
|
- Click "PUBLISH APP" to move from Testing to Production
|
|
- **Testing mode limitations:**
|
|
- Only manually added test users can authenticate (max 100 users)
|
|
- Refresh tokens expire after 7 days
|
|
- Users must be re-added periodically
|
|
- **Production mode:** Any Google user can authenticate, tokens don't expire
|
|
- Note: For sensitive scopes, Google may require verification (demo video, privacy policy)
|
|
|
|
**Step 2: Configure Environment Variables**
|
|
|
|
```bash
|
|
GEMINI_OAUTH_CLIENT_ID=your-client-id.apps.googleusercontent.com
|
|
GEMINI_OAUTH_CLIENT_SECRET=GOCSPX-your-client-secret
|
|
```
|
|
|
|
**Step 3: Create Account in Admin UI**
|
|
|
|
1. Create a Gemini OAuth account and select **"AI Studio"** type
|
|
2. Complete the OAuth flow
|
|
- After consent, your browser will be redirected to `http://localhost:1455/auth/callback?code=...&state=...`
|
|
- Copy the full callback URL (recommended) or just the `code` and paste it back into the Admin UI
|
|
|
|
### Method 3: API Key (Simplest)
|
|
|
|
1. Go to [Google AI Studio](https://aistudio.google.com/app/apikey)
|
|
2. Click "Create API key"
|
|
3. In Admin UI, create a Gemini **API Key** account
|
|
4. Paste your API key (starts with `AIza...`)
|
|
|
|
### Comparison Table
|
|
|
|
| Feature | Code Assist OAuth | AI Studio OAuth | API Key |
|
|
|---------|-------------------|-----------------|---------|
|
|
| Setup Complexity | Easy (no config) | Medium (OAuth client) | Easy |
|
|
| GCP Project Required | Yes | No | No |
|
|
| Custom OAuth Client | No (built-in) | Yes (required) | N/A |
|
|
| Rate Limits | GCP quota | Standard | Standard |
|
|
| Best For | GCP developers | Regular users needing OAuth | Quick testing |
|
|
|
|
---
|
|
|
|
## Binary Installation
|
|
|
|
For production servers using systemd.
|
|
|
|
### One-Line Installation
|
|
|
|
```bash
|
|
curl -sSL https://raw.githubusercontent.com/Wei-Shaw/sub2api/main/deploy/install.sh | sudo bash
|
|
```
|
|
|
|
### Manual Installation
|
|
|
|
1. Download the latest release from [GitHub Releases](https://github.com/Wei-Shaw/sub2api/releases)
|
|
2. Extract and copy the binary to `/opt/sub2api/`
|
|
3. Copy `sub2api.service` to `/etc/systemd/system/`
|
|
4. Run:
|
|
```bash
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable sub2api
|
|
sudo systemctl start sub2api
|
|
```
|
|
5. Open the Setup Wizard in your browser to complete configuration
|
|
|
|
### Commands
|
|
|
|
```bash
|
|
# Install
|
|
sudo ./install.sh
|
|
|
|
# Upgrade
|
|
sudo ./install.sh upgrade
|
|
|
|
# Uninstall
|
|
sudo ./install.sh uninstall
|
|
```
|
|
|
|
### Service Management
|
|
|
|
```bash
|
|
# Start the service
|
|
sudo systemctl start sub2api
|
|
|
|
# Stop the service
|
|
sudo systemctl stop sub2api
|
|
|
|
# Restart the service
|
|
sudo systemctl restart sub2api
|
|
|
|
# Check status
|
|
sudo systemctl status sub2api
|
|
|
|
# View logs
|
|
sudo journalctl -u sub2api -f
|
|
|
|
# Enable auto-start on boot
|
|
sudo systemctl enable sub2api
|
|
```
|
|
|
|
### Configuration
|
|
|
|
#### Server Address and Port
|
|
|
|
During installation, you will be prompted to configure the server listen address and port. These settings are stored in the systemd service file as environment variables.
|
|
|
|
To change after installation:
|
|
|
|
1. Edit the systemd service:
|
|
```bash
|
|
sudo systemctl edit sub2api
|
|
```
|
|
|
|
2. Add or modify:
|
|
```ini
|
|
[Service]
|
|
Environment=SERVER_HOST=0.0.0.0
|
|
Environment=SERVER_PORT=3000
|
|
```
|
|
|
|
3. Reload and restart:
|
|
```bash
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl restart sub2api
|
|
```
|
|
|
|
#### Gemini OAuth Configuration
|
|
|
|
If you need to use AI Studio OAuth for Gemini accounts, add the OAuth client credentials to the systemd service file:
|
|
|
|
1. Edit the service file:
|
|
```bash
|
|
sudo nano /etc/systemd/system/sub2api.service
|
|
```
|
|
|
|
2. Add your OAuth credentials in the `[Service]` section (after the existing `Environment=` lines):
|
|
```ini
|
|
Environment=GEMINI_OAUTH_CLIENT_ID=your-client-id.apps.googleusercontent.com
|
|
Environment=GEMINI_OAUTH_CLIENT_SECRET=GOCSPX-your-client-secret
|
|
```
|
|
|
|
3. Reload and restart:
|
|
```bash
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl restart sub2api
|
|
```
|
|
|
|
> **Note:** Code Assist OAuth does not require any configuration - it uses the built-in Gemini CLI client.
|
|
> See the [Gemini OAuth Configuration](#gemini-oauth-configuration) section above for detailed setup instructions.
|
|
|
|
#### Application Configuration
|
|
|
|
The main config file is at `/etc/sub2api/config.yaml` (created by Setup Wizard).
|
|
|
|
### Prerequisites
|
|
|
|
- Linux server (Ubuntu 20.04+, Debian 11+, CentOS 8+, etc.)
|
|
- PostgreSQL 14+
|
|
- Redis 6+
|
|
- systemd
|
|
|
|
### Directory Structure
|
|
|
|
```
|
|
/opt/sub2api/
|
|
├── sub2api # Main binary
|
|
├── sub2api.backup # Backup (after upgrade)
|
|
└── data/ # Runtime data
|
|
|
|
/etc/sub2api/
|
|
└── config.yaml # Configuration file
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Docker
|
|
|
|
```bash
|
|
# Check container status
|
|
docker-compose ps
|
|
|
|
# View detailed logs
|
|
docker-compose logs --tail=100 sub2api
|
|
|
|
# Check database connection
|
|
docker-compose exec postgres pg_isready
|
|
|
|
# Check Redis connection
|
|
docker-compose exec redis redis-cli ping
|
|
|
|
# Restart all services
|
|
docker-compose restart
|
|
```
|
|
|
|
### Binary Install
|
|
|
|
```bash
|
|
# Check service status
|
|
sudo systemctl status sub2api
|
|
|
|
# View recent logs
|
|
sudo journalctl -u sub2api -n 50
|
|
|
|
# Check config file
|
|
sudo cat /etc/sub2api/config.yaml
|
|
|
|
# Check PostgreSQL
|
|
sudo systemctl status postgresql
|
|
|
|
# Check Redis
|
|
sudo systemctl status redis
|
|
```
|
|
|
|
### Common Issues
|
|
|
|
1. **Port already in use**: Change `SERVER_PORT` in `.env` or systemd config
|
|
2. **Database connection failed**: Check PostgreSQL is running and credentials are correct
|
|
3. **Redis connection failed**: Check Redis is running and password is correct
|
|
4. **Permission denied**: Ensure proper file ownership for binary install
|