セルフホスト¶
アップデート¶
Tally は起動時に追加的なスキーママイグレーションを自動適用するため、データは
保持されたまま更新できます。リリースは stable ブランチとバージョンタグ
(v1.0.0 など)で管理しています。
検証済みの最新版を配信する stable ブランチを使います。
特定リリースに固定、または以前の版へロールバックしたい場合はタグを使います。
データの保存先¶
既定では、DB とバックアップは Docker 管理の名前付きボリューム(tally-data)に
保存されます。外部ストレージなど任意のホストディレクトリに置きたい場合は、
.env の TALLY_DATA_DIR にホストパスを指定するだけで切り替えられます。
# 1. 保存先ディレクトリを作成
sudo mkdir -p /mnt/storage/tally/data
# 2. .env に指定
echo "TALLY_DATA_DIR=/mnt/storage/tally/data" >> .env
# 3. 起動(既存コンテナは再作成)
docker compose up -d --build
これで /mnt/storage/tally/data/tally.db(DB)と .../backups/(自動バックアップ)
がそのディレクトリに置かれ、サーバ内蔵ディスクにはデータが残りません。DATABASE_URL
は file:/data/tally.db のまま変更不要です(/data はコンテナ内パスで、その実体を
TALLY_DATA_DIR が決めます)。
SQLite とネットワークストレージ
保存先はローカルにマウントされたディスクを推奨します。NFS / SMB などの ネットワークファイルシステムは SQLite のファイルロックが不安定になることが あります。
既存データの移行
すでに名前付きボリュームで運用している場合は、切り替え前に tally.db を
新しいディレクトリへコピーしてください(例:
docker compose cp tally:/data/tally.db /mnt/storage/tally/data/tally.db)。
バックアップ¶
自動バックアップ¶
Tally は SQLite の VACUUM INTO を使って整合性のあるバックアップを定期的に
作成します(既定で有効)。保存先はデータと同じボリューム内の backups/
(例: /data/backups/tally-YYYYMMDD-HHmmss.db)で、古い世代は自動的に整理され
ます。
- 間隔・世代数・保存先は環境変数で調整(はじめに を参照):
BACKUP_ENABLED/BACKUP_INTERVAL_HOURS/BACKUP_KEEP/BACKUP_DIR - 設定 → バックアップで状態を確認し、「今すぐバックアップ」を手動実行できます。
バックアップはボリューム内にあるため、ボリュームごと(またはホストのバックアップ 先へ)コピーして保全してください:
手動バックアップ / 復元¶
すべては 1 つの SQLite ファイルに保存されています:
ファイルをボリュームに戻して再起動すれば復元できます。アプリ内の CSV / JSON エクスポートでも、サブスクの可搬コピーを取得できます。
セキュリティチェックリスト¶
- 強く固定の
SESSION_SECRETを設定する(コミットしない)。 - HTTPS で配信する(リバースプロキシまたは Tailscale)。リクエストが
x-forwarded-proto: httpsで届くとセッション Cookie にSecureが付与 されます。 - アカウント作成後、
DISABLE_REGISTRATION=1で新規登録を止める。 - 送信先 Webhook(Discord / 汎用 / ntfy)は任意ホストを許可 — URL は自分で
管理する(Slack のみ
hooks.slack.comに限定)。 - パスワードは bcrypt でハッシュ化、セッションは署名付き JWT。
インターネット公開時の注意
初期セットアップができるよう、登録はデフォルトで開放されています。
インスタンスがインターネットから到達可能な場合は、自分のアカウントを作成
したらすぐに DISABLE_REGISTRATION=1 でロックしてください。
パスワードを忘れた場合¶
ユーザー一覧を確認したり、ハッシュを消してパスワードをリセット(次回ログイン 時に再設定)できます。例 — ユーザー名の一覧:
docker compose exec -T tally node -e "const{PrismaClient}=require('@prisma/client');const p=new PrismaClient();p.user.findMany().then(u=>{console.log(u.map(x=>x.username));return p.\$disconnect()})"
タイムゾーン¶
通知の送信時刻はコンテナのタイムゾーンを使用します。docker-compose.yml か
.env で TZ(既定 Asia/Tokyo)を設定してください。