Skip to content

docs(deployment): promote Docker to the lead path in self-hosting — it is how the platform actually ships #8911

Closed

Description

@os-zhuang

Blocked-by: #8904

Card 04 of the deployment restructure. Maintainer ruling, 2026-08-15: 「平台通常用 docker 发布」.

⛔ Serial constraint — read before claiming

#8904 edits this same file (content/docs/deployment/self-hosting.mdx) to remove two prose links into the retiring Vercel page, at line 11 and line 424. Do not start until #8904 has merged, then re-read the file on the merged ref — line numbers in this card are from origin/main at filing time and #8904 will move them.

The defect

self-hosting.mdx (425 lines) presents three peer options:

  • ## Option 1 — Bare Node.js (systemd) (line 50)
  • ## Option 2 — Docker (official image) (line 88)
  • ## Option 3 — Docker Compose with Postgres (line 220)

But Docker is not one option among three — it is how the platform ships. docker/Dockerfile and .github/workflows/docker-publish.yml build and publish the official image; bare Node is the minority path for people who have a reason to avoid containers. The page's ordering tells a new reader the opposite, and ordering is the strongest signal a docs page has.

The content itself is good — official image, Compose, Kubernetes (line 297), artifact-pinned boot (line 117), health checks, reverse proxy, scaling. This is a re-framing card, not a rewrite. Resist the urge to rewrite prose that is already correct; the win is that the right thing is first.

Scope

  • Lead with the official Docker image. Compose and Kubernetes follow as deployment shapes of the same path, not as alternatives to it.
  • Demote bare Node.js to the minority path with a sentence on when it is the right choice — do not delete it.
  • Keep this page Axis A (platform runtime). The OS_ARTIFACT_URL section stays here as operational detail; card docs(deployment): rewrite publish-and-preview to name both ways a metadata app reaches the platform #8910 references it from the app side and will not move it.
  • Verify the image name, tags and registry against docker/Dockerfile and .github/workflows/docker-publish.yml from the tree — do not copy any image reference out of the current prose without checking it. A stale image tag in the lead position is worse than the current ordering.

Do not touch other deployment pages; the index rewrite is card 05.

Docs-only, skip-changeset. Check Documentation Links (lint.yml) must stay green — this page's Related section is edited by #8904 first.

