初春图床 v3.5.8 更新来了!本版本是 v3.5.7 的修复版本,合并了社区反馈的 2 个问题修复(#38、#41 / PR #42,感谢 @MousseC、@Almighty-ap)。
本版本不含破坏性变更,可直接覆盖升级。升级前请务必备份 ./data 卷——数据库与自动生成的密钥都在里面。
[修复] SESSION_SECRET 每次重启重新生成,导致全员掉线(Issue #38)
SESSION_SECRET 留空时,进程每次启动都会重新生成一个随机值,后果是:
- 重启容器或进程 → 所有已登录用户立刻 401,必须重新登录
- 同时会使 OIDC / CAS 登录流程里的 state cookie 校验失败,第三方登录偶发报错
根因是一条链:docker-compose.yml 里注入了 SESSION_SECRET=${SESSION_SECRET:-}(空值也是”已定义”的变量)→ godotenv.Load() 不覆盖已存在的环境变量 → getEnv() 把空串当作未设置 → 最终走到 generateRandomSecret(32),而生成的值只存在于内存里。
本版本改为与 CONFIG_SECRET 完全一致的持久化策略(backend/config/config.go):
SESSION_SECRET | 行为 |
|---|---|
| 留空 | 自动生成 32 字节随机值,写入 data/.session_secret(权限 0600),只写一次,重启复用 |
| 非空 | 直接使用;显式配置时必须 ≥32 字符,否则启动失败 |
因此只要 ./data 卷保留,重启进程、重建容器、docker compose down && up -d 都不会再让用户掉线。
⚠️ 删除
./data会同时丢失数据库、.session_secret与.config_secret,请务必纳入备份。
[修复] 本地存储路径双重 uploads/ 嵌套(Issue #41 / PR #42)
本地存储 resolve() 把完整对象键(/uploads/2026/10/x.png)直接拼到上传根目录上,导致磁盘上出现 <root>/uploads/2026/10/x.png 这样多一层的结构。PR #42 修正了拼接逻辑,让写入回到规范的 <root>/2026/10/x.png。
但只修拼接会带来一个更严重的问题:v3.5.6 / v3.5.7 已经上传的图片会全部 404,因为它们的文件仍在旧的嵌套路径下。本版本在 PR #42 基础上补了兼容层(backend/storage/local.go):
resolve()先查规范路径,仅在文件缺失时回退到历史嵌套路径- 新写入的图片始终走规范路径,升级不需要手工搬
uploads目录 - 两条路径共用
safeJoin(),仍逐组件Lstat拒绝符号链接与目录穿越 cleanupLocalUpload()删除时同时清理历史嵌套路径,避免遗留孤儿文件
实测矩阵(同一数据库行、同一绑定挂载、仅切换磁盘布局):
磁盘布局 v3.5.7 PR#42 单独 本版本<root>/<rel>(规范) 404 200 200<root>/uploads/<rel>(v3.5.6/v3.5.7 遗留) 200 404 → 已修复 200新增 backend/storage/local_layout_test.go(137 行)覆盖两种布局、优先级与安全边界。
文档
.env.example与 README 补充说明:SESSION_SECRET/CONFIG_SECRET都会自动生成并持久化到./data卷内,./data必须纳入备份。- 再次明确版本差异:v3.5.5 及更早��本初始管理员密码固定为
123456;从 v3.5.6 起改为随机生成,写入data/.initial_admin_password。
下载与部署
| 产物 | 说明 |
|---|---|
oneImg_Win_amd64_v3.5.8.zip | Windows amd64(含 README,UPX -9) |
oneImg_Win_arm64_v3.5.8.zip | Windows arm64(含 README,UPX -9) |
oneImg_Linux_amd64_v3.5.8.tar.gz | Linux amd64 静态二进制(UPX -9) |
oneImg_Linux_arm64_v3.5.8.tar.gz | Linux arm64 静态二进制(UPX -9) |
oneImg_Docker_amd64_v3.5.8.tar | Docker 镜像,docker load 导入后标签 oneimg:v3.5.8-amd64 |
oneImg_Docker_arm64_v3.5.8.tar | Docker 镜像,docker load 导入后标签 oneimg:v3.5.8-arm64 |
- 全部二进制为静态链接(webp / sqlite3 由 cgo 内嵌编译),无运行时依赖。
- Windows arm64 版用 llvm-mingw 交叉编译,同样内嵌 cgo,运行时只依赖系统自带的 UCRT(Windows 10 起内置)。
- Docker 镜像 runtime 层与官方 Dockerfile 一致(alpine:3.23 + ca-certificates + tzdata),amd64 / arm64 均已推送至 Docker Hub:
onexru/oneimg-oneimg:v3.5.8(多架构 manifest)与onexru/oneimg-oneimg:latest。
首次运行的管理员密码(重要)
v3.5.5 及更早版本,初始管理员密码固定为
123456。从 v3.5.6 起改为随机生成。
v3.5.8 沿用 v3.5.6 起的规则:
DEFAULT_PASS | 行为 |
|---|---|
| 留空(推荐) | 仅在数据库还没有任何用户时生成 43 字符随机密码,写入 data/.initial_admin_password(权限 0600),不打印到日志 |
| 非空 | 直接作为初始管理员密码 |
- 该文件只写一次,重启不覆盖,也不会重置已有账号的密码。
- Docker 查看:
docker exec oneimg cat /app/data/.initial_admin_password - ⚠️ 从 v3.5.5 及更早版本升级时,若
.env里还留着DEFAULT_PASS=123456,它会被当作初始密码继续生效(仅影响还没有任何用户的空库)。请删除该行或改成强密码。
配置:直接在容器编排中设置
所有变量都可以在 compose 的 environment 或 docker run -e 里设置,不需要进容器改 /app/.env:
services: oneimg: image: onexru/oneimg-oneimg ports: ["8080:8080"] environment: - APP_URL=https://img.example.com - DEFAULT_USER=admin - DEFAULT_PASS= # 留空 → 自动生成随机密码 - DB_TYPE=mysql - DB_HOST=mysql - DB_TLS_MODE=auto # 自建/内网数据库自动降为 preferred - MAX_FILE_SIZE=10485760 - TRUSTED_PROXIES=172.17.0.0/16 volumes: - ./data:/app/data - ./uploads:/app/uploads优先级:编排注入的环境变量 > 容器内自动生成的 /app/.env。应用首次启动会生成 .env 模板,但加载时(godotenv)不覆盖已存在的环境变量,因此编排注入的值始终生效,容器内 .env 只补全未注入的默认项。密钥类自动生成值(data/.config_secret、data/.session_secret、data/.initial_admin_password)都落在 ./data 卷内,重建容器不会丢失。
完整变量清单见仓库 .env.example。
- 部署提醒:
APP_URL必须设为实际访问地址(图片 URL 取自该值);显式配置的CONFIG_SECRET必须 ≥32 字符,且启用加密存储后不可更换。
项目地址
项目地址: