Shukka 文档

自托管部署

用 Docker 或源码把 Shukka 跑在一台带持久盘的单机上,配好反向代理、对象存储与备份。

Shukka 是单管理员的自托管服务。服务自身的数据库与加密密钥存放在运行机器的磁盘上;安装包存放于每个应用各自配置的 S3 兼容存储。

推荐形态

一台 VPS(或同等单机)上跑公开镜像 ghcr.io/shukka-app/shukka,挂一个持久卷到 /data,前面用 Caddy 或 nginx 提供 HTTPS。对象存储用 Cloudflare R2、AWS S3 或独立 MinIO。

用 Docker 部署(主路径)

  1. 准备一台能跑 Docker 的 Linux 主机、一个域名、以及 S3 兼容存储。
  2. 拉取公开镜像并运行:
docker run -d --name shukka --restart unless-stopped \
  -p 127.0.0.1:3000:3000 \
  -v shukka-data:/data \
  ghcr.io/shukka-app/shukka

镜像在 GitHub Packages,无需登录即可拉取。推送 semver 标签(vMAJOR.MINOR.PATCH)会由 GitHub Actions 构建并发布;未加 tag 时拉的是 latest。钉版本用 ghcr.io/shukka-app/shukka:0.1.0。要从源码自行构建时,在仓库根执行 docker build -t shukka .,把上面的镜像名换成 shukka

  1. 反向代理到 127.0.0.1:3000,对外只暴露 HTTPS。
  2. 打开面板,首次访问进入 setup,设置至少 8 位管理员密码。
  3. 创建应用时测试存储连接;测试失败不会保存。
  4. 用下文「探活 / 冒烟」确认服务正常。

从源码 + systemd

需要 Node 24(与 CI / Dockerfile 一致)和能编译原生 Node 模块的环境。

npm ci
npm run build
npm start          # node .output/server/index.mjs ,默认 :3000

进程必须在仓库根启动,否则启动时不会执行数据库迁移。生产环境不要运行 npm run db:generate

示例 unit(按主机改路径与用户):

[Service]
WorkingDirectory=/opt/shukka
Environment=NODE_ENV=production
Environment=SHUKKA_DATA_DIR=/var/lib/shukka
ExecStart=/usr/bin/node .output/server/index.mjs
Restart=on-failure

环境变量

进程只读这些变量。S3、管理员密码、API key 都不是启动环境变量。

变量默认用途
PORTNITRO_PORT3000HTTP 端口(NITRO_PORT 优先)
HOSTNITRO_HOST未设(监听全部地址)绑定地址
SHUKKA_DATA_DIR./data(镜像内 /dataSQLite 与加密密钥目录
SHUKKA_DB_PATH{data}/shukka.db覆盖数据库文件路径
SHUKKA_KEY_PATH{data}/encryption.key覆盖 S3 secret 的 AES 密钥文件
NODE_ENV镜像内 productionNode 生产模式
NITRO_SSL_CERT + NITRO_SSL_KEY未设在 Node 进程上直接开 TLS(通常不如反代)
NITRO_UNIX_SOCKET未设改走 UNIX socket

反向代理与 TLS

  • 面板、/api/v1/api/update 同端口同进程。反代把整个 origin 转发到 Shukka,不要把路径拆到不同后端。
  • 保留 Host 头。对外用 HTTPS。
  • 已知坑:反代做 HTTPS、回源是 HTTP 时,Tauri feed 里的制品 URL 可能是 http://。用 curl -sS https://your.host/api/update/{app}/{channel} 验证;若看到 http://,让反代对后端也走 TLS,或给进程配 NITRO_SSL_CERT / NITRO_SSL_KEY

对象存储

每个 app 独立配置:endpoint、region、bucket、prefix、access key、secret、force path style。创建 / 保存前服务端会做一次写测试,失败则拒绝保存。

厂商要点
AWS S3endpoint 留空;region 为真实区域
Cloudflare R2endpoint 为 R2 S3 API;region auto
MinIO填 endpoint,强制 path-style
其他兼容实现按对方文档;多数要 path-style

CI 与桌面客户端必须能访问该 endpoint(上传 PUT、下载跟 302)。Shukka 主机也必须能 Head/Get/Delete(finalize 与删版本时用)。Presigned URL 有效期 1 小时。

本机 MinIO(可选)

Shukka 随镜像带对象存储。需要自建 S3 时另起 MinIO,再在面板创建 app(MinIO:填 endpoint、勾 path-style;向导默认 region us-east-1)。GitHub Actions 必须能从公网打到该 endpoint——上传由 CI 直传,不经过 Shukka。仓库没有 docker-compose.yml;需要时自行把 Shukka 容器与 MinIO 写在同一份 compose 里,Shukka 仍只挂自己的数据卷。

备份与升级

备份边界是整个数据目录(默认 ./data / 容器内 /data):shukka.db、WAL(shukka.db-wal / shukka.db-shm)、encryption.key。只拷数据库、丢掉密钥,就解不开已存的 S3 secret。

建议停写后拷整个目录,或:

sqlite3 /data/shukka.db ".backup /tmp/shukka-backup.db"

并同时复制 encryption.key。制品在各 app 的 bucket 里,单独做 bucket 版本或生命周期管理,不在数据目录里。

升级:拉新镜像或 git pull && npm ci && npm run build,停旧进程,用同一数据目录启动新进程。启动时会自动执行数据库迁移。同一数据目录不要同时跑两个 Shukka 进程。回滚:换回旧镜像 / 旧构建,保留数据目录。

探活 / 冒烟

进程探活用未鉴权的 health 接口:

curl -sS "$SHUKKA_URL/api/health"
# {"status":"ok","db":"ok"}            正常
# {"status":"degraded","db":"down"}    进程在但数据库不可用(HTTP 503)

忘记密码

没有邮箱找回。停掉写入后打开数据目录里的 SQLite,删掉管理员行与 session,重启后重走 setup:

sqlite3 /var/lib/shukka/shukka.db "DELETE FROM admin; DELETE FROM sessions;"

Docker 卷里默认在 /data/shukka.db。删的是密码与登录态,app / channel / 版本记录还在。

常见失败

现象原因与处理
重启后回到 setup数据卷没挂上,或 SHUKKA_DATA_DIR / SHUKKA_DB_PATH 指向空目录
能登录但改 / 建 app 报 storage 错只恢复了 .db,没有同目录的 encryption.key
启动后表结构旧进程未从应用根启动,数据库迁移未执行
创建 app 报 storage_error凭证、bucket、endpoint、path-style 配置错,或 Shukka 主机到 S3 不通
CI finalize 成功但客户端下不下来客户端到 S3 不通;或 Tauri feed 里的 urlhttp://(见 TLS 节)
登录成功但 cookie 没带上面板 origin 与 API origin 不一致(反代拆了主机名)
升级后数据没了新容器没挂原来的卷

On this page