docs(deployment): add Deploy to Fly.io guide#1885
Conversation
Add a dedicated Deploy to Fly.io how-to (next + current): pre-built Docker Hub images, a Fly-ready config.yaml (bind [::], state under /data), the engine/worker placement model (engine plus workers, each worker either in-engine or its own Fly Machine over the 6PN), file_based to external adapters, Rust binary workers, worker manifest, hardening, RBAC, Fly Proxy TLS, health checks, observability, the /dev/kvm micro-VM limit, end-to-end verification, and a Fly-specific deployment checklist. Group docs.json under Deployment (now Deployment, Deploy to Railway, Deploy to Fly.io) for both versions. Grounded in real Fly testing: engine plus a separate worker Machine over the 6PN verified end-to-end with state persisting across reboots; libkrun (iii-sandbox) cannot boot without /dev/kvm and reboots the Machine, while binary registry workers run as host processes.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ 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 |
skill-check — docs1 verified, 600 skipped.
Note 114 stale rendered artifact(s) detected on main, unrelated to this PR. This PR is fine; the drift was already there. A maintainer should open a chore PR to re-render these.
|
Replace anthropomorphic 'lives' with 'is stored on' / 'is held in' in the Fly guide (next + current) to clear Terminology.SlopMarketing errors.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
docs/using-iii/deploy-fly.mdx (1)
597-597: 💤 Low valueAdd trailing newline at end of file.
POSIX text files should end with a newline character.
🤖 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 `@docs/using-iii/deploy-fly.mdx` at line 597, The file docs/using-iii/deploy-fly.mdx is missing a trailing newline character at the end of the file. Add a newline character after the last line of content to ensure the file ends with a POSIX-compliant newline, which is the standard for text files.docs/next/using-iii/deploy-fly.mdx (1)
597-597: 💤 Low valueAdd trailing newline at end of file.
POSIX text files should end with a newline character.
🤖 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 `@docs/next/using-iii/deploy-fly.mdx` at line 597, The file deploy-fly.mdx is missing a trailing newline at the end of the file, which violates POSIX text file standards. Navigate to the very end of the file after the last character and add a newline character to ensure the file ends with a proper line break.
🤖 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 `@docs/next/using-iii/deploy-fly.mdx`:
- Line 255: The SQLite URL in the Fly configuration is using an incorrect format
with a single slash after the colon, which causes the path to be interpreted as
relative instead of absolute. Change the url value from sqlite:/data/iii.db to
sqlite:///data/iii.db by adding one additional slash after the colon to properly
specify an absolute path, ensuring SQLite correctly resolves the database
location on the Fly volume.
In `@docs/using-iii/deploy-fly.mdx`:
- Line 255: The SQLite URL on line 255 uses an incorrect format with only a
single slash after the colon in the protocol. Change the database URL from
sqlite:/data/iii.db to sqlite:///data/iii.db by adding two additional slashes.
The three-slash format (sqlite:///) correctly specifies an absolute path,
whereas the single-slash format (sqlite:/) may be interpreted as a relative
path, which can cause the database to be created in an incorrect location on the
Fly volume.
---
Nitpick comments:
In `@docs/next/using-iii/deploy-fly.mdx`:
- Line 597: The file deploy-fly.mdx is missing a trailing newline at the end of
the file, which violates POSIX text file standards. Navigate to the very end of
the file after the last character and add a newline character to ensure the file
ends with a proper line break.
In `@docs/using-iii/deploy-fly.mdx`:
- Line 597: The file docs/using-iii/deploy-fly.mdx is missing a trailing newline
character at the end of the file. Add a newline character after the last line of
content to ensure the file ends with a POSIX-compliant newline, which is the
standard for text files.
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: a1fc3d45-2279-4934-bff1-c5f757d49d58
📒 Files selected for processing (3)
docs/docs.jsondocs/next/using-iii/deploy-fly.mdxdocs/using-iii/deploy-fly.mdx
| ```yaml | ||
| - name: iii-state | ||
| config: | ||
| adapter: { name: redis, config: { url: "${REDIS_URL}" } } |
There was a problem hiding this comment.
adapter:
class: modules::queue::RedisAdapter
config:
redis_url: ${REDIS_URL:redis://localhost:6379}
| crash is a real signal. | ||
| - `scripts.install`: install from a lockfile without dev deps (`npm ci --omit=dev`). | ||
| - `env`: inject production config; keep secrets out of the file and supply them from the | ||
| environment (`fly secrets`). `III_URL` / `III_ENGINE_URL` are ignored; the engine sets |
There was a problem hiding this comment.
III_URL / III_ENGINE_URL are ignored
lines 222 and 230 tell you to fly secrets set III_URL=ws://iii-engine.internal:49134 and pass process.env.III_URL directly to registerWorker(). then line 394 says these env vars are ignored — the engine sets the connection URL. an agent following the guide step-by-step would set the secret, wire the SDK with it, and then hit line 394 and not know which is authoritative: does the worker need to read III_URL from the environment, or does the engine inject the URL? worth reconciling who owns the connection URL.
| ## Observability | ||
|
|
||
| Set `iii-observability` to the `otlp` exporter and point it at an OpenTelemetry collector | ||
| running as its own Fly app on the 6PN (`http://otel-collector.internal:4318`). The |
| destination = "/data" | ||
|
|
||
| # Keep the single stateful engine alive. The default policy is "on-failure", which | ||
| # does NOT restart on a clean exit (code 0) -- and the engine exits cleanly when it |
There was a problem hiding this comment.
is this rationale right? the guide says "the engine exits cleanly when it reloads config.yaml at runtime" (lines 141–142), but from the source a successful reload is applied hot in-process — the engine never exits. only a failed reload exits, and that exit is non-zero (so on-failure would also restart it). policy = "always" is still fine, but the stated reason is backwards — the engine does not produce a clean exit code 0 on reload.
| <Warning> | ||
| This is not a soft failure. Declaring an engine-managed micro-VM worker (for example | ||
| `iii worker add iii-sandbox`) makes the engine try to start a guest with no `/dev/kvm`; | ||
| in testing this took down the engine's worker connection and **rebooted the Machine**. |
There was a problem hiding this comment.
does it actually reboot the machine? from the code, a missing /dev/kvm just fails a pre-flight check and the worker exits with an error (clean exit 1) — the engine itself doesn't crash. is the reboot something you saw on fly specifically? might be worth framing it as an observed fly side-effect vs iii behavior.
| `configuration`, `iii-observability`). | ||
| - Registry workers that deploy as **binaries**: `iii worker add database` resolves to a | ||
| binary (`x86_64-unknown-linux-gnu`) and runs as a plain host child process | ||
| (`sandbox: n/a`), no `/dev/kvm` needed. Check a worker's deploy type before adding it; |
There was a problem hiding this comment.
could we point to where the deploy type actually lives? it's the top-level deploy: field in the worker's iii.worker.yaml — binary runs as a host process (ok on fly), while image and bundle both go through libkrun (need /dev/kvm).
| ```bash | ||
| fly logs -a iii-engine | ||
|
|
||
| curl https://iii-engine.fly.dev/orders -X POST \ |
There was a problem hiding this comment.
where does /orders come from? the only worker example registers database::query/execute — there's no /orders route created anywhere in the guide, so this curl would 404. should we use <your route> or add a small http handler earlier so the verify step is reproducible?
| [custom domain](https://fly.io/docs/networking/custom-domain/) works the same way with | ||
| a `fly certs` entry. | ||
| - **WebSocket surfaces** (stream `3112`, RBAC `49135`): Fly Proxy passes WebSocket | ||
| upgrades through natively. Expose each on its own service port; each WS surface is |
There was a problem hiding this comment.
this says expose stream 3112, but a few lines down (and the checklist) say keep 3112 private — which is it? grouping it with 49135 (the rbac port that is public) makes it read like both should be exposed.
Stacked on #1880 (Deploy to Railway), which is stacked on #1872 (Self-hosted deployment).
What changed
config.yaml(bind[::], state under/data), the engine + worker placement model (engine plus workers, each worker either in-engine or its own Fly Machine over the 6PN),file_basedto external adapters (Redis/RabbitMQ/Postgres), Rust binary workers, worker manifest, hardening, RBAC, Fly Proxy TLS, health checks, observability, the/dev/kvmmicro-VM limit, end-to-end verification, and a Fly-specific deployment checklist.docs.jsonDeployment group is now Deployment + Deploy to Railway + Deploy to Fly.io, for both versions.Depends on (merge order)
docs/deployment-guide)docs/deploy-railway-guide)Base branch is
docs/deploy-railway-guide; it will retarget tomainautomatically as the parents merge.Grounded in real Fly testing
/hello-> Fly Proxy -> engine -> worker -> state worker); state persisted across Machine reboots.iii-sandbox(libkrun) cannot boot without/dev/kvmand reboots the Machine; binary registry workers (e.g.database) run as host processes.always(a clean config-reload exit is otherwise not restarted).skill.md note
No
skill.mdcommitted; rendered artifacts are generated in CI (matching #1880).Test plan
Summary by CodeRabbit