Skip to content

feat: docker self hosting#67

Merged
ian-pascoe merged 26 commits into
mainfrom
feat/docker-self-hosting
May 21, 2026
Merged

feat: docker self hosting#67
ian-pascoe merged 26 commits into
mainfrom
feat/docker-self-hosting

Conversation

@ian-pascoe

@ian-pascoe ian-pascoe commented May 21, 2026

Copy link
Copy Markdown
Contributor

This pull request introduces and refines documentation and conventions for RLM curation runtime workflows and Docker image publishing in the release pipeline. The key changes focus on clarifying the curation flow (especially single-pass and chunked extraction, verification, and timeout requirements), capturing project outcomes for Docker self-hosting, and updating related facts and plans for better maintainability and traceability.

Curation Runtime Conventions

  • Added and updated documentation to clearly define the RLM curation workflow, emphasizing:
    • When to use single-pass versus chunked extraction, including the use of mapExtract with a bare taskId and a 300000ms timeout for code_exec calls. [1] [2] [3] [4] [5] [6]
    • Verification should always be performed via result.applied[].filePath and must not use readFile. [1] [2] [3] [4] [5]
    • The workflow should never print raw context or recompute recon if it's already available. [1] [2] [3]
    • Added a new context summary file and improved cross-references between convention documents. [1] [2]

Project Implementation Plans and Outcomes

  • Documented the implementation plan and successful verification for Docker self-hosting, including file locations, commit hashes, and formatting validation.
  • Updated project facts to reflect the creation and verification of the Docker self-hosting plan and to capture the assistant's execution options and actions. [1] [2]

Release Pipeline and Docker Image Publishing

  • Added a plan for Docker image publishing in the release workflow, specifying that Docker images should only be published to GHCR after npm packages are released, with proper permissions and gated steps.

These changes ensure the curation workflow is consistent, verifiable, and well-documented, and that release and deployment processes are traceable and robust.

Summary by CodeRabbit

  • New Features

    • Docker and Docker Compose support for self-hosting the Caplets HTTP service with persistent configuration
    • Automated Docker image publishing to GHCR with version-based tagging during package releases
  • Documentation

    • Added comprehensive Docker Compose setup guide in README with environment variable configuration options
    • Added implementation and design specifications for Docker self-hosting and GHCR publishing

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@ian-pascoe has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 58 minutes and 7 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3cd02333-39e8-4620-b349-971812006cca

📥 Commits

Reviewing files that changed from the base of the PR and between 745d519 and fa2f9a9.

⛔ Files ignored due to path filters (39)
  • .brv/.gitignore is excluded by !.brv/**
  • .brv/context-tree/architecture/auth/context.md is excluded by !.brv/**
  • .brv/context-tree/architecture/auth/remote_auth_and_state_ownership.md is excluded by !.brv/**
  • .brv/context-tree/architecture/auth/remote_auth_review_findings.md is excluded by !.brv/**
  • .brv/context-tree/architecture/remote_control/caplets_interface_ux.md is excluded by !.brv/**
  • .brv/context-tree/architecture/remote_control/caplets_remote_control_module.md is excluded by !.brv/**
  • .brv/context-tree/architecture/remote_control/cli_remote_mode_selection.md is excluded by !.brv/**
  • .brv/context-tree/architecture/remote_control/context.md is excluded by !.brv/**
  • .brv/context-tree/architecture/remote_control/context_module.md is excluded by !.brv/**
  • .brv/context-tree/architecture/remote_control/remote_control_api_shape.md is excluded by !.brv/**
  • .brv/context-tree/architecture/remote_control/remote_control_context.md is excluded by !.brv/**
  • .brv/context-tree/architecture/remote_control/task_1_spec_compliance_review.md is excluded by !.brv/**
  • .brv/context-tree/architecture/remote_control/unified_environment_variable_interface.md is excluded by !.brv/**
  • .brv/context-tree/architecture/remote_control/working_module.md is excluded by !.brv/**
  • .brv/context-tree/facts/conventions/context.md is excluded by !.brv/**
  • .brv/context-tree/facts/conventions/curate_runtime_conventions.md is excluded by !.brv/**
  • .brv/context-tree/facts/conventions/curation_runtime_conventions.md is excluded by !.brv/**
  • .brv/context-tree/facts/conventions/rlm_curate_runtime_conventions.md is excluded by !.brv/**
  • .brv/context-tree/facts/conventions/rlm_curation_runtime_conventions.md is excluded by !.brv/**
  • .brv/context-tree/facts/conventions/task_3_spec_review_fix.md is excluded by !.brv/**
  • .brv/context-tree/facts/conventions/task_5_regression_test_update.md is excluded by !.brv/**
  • .brv/context-tree/facts/conventions/task_6_review_outcome.md is excluded by !.brv/**
  • .brv/context-tree/facts/conventions/task_7_remote_mutation_routing_review.md is excluded by !.brv/**
  • .brv/context-tree/facts/conventions/task_7_review_outcome.md is excluded by !.brv/**
  • .brv/context-tree/facts/conventions/task_9_remote_config_test_fix.md is excluded by !.brv/**
  • .brv/context-tree/facts/conventions/trivial_continuation_marker.md is excluded by !.brv/**
  • .brv/context-tree/facts/project/context.md is excluded by !.brv/**
  • .brv/context-tree/facts/project/curate_runtime_conventions.md is excluded by !.brv/**
  • .brv/context-tree/facts/project/curation_context_facts.md is excluded by !.brv/**
  • .brv/context-tree/facts/project/curation_input_notes.md is excluded by !.brv/**
  • .brv/context-tree/facts/project/curation_runtime_conventions.md is excluded by !.brv/**
  • .brv/context-tree/facts/project/greptile_review_comments.md is excluded by !.brv/**
  • .brv/context-tree/facts/project/pr_65_fixes_and_verification.md is excluded by !.brv/**
  • .brv/context-tree/facts/project/project_knowledge_notes.md is excluded by !.brv/**
  • .brv/context-tree/facts/project/remote_control_review_outcome.md is excluded by !.brv/**
  • .brv/context-tree/facts/project/rlm_curate_runtime_conventions.md is excluded by !.brv/**
  • .brv/context-tree/facts/project/rlm_curation_workflow.md is excluded by !.brv/**
  • .brv/context-tree/facts/project/task_6_spec_review_after_envelope_fix.md is excluded by !.brv/**
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (17)
  • .brv
  • .changeset/funny-news-act.md
  • .coderabbit.yaml
  • .github/workflows/release.yml
  • .gitmodules
  • .greptile/config.json
  • .husky/pre-commit
  • .husky/pre-push
  • .opencode/opencode.json
  • .pi/settings.json
  • Dockerfile
  • docker-compose.yml
  • docs/plans/2026-05-21-docker-self-hosting.md
  • docs/plans/2026-05-21-ghcr-release-publishing.md
  • docs/specs/2026-05-21-ghcr-release-publishing-design.md
  • packages/pi/package.json
  • scripts/commit-brv-submodule.sh
📝 Walkthrough

Walkthrough

This pull request introduces Docker-based containerization and local self-hosting infrastructure for the Caplets service, integrates Docker image publishing into the release workflow gated on Changesets publication, and updates RLM curation runtime conventions documentation with formalized constraints and verification rules.

Changes

Docker Self-Hosting Implementation

Layer / File(s) Summary
Docker build context and multistage Dockerfile
.dockerignore, Dockerfile
.dockerignore excludes development metadata, build artifacts, and state; multistage Dockerfile uses Corepack-pinned pnpm@11.0.9, installs frozen deps, builds the monorepo, and produces a runtime image with XDG-based persistent /data state and HTTP server on port 5387.
Docker Compose service and volume management
docker-compose.yml
Defines caplets service built from root Dockerfile with unified CAPLETS_* environment variables, configurable external bind address/port, named-volume persistence at /data, and HTTP /healthz health check on localhost.
Self-hosting user guide in README
README.md
New "Docker Compose self-hosting" section documents default loopback endpoints, named-volume and bind-mount storage options, LAN/reverse-proxy exposure via environment variables, and HTTPS/Basic Auth configuration.
Docker self-hosting implementation plan and design spec
docs/plans/2026-05-21-docker-self-hosting.md, docs/specs/2026-05-21-docker-self-hosting-design.md
Implementation plan specifies step-by-step tasks for build artifacts, Compose config, and README updates with verification steps; design spec outlines multistage Dockerfile architecture, Corepack/pnpm pinning, XDG path usage, and health check contract.
Docker self-hosting implementation fact record
.brv/context-tree/facts/project/docker_self_hosting_implementation_plan.md
Records planning outcome with metadata, saved plan file, commit hash, and formatting verification command.

GHCR Release Publishing Workflow

Layer / File(s) Summary
Release workflow permissions, step ID, and Docker publishing
.github/workflows/release.yml
Added packages: write permission; assigned id: changesets to Changesets action; added conditional Docker Buildx setup, GHCR login, Docker metadata generation, and build/push to GHCR gated on steps.changesets.outputs.published == 'true'.
GHCR release publishing implementation plan and design spec
docs/plans/2026-05-21-ghcr-release-publishing.md, docs/specs/2026-05-21-ghcr-release-publishing-design.md
Implementation plan details step-by-step workflow modifications (permissions, gating, Docker steps) and verification tasks; design spec documents conditional gating logic, GHCR tag scheme (latest, version, v-prefixed, sha-based), and security/permission requirements.
Release pipeline planning context
.brv/context-tree/docs/plans/docker_image_publishing_for_release_pipeline.md
Documents approved release workflow changes for GHCR publishing, including Changesets-success gating condition, required packages: write permission, and Docker login/metadata/build-push sequence.

RLM Curation Runtime Conventions and Planning Context

Layer / File(s) Summary
RLM curation runtime convention updates
.brv/context-tree/facts/conventions/rlm_curate_runtime_conventions.md, .brv/context-tree/facts/conventions/rlm_curation_runtime_conventions.md
Formalized single-pass-first workflow with precomputed recon, forbidding tools.curation.recon calls, requiring timeout: 300000 for mapExtract-using code_exec calls, enforcing bare taskId parameter, and mandating verification via result.applied[].filePath without readFile.
Curation runtime conventions documentation structure
.brv/context-tree/facts/curation_runtime_conventions/context.md, .brv/context-tree/facts/curation_runtime_conventions/rlm_curate_runtime_conventions.md, .brv/context-tree/facts/project/curation_runtime_conventions.md, .brv/context-tree/facts/project/rlm_curation_run_constraints.md
Created nested documentation structure with overview and detailed conventions; updated project-level documents to formalize RLM-based context processing constraints with explicit rules, Flow/Patterns sections, and verification expectations.
Planning roadmap index and caplets runtime facts
.brv/context-tree/docs/plans/context.md, .brv/context-tree/docs/plans/active_caplets_planning_documents.md, .brv/context-tree/facts/project/caplets_runtime_and_caplet_files.md
Added planning context overview; consolidated active planning references with GHCR workflow facts and validation evidence; documented caplet repository structure and integration-area file layout.
Documentation convention clarification
AGENTS.md
Clarified approved documentation directories (docs/specs/, docs/plans/, docs/product/) and banned docs/superpowers/ usage.

🎯 3 (Moderate) | ⏱️ ~25 minutes

🐰 A Dockerfile springs to life,
Docker Compose eases the strife,
Release pipelines flow,
Conventions now glow,
And self-hosting thrives in the light! 🚀

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: docker self hosting' directly reflects the primary change: implementation of Docker-based self-hosting infrastructure including Dockerfile, docker-compose.yml, build workflows, and documentation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/docker-self-hosting

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 20

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/release.yml (1)

9-13: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Scope packages: write at the job level to avoid future over-permission
.github/workflows/release.yml currently has only a single job (release), so the broader scope isn’t harmful today—but workflow-level packages: write will apply to any future jobs added to this workflow.

Suggested change
 permissions:
   contents: write
   pull-requests: write
   id-token: write
-  packages: write

 jobs:
   release:
     name: Version or Publish
     runs-on: ubuntu-latest
+    permissions:
+      contents: write
+      pull-requests: write
+      id-token: write
+      packages: write
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 9 - 13, Move the broad `packages:
write` permission out of the top-level `permissions` block and instead scope it
to the existing `release` job so future jobs won't inherit it; update the
workflow by removing the `packages: write` entry from the global `permissions`
section and adding `permissions: packages: write` under the `release` job (the
job named "release") to limit the write scope to that job only.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.brv/context-tree/docs/plans/active_caplets_planning_documents.md:
- Line 10: Add blank lines immediately before and after each Markdown heading to
satisfy markdownlint MD022: specifically insert an empty line above and below
the "## Reason" heading and do the same for the other headings noted in the
comment (the headings at the ranges referenced). Update the heading blocks
(e.g., "## Reason" and the headings at 13, 44-45, 48, 51, 54, 57) so each has a
preceding and trailing blank line.
- Around line 58-59: Replace the user-specific absolute filesystem paths inside
the two "**curated_context_line**" entries (the lines that currently contain
"/home/ianpascoe/code/caplets/plan.md" and
"/home/ianpascoe/code/caplets/progress.md" and the later full-path mention) with
repo-relative paths or neutral placeholders (e.g., "code/caplets/plan.md" or
"<repo>/caplets/plan.md"), and update the second curated_context_line to remove
the username and absolute path (e.g., "Fresh context in code/caplets"); also
scan other occurrences of the symbol "curated_context_line" in the document to
redact any remaining absolute paths and replace them with repository-relative
paths or placeholders to avoid leaking environment-specific details.

In @.brv/context-tree/docs/plans/context.md:
- Line 3: Add blank lines before and after markdown headings to satisfy MD022:
ensure the "## Overview" heading has an empty line immediately above and an
empty line immediately below it (and do the same for the other heading instance
noted), updating the headings in this file so each heading is surrounded by a
single blank line.

In
@.brv/context-tree/docs/plans/docker_image_publishing_for_release_pipeline.md:
- Line 10: The Markdown headings in this file (e.g., the "## Reason" heading and
other headings at the noted locations) are missing required blank lines; update
the document so there is a single blank line before and after each heading
(normalize spacing consistently across all headings listed: lines referenced
around 13, 32, 33, 36, 39, 42, 45, 48), ensuring each heading is separated from
surrounding paragraphs with one empty line to satisfy MD022.

In @.brv/context-tree/facts/conventions/rlm_curate_runtime_conventions.md:
- Line 10: Add blank lines above and below each Markdown heading in this
document so they are surrounded by empty lines (fixing MD022). Specifically,
ensure headings like "Reason" and the other headings referenced in the comment
have an empty line before and after them, adjusting the lines where headings
occur so every heading is separated from adjacent text by a blank line.
- Line 92: The document contains conflicting context-size facts for the same
recon run (one stating single-pass mode with charCount 1472, lineCount 25,
messageCount 0 and another different metric set), so consolidate by choosing one
authoritative context-size entry (or add an explicit annotation explaining why
both metrics coexist) inside rlm_curate_runtime_conventions.md; update the recon
result block(s) (the “single-pass” recon result entries) to either remove the
duplicate/mismatched entry or add a clarifying note referencing which metric is
canonical and why.

In @.brv/context-tree/facts/conventions/rlm_curation_runtime_conventions.md:
- Line 91: The definition of rlm_single_pass_flow conflicts with the
precomputed-recon rule: update the rlm_single_pass_flow convention so it does
not include a recon call when precomputed recon is required to be prohibited (or
add an explicit conditional note) — locate the rlm_single_pass_flow entry in
rlm_curation_runtime_conventions.md and either remove the "recon plus curate"
wording or add a clear exception that when "precomputed-recon" is in effect the
flow is curate-only; ensure the precomputed-recon rule and rlm_single_pass_flow
wording are consistent and unambiguous.
- Line 10: Add blank lines before and after each top-level and sub-heading to
satisfy markdownlint MD022: specifically insert an empty line above and below
the "## Reason" heading (and likewise for the other headings noted at lines 13,
77, 80, 83, 86, 89) so each heading is separated from surrounding paragraphs and
lists; search for the literal heading texts (e.g., "## Reason") in the file and
ensure there's exactly one blank line before and one blank line after each
heading.

In @.brv/context-tree/facts/curation_runtime_conventions/context.md:
- Line 3: Add required blank lines around Markdown headings to satisfy MD022:
ensure there is an empty line before and after the "## Overview" heading (and
the other heading noted at the same location), e.g., insert one blank line above
the "## Overview" line and one blank line below it so the heading is separated
from surrounding content; update any other headings in this file with the same
pattern (the other reported heading at lines 6-6) to match this spacing
convention.

In
@.brv/context-tree/facts/curation_runtime_conventions/rlm_curate_runtime_conventions.md:
- Line 10: Add a blank line before and after the markdown headings (e.g., the
"## Reason" heading and the other headings referenced) so they are surrounded by
empty lines to satisfy markdownlint MD022; update the headings in this document
(including the ones noted at the other locations) to have a single blank line
above and below each heading.
- Line 29: The regex in the markdown (`^taskId:s*__taskId_[a-f0-9_]+$`) uses
"s*" instead of an escaped whitespace token; update the pattern by replacing the
literal "s*" with the escaped whitespace sequence "\s*" so the line reads the
intended pattern with "\s*" between "taskId:" and "__taskId_..." (i.e., use
caret taskId colon backslash-s-star double-underscore taskId pattern) to
correctly match optional whitespace.

In @.brv/context-tree/facts/project/caplets_runtime_and_caplet_files.md:
- Around line 10-45: Add or normalize blank lines around the markdown headings
listed in this file so they comply with markdownlint MD022: ensure there is
exactly one blank line above and one blank line below each heading (or at least
a blank line after a heading at the top of the file). Specifically update the
headings "## Reason", "## Raw Concept", "## Narrative", "### Structure", "###
Dependencies", "### Highlights" and "## Facts" to have the required surrounding
blank lines; this will remove the MD022 warnings without changing heading text
or content.

In @.brv/context-tree/facts/project/curation_runtime_conventions.md:
- Line 10: Add a blank line after each Markdown heading in this file to satisfy
MD022; for example, insert an empty line immediately after headings like "##
Reason" and the other top-level and subheadings referenced in the file so there
is one blank line between the heading and the following paragraph or list
content, then repeat this for the other headings flagged by the linter to remove
the repeated warnings.

In @.brv/context-tree/facts/project/docker_self_hosting_implementation_plan.md:
- Around line 10-47: Add blank lines before and after each Markdown heading in
the file to satisfy MD022: ensure top-level headings like "## Reason", "## Raw
Concept", "## Narrative", and "## Facts" and nested headings such as "###
Structure" and "### Dependencies" each have a blank line above and below them
(i.e., separate headings from surrounding paragraphs or lists); update the
document around those heading tokens to insert the missing blank lines so
markdownlint passes.

In @.brv/context-tree/facts/project/rlm_curation_run_constraints.md:
- Line 10: Add blank lines before and after Markdown heading lines in
.brv/context-tree/facts/project/rlm_curation_run_constraints.md so headings are
separated by a blank line; specifically ensure the "## Reason" heading (and any
other headings in that file) has one blank line above and one blank line below
to resolve MD022 spacing issues.

In @.github/workflows/release.yml:
- Line 84: Pin each Docker GitHub Action invocation (e.g., the uses entries like
docker/setup-buildx-action@v3, docker/login-action@v3,
docker/metadata-action@v5, docker/build-push-action@v6) to their corresponding
full commit SHAs instead of tag versions, and narrow the repository permissions
by removing or reducing the global workflow-level permissions: packages: write
and instead grant only the minimal packages: write permission at the specific
job or step that performs the GHCR push (the job/step that runs the build/push
actions); update the uses entries to the SHA values and move the packages: write
permission into that job/step to limit scope.

In `@Dockerfile`:
- Around line 25-40: Add a non-root user in the runtime stage and a HEALTHCHECK
instruction: after COPY --from=build /app /app create a dedicated user/group
(e.g., caplets), chown /app and /data (or the XDG paths) to that user, set USER
to that non-root account before CMD so the container does not run as root, and
add a HEALTHCHECK that probes the service (for example using curl/wget against
http://127.0.0.1:5387/health or the CLI’s HTTP transport) with an appropriate
interval/retries to reflect service readiness; ensure file permissions allow the
new user to write XDG_CONFIG_HOME/XDG_STATE_HOME.

In `@docs/plans/2026-05-21-docker-self-hosting.md`:
- Around line 426-433: Update Step 5 ("Run repo-level non-Docker checks") so it
uses the repo-standard verification command: replace the separate commands `pnpm
lint` and `pnpm typecheck` with `pnpm verify` (or explicitly list the full
verify chain if you prefer to show what verify runs). Ensure the step text and
example command reflect `pnpm verify` exactly so local execution mirrors
CI/pre-push behavior and the plan matches the repository gating used in `pnpm
verify`.

In `@docs/plans/2026-05-21-ghcr-release-publishing.md`:
- Around line 98-139: The plan's Docker steps are gated only on
steps.changesets.outputs.published == 'true' but the workflow requires both
changesets and cli-package to be published; update every docker-step conditional
(e.g., the Read Docker image version step that sets id:image-version, the Setup
Docker Buildx, Log in to GitHub Container Registry, Generate Docker metadata
(id:docker-meta), and Publish Docker image) to also require
steps.cli-package.outputs.published == 'true' (combine the conditions with &&),
and mirror that same gating change in the verification checklist and the other
occurrences mentioned (around the blocks at 181-210 and 252-257) so the docs
match the implemented cli-package publish guard.

In `@docs/specs/2026-05-21-ghcr-release-publishing-design.md`:
- Line 13: Update the design doc to document both publish gates used by the
release workflow: explicitly state that Docker publish steps are gated on
steps.changesets.outputs.published == 'true' AND the CLI-package publish check
steps.cli-package.outputs.published == 'true' so future implementers include
both conditions; also move or ensure the doc remains under docs/specs/ (not
docs/superpowers/) per repo guidelines.

---

Outside diff comments:
In @.github/workflows/release.yml:
- Around line 9-13: Move the broad `packages: write` permission out of the
top-level `permissions` block and instead scope it to the existing `release` job
so future jobs won't inherit it; update the workflow by removing the `packages:
write` entry from the global `permissions` section and adding `permissions:
packages: write` under the `release` job (the job named "release") to limit the
write scope to that job only.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 29751464-9e5b-40a2-bb8b-692e6259f332

📥 Commits

Reviewing files that changed from the base of the PR and between 2b10a19 and 745d519.

📒 Files selected for processing (21)
  • .brv/context-tree/docs/plans/active_caplets_planning_documents.md
  • .brv/context-tree/docs/plans/context.md
  • .brv/context-tree/docs/plans/docker_image_publishing_for_release_pipeline.md
  • .brv/context-tree/facts/conventions/rlm_curate_runtime_conventions.md
  • .brv/context-tree/facts/conventions/rlm_curation_runtime_conventions.md
  • .brv/context-tree/facts/curation_runtime_conventions/context.md
  • .brv/context-tree/facts/curation_runtime_conventions/rlm_curate_runtime_conventions.md
  • .brv/context-tree/facts/project/caplets_runtime_and_caplet_files.md
  • .brv/context-tree/facts/project/curation_runtime_conventions.md
  • .brv/context-tree/facts/project/docker_self_hosting_implementation_plan.md
  • .brv/context-tree/facts/project/rlm_curation_run_constraints.md
  • .dockerignore
  • .github/workflows/release.yml
  • AGENTS.md
  • Dockerfile
  • README.md
  • docker-compose.yml
  • docs/plans/2026-05-21-docker-self-hosting.md
  • docs/plans/2026-05-21-ghcr-release-publishing.md
  • docs/specs/2026-05-21-docker-self-hosting-design.md
  • docs/specs/2026-05-21-ghcr-release-publishing-design.md

Comment thread .brv/context-tree/docs/plans/active_caplets_planning_documents.md Outdated
Comment thread .brv/context-tree/docs/plans/active_caplets_planning_documents.md Outdated
Comment thread .brv/context-tree/docs/plans/context.md Outdated
Comment thread .brv/context-tree/docs/plans/docker_image_publishing_for_release_pipeline.md Outdated
Comment thread .brv/context-tree/facts/conventions/rlm_curate_runtime_conventions.md Outdated
Comment thread .github/workflows/release.yml Outdated
Comment thread Dockerfile
Comment thread docs/plans/2026-05-21-docker-self-hosting.md
Comment thread docs/plans/2026-05-21-ghcr-release-publishing.md
Comment thread docs/specs/2026-05-21-ghcr-release-publishing-design.md Outdated
@greptile-apps

greptile-apps Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds Docker self-hosting support for the Caplets HTTP service via a multi-stage Dockerfile and docker-compose.yml, and wires up automated GHCR image publishing into the release workflow after npm packages are released. It also introduces a scripts/commit-brv-submodule.sh helper that auto-commits and pushes the .brv memory submodule through Husky hooks, and ships a patch changeset for @caplets/pi peer dependency resolution.

  • Dockerfile uses a proper multi-stage build: build stage installs/compiles everything, runtime stage selectively copies only root node_modules, packages/core/dist, and packages/cli/dist. QEMU + Buildx + linux/amd64,linux/arm64 multi-platform publishing is correctly wired into the release workflow behind a changesets gate.
  • Husky hooks now invoke scripts/commit-brv-submodule.sh before lint/verify; the pre-push path exits 1 after writing a new gitlink commit so the user must re-run git push to ship the updated parent pointer — intentional but notable for contributors."

Confidence Score: 5/5

The Docker infrastructure is well-structured and safe to merge; all previous review concerns have been addressed in this revision.

The multi-stage Dockerfile correctly isolates build and runtime artifacts, the release workflow gates Docker publishing behind a verified changesets output with the correct CLI package name, and QEMU + multi-platform support is properly configured. No logic errors or security issues were found in the changed code paths.

No files require special attention beyond the two-step git push behavior in scripts/commit-brv-submodule.sh.

Important Files Changed

Filename Overview
Dockerfile Multi-stage build with selective runtime COPY; only core/cli dist + root node_modules copied; proper healthcheck and non-root USER node.
.github/workflows/release.yml Adds QEMU, Buildx, multi-platform (amd64+arm64) Docker publish gated on changesets output; packages: write permission added; CLI package name check matches actual package.json name.
docker-compose.yml Loopback-only port binding by default, named volume for persistence, image tagged caplets:local (distinct from GHCR image), optional .env file support.
scripts/commit-brv-submodule.sh Auto-commits .brv submodule in pre-commit and pushes in pre-push; uses --no-verify for parent pointer commit (intentional); pre-push exits 1 after new gitlink commit, requiring a second push.
.dockerignore Correctly excludes node_modules, dist, .env files, dev tool dirs from build context; allows .env.example.
packages/pi/package.json Peer dependency range changed from >=0 to * (semantically equivalent); paired with patch changeset entry.
.husky/pre-push Pre-push hook runs commit-brv-submodule.sh --push; will exit 1 when a new gitlink commit is created, requiring contributors to re-run git push.
README.md Adds Docker Compose self-hosting section with correct base URL, volume mount, and LAN exposure guidance including TLS and auth warnings.

Sequence Diagram

sequenceDiagram
    participant Dev as Developer
    participant Hook as Husky pre-push
    participant BRV as commit-brv-submodule.sh
    participant GH as GitHub Actions (release.yml)
    participant NPM as npm Registry
    participant GHCR as GHCR (Docker)

    Dev->>Hook: git push
    Hook->>BRV: --push flag
    BRV->>BRV: commit submodule changes
    BRV->>BRV: push .brv branch
    alt new gitlink commit created
        BRV-->>Dev: exit 1 — re-run git push
        Dev->>GH: git push (second attempt)
    else no new pointer
        BRV-->>Hook: exit 0
        Hook->>GH: push reaches main
    end
    GH->>GH: pnpm verify
    GH->>NPM: changesets publish
    NPM-->>GH: publishedPackages (includes caplets?)
    alt caplets CLI published
        GH->>GH: read packages/cli/package.json version
        GH->>GH: QEMU + Buildx setup
        GH->>GHCR: docker build --platform linux/amd64,linux/arm64
        GH->>GHCR: push :latest, :vX.Y.Z, :sha-XXXXXXX
    else CLI not in published set
        GH->>GH: skip Docker steps
    end
Loading

Fix All in Codex

Reviews (7): Last reviewed commit: "chore: harden byterover memory hook" | Re-trigger Greptile

Comment thread .github/workflows/release.yml
Comment thread Dockerfile Outdated
Comment thread Dockerfile Outdated
Comment thread docker-compose.yml Outdated
Comment thread .github/workflows/release.yml
@ian-pascoe
ian-pascoe merged commit dd56fd0 into main May 21, 2026
5 checks passed
@ian-pascoe
ian-pascoe deleted the feat/docker-self-hosting branch May 21, 2026 12:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant