Skip to content

docs(deployment): adiciona guia de deploy docker, headroom e acesso remoto - #22

Merged
elielsousa-pathbit merged 1 commit into
masterfrom
feat/docker-deployment-guide
Oct 7, 2026
Merged

elielsousa-pathbit merged 1 commit into
masterfrom
feat/docker-deployment-guide

Conversation

@elielsousa-pathbit

Copy link
Copy Markdown
Contributor

Adiciona guia completo de deploy com Docker, Headroom, Caveman, Cloudflare Tunnel e Tailscale.

@elielsousa-pathbit
elielsousa-pathbit merged commit 6ada364 into master Oct 7, 2026
6 checks passed
@elielsousa-pathbit
elielsousa-pathbit deleted the feat/docker-deployment-guide branch October 7, 2026 23:50

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 47b078d0c5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +140 to +141
> 1. `REQUIRE_LOGIN=true` (with a strong custom password)
> 2. `REQUIRE_API_KEY=true` (for coding tool authentication)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Wire the remote-auth flags into Compose

In the documented Compose flow, changing these values in .env does not enable either protection: docker-compose.example.yml hardcodes REQUIRE_LOGIN=false and REQUIRE_API_KEY=false instead of interpolating the corresponding .env entries. A user who follows this warning and then starts the tunel profile still exposes the gateway's admin and inference endpoints without authentication, so the Compose service must consume these variables or the guide must explicitly require editing the Compose file.

Useful? React with 👍 / 👎.

### Step 2: Launch Stack

```bash
docker compose -f docker-compose.example.yml up -d

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Create the external network in the quick start

On a fresh host, this launch command fails before creating any containers because docker-compose.example.yml attaches 9rtk-router to rtk-inference-net, which is declared external: true. Docker requires external networks to exist before docker compose up, as stated in the official Compose networking documentation; the repository's make setup already creates it, so the production steps should use that target or run docker network create rtk-inference-net first.

Useful? React with 👍 / 👎.

Comment on lines +176 to +178
environment:
- UPSTREAM_URL=http://9rtk-router:20128
- PORT=8787

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Bind Headroom to the container interface

The published Headroom image defaults HEADROOM_HOST to 127.0.0.1 inside the container, so Docker's port forwarding to the container address cannot reach this listener and http://127.0.0.1:8787/v1 returns connection failures. Headroom's own Compose example explicitly sets HEADROOM_HOST=0.0.0.0 for this reason; add that setting while retaining the host-side loopback publication.

Useful? React with 👍 / 👎.

ports:
- "127.0.0.1:8787:8787"
environment:
- UPSTREAM_URL=http://9rtk-router:20128

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use Headroom's supported upstream settings

UPSTREAM_URL is not Headroom's setting for an OpenAI-compatible backend, so this service does not route requests to 9Router as the guide claims. Headroom documents OPENAI_TARGET_API_URL and ANTHROPIC_TARGET_API_URL for custom targets in its proxy configuration; without the appropriate target, OpenAI-compatible traffic uses the public provider default and a 9Router credential is rejected rather than reaching the gateway.

Useful? React with 👍 / 👎.

--name 9rtk-sync \
--restart unless-stopped \
-p 127.0.0.1:9091:9090 \
-v 9router_data:/app/data \

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Mount the gateway's real data volume

When the existing gateway does not already use a Docker volume named exactly 9router_data—including the repository's standard Compose deployment, whose project-scoped volume has a different engine name—this option silently creates a new empty volume. Because synchronization reads /app/data/db/data.sqlite directly and ROUTER_URL is only used for diagnostics, the standalone container then remains DATABASE_NOT_READY; a remote gateway cannot work with this recipe at all unless its database is mounted or otherwise made locally accessible.

Useful? React with 👍 / 👎.

-v "${HOME}:/root/host:ro" \
-v 9rtksync_logs:/app/logs \
-e DB_PATH=/app/data/db/data.sqlite \
-e ROUTER_URL=http://host.docker.internal:20128 \

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Add the Linux host-gateway mapping

On a plain Linux Docker Engine host, host.docker.internal is not automatically installed in the container's hosts file, so this advertised standalone command cannot resolve the host-side 9Router. Docker documents that Docker Desktop supplies the name automatically, while docker run on Engine should add --add-host host.docker.internal=host-gateway (Docker run documentation); alternatively the guide should use a reachable LAN address.

Useful? React with 👍 / 👎.

```bash
docker compose -f docker-compose.example.yml --profile tailnet up -d
```
4. Access via MagicDNS at `http://9rtk:20128` or Tailscale IP `100.x.y.z:20128`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Provide the advertised Tailscale serve config

Starting the documented tailnet profile does not make port 20128 reachable: the Compose service sets TS_SERVE_CONFIG=/config/serve.json, but mounts only /var/lib/tailscale, and a repository-wide search finds no serve.json to mount. Tailscale requires that JSON file to define the services being proxied and says it must be mounted into the container (Tailscale Docker parameters); merely joining the sidecar to the Docker network does not expose 9rtk-router, so this access instruction fails until the config and mount are added.

Useful? React with 👍 / 👎.

Comment on lines +35 to +37
docker run -d \
--name 9rtk-sync \
--restart unless-stopped \

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Run the standalone synchronizer as the gateway UID

When this standalone command is corrected to mount the gateway's actual shared volume, it still runs the image as root because the Dockerfile declares no USER and the command omits --user. The synchronizer performs SQLite writes and creates state beside DB_PATH, so SQLite journals or directories can become root-owned and leave the UID-1000 gateway unable to write its own database; the repository's Compose service explicitly uses user: "1000:1000" to prevent this EACCES failure, and the standalone recipe needs the same setting.

Useful? React with 👍 / 👎.

Comment on lines +14 to +15
# Pull latest stable release
docker pull ghcr.io/pathbit/9rtksync:latest

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Stop labeling the moving master image as stable

The latest image is not the latest stable release: .github/workflows/release.yml applies the latest tag only when github.ref == 'refs/heads/master', while version-tag builds publish semver tags without advancing latest. Consequently, every qualifying master push can replace this image independently of a release, and users following the comment may deploy unreleased code; either recommend a versioned tag here or change the release workflow to promote releases to latest.

Useful? React with 👍 / 👎.

Comment on lines +179 to +180
networks:
- 9rtksync-net

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep Headroom off the management network

This attaches a third-party inference proxy to 9rtksync-net, even though the network contract below states that this management network is isolated so only the synchronizer reaches the gateway; the router also defaults to REQUIRE_LOGIN=false, so Headroom gains access to the unprotected administrative surface in addition to /v1. Since 9rtk-router is already attached to the purpose-built rtk-inference-net, Headroom should use that inference network instead of expanding the management trust boundary.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-07T23:56:12.730820Z 47b078d PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

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