Skip to content

Tailscale sidecar 付き multi-user Docker 配備を実地検証する #93

@terisuke

Description

@terisuke

目的

小規模チームが Note Maker を1台のホストで共有できる Tier 3 Docker 配備を実地検証する。範囲は LAN / VPN 前提で、public internet SaaS 化は対象外。

現在の状態

ソース側の準備は develop に入っている。

  • non-root Docker image
  • compose.yaml の app service
  • optional Tailscale sidecar profile
  • sidecar healthcheck: tailscale status
  • MULTI_USER=1 trusted-header auth
  • SQLite user_id migration
  • two-user isolation e2e
  • GHCR multi-arch workflow dry-run path
  • TS_AUTHKEY 未設定時の fail-fast
  • scripts/release-readiness-check.sh
  • 詳細手順は docs/handoffs/open-issues-field-validation-2026-05-04.mddocs/operations/docker-deployment-runbook.md にある

現在の外部 blocker:

  • real TS_AUTHKEY での sidecar 起動は未実施
  • workflow files は main に到達するまで manual dispatch できない
  • GHCR publish と target architecture runtime smoke は未実施

ローカル確認

git checkout develop
git pull --ff-only origin develop
docker build -t note-maker:dev .
docker image inspect note-maker:dev --format '{{.Size}} {{.Architecture}} {{.Os}}'
docker compose config
docker compose --profile tailscale config
python3 -m pytest tests/e2e/test_multi_user_isolation.py -q
RUN_MULTI_ARCH_BUILD=0 RUN_TAILSCALE_STARTUP=1 ./scripts/release-readiness-check.sh
git diff --check

期待値:

  • image size が 100 MB 未満
  • container が non-root で動く
  • /healthz は public
  • MULTI_USER=1 で trusted header なしの protected API は 401
  • trusted header ありなら protected API は 200
  • user A が user B の draft を読めない
  • TS_AUTHKEY 空なら sidecar は interactive auth 待ちせず fail-fast

real Tailscale sidecar 検証

uncommitted shell または uncommitted .env で reusable auth key を渡す。

export TS_AUTHKEY='tskey-auth-...'
export TS_HOSTNAME='note-maker-test'
docker compose --profile tailscale up -d tailscale app-via-tailscale

確認:

docker compose --profile tailscale ps
docker compose --profile tailscale logs --tail=200 tailscale
docker compose --profile tailscale logs --tail=200 app-via-tailscale
curl -i http://127.0.0.1:${NOTE_MAKER_TAILSCALE_HOST_PORT:-8081}/healthz
curl -i http://127.0.0.1:${NOTE_MAKER_TAILSCALE_HOST_PORT:-8081}/api/models

終了:

docker compose --profile tailscale down

記録すること:

  • docker compose ps
  • tailscale logs
  • app logs
  • /healthz response
  • /api/models response
  • TS_AUTHKEY 自体は貼らない

GHCR dry-run と publish

workflow files が main に到達してから dry-run を実行する。

gh workflow run docker-publish.yml --repo terisuke/note_maker --ref main \
  -f dry_run=1

本番 publish は release tag または non-dry dispatch で実行する。

manifest 確認:

docker buildx imagetools inspect ghcr.io/terisuke/note_maker:<tag>

runtime smoke:

docker run --rm -p 8080:8080 ghcr.io/terisuke/note_maker:<tag>
curl -i http://127.0.0.1:8080/healthz

linux/amd64linux/arm64 の両方で確認する。

Close 条件

次をすべて満たしたら close する。

  • docker build -t note-maker:dev . が成功し image size が 100 MB 未満
  • real TS_AUTHKEY で sidecar + app が起動する
  • sidecar healthcheck が healthy になる
  • app が sidecar profile 経由で /healthz/api/models を返す
  • 0004_user_id.sql migration と backfill が data loss なく機能する
  • two-user isolation e2e が pass する
  • default mode (MULTI_USER unset/0) が Tier 1 / Tier 2 挙動を保つ
  • GHCR multi-arch publish が成功する
  • manifest に linux/amd64linux/arm64 がある
  • target architecture 上で runtime smoke が pass する
  • runbook が start / upgrade / backup / restore / Tailscale troubleshooting を案内できる

Close してはいけない条件

  • TS_AUTHKEY なしの fail-fast だけで終わっている
  • GHCR dry-run だけで publish していない
  • manifest を見ていない
  • arm64 または amd64 の片方だけでしか smoke していない
  • multi-user isolation の証跡がない

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions