Skip to content

feat(deploy): one-click cloud deployment for OpenHuman Core (closes #1280)#1304

Merged
senamakel merged 3 commits intotinyhumansai:mainfrom
CodeGhost21:feat/issue-1280-cloud-deploy
May 6, 2026
Merged

feat(deploy): one-click cloud deployment for OpenHuman Core (closes #1280)#1304
senamakel merged 3 commits intotinyhumansai:mainfrom
CodeGhost21:feat/issue-1280-cloud-deploy

Conversation

@CodeGhost21
Copy link
Copy Markdown
Contributor

@CodeGhost21 CodeGhost21 commented May 6, 2026

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 for OPENHUMAN_WORKSPACE, env-file pattern, healthcheck, restart: unless-stopped. Validated with docker compose config -q.
  • .do/app.yaml (new) — DigitalOcean App Platform spec referencing the same Dockerfile, /health probe, and OPENHUMAN_CORE_TOKEN flagged as a SECRET. Enables the "Deploy to DO" button in the docs. Validated with doctl apps spec validate --schema-only.
  • docs/CLOUD_DEPLOY.md (new) — three-path deploy guide: DO one-click, DO via doctl, 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 /rpc returns 401 without bearer and 200 with the configured OPENHUMAN_CORE_TOKEN. Triggers on changes to deploy artifacts and src/**. 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-dev to the builder; matching runtime libs to the runtime stage). Required because cpal / enigo / arboard / rdev are unconditional crate deps; without them the bookworm build of openhuman-core fails at alsa-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:

  • Provider template.do/app.yaml so the "Deploy to DigitalOcean" button works straight from the docs.
  • Self-host fallbackdocker-compose.yml for any VPS, with persistent named volume (App Platform Basic doesn't have block storage; this is the durable path).
  • Single docdocs/CLOUD_DEPLOY.md covers both flows, required envs, the bearer-token contract, and the "point my desktop app at a hosted core" handoff.
  • Regression gatedeploy-smoke.yml builds the image, boots it, and probes /health + /rpc (401 without bearer, 200 with) on every PR that touches deploy artifacts or src/**.
  • Build-deps fix — Dockerfile now installs the ALSA/X11 packages the unconditional crate deps need to link, so the image actually builds on Linux.

No Rust or TS code changed; the existing core already binds 0.0.0.0:7788 and enforces bearer auth on /rpc.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per docs/TESTING-STRATEGY.mddeploy-smoke.yml covers the happy path (/health 200, authed /rpc 200) and the failure path (unauthed /rpc 401).
  • Diff coverage ≥ 80% — N/A: no Rust or TS code changed. All new files are YAML / Markdown / Compose / Workflow.
  • Coverage matrix updated — N/A: behaviour-only addition (deploy artifacts + docs); no new feature rows in docs/TEST-COVERAGE-MATRIX.md.
  • All affected feature IDs from the matrix are listed in the PR description under ## Related — N/A, see above.
  • No new external network dependencies introduced — the smoke workflow only fetches from localhost; no new mock backend changes.
  • Manual smoke checklist updated if this touches release-cut surfaces — N/A, this is a hosting/deploy artifact, not a desktop release surface.
  • Linked issue closed via Closes #NNN in the ## Related section — see below.

Impact

  • Runtime/platform: server-side only — the Rust core hosted on a Docker-capable platform (DO App Platform / any Linux VPS). Zero desktop runtime impact.
  • Performance: none for existing flows. Hosted core latency is now bounded by the network hop + DO's basic-xs instance (~1 vCPU / 512 MB).
  • Security: OPENHUMAN_CORE_TOKEN is the gate to /rpc; the spec marks it type: SECRET and the doc flags the placeholder swap as a hard prerequisite. /health, /events, /ws/dictation remain public per src/core/auth.rs:49.
  • Migration: none. Existing local-sidecar setups are unchanged.
  • Compatibility: no schema or RPC changes.

Test plan

  • docker compose config -q parses docker-compose.yml.
  • doctl apps spec validate .do/app.yaml --schema-only accepts the App Platform spec.
  • YAML parsers accept .github/workflows/deploy-smoke.yml.
  • Smoke workflow's /rpc probe uses a real registered method (openhuman.about_app_list — exercised by tests/json_rpc_e2e.rs:2656).
  • Native smoke against a cargo build --release openhuman-core with OPENHUMAN_CORE_TOKEN=test-token:
    • GET /health200 {"ok":true}
    • POST /rpc no bearer → 401
    • POST /rpc correct bearer → 200 (returns 83 capabilities)
    • POST /rpc wrong bearer → 401
  • CI deploy-smoke.yml is wired up and runs on this PR; the green status here IS the test (full Docker image build + container boot + same /health and /rpc probes against the running container).
  • Manual end-to-end DO deploy validation — N/A pre-merge: deferred to post-merge by the issue assignee (.do/app.yaml references tinyhumansai/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

  • The placeholder OPENHUMAN_CORE_TOKEN: CHANGE_ME_BEFORE_DEPLOY in .do/app.yaml is intentional — the docs call out replacing it with openssl rand -hex 32 in the App Platform UI before the first deploy. The field is type: SECRET so it is encrypted at rest.
  • App Platform basic-xs does 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.
  • The Linux build-deps additions to Dockerfile are 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

    • Added cloud deployment support for OpenHuman Core on DigitalOcean App Platform with one-click and manual deployment options.
    • Added Docker Compose configuration enabling self-hosted deployment on any VPS.
  • Documentation

    • New comprehensive cloud deployment guide covering prerequisites, configuration, and setup instructions.
    • Updated README with links to deployment documentation.

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.
@CodeGhost21 CodeGhost21 requested a review from a team May 6, 2026 17:23
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 6, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7b7e2fb2-3250-47ed-a426-2fc0d12dcfed

📥 Commits

Reviewing files that changed from the base of the PR and between cee7f25 and 02d09a5.

📒 Files selected for processing (2)
  • Dockerfile
  • docs/CLOUD_DEPLOY.md
✅ Files skipped from review due to trivial changes (1)
  • docs/CLOUD_DEPLOY.md

📝 Walkthrough

Walkthrough

Adds 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.

Changes

Cloud Deployment Infrastructure

Layer / File(s) Summary
Deployment Manifest
.do/app.yaml
New DigitalOcean App Platform manifest for openhuman-core: GitHub build source, instance/port/host settings, health check, runtime env vars, and a placeholder secret token.
Container Build / Runtime deps
Dockerfile
Expanded build- and runtime-side apt packages to add ALSA/X11/input-related libraries (libasound2-dev, libxdo-dev, libxtst-dev, libx11-dev, libevdev-dev and runtime counterparts) alongside existing SSL and certificate packages.
Local Compose Runtime
docker-compose.yml
New Docker Compose service openhuman-core: build context, Dockerfile, configurable port (default 7788), env_file, explicit env defaults, workspace volume mount, restart policy, and /health healthcheck.
CI Smoke Validation
.github/workflows/deploy-smoke.yml
New GitHub Actions workflow deploy-smoke: builds image with buildx, runs container, polls /health (up to 30 retries), asserts /rpc rejects unauthorized (expect 401) and accepts authorized (expect 200), captures logs, and tears down container.
Documentation & References
docs/CLOUD_DEPLOY.md, README.md
New CLOUD_DEPLOY guide covering DigitalOcean App Platform (one‑click/manual) and Docker Compose VPS flows; README updated to link the guide.

Sequence Diagram

sequenceDiagram
    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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • tinyhumansai/openhuman#174: Modifies Docker packaging and cloud deployment configuration (Dockerfile / container runtime), closely related to these deployment changes.

Poem

🐰 A hop, a build, a health-check bright,

The core wakes up into cloud-lit night.
One click or compose, the workflow sings,
Tokens and tests and persistent things.
The rabbit cheers — deploys take flight!

🚥 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 clearly and concisely summarizes the main change: adding one-click cloud deployment for OpenHuman Core, with issue reference.
Linked Issues check ✅ Passed All acceptance criteria from #1280 are met: one-click DigitalOcean template (.do/app.yaml), Docker Compose VPS fallback, smoke test CI workflow, deployment docs, runtime reachability validation, configuration documentation, and operational basics coverage.
Out of Scope Changes check ✅ Passed All changes directly support cloud deployment: Docker config files, deployment docs, CI smoke tests, Dockerfile system deps for Debian Bookworm compatibility, and README cross-link. No unrelated modifications present.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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


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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
.do/app.yaml (1)

51-56: 💤 Low value

Placeholder token is appropriately marked SECRET, but consider adding a validation hint.

The placeholder CHANGE_ME_BEFORE_DEPLOY is intentional per the PR objectives, and type: SECRET ensures 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 value

Consider adding OPENHUMAN_CORE_HOST to 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 in docker-compose.yml and .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

📥 Commits

Reviewing files that changed from the base of the PR and between a3a1843 and cee7f25.

📒 Files selected for processing (5)
  • .do/app.yaml
  • .github/workflows/deploy-smoke.yml
  • README.md
  • docker-compose.yml
  • docs/CLOUD_DEPLOY.md

Comment thread docs/CLOUD_DEPLOY.md Outdated
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.
@senamakel senamakel merged commit 5189ca9 into tinyhumansai:main May 6, 2026
24 checks passed
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.

OpenHuman is not available as a one-click cloud deployment

2 participants