diff --git a/apps/sub2api/0.1.147/scripts/init.sh b/apps/sub2api/0.1.147/scripts/init.sh deleted file mode 100755 index 51bfe1764..000000000 --- a/apps/sub2api/0.1.147/scripts/init.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -set -euo pipefail - -# 当前适配使用 1Panel 数据库 / Redis 依赖注入。 -# 这里只初始化应用自身的数据目录。 -mkdir -p "${APP_DATA_DIR_1:-./data}" diff --git a/apps/sub2api/0.1.147/scripts/upgrade.sh b/apps/sub2api/0.1.147/scripts/upgrade.sh deleted file mode 100755 index 622a93268..000000000 --- a/apps/sub2api/0.1.147/scripts/upgrade.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -set -euo pipefail - -# 升级时确保应用自身的数据目录存在。 -# 数据库与 Redis 数据由 1Panel 依赖应用管理。 -mkdir -p "${APP_DATA_DIR_1:-./data}" diff --git a/apps/sub2api/0.1.147/.env.sample b/apps/sub2api/0.1.150/.env.sample similarity index 100% rename from apps/sub2api/0.1.147/.env.sample rename to apps/sub2api/0.1.150/.env.sample diff --git a/apps/sub2api/0.1.147/data.yml b/apps/sub2api/0.1.150/data.yml similarity index 82% rename from apps/sub2api/0.1.147/data.yml rename to apps/sub2api/0.1.150/data.yml index e3dfe8d8f..fa85840e1 100644 --- a/apps/sub2api/0.1.147/data.yml +++ b/apps/sub2api/0.1.150/data.yml @@ -8,7 +8,7 @@ additionalProperties: label: en: Database Service zh: 数据库服务 - zh-hant: 資料庫服務 + zh-Hant: 資料庫服務 ja: データベースサービス ko: 데이터베이스 서비스 ru: Служба базы данных @@ -23,7 +23,7 @@ additionalProperties: label: en: Database zh: 数据库服务 - zh-hant: 資料庫服務 + zh-Hant: 資料庫服務 ja: データベース ko: 데이터베이스 ru: База данных @@ -42,7 +42,7 @@ additionalProperties: label: en: Database Name zh: 数据库名 - zh-hant: 資料庫名稱 + zh-Hant: 資料庫名稱 ja: データベース名 ko: 데이터베이스 이름 ru: Имя базы данных @@ -60,7 +60,7 @@ additionalProperties: label: en: Database User zh: 数据库用户 - zh-hant: 資料庫使用者 + zh-Hant: 資料庫使用者 ja: データベースユーザー ko: 데이터베이스 사용자 ru: Пользователь базы данных @@ -78,7 +78,7 @@ additionalProperties: label: en: Database Port zh: 数据库端口 - zh-hant: 資料庫連接埠 + zh-Hant: 資料庫連接埠 ja: データベースポート ko: 데이터베이스 포트 ru: Порт базы данных @@ -95,7 +95,7 @@ additionalProperties: label: en: Database Password zh: 数据库用户密码 - zh-hant: 資料庫使用者密碼 + zh-Hant: 資料庫使用者密碼 ja: データベースパスワード ko: 데이터베이스 비밀번호 ru: Пароль базы данных @@ -114,7 +114,7 @@ additionalProperties: label: en: Redis Service zh: Redis服务 - zh-hant: Redis 服務 + zh-Hant: Redis 服務 ja: Redis サービス ko: Redis 서비스 ru: Служба Redis @@ -130,7 +130,7 @@ additionalProperties: label: en: Redis Service Port zh: Redis服务端口 - zh-hant: Redis 服務連接埠 + zh-Hant: Redis 服務連接埠 ja: Redis サービスポート ko: Redis 서비스 포트 ru: Порт службы Redis @@ -147,7 +147,7 @@ additionalProperties: label: en: Redis Password zh: Redis 密码 - zh-hant: Redis 密碼 + zh-Hant: Redis 密碼 ja: Redis パスワード ko: Redis 비밀번호 ru: Пароль Redis @@ -164,7 +164,7 @@ additionalProperties: label: en: Redis Database zh: Redis 数据库 - zh-hant: Redis 資料庫 + zh-Hant: Redis 資料庫 ja: Redis データベース ko: Redis 데이터베이스 ru: База данных Redis @@ -180,7 +180,7 @@ additionalProperties: label: en: Web Port zh: Web 访问端口 - zh-hant: Web 訪問埠 + zh-Hant: Web 訪問埠 ja: Webポート ko: 웹 포트 ru: Веб-порт @@ -197,7 +197,7 @@ additionalProperties: label: en: Timezone zh: 时区 - zh-hant: 時區 + zh-Hant: 時區 ja: タイムゾーン ko: 시간대 ru: Часовой пояс @@ -213,7 +213,7 @@ additionalProperties: label: en: Server Mode zh: 服务模式 - zh-hant: 服務模式 + zh-Hant: 服務模式 ja: サーバーモード ko: 서버 모드 ru: Режим сервера @@ -234,7 +234,7 @@ additionalProperties: label: en: Run Mode zh: 运行模式 - zh-hant: 運行模式 + zh-Hant: 運行模式 ja: 実行モード ko: 실행 모드 ru: Режим работы @@ -255,7 +255,7 @@ additionalProperties: label: en: Admin Email zh: 管理员邮箱 - zh-hant: 管理員郵箱 + zh-Hant: 管理員郵箱 ja: 管理者メール ko: 관리자 이메일 ru: Email администратора @@ -271,7 +271,7 @@ additionalProperties: label: en: Admin Password zh: 管理员密码 - zh-hant: 管理員密碼 + zh-Hant: 管理員密碼 ja: 管理者パスワード ko: 관리자 비밀번호 ru: Пароль администратора @@ -284,36 +284,34 @@ additionalProperties: - default: "" edit: true envKey: JWT_SECRET - labelEn: JWT Secret - labelZh: JWT 密钥 + labelEn: JWT Secret (blank to auto-generate) + labelZh: JWT 密钥(留空自动生成) label: - en: JWT Secret - zh: JWT 密钥 - zh-hant: JWT 金鑰 - ja: JWT シークレット - ko: JWT 시크릿 - ru: JWT-секрет - ms: Rahsia JWT - pt-br: Segredo JWT - random: true - required: true + en: JWT Secret (blank to auto-generate) + zh: JWT 密钥(留空自动生成) + zh-Hant: JWT 金鑰(留空自動產生) + ja: JWT シークレット(空欄で自動生成) + ko: JWT 시크릿(비워 두면 자동 생성) + ru: JWT-секрет (пусто = создать автоматически) + ms: Rahsia JWT (kosong untuk jana automatik) + pt-br: Segredo JWT (vazio para gerar automaticamente) + required: false type: password - default: "" edit: true envKey: TOTP_ENCRYPTION_KEY - labelEn: TOTP Encryption Key - labelZh: TOTP 加密密钥 + labelEn: TOTP Encryption Key (blank to auto-generate) + labelZh: TOTP 加密密钥(留空自动生成) label: - en: TOTP Encryption Key - zh: TOTP 加密密钥 - zh-hant: TOTP 加密金鑰 - ja: TOTP 暗号化キー - ko: TOTP 암호화 키 - ru: Ключ шифрования TOTP - ms: Kunci penyulitan TOTP - pt-br: Chave de criptografia TOTP - random: true - required: true + en: TOTP Encryption Key (blank to auto-generate) + zh: TOTP 加密密钥(留空自动生成) + zh-Hant: TOTP 加密金鑰(留空自動產生) + ja: TOTP 暗号化キー(空欄で自動生成) + ko: TOTP 암호화 키(비워 두면 자동 생성) + ru: Ключ TOTP (пусто = создать автоматически) + ms: Kunci TOTP (kosong untuk jana automatik) + pt-br: Chave TOTP (vazia para gerar automaticamente) + required: false type: password - default: "" edit: true @@ -323,7 +321,7 @@ additionalProperties: label: en: Update Proxy URL zh: 更新代理地址 - zh-hant: 更新代理地址 + zh-Hant: 更新代理地址 ja: 更新プロキシ URL ko: 업데이트 프록시 URL ru: URL прокси для обновлений @@ -340,7 +338,7 @@ additionalProperties: label: en: App Data Directory zh: 应用数据目录 - zh-hant: 應用資料目錄 + zh-Hant: 應用資料目錄 ja: アプリデータディレクトリ ko: 앱 데이터 디렉터리 ru: Каталог данных приложения diff --git a/apps/sub2api/0.1.147/data/.gitkeep b/apps/sub2api/0.1.150/data/.gitkeep similarity index 100% rename from apps/sub2api/0.1.147/data/.gitkeep rename to apps/sub2api/0.1.150/data/.gitkeep diff --git a/apps/sub2api/0.1.147/docker-compose.yml b/apps/sub2api/0.1.150/docker-compose.yml similarity index 96% rename from apps/sub2api/0.1.147/docker-compose.yml rename to apps/sub2api/0.1.150/docker-compose.yml index c458c6499..57e05cb7e 100644 --- a/apps/sub2api/0.1.147/docker-compose.yml +++ b/apps/sub2api/0.1.150/docker-compose.yml @@ -1,6 +1,6 @@ services: sub2api: - image: "ghcr.io/wei-shaw/sub2api:0.1.147" + image: "ghcr.io/wei-shaw/sub2api:0.1.150" container_name: ${CONTAINER_NAME} restart: always networks: diff --git a/apps/sub2api/0.1.150/scripts/init.sh b/apps/sub2api/0.1.150/scripts/init.sh new file mode 100755 index 000000000..d90eb5906 --- /dev/null +++ b/apps/sub2api/0.1.150/scripts/init.sh @@ -0,0 +1,45 @@ +#!/bin/bash +set -euo pipefail + +mkdir -p "${APP_DATA_DIR_1:-./data}" +touch .env +chmod 600 .env + +generate_secret() { + if command -v openssl >/dev/null 2>&1; then + openssl rand -hex 32 + else + od -An -N32 -tx1 /dev/urandom | tr -d ' \n' + fi +} + +read_env_value() { + key="$1" + [ -f .env ] || return 0 + sed -n "s/^${key}=//p" .env | tail -n 1 | sed -e 's/^"//' -e 's/"$//' -e "s/^'//" -e "s/'$//" +} + +write_env_value() { + key="$1" + value="$2" + touch .env + tmp_file="$(mktemp .env.XXXXXX)" + awk -v key="$key" -v value="$value" ' + BEGIN { updated = 0 } + $0 ~ "^" key "=" { print key "=" value; updated = 1; next } + { print } + END { if (!updated) print key "=" value } + ' .env >"$tmp_file" + chmod 600 "$tmp_file" + mv "$tmp_file" .env +} + +jwt_secret="${JWT_SECRET:-$(read_env_value JWT_SECRET)}" +if [ "${#jwt_secret}" -lt 32 ]; then + write_env_value JWT_SECRET "$(generate_secret)" +fi + +totp_key="${TOTP_ENCRYPTION_KEY:-$(read_env_value TOTP_ENCRYPTION_KEY)}" +if [ -z "$totp_key" ]; then + write_env_value TOTP_ENCRYPTION_KEY "$(generate_secret)" +fi diff --git a/apps/sub2api/0.1.147/scripts/uninstall.sh b/apps/sub2api/0.1.150/scripts/uninstall.sh similarity index 100% rename from apps/sub2api/0.1.147/scripts/uninstall.sh rename to apps/sub2api/0.1.150/scripts/uninstall.sh diff --git a/apps/sub2api/0.1.150/scripts/upgrade.sh b/apps/sub2api/0.1.150/scripts/upgrade.sh new file mode 100755 index 000000000..d90eb5906 --- /dev/null +++ b/apps/sub2api/0.1.150/scripts/upgrade.sh @@ -0,0 +1,45 @@ +#!/bin/bash +set -euo pipefail + +mkdir -p "${APP_DATA_DIR_1:-./data}" +touch .env +chmod 600 .env + +generate_secret() { + if command -v openssl >/dev/null 2>&1; then + openssl rand -hex 32 + else + od -An -N32 -tx1 /dev/urandom | tr -d ' \n' + fi +} + +read_env_value() { + key="$1" + [ -f .env ] || return 0 + sed -n "s/^${key}=//p" .env | tail -n 1 | sed -e 's/^"//' -e 's/"$//' -e "s/^'//" -e "s/'$//" +} + +write_env_value() { + key="$1" + value="$2" + touch .env + tmp_file="$(mktemp .env.XXXXXX)" + awk -v key="$key" -v value="$value" ' + BEGIN { updated = 0 } + $0 ~ "^" key "=" { print key "=" value; updated = 1; next } + { print } + END { if (!updated) print key "=" value } + ' .env >"$tmp_file" + chmod 600 "$tmp_file" + mv "$tmp_file" .env +} + +jwt_secret="${JWT_SECRET:-$(read_env_value JWT_SECRET)}" +if [ "${#jwt_secret}" -lt 32 ]; then + write_env_value JWT_SECRET "$(generate_secret)" +fi + +totp_key="${TOTP_ENCRYPTION_KEY:-$(read_env_value TOTP_ENCRYPTION_KEY)}" +if [ -z "$totp_key" ]; then + write_env_value TOTP_ENCRYPTION_KEY "$(generate_secret)" +fi diff --git a/apps/sub2api/README.md b/apps/sub2api/README.md index 5d4a2a8ce..702dd28a9 100644 --- a/apps/sub2api/README.md +++ b/apps/sub2api/README.md @@ -1,55 +1,50 @@ # Sub2API -## 应用简介 -提供 OpenAI 兼容接口的 AI 网关服务。 +## 产品介绍 +Sub2API 是一个提供 OpenAI 兼容接口的 AI 网关服务,可集中管理上游账号、订阅配额、访问令牌和用量统计。 -英文说明:AI gateway service with OpenAI-compatible APIs. +## 主要功能 +- 提供 OpenAI 兼容 API 和统一管理界面 +- 管理账号、用户、令牌、配额与用量统计 +- 支持 PostgreSQL 持久化和 Redis 缓存 +- 支持多种 AI 服务的转发与兼容处理 + +## 访问说明 +安装完成后,通过 1Panel 显示的 Web 端口访问管理界面。首次安装会根据表单参数初始化管理员账号、数据库和 Redis 连接。 + +## Introduction +Sub2API is an AI gateway with OpenAI-compatible APIs for managing upstream accounts, subscriptions, access tokens, quotas, and usage. + +## Features +- OpenAI-compatible APIs and a centralized administration interface +- Account, user, token, quota, and usage management +- PostgreSQL persistence and Redis caching +- Forwarding and compatibility support for multiple AI providers ## 部署说明 -- 本应用使用 Docker Compose 在 1Panel 中部署。 -- 应用分类:AI。 -- 支持架构:amd64。 -- 可选版本:`latest`、`0.1.138`。 -- 安装后按应用表单中的端口访问 Web UI、SSH 或对应服务。 +- 安装前需要在 1Panel 中准备 PostgreSQL 和 Redis 服务。 +- `JWT_SECRET` 和 `TOTP_ENCRYPTION_KEY` 留空时,生命周期脚本会生成 64 位十六进制密钥并写入 `.env`。 +- 升级时会保留长度不少于 32 字节的自定义 `JWT_SECRET`;旧版生成的过短值会被替换,因此现有登录会话可能需要重新登录。 +- 已配置的 TOTP 加密密钥不会在升级时覆盖,避免破坏现有双因素认证。 -## 端口 -| 变量 | 说明 | 默认值 | 必填 | -| --- | --- | --- | --- | -| PANEL_DB_PORT | 数据库端口 | 5432 | 是 | -| REDIS_PORT | Redis服务端口 | 6379 | 是 | -| PANEL_APP_PORT_HTTP | Web 访问端口 | 8080 | 是 | - -## 数据持久化 -| 变量 | 说明 | 默认值 | 必填 | -| --- | --- | --- | --- | -| APP_DATA_DIR_1 | 应用数据目录 | ./data | 是 | - -升级或迁移前,请在 1Panel 中备份上述数据目录。 - -## 配置项 -| 变量 | 说明 | 默认值 | 必填 | -| --- | --- | --- | --- | -| PANEL_DB_TYPE | 数据库服务 | postgresql | 是 | -| PANEL_DB_NAME | 数据库名 | sub2api | 是 | -| PANEL_DB_USER | 数据库用户 | sub2api | 是 | -| PANEL_DB_USER_PASSWORD | 数据库用户密码 | - | 是 | -| REDIS_HOST | Redis服务 | - | 是 | -| PANEL_REDIS_ROOT_PASSWORD | Redis 密码 | - | 是 | -| REDIS_DB | Redis 数据库 | 0 | 是 | -| SERVER_MODE | 服务模式 | release | 是 | -| RUN_MODE | 运行模式 | standard | 是 | -| ADMIN_EMAIL | 管理员邮箱 | admin@sub2api.local | 是 | - -## 使用说明 -### 反向代理说明 - -如果你在 Nginx 后面反代 Sub2API,并且需要兼容 Codex CLI 等依赖下划线请求头的客户端,请在 Nginx 的 `http` 块中开启: +## 反向代理说明 +如果在 Nginx 后面反代 Sub2API,并需要兼容 Codex CLI 等依赖下划线请求头的客户端,请在 Nginx 的 `http` 块中开启: ```nginx underscores_in_headers on; ``` -这是上游 README 明确提到的要求,否则某些带下划线的头部可能会被 Nginx 丢弃,影响会话粘性与部分 CLI 场景。 +否则部分带下划线的请求头可能被 Nginx 丢弃,影响会话粘性和部分 CLI 场景。 + +## 数据持久化 +| 路径 | 说明 | +| --- | --- | +| `${APP_DATA_DIR_1}` | Sub2API 应用数据目录 | +| PostgreSQL 服务 | 业务数据和配置 | +| Redis 服务 | 缓存和运行状态 | + +升级或迁移前,请备份应用数据目录和 PostgreSQL 数据库。 ## 参考资料 -- 官网: +- 项目仓库: +- 部署文档: diff --git a/apps/sub2api/latest/data.yml b/apps/sub2api/latest/data.yml index e3dfe8d8f..fa85840e1 100644 --- a/apps/sub2api/latest/data.yml +++ b/apps/sub2api/latest/data.yml @@ -8,7 +8,7 @@ additionalProperties: label: en: Database Service zh: 数据库服务 - zh-hant: 資料庫服務 + zh-Hant: 資料庫服務 ja: データベースサービス ko: 데이터베이스 서비스 ru: Служба базы данных @@ -23,7 +23,7 @@ additionalProperties: label: en: Database zh: 数据库服务 - zh-hant: 資料庫服務 + zh-Hant: 資料庫服務 ja: データベース ko: 데이터베이스 ru: База данных @@ -42,7 +42,7 @@ additionalProperties: label: en: Database Name zh: 数据库名 - zh-hant: 資料庫名稱 + zh-Hant: 資料庫名稱 ja: データベース名 ko: 데이터베이스 이름 ru: Имя базы данных @@ -60,7 +60,7 @@ additionalProperties: label: en: Database User zh: 数据库用户 - zh-hant: 資料庫使用者 + zh-Hant: 資料庫使用者 ja: データベースユーザー ko: 데이터베이스 사용자 ru: Пользователь базы данных @@ -78,7 +78,7 @@ additionalProperties: label: en: Database Port zh: 数据库端口 - zh-hant: 資料庫連接埠 + zh-Hant: 資料庫連接埠 ja: データベースポート ko: 데이터베이스 포트 ru: Порт базы данных @@ -95,7 +95,7 @@ additionalProperties: label: en: Database Password zh: 数据库用户密码 - zh-hant: 資料庫使用者密碼 + zh-Hant: 資料庫使用者密碼 ja: データベースパスワード ko: 데이터베이스 비밀번호 ru: Пароль базы данных @@ -114,7 +114,7 @@ additionalProperties: label: en: Redis Service zh: Redis服务 - zh-hant: Redis 服務 + zh-Hant: Redis 服務 ja: Redis サービス ko: Redis 서비스 ru: Служба Redis @@ -130,7 +130,7 @@ additionalProperties: label: en: Redis Service Port zh: Redis服务端口 - zh-hant: Redis 服務連接埠 + zh-Hant: Redis 服務連接埠 ja: Redis サービスポート ko: Redis 서비스 포트 ru: Порт службы Redis @@ -147,7 +147,7 @@ additionalProperties: label: en: Redis Password zh: Redis 密码 - zh-hant: Redis 密碼 + zh-Hant: Redis 密碼 ja: Redis パスワード ko: Redis 비밀번호 ru: Пароль Redis @@ -164,7 +164,7 @@ additionalProperties: label: en: Redis Database zh: Redis 数据库 - zh-hant: Redis 資料庫 + zh-Hant: Redis 資料庫 ja: Redis データベース ko: Redis 데이터베이스 ru: База данных Redis @@ -180,7 +180,7 @@ additionalProperties: label: en: Web Port zh: Web 访问端口 - zh-hant: Web 訪問埠 + zh-Hant: Web 訪問埠 ja: Webポート ko: 웹 포트 ru: Веб-порт @@ -197,7 +197,7 @@ additionalProperties: label: en: Timezone zh: 时区 - zh-hant: 時區 + zh-Hant: 時區 ja: タイムゾーン ko: 시간대 ru: Часовой пояс @@ -213,7 +213,7 @@ additionalProperties: label: en: Server Mode zh: 服务模式 - zh-hant: 服務模式 + zh-Hant: 服務模式 ja: サーバーモード ko: 서버 모드 ru: Режим сервера @@ -234,7 +234,7 @@ additionalProperties: label: en: Run Mode zh: 运行模式 - zh-hant: 運行模式 + zh-Hant: 運行模式 ja: 実行モード ko: 실행 모드 ru: Режим работы @@ -255,7 +255,7 @@ additionalProperties: label: en: Admin Email zh: 管理员邮箱 - zh-hant: 管理員郵箱 + zh-Hant: 管理員郵箱 ja: 管理者メール ko: 관리자 이메일 ru: Email администратора @@ -271,7 +271,7 @@ additionalProperties: label: en: Admin Password zh: 管理员密码 - zh-hant: 管理員密碼 + zh-Hant: 管理員密碼 ja: 管理者パスワード ko: 관리자 비밀번호 ru: Пароль администратора @@ -284,36 +284,34 @@ additionalProperties: - default: "" edit: true envKey: JWT_SECRET - labelEn: JWT Secret - labelZh: JWT 密钥 + labelEn: JWT Secret (blank to auto-generate) + labelZh: JWT 密钥(留空自动生成) label: - en: JWT Secret - zh: JWT 密钥 - zh-hant: JWT 金鑰 - ja: JWT シークレット - ko: JWT 시크릿 - ru: JWT-секрет - ms: Rahsia JWT - pt-br: Segredo JWT - random: true - required: true + en: JWT Secret (blank to auto-generate) + zh: JWT 密钥(留空自动生成) + zh-Hant: JWT 金鑰(留空自動產生) + ja: JWT シークレット(空欄で自動生成) + ko: JWT 시크릿(비워 두면 자동 생성) + ru: JWT-секрет (пусто = создать автоматически) + ms: Rahsia JWT (kosong untuk jana automatik) + pt-br: Segredo JWT (vazio para gerar automaticamente) + required: false type: password - default: "" edit: true envKey: TOTP_ENCRYPTION_KEY - labelEn: TOTP Encryption Key - labelZh: TOTP 加密密钥 + labelEn: TOTP Encryption Key (blank to auto-generate) + labelZh: TOTP 加密密钥(留空自动生成) label: - en: TOTP Encryption Key - zh: TOTP 加密密钥 - zh-hant: TOTP 加密金鑰 - ja: TOTP 暗号化キー - ko: TOTP 암호화 키 - ru: Ключ шифрования TOTP - ms: Kunci penyulitan TOTP - pt-br: Chave de criptografia TOTP - random: true - required: true + en: TOTP Encryption Key (blank to auto-generate) + zh: TOTP 加密密钥(留空自动生成) + zh-Hant: TOTP 加密金鑰(留空自動產生) + ja: TOTP 暗号化キー(空欄で自動生成) + ko: TOTP 암호화 키(비워 두면 자동 생성) + ru: Ключ TOTP (пусто = создать автоматически) + ms: Kunci TOTP (kosong untuk jana automatik) + pt-br: Chave TOTP (vazia para gerar automaticamente) + required: false type: password - default: "" edit: true @@ -323,7 +321,7 @@ additionalProperties: label: en: Update Proxy URL zh: 更新代理地址 - zh-hant: 更新代理地址 + zh-Hant: 更新代理地址 ja: 更新プロキシ URL ko: 업데이트 프록시 URL ru: URL прокси для обновлений @@ -340,7 +338,7 @@ additionalProperties: label: en: App Data Directory zh: 应用数据目录 - zh-hant: 應用資料目錄 + zh-Hant: 應用資料目錄 ja: アプリデータディレクトリ ko: 앱 데이터 디렉터리 ru: Каталог данных приложения diff --git a/apps/sub2api/latest/scripts/init.sh b/apps/sub2api/latest/scripts/init.sh index 51bfe1764..d90eb5906 100755 --- a/apps/sub2api/latest/scripts/init.sh +++ b/apps/sub2api/latest/scripts/init.sh @@ -1,6 +1,45 @@ #!/bin/bash set -euo pipefail -# 当前适配使用 1Panel 数据库 / Redis 依赖注入。 -# 这里只初始化应用自身的数据目录。 mkdir -p "${APP_DATA_DIR_1:-./data}" +touch .env +chmod 600 .env + +generate_secret() { + if command -v openssl >/dev/null 2>&1; then + openssl rand -hex 32 + else + od -An -N32 -tx1 /dev/urandom | tr -d ' \n' + fi +} + +read_env_value() { + key="$1" + [ -f .env ] || return 0 + sed -n "s/^${key}=//p" .env | tail -n 1 | sed -e 's/^"//' -e 's/"$//' -e "s/^'//" -e "s/'$//" +} + +write_env_value() { + key="$1" + value="$2" + touch .env + tmp_file="$(mktemp .env.XXXXXX)" + awk -v key="$key" -v value="$value" ' + BEGIN { updated = 0 } + $0 ~ "^" key "=" { print key "=" value; updated = 1; next } + { print } + END { if (!updated) print key "=" value } + ' .env >"$tmp_file" + chmod 600 "$tmp_file" + mv "$tmp_file" .env +} + +jwt_secret="${JWT_SECRET:-$(read_env_value JWT_SECRET)}" +if [ "${#jwt_secret}" -lt 32 ]; then + write_env_value JWT_SECRET "$(generate_secret)" +fi + +totp_key="${TOTP_ENCRYPTION_KEY:-$(read_env_value TOTP_ENCRYPTION_KEY)}" +if [ -z "$totp_key" ]; then + write_env_value TOTP_ENCRYPTION_KEY "$(generate_secret)" +fi diff --git a/apps/sub2api/latest/scripts/upgrade.sh b/apps/sub2api/latest/scripts/upgrade.sh index 622a93268..d90eb5906 100755 --- a/apps/sub2api/latest/scripts/upgrade.sh +++ b/apps/sub2api/latest/scripts/upgrade.sh @@ -1,6 +1,45 @@ #!/bin/bash set -euo pipefail -# 升级时确保应用自身的数据目录存在。 -# 数据库与 Redis 数据由 1Panel 依赖应用管理。 mkdir -p "${APP_DATA_DIR_1:-./data}" +touch .env +chmod 600 .env + +generate_secret() { + if command -v openssl >/dev/null 2>&1; then + openssl rand -hex 32 + else + od -An -N32 -tx1 /dev/urandom | tr -d ' \n' + fi +} + +read_env_value() { + key="$1" + [ -f .env ] || return 0 + sed -n "s/^${key}=//p" .env | tail -n 1 | sed -e 's/^"//' -e 's/"$//' -e "s/^'//" -e "s/'$//" +} + +write_env_value() { + key="$1" + value="$2" + touch .env + tmp_file="$(mktemp .env.XXXXXX)" + awk -v key="$key" -v value="$value" ' + BEGIN { updated = 0 } + $0 ~ "^" key "=" { print key "=" value; updated = 1; next } + { print } + END { if (!updated) print key "=" value } + ' .env >"$tmp_file" + chmod 600 "$tmp_file" + mv "$tmp_file" .env +} + +jwt_secret="${JWT_SECRET:-$(read_env_value JWT_SECRET)}" +if [ "${#jwt_secret}" -lt 32 ]; then + write_env_value JWT_SECRET "$(generate_secret)" +fi + +totp_key="${TOTP_ENCRYPTION_KEY:-$(read_env_value TOTP_ENCRYPTION_KEY)}" +if [ -z "$totp_key" ]; then + write_env_value TOTP_ENCRYPTION_KEY "$(generate_secret)" +fi