feat(deploy): one-click cloud deployment for OpenHuman Core (closes #1280)#1304
Conversation
Closes tinyhumansai#1280 — packages the headless Rust core for cloud hosting. - docker-compose.yml at repo root: single-service compose wrapping the existing Dockerfile, named volume for OPENHUMAN_WORKSPACE, env-file pattern, healthcheck, restart unless-stopped. - .do/app.yaml: DigitalOcean App Platform spec referencing the Dockerfile, /health probe, secret-flagged OPENHUMAN_CORE_TOKEN. Enables the "Deploy to DigitalOcean" button in docs. - docs/CLOUD_DEPLOY.md: cloud deploy guide covering DO App Platform (one-click + doctl) and any-VPS Compose flow. Documents required envs, ports, persistence, health, restart, update path, and how to point the desktop app at a hosted core. - .github/workflows/deploy-smoke.yml: PR-gated smoke that builds the image, boots the container, polls /health, and confirms /rpc rejects unauthenticated calls and accepts the configured bearer token. Triggers on changes to deploy artifacts and src/**. - README.md: cross-link to the cloud deploy doc. The Dockerfile and OPENHUMAN_CORE_* env knobs already existed; this PR bundles them into a one-click flow with regression coverage.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
✅ Files skipped from review due to trivial changes (1)
📝 WalkthroughWalkthroughAdds cloud deployment artifacts and docs: a DigitalOcean App Platform manifest, Docker Compose file, expanded Docker runtime/build deps, a GitHub Actions smoke-test workflow that builds and validates the container, and a CLOUD_DEPLOY guide with a README link. No public API/signature changes. ChangesCloud Deployment Infrastructure
Sequence DiagramsequenceDiagram
actor Trigger as GitHub Push/PR/Manual
participant GHA as GitHub Actions
participant Builder as Buildx/Docker
participant Container as Running Container
participant Health as /health Endpoint
participant RPC as /rpc Endpoint
Trigger->>GHA: start deploy-smoke workflow
GHA->>Builder: checkout & build image
Builder-->>GHA: image built and loaded
GHA->>Container: run container with env & ports
Container->>Health: initialize and listen on port
loop Health Check (up to 30 retries)
GHA->>Health: GET /health
Health-->>GHA: 200 OK or retry
end
GHA->>RPC: GET /rpc (no Authorization)
RPC-->>GHA: 401 Unauthorized (expected)
GHA->>RPC: GET /rpc (with Bearer token)
RPC-->>GHA: 200 OK (expected)
GHA->>Container: dump logs
GHA->>Container: stop & remove container
GHA->>Trigger: report results
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
.do/app.yaml (1)
51-56: 💤 Low valuePlaceholder token is appropriately marked SECRET, but consider adding a validation hint.
The placeholder
CHANGE_ME_BEFORE_DEPLOYis intentional per the PR objectives, andtype: SECRETensures App Platform treats it securely. However, operators who forget to change it will have a guessable token.Consider adding a comment indicating that App Platform will reject this specific placeholder, or update the deploy docs to emphasize the token must be changed before the app becomes reachable.
🤖 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 @.do/app.yaml around lines 51 - 56, Add a validation hint for the OPENHUMAN_CORE_TOKEN secret so operators know the placeholder "CHANGE_ME_BEFORE_DEPLOY" must be replaced; update the .do/app.yaml entry for OPENHUMAN_CORE_TOKEN to include a clear comment immediately above or beside the value that App Platform will reject this placeholder (or reference the deploy docs), and/or add a short note in the deployment documentation stating that OPENHUMAN_CORE_TOKEN must be changed from "CHANGE_ME_BEFORE_DEPLOY" to a strong random secret before deployment..github/workflows/deploy-smoke.yml (1)
61-69: 💤 Low valueConsider adding
OPENHUMAN_CORE_HOSTto match production configuration.The container is started without
OPENHUMAN_CORE_HOST=0.0.0.0. While this likely works if the Dockerfile sets a default, explicitly setting it would ensure the smoke test mirrors the production environment defined indocker-compose.ymland.do/app.yaml.🔧 Optional: align env vars with production specs
docker run -d \ --name oh-smoke \ -p 7788:7788 \ -e OPENHUMAN_CORE_TOKEN=ci-smoke-token \ + -e OPENHUMAN_CORE_HOST=0.0.0.0 \ -e OPENHUMAN_APP_ENV=staging \ -e BACKEND_URL=https://staging-api.tinyhumans.ai \ openhuman-core:smoke🤖 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/deploy-smoke.yml around lines 61 - 69, Add the missing OPENHUMAN_CORE_HOST env var to the docker run invocation that starts the smoke container (the step that creates container name oh-smoke) so the smoke test mirrors production; update the Run container step to include -e OPENHUMAN_CORE_HOST=0.0.0.0 alongside the existing OPENHUMAN_CORE_TOKEN, OPENHUMAN_APP_ENV and BACKEND_URL environment variables to ensure the container binds the same host as in docker-compose.yml/.do/app.yaml.
🤖 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/CLOUD_DEPLOY.md`:
- Around line 13-15: The three table-of-contents links using "DigitalOcean App
Platform — one-click", "DigitalOcean App Platform — manual `doctl`", and "Any
VPS via Docker Compose" use em-dashes that don't match GitHub's generated
heading anchors; update either the headings or the fragment links so they match
exactly — simplest fix: replace the em-dash (—) with a regular hyphen (-) in the
headings or change the link fragments to the exact anchors GitHub generates
(e.g., "digitalocean-app-platform-one-click" and
"digitalocean-app-platform-manual-doctl") so the fragment identifiers resolve
and the markdown link checker passes.
---
Nitpick comments:
In @.do/app.yaml:
- Around line 51-56: Add a validation hint for the OPENHUMAN_CORE_TOKEN secret
so operators know the placeholder "CHANGE_ME_BEFORE_DEPLOY" must be replaced;
update the .do/app.yaml entry for OPENHUMAN_CORE_TOKEN to include a clear
comment immediately above or beside the value that App Platform will reject this
placeholder (or reference the deploy docs), and/or add a short note in the
deployment documentation stating that OPENHUMAN_CORE_TOKEN must be changed from
"CHANGE_ME_BEFORE_DEPLOY" to a strong random secret before deployment.
In @.github/workflows/deploy-smoke.yml:
- Around line 61-69: Add the missing OPENHUMAN_CORE_HOST env var to the docker
run invocation that starts the smoke container (the step that creates container
name oh-smoke) so the smoke test mirrors production; update the Run container
step to include -e OPENHUMAN_CORE_HOST=0.0.0.0 alongside the existing
OPENHUMAN_CORE_TOKEN, OPENHUMAN_APP_ENV and BACKEND_URL environment variables to
ensure the container binds the same host as in docker-compose.yml/.do/app.yaml.
🪄 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: CHILL
Plan: Pro
Run ID: 6912b7dc-04c9-427c-9074-4ca679479d7b
📒 Files selected for processing (5)
.do/app.yaml.github/workflows/deploy-smoke.ymlREADME.mddocker-compose.ymldocs/CLOUD_DEPLOY.md
Two CI fixes for tinyhumansai#1304 (tinyhumansai#1280): - Dockerfile: add libasound2-dev / libxdo-dev / libxtst-dev / libx11-dev / libevdev-dev to the builder stage and the matching libasound2 / libxdo3 / libxtst6 / libx11-6 / libevdev2 to the runtime stage. The core crate has unconditional dependencies on cpal, enigo, arboard, and rdev (voice / autocomplete / clipboard subsystems) that link against ALSA and X11, even when those features are inactive at runtime. Without these packages the bookworm build of openhuman-core fails at the alsa-sys pkg-config step. - docs/CLOUD_DEPLOY.md: replace em-dashes in section headings with colons so GitHub's slug algorithm produces single-hyphen anchors matching the TOC links. Lychee was failing on 'tinyhumansai#1-digitalocean-app-platform-one-click' / '...manual-doctl' because the actual headings produced double-hyphen slugs.
Summary
Packages the headless Rust core (
openhuman-core) for one-click cloud hosting. The Dockerfile and bind-address env knobs already existed; this PR bundles them into deployable artifacts plus regression coverage.docker-compose.yml(new, repo root) — single-service Compose wrapping the existing Dockerfile, named volume forOPENHUMAN_WORKSPACE, env-file pattern, healthcheck,restart: unless-stopped. Validated withdocker compose config -q..do/app.yaml(new) — DigitalOcean App Platform spec referencing the same Dockerfile,/healthprobe, andOPENHUMAN_CORE_TOKENflagged as aSECRET. Enables the "Deploy to DO" button in the docs. Validated withdoctl apps spec validate --schema-only.docs/CLOUD_DEPLOY.md(new) — three-path deploy guide: DO one-click, DO viadoctl, any-VPS Compose. Documents required envs, ports, persistence, health, restart, update path, and how to point the desktop app at a hosted core..github/workflows/deploy-smoke.yml(new) — PR-gated smoke: build image, boot container, poll/health, assert/rpcreturns 401 without bearer and 200 with the configuredOPENHUMAN_CORE_TOKEN. Triggers on changes to deploy artifacts andsrc/**. Satisfies the regression-safety bullet in the issue.Dockerfile— added Linux ALSA + X11 + input system dependencies (libasound2-dev,libxdo-dev,libxtst-dev,libx11-dev,libevdev-devto the builder; matching runtime libs to the runtime stage). Required becausecpal/enigo/arboard/rdevare unconditional crate deps; without them the bookworm build ofopenhuman-corefails atalsa-sys.README.md— cross-link to the new deploy doc.Problem
Per #1280: OpenHuman has no documented one-click cloud deploy. Users / internal testers who want a hosted core (instead of a local sidecar) have nothing to point at — there's a Dockerfile but no Compose, no provider template, no docs, and no smoke coverage to keep the deploy path from silently breaking. The Dockerfile itself was also missing Linux audio/X11 build deps and would fail to compile on bookworm.
Solution
Ship the smallest credible deploy bundle:
.do/app.yamlso the "Deploy to DigitalOcean" button works straight from the docs.docker-compose.ymlfor any VPS, with persistent named volume (App Platform Basic doesn't have block storage; this is the durable path).docs/CLOUD_DEPLOY.mdcovers both flows, required envs, the bearer-token contract, and the "point my desktop app at a hosted core" handoff.deploy-smoke.ymlbuilds the image, boots it, and probes/health+/rpc(401 without bearer, 200 with) on every PR that touches deploy artifacts orsrc/**.No Rust or TS code changed; the existing core already binds
0.0.0.0:7788and enforces bearer auth on/rpc.Submission Checklist
docs/TESTING-STRATEGY.md—deploy-smoke.ymlcovers the happy path (/health200, authed/rpc200) and the failure path (unauthed/rpc401).docs/TEST-COVERAGE-MATRIX.md.## Related— N/A, see above.localhost; no new mock backend changes.Closes #NNNin the## Relatedsection — see below.Impact
basic-xsinstance (~1 vCPU / 512 MB).OPENHUMAN_CORE_TOKENis the gate to/rpc; the spec marks ittype: SECRETand the doc flags the placeholder swap as a hard prerequisite./health,/events,/ws/dictationremain public persrc/core/auth.rs:49.Test plan
docker compose config -qparsesdocker-compose.yml.doctl apps spec validate .do/app.yaml --schema-onlyaccepts the App Platform spec..github/workflows/deploy-smoke.yml./rpcprobe uses a real registered method (openhuman.about_app_list— exercised bytests/json_rpc_e2e.rs:2656).cargo build --releaseopenhuman-corewithOPENHUMAN_CORE_TOKEN=test-token:GET /health→200 {"ok":true}POST /rpcno bearer →401POST /rpccorrect bearer →200(returns 83 capabilities)POST /rpcwrong bearer →401deploy-smoke.ymlis wired up and runs on this PR; the green status here IS the test (full Docker image build + container boot + same/healthand/rpcprobes against the running container)..do/app.yamlreferencestinyhumansai/openhuman:main, so the "Deploy to DO" button only resolves once this PR has landed). Pre-merge validation is covered by schema-validated spec + green CI image build.Notes for reviewers
OPENHUMAN_CORE_TOKEN: CHANGE_ME_BEFORE_DEPLOYin.do/app.yamlis intentional — the docs call out replacing it withopenssl rand -hex 32in the App Platform UI before the first deploy. The field istype: SECRETso it is encrypted at rest.basic-xsdoes not provide block storage; the workspace lives on the container's ephemeral FS and is wiped on redeploy. The doc points operators at the Compose path on a Droplet for durable storage and flags this explicitly under the App Platform section.Dockerfileare technically a fix for a pre-existing image-build bug (the file existed but had never been built in CI). Bundling them here keeps the deploy-smoke workflow as the regression gate that would have caught this earlier.Related
Closes #1280
Summary by CodeRabbit
New Features
Documentation