自托管 Vikunja:容器里挂的 config.yml 改不动数据库路径,几个默认值也要手动收口
项目信息
- 仓库:go-vikunja/vikunja,Go 编写,AGPL-3.0-or-later,默认分支
main - 安装文档:vikunja.io/docs/installing,配置项参考:vikunja.io/docs/config-options
- 在线 Demo:try.vikunja.io,OpenAPI/Swagger:try.vikunja.io/api/v2/docs
- Docker 镜像:
vikunja/vikunja(Docker Hub) - 当前版本 v2.6.0
API 和前端打包在同一个可执行文件、同一个容器里,部署时只需要跑一个东西,这是它相比前后端分开部署的项目省事的地方。
部署:三件官方一句带过但会卡住的事
uid 1000 与挂载目录权限
官方 Docker 跑法:
mkdir $PWD/files $PWD/db
chown 1000 $PWD/files $PWD/db
docker run -p 3456:3456 \
-v $PWD/files:/app/vikunja/files \
-v $PWD/db:/db \
vikunja/vikunja
容器默认以用户 1000、无附加组运行。挂载目录没 chown 1000,写库和写附件就会失败。用 --user 换用户可以,但新用户必须对 db 和 files 两个目录都有权限。files 卷默认在 /app/vikunja/files,必须挂到宿主,不然容器一重启附件就没了。
CORS 与 publicurl 的互斥关系
默认配置下 CORS 是开启的,而开启状态要求有一个 public URL。两条路二选一:把 service.publicurl(环境变量 VIKUNJA_SERVICE_PUBLICURL)设成外部可访问地址,或者把 cors.enable(VIKUNJA_CORS_ENABLE)设为 false。不处理这一项,服务起不来,或者前端连不上 API。
config.yml 里的 rootpath / database.path 不生效
配置可以走 config.yml,也可以走环境变量,同名时环境变量优先。嵌套变量按 first.child -> VIKUNJA_FIRST_CHILD 映射。
官方镜像预设了两个环境变量:
VIKUNJA_SERVICE_ROOTPATH=/app/vikunja/
VIKUNJA_DATABASE_PATH=/db/vikunja.db
因为环境变量优先级高于配置文件,你在挂进容器的 config.yml 里写 service.rootpath 或 database.path,是没有效果的。想把数据库放到别处,改 bind mount 的宿主侧(例如 ./my-db:/db),或者直接覆盖环境变量,而不是改容器内的路径。files.basepath 走相对路径时会相对 service.rootpath 解析,所以默认上传目录落在 /app/vikunja/files。
Docker Compose 里用配置文件的话,volumes 加一行:
volumes:
- ./path/to/config.yml:/etc/vikunja/config.yml
配置文件的搜索位置是 service.rootpath、/etc/vikunja、~/.config/vikunja、当前工作目录。--config 可以精确指定并跳过搜索路径,任何子命令都支持;文件读不到会直接报错,不会回退默认值。反过来,不在安装目录执行命令、又不加 --config,可能找不到配置、回退默认值、相对路径解析到错误目录——表现起来就像装好的实例突然变空了。
升级与数据迁移
升级前先备份。替换二进制后重启,会自动跑完所有数据库迁移。升级前看一下 changelog,有些版本带需要手工操作的步骤,漏掉就麻烦了。Vikunja 没有默认账号密码,装好之后自行注册第一个账号。
容易被忽略的默认值
service.secret:用于签名 JWT 等,默认每次启动随机生成。这意味着重启后已签发的 token 全部失效,用户掉登录。生产环境必须显式固定。service.jwtttl默认 259200 秒(3 天);jwtttllong(记住我)2592000 秒(30 天);jwtttlshort600 秒(10 分钟)。service.timezone默认 GMT。这里必须填官方 tz 数据库名,UTC或 GMT 偏移量这种写法不生效。service.enableregistration默认true,也就是开放注册。公网实例必须改成false。service.enablelinksharing默认true(项目链接分享),service.enablecaldav默认true。service.maxitemsperpage默认 50。service.ipextractionmethod默认direct,用的是 TCP 远端地址、忽略转发头。跑在 nginx / Traefik / 云 LB 后面要改成'xff'读X-Forwarded-For,同时配service.trustedproxies填代理 CIDR,例如127.0.0.1/32,::1/128,10.0.0.0/8,172.16.0.0/12。database.type默认sqlite,支持 mysql 8.0+ / mariadb 10.2+ / postgres 12+ / sqlite。用 MySQL 或 MariaDB 且要存非拉丁字符,库必须是 utf-8。- 数据库连接池:
database.maxopenconnections默认 100(仅 mysql/pg),maxidleconnections默认 50,maxconnectionlifetime默认 1800000ms。 bcryptrounds默认 11。service.testingtoken默认空。一旦非空,会开启/test/{table}写库端点,官方明确警告不要用。
许可与边界
大部分仓库是 AGPL-3.0-or-later,desktop/ 目录是 GPL-3.0-or-later。官方另有 Vikunja Pro(admin panel、审计日志、工时统计等企业能力)和托管版 Vikunja Cloud。免费自托管不含 admin panel、审计日志和 time tracking,移动端目前也只支持很基础的功能。介意外部依赖和这些能力缺口的,部署前先确认清楚。