- 数据库默认文件 filecodebox.db → fileshare.db(config.go 默认值与全部文档/编排同步)
- Go module filecodebox → fileshare(全部 import 同步,build/vet/test 全绿)
- 应用版本 APP_VERSION 2.5.6 → 26.9(health 接口已验证返回 26.9)
- deploy 编排统一:compose 项目名、Postgres 默认凭据、minio 桶名、env 注释
- JWT issuer、存储临时目录前缀、web 包名同步 fileshare
- CI:镜像 tag 以 APP_VERSION 为唯一版本源,main/tag 推送即发布
${VER} + latest;tag 触发时校验 tag 名与 APP_VERSION 一致,防错版
- 本地开发库文件已改名 fileshare.db(含 -shm/-wal 清理)
191 lines
12 KiB
Markdown
191 lines
12 KiB
Markdown
# 环境变量与配置项
|
||
|
||
配置分三层:**默认值 → `FCB_*` 环境变量 → 数据库 settings KV(管理端运行时修改)**。
|
||
v2 起进程必需的环境变量为空集:数据库默认 **SQLite**(modernc.org/sqlite 纯 Go 驱动,零外部依赖,
|
||
DSN 缺省落 `./data/fileshare.db`);`FCB_DB_DRIVER=postgres` 时 `FCB_DB_DSN` 必需(需求 ⑧)。
|
||
|
||
## 环境变量(进程级)
|
||
|
||
| 变量 | 必需 | 默认 | 说明 |
|
||
|---|---|---|---|
|
||
| `FCB_DB_DRIVER` | ❌ | `sqlite` | 数据库驱动:`sqlite` / `postgres`(需求 ⑧) |
|
||
| `FCB_DB_DSN` | 视驱动 | `./data/fileshare.db` | postgres:连接串(**必需**,如 `postgres://user:pass@host:5432/filecodebox?sslmode=disable`);sqlite:数据库文件路径(可空,父目录自动创建) |
|
||
| `FCB_REDIS_ADDR` | ❌ | 空 | Redis 地址(如 `redis:6379`),也支持 `redis://[:password@]host:port[/db]` / `rediss://`(TLS)URL 形式;**空则缓存降级为进程内存实现**(缓存故障时自动降级为进程内限流计数) |
|
||
| `FCB_REDIS_DB` | ❌ | `0` | Redis 逻辑库号 0-15;URL 形式地址显式携带 `/N` 时以 URL 为准 |
|
||
| `FCB_ADMIN_PASSWORD` | ❌ | 空 | 设置后服务首次启动即自动初始化管理员(≥8 位,不足告警跳过),消除 `/setup` 被抢占窗口;初始化完成后建议移除 |
|
||
| `FCB_LISTEN` | ❌ | `:8466` | HTTP 监听地址 |
|
||
| `FCB_STORAGE_ENGINE` | ❌ | `local` | 存储引擎:`local` / `s3` / `webdav` |
|
||
| `FCB_TRUSTED_PROXIES` | ❌ | 空 | 可信代理 CIDR(逗号分隔),命中时从 `X-Forwarded-For` 解析真实客户端 IP |
|
||
|
||
- SQLite 连接参数(驱动自动注入):`busy_timeout=10s` + `WAL` 日志模式 + `foreign_keys=1`;连接池 8/4。
|
||
- Postgres 连接池沿用 v1 参数(32/8,1h 轮换);`FCB_DB_DRIVER=postgres` 且未设 `FCB_DB_DSN` 时**启动直接报错**。
|
||
|
||
引擎相关环境变量(种子注入 settings KV,见《存储引擎配置》):`FCB_LOCAL_STORAGE_PATH`、
|
||
`FCB_STORAGE_PATH`、`FCB_S3_ACCESS_KEY_ID`、`FCB_S3_SECRET_ACCESS_KEY`、`FCB_AWS_SESSION_TOKEN`、
|
||
`FCB_S3_BUCKET_NAME`、`FCB_S3_ENDPOINT_URL`、`FCB_S3_REGION_NAME`、`FCB_S3_ADDRESSING_STYLE`、
|
||
`FCB_WEBDAV_URL`、`FCB_WEBDAV_USERNAME`、`FCB_WEBDAV_PASSWORD`、`FCB_WEBDAV_ROOT_PATH`。
|
||
|
||
部署用编排变量(`deploy/.env.example`):`WEB_PORT`(默认 8466)、
|
||
`POSTGRES_USER` / `POSTGRES_PASSWORD` / `POSTGRES_DB`(默认 fileshare,仅 `--profile postgres` 时使用)。
|
||
|
||
## 配置项(settings KV,默认值对齐参考实现)
|
||
|
||
> 键名/类型/默认值/边界以 `server/internal/config/schema.go` 的 `KVSchema()` 为单一事实来源
|
||
> (schema 同步测试保证与 defaults() 逐键一致);v2 新增键统一 snake_case。
|
||
|
||
### 站点信息与展示(需求 ①②③)
|
||
|
||
| 键 | 类型/边界 | 默认 | 说明 |
|
||
|---|---|---|---|
|
||
| `site_name` / `name` | string | 文件快传 | 站点名称(`site_name` 优先) |
|
||
| `site_domain` | string,≤256 | 空 | **v3.1**:站点对外域名(`http(s)://host[:port]`,不带路径;裸主机自动补 `http://`)。配置后分享链接(结果卡/管理端复制)用该域名生成——内网部署也能把公网链接发出去;留空=用当前访问地址 |
|
||
| `description` | string | 开箱即用的文件快传系统 | 站点描述 |
|
||
| `page_explain` | string | (合规声明) | 页面说明文案 |
|
||
| `keywords` | string | 文件快传, 文件分享… | SEO 关键词 |
|
||
| `logo_url` | string | 空(前端回落本地打包 `/assets/logo-*.svg`,需求 ⑤) | 页面导航 Logo,管理端可设任意 URL |
|
||
| `favicon_url` | string | 空(前端回落本地打包 `/assets/favicon-*.png`,需求 ⑤) | favicon / 备用 Logo |
|
||
| `opacity` | float | 0.9 | 界面不透明度 |
|
||
| `background` | string | 空 | 背景图 URL(参考实现既有键,v1 兼容保留) |
|
||
| `background_url` | string,≤2048 字符 | 空 | **v2 需求 ①**:背景图 URL 或上传后地址(空=主题默认;取值时 legacy `background` 键兜底)。管理端保存时校验协议白名单:仅 `http(s)`、`data:image/*` 与站内相对路径(防 `javascript:` 注入,非法 400) |
|
||
| `footer_text` | string,≤2000 字符 | 空 | **v2 需求 ②**:页脚自定义内容(纯文本或受控 HTML 片段) |
|
||
| `footer_beian` | string,≤128 字符 | 空 | **v2 需求 ②**:备案号(如 `京ICP备2024xxxxxx号-1`),展示于页脚 |
|
||
| `notify_enabled` | int(0/1) | 1 | **v2 需求 ③**:通知开关(1=前台右上角悬浮窗展示 / 0=关闭) |
|
||
| `notify_title` | string,≤128 字符 | 系统通知 | 通知标题 |
|
||
| `notify_content` | string,≤2000 字符 | 欢迎使用… | 通知正文(**服务端白名单净化**:仅保留纯文本与 `<a href>` 为 http(s)/站内相对/`#` 锚点的链接,其余标签与事件属性剥离,保存与读取双侧生效) |
|
||
| `showAdminAddr` | int(0/1) | 0 | 是否展示后台入口 |
|
||
| `robotsText` | string | `User-agent: *\nDisallow: /` | robots.txt 内容(由公开端点 `GET /robots.txt` 输出) |
|
||
|
||
### 保存策略(需求 ④,上传页动态读取并在范围内选择)
|
||
|
||
| 键 | 类型/边界 | 默认 | 说明 |
|
||
|---|---|---|---|
|
||
| `max_save_seconds` | int64,0~31536000 | 0 | 最长保存秒数上限(0=仅默认 7 天兜底;>0 时按时间过期超限 403「限制最长时间为 X,可换用其他方式」)。**v3**:管理界面以「小时/天」下拉单位编辑(≥1 天自动显示天),提交时前端换算为秒——canonical 单位保持秒,接口语义不变 |
|
||
| `max_save_count` | int,0~100000 | 0 | **v2 新增**:单次分享最大可取(保存)次数上限(0=不限制;`expire_style=count` 且 `expire_value` 超上限时 403「限制次数最多为 N 次」) |
|
||
| `expireStyle` | []string | `["day","hour","minute","forever","count"]` | 允许的过期方式白名单(上传时不在白名单 400「过期时间类型错误」) |
|
||
|
||
### 存储策略(需求 ④⑩)
|
||
|
||
| 键 | 类型/边界 | 默认 | 说明 |
|
||
|---|---|---|---|
|
||
| `uploadSize` | int64,1024~10GiB | 10485760(10MB) | 单文件大小上限(字节),参考实现语义;`max_file_size=0` 时作为生效上限 |
|
||
| `max_file_size` | int64,0~10GiB | 0 | **v2 新增**:存储策略-单文件上限(字节),0=回落 `uploadSize`;超出 403(文案 humanSize 自适应 B/KB/MB/GB)。**v3**:管理界面以「MB/GB」下拉单位编辑(≥1 GiB 自动显示 GB),提交时前端换算为字节 |
|
||
| `allowed_file_types` | []string | `["*"]` | 允许类型白名单(扩展名/MIME 通配,`*` 不限制;非白名单 403「不允许上传该类型文件」) |
|
||
| `storageLimit` | int64,≥0 | 0 | 站点总容量(字节),0=不限制(超限 507) |
|
||
| `openUpload` | int(0/1) | 1 | 游客上传开关(0 时上传接口要求管理员令牌 403) |
|
||
| `enableChunk` | int(0/1) | 0 | 启用分片上传 |
|
||
|
||
### 上传频率限制(需求 ④,既有键对齐参考 ip_limit["upload"])
|
||
|
||
| 键 | 类型/边界 | 默认 | 说明 |
|
||
|---|---|---|---|
|
||
| `uploadCount` / `uploadMinute` | int(1~10000 / 1~1440) | 10 / 1 | 窗口内允许上传次数 / 窗口分钟(上传成功才计数,超限 423;管理端修改后运行时同步限流规则,立即生效) |
|
||
| `errorCount` / `errorMinute` | int | 10 / 1 | 取件错误(失败计数)+ metadata 每次计数 |
|
||
| `loginCount` / `loginMinute` | int | 5 / 15 | 登录失败计数 |
|
||
|
||
### 安全与会话
|
||
|
||
| 键 | 默认 | 说明 |
|
||
|---|---|---|
|
||
| `admin_token` | 空(未初始化) | 管理员密码哈希(`sha256$salt$hash`);GET 配置时屏蔽为空串 |
|
||
| `jwt_secret` | 空 | JWT 签名密钥(初始化/改密时自动生成轮换;不下发;`settings.SensitiveKeys` 双模式下一致屏蔽) |
|
||
| `adminSessionExpire` | 604800(7 天) | 管理员会话秒数(须 1~365 整天) |
|
||
|
||
### 存储引擎(v3 运行时可配 + 热切换)
|
||
|
||
**`storage_engine`**(v3 新增键):string,`local|s3|webdav`,默认空=回落启动值 `FCB_STORAGE_ENGINE`。
|
||
运行时切换走 **`POST /admin/storage/switch`**(JWT 保护):构建新引擎 → 健康检查通过才生效;
|
||
失败返回 503「存储引擎切换失败,已保持原引擎: …」且不改 KV。成功后持久化 `storage_engine`,重启沿用。
|
||
`GET /api/v1/config` 公开下发 `storage_engine` 当前名(仅名称,任何引擎参数/凭据不下发)。
|
||
|
||
引擎参数键(管理端可改;保存后对应引擎实例缓存失效,下次切换/构建生效):
|
||
|
||
| 键 | 默认 |
|
||
|---|---|
|
||
| `file_storage` | `local` |
|
||
| `storage_path` | 空 |
|
||
| `local_storage_path` | 空(容器内由 `FCB_LOCAL_STORAGE_PATH=/app/data` 注入) |
|
||
| `s3_access_key_id` / `s3_secret_access_key` / `aws_session_token` | 空 |
|
||
| `s3_bucket_name` / `s3_endpoint_url` / `s3_hostname` | 空 |
|
||
| `s3_region_name` | `auto` |
|
||
| `s3_signature_version` | `s3v4` |
|
||
| `s3_addressing_style` | `auto` |
|
||
| `s3_proxy` | 0 |
|
||
| `webdav_url` / `webdav_username` / `webdav_password` | 空 |
|
||
| `webdav_root_path` | `filebox_storage` |
|
||
| `webdav_proxy` | 0 |
|
||
|
||
> 敏感键 `webdav_password` / `s3_secret_access_key` / `aws_session_token`(v3 加入 `settings.SensitiveKeys`):
|
||
> 管理端 GET 返回掩码 `******`;PATCH 时空串或 `******` 表示不修改。直接写库 settings KV 后重启同样生效。
|
||
|
||
## 策略动态生效机制(v2 需求 ④⑩)
|
||
|
||
上传页通过 `GET /api/v1/config` 的 `config` 字段读取**当前策略快照**并在范围内渲染选项;
|
||
上传链路(`/share/file`、`/chunk/*`、`/presign/*`)**每次请求实时读取** settings KV 同一组值校验:
|
||
|
||
- 管理端改策略(`PATCH /admin/config/update`)→ 公开 config 即时反映 → 后续上传立即按新策略执行(含 403/400 拒绝与恢复放行)。
|
||
- 生效上限:`max_file_size > 0` 时为 `max_file_size`,否则回落 `uploadSize`。
|
||
- 校验点覆盖:单文件(`/share/file`)、分片 init 按分片数上限、分片上传累计、分片 complete 累计、预签名 init 声明大小,五处口径一致(`api.UploadPolicy.CheckSize`)。
|
||
|
||
## 公共配置接口
|
||
|
||
前端启动时经 `GET /api/v1/config` 获取站点公开配置(无需认证;v2 扩展需求 ①②③④⑩):
|
||
|
||
```json
|
||
{
|
||
"code": 200, "msg": "ok",
|
||
"data": {
|
||
"config": {
|
||
"name": "文件快传",
|
||
"description": "开箱即用的文件快传系统",
|
||
"explain": "请勿上传或分享违法内容…",
|
||
"logo_url": "",
|
||
"favicon_url": "",
|
||
"background_url": "",
|
||
"footer_text": "自定义页脚内容",
|
||
"footer_beian": "京ICP备2024xxxxxx号-1",
|
||
"notify_enabled": 1,
|
||
"notify_title": "系统通知",
|
||
"notify_content": "欢迎使用文件快传…",
|
||
"uploadSize": 10485760,
|
||
"max_file_size": 10485760,
|
||
"maxFileSize": 10485760,
|
||
"allowedFileTypes": ["*"],
|
||
"expireStyle": ["day", "hour", "minute", "forever", "count"],
|
||
"max_save_seconds": 0,
|
||
"maxSaveSeconds": 0,
|
||
"max_save_count": 0,
|
||
"maxSaveCount": 0,
|
||
"uploadCount": 10,
|
||
"uploadMinute": 1,
|
||
"enableChunk": false,
|
||
"openUpload": true
|
||
},
|
||
"meta": {
|
||
"version": "26.9",
|
||
"features": { "chunkUpload": false, "guestUpload": true }
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
> 策略字段 snake_case 与 camelCase 双份下发(前端宽松解析);响应为白名单显式构造,
|
||
> 任何敏感键(`admin_token`/`jwt_secret`)均不会出现。
|
||
|
||
## 健康检查
|
||
|
||
```bash
|
||
curl -s http://localhost:8466/api/v1/health
|
||
```
|
||
|
||
```json
|
||
{
|
||
"code": 200, "msg": "ok",
|
||
"data": {
|
||
"status": "ok",
|
||
"version": "26.9",
|
||
"storage": "local",
|
||
"time": "2025-06-01T12:00:00+08:00"
|
||
}
|
||
}
|
||
```
|