|
|
1 kuukausi sitten | |
|---|---|---|
| .. | ||
| __pycache__ | 1 kuukausi sitten | |
| tests | 1 kuukausi sitten | |
| .gitignore | 1 kuukausi sitten | |
| APPLE_CONTAINER.md | 1 kuukausi sitten | |
| Caddyfile | 1 kuukausi sitten | |
| Caddyfile.juhe.pub | 1 kuukausi sitten | |
| DATAMANAGEMENTD_CN.md | 1 kuukausi sitten | |
| DOCKER.md | 1 kuukausi sitten | |
| Dockerfile | 1 kuukausi sitten | |
| EDGE_SECURITY.md | 1 kuukausi sitten | |
| Makefile | 1 kuukausi sitten | |
| README.md | 1 kuukausi sitten | |
| activate-optional-release.py | 1 kuukausi sitten | |
| apple-container.sh | 1 kuukausi sitten | |
| build-relay.sh | 1 kuukausi sitten | |
| build_image.sh | 1 kuukausi sitten | |
| check-optional-release.py | 1 kuukausi sitten | |
| codex-instructions.md.tmpl | 1 kuukausi sitten | |
| compose.relay.yml | 1 kuukausi sitten | |
| config.example.yaml | 1 kuukausi sitten | |
| docker-compose.dev.yml | 1 kuukausi sitten | |
| docker-compose.local.yml | 1 kuukausi sitten | |
| docker-compose.standalone.yml | 1 kuukausi sitten | |
| docker-compose.yml | 1 kuukausi sitten | |
| docker-deploy.sh | 1 kuukausi sitten | |
| docker-entrypoint.sh | 1 kuukausi sitten | |
| init-relay-env.py | 1 kuukausi sitten | |
| install-datamanagementd.sh | 1 kuukausi sitten | |
| install.sh | 1 kuukausi sitten | |
| prepare-optional-release.py | 1 kuukausi sitten | |
| relay.env.example | 1 kuukausi sitten | |
| smoke-relay.py | 1 kuukausi sitten | |
| sub2api-datamanagementd.service | 1 kuukausi sitten | |
| sub2api.service | 1 kuukausi sitten | |
| test-caddyfile-cache.sh | 1 kuukausi sitten | |
| verify-optional-stage.py | 1 kuukausi sitten | |
This directory contains files for deploying Sub2API on Linux servers and Apple-silicon Macs.
| Method | Best For | Setup Wizard |
|---|---|---|
| Docker Compose | Quick setup, all-in-one | Not needed (auto-setup) |
| Apple container | Native local stack on macOS 26 | Not needed (auto-setup) |
| Binary Install | Production servers, systemd | Web-based wizard |
| File | Description |
|---|---|
docker-compose.yml |
Docker Compose configuration (named volumes) |
docker-compose.local.yml |
Docker Compose configuration (local directories, easy migration) |
docker-deploy.sh |
One-click Docker deployment script (recommended) |
apple-container.sh |
Native Apple container lifecycle script |
APPLE_CONTAINER.md |
Apple container deployment and operations guide |
.env.example |
Container environment variables template |
DOCKER.md |
Docker Hub documentation |
install.sh |
One-click binary installation script |
install-datamanagementd.sh |
datamanagementd 一键安装脚本 |
sub2api.service |
Systemd service unit file |
sub2api-datamanagementd.service |
datamanagementd systemd service unit file |
DATAMANAGEMENTD_CN.md |
datamanagementd 部署与联动说明(中文) |
config.example.yaml |
Example configuration file |
EDGE_SECURITY.md |
Reverse proxy, CDN/WAF, trusted proxy, and ingress hardening guide |
Apple-silicon Macs running macOS 26 can run the complete Sub2API, PostgreSQL, and Redis stack with Apple container 1.1.0 or newer:
./apple-container.sh init
./apple-container.sh up
./apple-container.sh status
./apple-container.sh logs app -f
The script uses Apple named volumes, starts dependencies in order, and performs live readiness checks. It does not provide a continuous restart supervisor; run ./apple-container.sh up after a host reboot. Docker Compose remains the recommended production deployment path.
See APPLE_CONTAINER.md for configuration, upgrades, persistence, networking behavior, and limitations.
Use the automated preparation script for the easiest setup:
# Download and run the preparation script
curl -sSL https://raw.githubusercontent.com/Wei-Shaw/sub2api/main/deploy/docker-deploy.sh | bash
# Or download first, then run
curl -sSL https://raw.githubusercontent.com/Wei-Shaw/sub2api/main/deploy/docker-deploy.sh -o docker-deploy.sh
chmod +x docker-deploy.sh
./docker-deploy.sh
What the script does:
docker-compose.local.yml and .env.example.env file with generated secretsAfter running the script:
# Start services
docker compose -f docker-compose.local.yml up -d
# View logs
docker compose -f docker-compose.local.yml logs -f sub2api
# If admin password was auto-generated, find it in logs:
docker compose -f docker-compose.local.yml logs sub2api | grep "admin password"
# Access Web UI
# http://localhost:8080
If you prefer manual control:
# Clone repository
git clone https://github.com/Wei-Shaw/sub2api.git
cd sub2api/deploy
# Configure environment
cp .env.example .env
chmod 600 .env
nano .env # Set POSTGRES_PASSWORD and other required variables
# Generate secure secrets (recommended)
JWT_SECRET=$(openssl rand -hex 32)
TOTP_ENCRYPTION_KEY=$(openssl rand -hex 32)
echo "JWT_SECRET=${JWT_SECRET}" >> .env
echo "TOTP_ENCRYPTION_KEY=${TOTP_ENCRYPTION_KEY}" >> .env
# Create data directories
mkdir -p data postgres_data redis_data
# Start all services using local directory version
docker compose -f docker-compose.local.yml up -d
# View logs (check for auto-generated admin password)
docker compose -f docker-compose.local.yml logs -f sub2api
# Access Web UI
# http://localhost:8080
| Version | Data Storage | Migration | Best For |
|---|---|---|---|
| docker-compose.local.yml | Local directories (./data, ./postgres_data, ./redis_data) | ✅ Easy (tar entire directory) | Production, need frequent backups/migration |
| docker-compose.yml | Named volumes (/var/lib/docker/volumes/) | ⚠️ Requires docker commands | Simple setup, don't need migration |
Recommendation: Use docker-compose.local.yml (deployed by docker-deploy.sh) for easier data management and migration.
When using Docker Compose with AUTO_SETUP=true:
On first run, the system automatically:
backend/migrations/*.sql) and records them in schema_migrationsNo manual Setup Wizard needed - just configure .env and start
If ADMIN_PASSWORD is not set, check logs for the generated password:
docker compose logs sub2api | grep "admin password"
Sub2API applies database migrations during application startup. PostgreSQL can remain in its recovery/startup phase briefly after a host or Docker daemon restart. The application retries transient PostgreSQL startup and connection errors with bounded exponential backoff, then starts automatically when the database becomes ready. Authentication errors, migration checksum mismatches, SQL errors, and other permanent configuration or data errors fail immediately.
The Compose example also uses a PostgreSQL health check that verifies both
server readiness and a simple SQL query. depends_on: condition: service_healthy
controls dependency ordering for a fresh Compose start, but it is not a
replacement for application-level retries when Docker restores existing
containers after a host restart.
For systemd deployments, keep Restart=always and RestartSec configured in
sub2api.service; the application retry covers transient database startup,
while systemd remains the supervisor for permanent process exits. For
Kubernetes, use a PostgreSQL readiness probe and retain the Sub2API startup
retry behavior; configure the application liveness probe separately so a
database recovery period is not treated as a permanent process failure.
001_...sql, 002_...sql).schema_migrations tracks applied migrations (filename + checksum).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:
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;
如需启用管理后台“数据管理”功能,请额外部署宿主机 datamanagementd:
/tmp/sub2api-datamanagement.sockdeploy/DATAMANAGEMENTD_CN.mdFor local directory version (docker-compose.local.yml):
# Start services
docker compose -f docker-compose.local.yml up -d
# Stop services
docker compose -f docker-compose.local.yml down
# View logs
docker compose -f docker-compose.local.yml logs -f sub2api
# Restart Sub2API only
docker compose -f docker-compose.local.yml restart sub2api
# Update to latest version
docker compose -f docker-compose.local.yml pull
docker compose -f docker-compose.local.yml up -d
# Remove all data (caution!)
docker compose -f docker-compose.local.yml down
rm -rf data/ postgres_data/ redis_data/
For named volumes version (docker-compose.yml):
# 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
| Variable | Required | Default | Description |
|---|---|---|---|
POSTGRES_PASSWORD |
Yes | - | PostgreSQL password |
JWT_SECRET |
Recommended | (auto-generated) | JWT secret (fixed for persistent sessions) |
TOTP_ENCRYPTION_KEY |
Recommended | (auto-generated) | TOTP encryption key (fixed for persistent 2FA) |
SERVER_PORT |
No | 8080 |
Server port |
ADMIN_EMAIL |
No | admin@sub2api.local |
Admin email |
ADMIN_PASSWORD |
No | (auto-generated) | Admin password |
TZ |
No | Asia/Shanghai |
Timezone |
UPDATE_GITHUB_TOKEN |
No | (empty) | Token for api.github.com release checks only; asset downloads remain anonymous. |
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) |
GEMINI_QUOTA_POLICY |
No | (empty) | JSON overrides for Gemini local quota simulation (Code Assist only). |
See .env.example for all available options.
Note: The
docker-deploy.shscript automatically generatesJWT_SECRET,TOTP_ENCRYPTION_KEY, andPOSTGRES_PASSWORDfor you.
When using docker-compose.local.yml, all data is stored in local directories, making migration simple:
# On source server: Stop services and create archive
cd /path/to/deployment
docker compose -f docker-compose.local.yml down
cd ..
tar czf sub2api-complete.tar.gz deployment/
# Transfer to new server
scp sub2api-complete.tar.gz user@new-server:/path/to/destination/
# On new server: Extract and start
tar xzf sub2api-complete.tar.gz
cd deployment/
docker compose -f docker-compose.local.yml up -d
Your entire deployment (configuration + data) is migrated!
Sub2API supports three methods to connect to Gemini:
No configuration needed - always uses the built-in Gemini CLI OAuth client (public).
GEMINI_OAUTH_CLIENT_ID and GEMINI_OAUTH_CLIENT_SECRET emptyNote: Even if you configure
GEMINI_OAUTH_CLIENT_ID/GEMINI_OAUTH_CLIENT_SECRETfor AI Studio OAuth, Code Assist OAuth will still use the built-in Gemini CLI client.
Requirements:
How to get Project ID (if auto-detection fails):
my-project-123456 or cloud-ai-companion-xxxxxRequires your own OAuth client credentials.
Step 1: Create OAuth Client in Google Cloud Console
https://www.googleapis.com/auth/generative-language.retriever (and optionally https://www.googleapis.com/auth/cloud-platform)http://localhost:1455/auth/callbackStep 2: Configure Environment Variables
GEMINI_OAUTH_CLIENT_ID=your-client-id.apps.googleusercontent.com
GEMINI_OAUTH_CLIENT_SECRET=GOCSPX-your-client-secret
# 可选:如需使用 Gemini CLI 内置 OAuth Client(Code Assist / Google One)
# 安全说明:本仓库不会内置该 client_secret,请在运行环境通过环境变量注入。
# GEMINI_CLI_OAUTH_CLIENT_SECRET=GOCSPX-your-built-in-secret
Step 3: Create Account in Admin UI
http://localhost:1455/auth/callback?code=...&state=...code and paste it back into the Admin UIAIza...)| 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 |
For production servers using systemd.
curl -sSL https://raw.githubusercontent.com/Wei-Shaw/sub2api/main/deploy/install.sh | sudo bash
/opt/sub2api/sub2api.service to /etc/systemd/system/Run:
sudo systemctl daemon-reload
sudo systemctl enable sub2api
sudo systemctl start sub2api
Open the Setup Wizard in your browser to complete configuration
# Install
sudo ./install.sh
# Upgrade
sudo ./install.sh upgrade
# Uninstall
sudo ./install.sh uninstall
# 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
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:
Edit the systemd service:
sudo systemctl edit sub2api
Add or modify:
[Service]
Environment=SERVER_HOST=0.0.0.0
Environment=SERVER_PORT=3000
Reload and restart:
sudo systemctl daemon-reload
sudo systemctl restart sub2api
If you need to use AI Studio OAuth for Gemini accounts, add the OAuth client credentials to the systemd service file:
Edit the service file:
sudo nano /etc/systemd/system/sub2api.service
Add your OAuth credentials in the [Service] section (after the existing Environment= lines):
Environment=GEMINI_OAUTH_CLIENT_ID=your-client-id.apps.googleusercontent.com
Environment=GEMINI_OAUTH_CLIENT_SECRET=GOCSPX-your-client-secret
如需使用“内置 Gemini CLI OAuth Client”(Code Assist / Google One),还需要注入:
Environment=GEMINI_CLI_OAUTH_CLIENT_SECRET=GOCSPX-your-built-in-secret
Reload and restart:
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 section above for detailed setup instructions.
The main config file is at /etc/sub2api/config.yaml (created by Setup Wizard).
/opt/sub2api/
├── sub2api # Main binary
├── sub2api.backup # Backup (after upgrade)
└── data/ # Runtime data
/etc/sub2api/
└── config.yaml # Configuration file
For local directory version:
# Check container status
docker compose -f docker-compose.local.yml ps
# View detailed logs
docker compose -f docker-compose.local.yml logs --tail=100 sub2api
# Check database connection
docker compose -f docker-compose.local.yml exec postgres pg_isready
# Check Redis connection
docker compose -f docker-compose.local.yml exec redis redis-cli ping
# Restart all services
docker compose -f docker-compose.local.yml restart
# Check data directories
ls -la data/ postgres_data/ redis_data/
For named volumes version:
# 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
# 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
SERVER_PORT in .env or systemd configSub2API supports TLS fingerprint simulation to make requests appear as if they come from the official Claude CLI (Node.js client).
💡 Tip: Visit tls.sub2api.org to get TLS fingerprint information for different devices and browsers.
claude_cli_v2 profile simulates Node.js 20.x + OpenSSL 3.x1a28e69016765d92e3b381168d68922ct13d5911h1_a33745022dd6_1f22a2ca17c4accountID % profileCountgateway:
tls_fingerprint:
enabled: true # Global switch
profiles:
# Simple profile (uses default cipher suites)
profile_1:
name: "Profile 1"
# Profile with custom cipher suites (use compact array format)
profile_2:
name: "Profile 2"
cipher_suites: [4866, 4867, 4865, 49199, 49195, 49200, 49196]
curves: [29, 23, 24]
point_formats: 0
# Another custom profile
profile_3:
name: "Profile 3"
cipher_suites: [4865, 4866, 4867, 49199, 49200]
curves: [29, 23, 24, 25]
| Field | Type | Description |
|---|---|---|
name |
string | Display name (required) |
cipher_suites |
[]uint16 | Cipher suites in decimal. Empty = default |
curves |
[]uint16 | Elliptic curves in decimal. Empty = default |
point_formats |
[]uint8 | EC point formats. Empty = default |
Cipher Suites (TLS 1.3): 4865 (AES_128_GCM), 4866 (AES_256_GCM), 4867 (CHACHA20)
Cipher Suites (TLS 1.2): 49195, 49196, 49199, 49200 (ECDHE variants)
Curves: 29 (X25519), 23 (P-256), 24 (P-384), 25 (P-521)