feat: add plain self-hosted Docker deploy template#976
Conversation
Adapts the existing Coolify template's Dockerfile/entrypoint pattern (official iiidev/iii binary via multi-stage build, HMAC secret generated and persisted on first boot, 0.0.0.0 bind override for the engine's REST/ streams workers) for operators who already run their own Docker host with no PaaS control plane at all - a NAS, a homelab box, or a Windows machine running Docker Desktop - and don't want Coolify-specific env vars or a managed proxy in the way. The README documents the one failure mode most likely to confuse a self-hoster who fronts this with their own reverse proxy: nginx's $host variable strips the port, which silently breaks the viewer's Host-header allowlist even when VIEWER_ALLOWED_HOSTS is configured correctly. Use $http_host instead. Signed-off-by: LIOsDev <liviu.oncioiu@gmail.com>
|
@LIOsDev is attempting to deploy a commit to the rohitg00's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThe PR adds a plain-Docker deployment path alongside managed deployment guidance. It introduces a container image, compose service, startup entrypoint, and updated deployment docs covering setup, access, secret handling, backups, and runtime notes. ChangesPlain Docker deployment
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
deploy/README.md (1)
32-41: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winClarify port exposure for Plain Docker.
The "never to the host" claim on line 37 is inaccurate for the Plain Docker template, which publishes
3111directly to the host network viaports:rather than to an upstream proxy. Consider qualifying this bullet as applying to managed platforms, or add a Plain Docker exception note.🤖 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 `@deploy/README.md` around lines 32 - 41, Clarify the port exposure wording in deploy/README.md so it does not claim all templates publish 3111 only to an upstream proxy; update the TLS upstream bullet to apply specifically to managed platforms and add a Plain Docker exception noting that its compose setup exposes port 3111 directly to the host. Keep the existing public-port guidance consistent with the platform-specific docs and the managed-vs-plain distinction.
🧹 Nitpick comments (3)
deploy/docker/README.md (1)
104-106: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueBackup command assumes Linux/WSL2 environment.
The
$(pwd)expansion andtarcommand work correctly in WSL2 or Linux shells as advised in the Windows section. For users on native Windows PowerShell without WSL2, this command would fail. Consider adding a brief note cross-referencing the Windows section, or provide a Windows-equivalent using%CD%or absolute paths.🤖 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 `@deploy/docker/README.md` around lines 104 - 106, The backup example currently assumes a Linux/WSL2 shell, so update the README guidance around the docker run/tar command to call out that it will not work unchanged in native Windows PowerShell. Add a brief cross-reference to the Windows section near the backup instructions, or provide a Windows-friendly equivalent using PowerShell-compatible path syntax (for example, an absolute path or %CD%) so users can choose the correct command based on their shell.deploy/docker/entrypoint.sh (1)
23-24: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winRecursive
chownon every boot can slow startup for large/datavolumes.
chown -R "$RUN_AS" "$DATA_DIR"runs on each container start, so its cost scales with the number of files under/data. On a populated volume this adds restart latency and could approach the composestart_period: 30sbefore livez is reachable. Since fixing ownership is only required when the mount is root-owned, consider gating the recursive walk on a sentinel (e.g. skip if/datais already owned bynode).♻️ Conditional chown
mkdir -p "$DATA_DIR" -chown -R "$RUN_AS" "$DATA_DIR" +# Only fix ownership when the volume isn't already owned by the runtime user +# (a freshly created bind mount/named volume is root-owned). Avoids a costly +# recursive walk on every restart of a populated volume. +if [ "$(stat -c '%U' "$DATA_DIR")" != "node" ]; then + chown -R "$RUN_AS" "$DATA_DIR" +fi🤖 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 `@deploy/docker/entrypoint.sh` around lines 23 - 24, The startup script unconditionally performs a recursive ownership fix on every boot, which can make container startup slow on large data volumes. Update the entrypoint logic around mkdir -p and chown -R in the entrypoint.sh flow to skip the recursive ownership walk unless /data actually needs it, using an ownership check or sentinel so the chown only runs when the mount is root-owned. Keep the existing RUN_AS and DATA_DIR handling, but gate the recursive chown to avoid repeated work on already-correct volumes.deploy/docker/docker-compose.yml (1)
19-21: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low valueOptional: document the loopback-bind variant for same-host reverse proxies.
"3111:3111"publishes the REST/MCP API on0.0.0.0of the host, which is the intended LAN-self-host behavior and is clearly called out in the comment above. For operators who terminate TLS with a reverse proxy on the same host, binding to loopback ("127.0.0.1:3111:3111") keeps the API off the LAN entirely. Consider mentioning this alternative in the inline comment or README.🤖 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 `@deploy/docker/docker-compose.yml` around lines 19 - 21, The docker-compose ports comment currently only describes the LAN/self-host bind, so update the inline documentation around the ports mapping to also mention the loopback-only variant for same-host reverse proxies. Reference the ports section in docker-compose.yml and clarify that alongside "3111:3111", operators can use a host-bound mapping like "127.0.0.1:3111:3111" when TLS is terminated locally, or add the same note to the README if that is the preferred documentation location.
🤖 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 `@deploy/docker/README.md`:
- Around line 56-62: The SSH/local tunnel “Option A” in the Docker README is
missing the prerequisite setup, so users are told to run the tunnel before the
viewer port is exposed. Update that section to clearly say that the compose
service must first expose the viewer port by uncommenting the 3113 mapping in
docker-compose.yml, optionally setting AGENTMEMORY_VIEWER_HOST and
VIEWER_ALLOWED_HOSTS, and restarting the stack before running the ssh -L
command. Make the prerequisite explicit in the Option A text so the sequence is
unambiguous.
In `@deploy/README.md`:
- Line 59: The README text in the platform list is outdated because “All four”
no longer matches the set after adding Plain Docker. Update the wording in the
affected README sentence to “All five” or a neutral phrase like “All of them,”
keeping the reference to the same agentmemory API and port description
unchanged.
---
Outside diff comments:
In `@deploy/README.md`:
- Around line 32-41: Clarify the port exposure wording in deploy/README.md so it
does not claim all templates publish 3111 only to an upstream proxy; update the
TLS upstream bullet to apply specifically to managed platforms and add a Plain
Docker exception noting that its compose setup exposes port 3111 directly to the
host. Keep the existing public-port guidance consistent with the
platform-specific docs and the managed-vs-plain distinction.
---
Nitpick comments:
In `@deploy/docker/docker-compose.yml`:
- Around line 19-21: The docker-compose ports comment currently only describes
the LAN/self-host bind, so update the inline documentation around the ports
mapping to also mention the loopback-only variant for same-host reverse proxies.
Reference the ports section in docker-compose.yml and clarify that alongside
"3111:3111", operators can use a host-bound mapping like "127.0.0.1:3111:3111"
when TLS is terminated locally, or add the same note to the README if that is
the preferred documentation location.
In `@deploy/docker/entrypoint.sh`:
- Around line 23-24: The startup script unconditionally performs a recursive
ownership fix on every boot, which can make container startup slow on large data
volumes. Update the entrypoint logic around mkdir -p and chown -R in the
entrypoint.sh flow to skip the recursive ownership walk unless /data actually
needs it, using an ownership check or sentinel so the chown only runs when the
mount is root-owned. Keep the existing RUN_AS and DATA_DIR handling, but gate
the recursive chown to avoid repeated work on already-correct volumes.
In `@deploy/docker/README.md`:
- Around line 104-106: The backup example currently assumes a Linux/WSL2 shell,
so update the README guidance around the docker run/tar command to call out that
it will not work unchanged in native Windows PowerShell. Add a brief
cross-reference to the Windows section near the backup instructions, or provide
a Windows-friendly equivalent using PowerShell-compatible path syntax (for
example, an absolute path or %CD%) so users can choose the correct command based
on their shell.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3cbff03f-df3a-48ef-a4db-fe419a420c59
📒 Files selected for processing (5)
deploy/README.mddeploy/docker/Dockerfiledeploy/docker/README.mddeploy/docker/docker-compose.ymldeploy/docker/entrypoint.sh
- Scope the TLS-upstream/never-to-host claim to managed platforms; note Plain Docker's exception - Fix stale 'All four' platform count to 'All five' - Document the viewer-port prerequisite for the SSH tunnel option - Note Windows PowerShell incompatibility in the backup command - Skip the recursive chown on /data once it is already node-owned - Document the loopback-bind variant for same-host reverse proxies
|
Pushed 94d6729 addressing the CodeRabbit findings:
|
Summary
Adds
deploy/docker/— a deploy template for operators who already run their own Docker host with no PaaS control plane at all (a NAS, a homelab box, a Windows machine with Docker Desktop) and don't want a managed proxy or platform-specific env vars in the way.Reuses the existing Coolify template's Dockerfile/entrypoint pattern as-is (official
iiidev/iiibinary via multi-stage build, HMAC secret generated and persisted on first boot,0.0.0.0bind override for the REST/streams workers) — the only changes are swapping Coolify'sSERVICE_FQDN_*/managed-proxy wiring for plainports:publishing, and a README written for someone with no PaaS dashboard at all.The README also documents a failure mode I hit and want to save the next self-hoster from: if you front this with your own reverse proxy (common on a NAS that already runs one), nginx's
$hostvariable strips the port, which silently breaks the viewer'sHost-header allowlist even whenVIEWER_ALLOWED_HOSTSis set correctly — use$http_hostinstead. This isn't obvious from the error (403 forbidden host) and cost real debugging time before tracing it to nginx's documented (if non-obvious) behavior.Test plan
docker compose up -d --buildon a Linux Docker host (Debian-based NAS) — image builds clean, pullsnode:22-slim+iiidev/iii:0.11.2AGENTMEMORY_SECRET=<64 hex chars>exactly oncedocker compose psshows the containerhealthycurl http://localhost:3111/agentmemory/livezreturns{service:agentmemory,status:ok}AGENTMEMORY_VIEWER_HOST/VIEWER_ALLOWED_HOSTS) — the REST/MCP path above is the default, tested config; the viewer opt-in is documented but unverified in this PRSummary by CodeRabbit
New Features
/datastorage, and an exposed API on port3111, including health checks.Documentation