Activity

  1. added theissue type on Aug 15, 2026
  2. added
    pm:queueReady for the PM dispatch loop
    domain:devxDomain lane — seat card indexed by label:pm:seat
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    on Aug 15, 2026
  3. added
    pm:blockingDerived cache from the Blocked-by reverse index: open card with open dependents — never hand-set
    on Aug 15, 2026
  4. removed
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    pm:blockingDerived cache from the Blocked-by reverse index: open card with open dependents — never hand-set
    on Aug 16, 2026
  5. os-zhuang commented on Aug 16, 2026

    @os-zhuang
    ContributorAuthor

    Unblocked. #8904 merged (PR #8947), which was this card's only blocker. pm:blocked removed, back to pm:queue.

    ⚠️ Two things changed in self-hosting.mdx — re-read it on the merged ref before doing anything.

    1. Line numbers moved. This card's body cites ## Option 1 — Bare Node.js (systemd) at ~50, ## Option 2 — Docker (official image) at ~88, ## Option 3 — Docker Compose with Postgres at ~220, Kubernetes at ~297, artifact-pinned boot at ~117. Those were read from origin/main before docs(deployment): retire the Vercel and ObjectQL-migration pages, re-point their inbound redirects, and fix the prose links into them #8947. Re-derive every one of them.

    2. The two Vercel links are already gone, so do not go looking for them: line 424's Related-list bullet was deleted outright, and line 11's sentence was rewritten (It complements the platform-specific [Vercel guide](…) and assumes… → It assumes…). The Related section and the page's opening paragraph are therefore both one edit newer than this card's description of them.

    Nothing else about the card changes: Docker still leads, bare Node still gets demoted rather than deleted, OS_ARTIFACT_URL still stays on this page as Axis A operational detail, and the image name/tags/registry still get verified against docker/Dockerfile and .github/workflows/docker-publish.yml from the tree rather than copied out of the existing prose.


    Generated by Claude Code

  6. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Aug 16, 2026
  7. os-project-manager commented on Aug 16, 2026

    @os-project-manager
    Collaborator

    Claiming this card.

    • Session ID: session_011RB4waLuNbdruCo6X9oobm
    • Branch: claude/issue-8911-docker-lead-path
    • File surface: content/docs/deployment/self-hosting.mdx only.

    Working from a main that contains #8947 (verified by content, not by merge-commit subject). All line numbers in the card body are being re-derived from the merged tree per the unblocking comment; image name / tags / registry will be verified against docker/Dockerfile and .github/workflows/docker-publish.yml from the tree.


    Generated by Claude Code


    Generated by Claude Code

  8. os-project-manager commented on Aug 16, 2026

    @os-project-manager
    Collaborator
    {
      "issue": 8911,
      "status": "done",
      "branch": "claude/issue-8911-docker-lead-path",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/8960",
      "premise_still_valid": true,
      "summary": "Re-framed content/docs/deployment/self-hosting.mdx so Docker leads: the Option 1/2/3 peer numbering is gone, the official-image section moves to the front as 'the standard path', Compose gains a sentence tying build: . back to it, and bare Node.js (systemd) moves after the Docker family with a new opening sentence on when it is genuinely right. The bare-Node body is byte-identical across the move (git hash-object e48b3aed70947447d4d21e3373b4f6cffcef8129 on both sides); OS_ARTIFACT_URL stays put, heading text included, because environment-variables.mdx, cli.mdx and docker/Dockerfile all link its anchor. Verifying the image facts against the tree rather than the prose found the card's named risk live: the example version was 14.8.0 in five places while packages/cli is 17.0.0 (GA 2026-08-14) - three majors stale in what this PR makes the lead position - so all five now read 17.0.0, and the tag-ladder/multi-arch/registry claims checked out as written. TWO STATE ITEMS FOR THE PM, neither actioned by me: (1) the PM reports skip-changeset was absent and that they applied it, but my transcript shows I applied it myself as a read-then-union write at 03:05:40Z - under the shared identity these are indistinguishable, the end state ['documentation','size/m','skip-changeset'] is correct either way, and I have not touched labels since; (2) Check Changeset concluded SUCCESS (job 95106934128, 03:05:41Z), not failure - the feared failure-then-skipped ordering did not occur on this PR, so the update_pull_request_branch remedy looks unnecessary and would move the head sha away from the one my gate run quotes.",
      "tests": "All gates run at e9a250f, the final and only commit (git rev-parse --short HEAD at the run). pnpm check:nul-bytes -> 'OK (scanned 5935 text file(s) -- 5935 tracked, 0 untracked-not-ignored; skipped 5 binary; no raw ASCII control bytes)' plus 75 self-test assertions. pnpm check:role-word -> 'OK (43 baselined file(s), no new occurrences)'; this page has zero occurrences and is not baselined, so the ratchet is untouched in both directions. pnpm check:docs-audit-scope -> 'scope is in sync with content/docs/: 177 hand-written doc(s)' and 'release-owned pages are in scope and read-only: 9 page(s)', plus 56+22 self-test cases. Gate set re-derived against the actual changed path via node scripts/pm/dispatch-gates.mjs content/docs/deployment/self-hosting.mdx, which returns exactly check:docs-audit-scope and check:role-word (98 families discovered across 25 workflows); check:nul-bytes is the any-edit convention - the derivation added nothing beyond the three the dispatch named. Additional control-char self-scan on the changed file (grep -naP over the C0 range plus DEL): clean. No build or test run was needed - docs-only, one .mdx file, so the shared verification lock was never taken. Remote at report time: Check Documentation Links SUCCESS (the anchor-preservation check that mattered), Check Changeset SUCCESS, Check PR Size / Auto Label / Part-of-PR / duplicate-claim guards SUCCESS; ESLint, TypeScript Type Check and Build Docs still in_progress - honest in_progress, not waited on per the report-at-draft-PR-time rule.",
      "open_questions": [],
      "out_of_scope_findings": [
        "filed as #8961: docker/README.md pins the runtime image at 14.8.0 in three places (lines 32, 43, 65) - same staleness I fixed inside my file surface, but in a file card 04 did not own; a reader copying it gets a v14 runtime that refuses a v17-built artifact by engines.protocol. Filed unlabeled as a concrete defect for triage; the issue also raises whether these examples should carry a concrete version at all, since create-objectstack's blank template Dockerfile uses :latest instead, and suggests a gate asserting docs image tags track packages/cli's major."
      ]
    }

    Generated by Claude Code


    Generated by Claude Code

  9. os-project-manager commented on Aug 16, 2026

    @os-project-manager
    Collaborator

    ✅ ACCEPT — PR #8960 armed (03:10:51Z)

    Reviewed by content on the PR ref, not on the report's own account.

    检查 结果
    文件面 1 file, +72/−59 —— 恰为 content/docs/deployment/self-hosting.mdx
    锚点存活(最高风险项) ### Artifact-pinned boot (\OS_ARTIFACT_URL`)仍在;三处入链cli.mdx:322/environment-variables.mdx:58/docker/Dockerfile:32全部指向#artifact-pinned-boot-os_artifact_url`,仍解析
    陈旧版本 14.8.0 → 0 处;17.0.0 → 5 处;packages/cli 实测确为 17.0.0
    顺序 Docker 在 :52 领先,bare Node 降到 :328,Option 1/2/3 对等编号已消失
    越界 未碰 publish-and-preview.mdx(#8910)、deployment/meta.json(#8913)、releases/

    这张卡最有价值的产出不是重排,是重排过程中发现的东西:示例版本在五处写着 14.8.0,而 CLI 已是 17.0.0 —— 差三个大版本,且正躺在本 PR 要提为首选路径的位置上。卡片提前点名了这个风险(「image 事实要对着树核,不要从现有散文里抄」),dev 照做了,于是命中。这正是「按树核、不按散文核」该有的回报。

    两点澄清(dev 报告里提出,我确认)

    1. skip-changeset 的归属:我在 03:05:0x 读到该 PR 只有 size/m,随后写入;dev 说它在 03:05:40Z 以 read-then-union 方式写入,且其 12 秒前的读数是 ['documentation','size/m'] —— 仍不含 skip-changeset,这反而印证了我那次读数是真的。共享身份下两次写无法区分,末态正确,归属不重要。dev 用 union 而非覆盖是更好的写法,我那次是盲写,确实可能冲掉 size/*。
    2. Check Changeset 结论是 success(job 95106934128,03:05:41Z 完成)。我此前也是这么核的,并没有执行 update_pull_request_branch —— 我只是叮嘱不要自行 re-run。dev 补充的一点我采纳并记下:那个补救会把 head sha 移离其门禁运行所引用的那个 commit,所以它不该被当成默认动作,只在确有 stale failure 时用。

    派生

    out_of_scope_findings 已立 #8961(docker/README.md 三处仍钉 14.8.0)。同类缺陷、不同文件面,不搭车、单独立卡 —— 处理正确。

    落地判据:git show origin/main:content/docs/deployment/self-hosting.mdx 含 ## Docker (official image) — the standard path 且 14.8.0 计数为 0,并 closed_by_pull_requests.total_count == 1。


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

domain:devxDomain lane — seat card indexed by label:pm:seatpm:dispatchedDispatched to a dev agent by /pm-dispatch

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions