Skip to content

feat(docker): Dockerfile, cloud server support, and parallel release pipeline#174

Merged
senamakel merged 6 commits intotinyhumansai:mainfrom
senamakel:feat/docker
Apr 1, 2026
Merged

feat(docker): Dockerfile, cloud server support, and parallel release pipeline#174
senamakel merged 6 commits intotinyhumansai:mainfrom
senamakel:feat/docker

Conversation

@senamakel
Copy link
Copy Markdown
Member

@senamakel senamakel commented Apr 1, 2026

Summary

  • Add a multi-stage Dockerfile for running openhuman-core as a standalone JSON-RPC server on cloud devices (lean debian:bookworm-slim runtime image, non-root user, healthcheck)
  • Add --host CLI flag and OPENHUMAN_CORE_HOST env var so the server can bind to 0.0.0.0 (required for Docker/cloud — previously hardcoded to 127.0.0.1)
  • Restructure release.yml into parallel build phases: build-desktop (matrix) and build-docker (GHCR push) run concurrently after create-release; publish-release gates on both succeeding
  • Add .dockerignore to keep Docker build context small

Changes

File Change
Dockerfile New — multi-stage build (rust:1.93 builder → debian:bookworm-slim runtime)
.dockerignore New — excludes app/, node_modules/, .git/, tests/, etc.
src/core/cli.rs Add --host <addr> flag to openhuman run/serve
src/core/jsonrpc.rs run_server() accepts host param, falls back to OPENHUMAN_CORE_HOST env var
.env.example Document OPENHUMAN_CORE_HOST
.github/workflows/release.yml Parallel build phases (desktop matrix + Docker), cleanup gates on both

Test plan

  • cargo check passes with host binding changes
  • docker build -t openhuman-core . completes successfully
  • docker run -p 7788:7788 openhuman-core starts and responds on /health
  • openhuman-core serve --host 0.0.0.0 --port 8080 binds correctly
  • OPENHUMAN_CORE_HOST=0.0.0.0 openhuman-core serve binds correctly
  • Release workflow YAML is valid and job dependency graph is correct

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Docker containerization for simplified deployment (runtime image included)
    • Configurable host binding via new --host CLI option and corresponding env var (documented in example)
  • Chores

    • Automated Docker image builds, promotion, and publishing in CI/CD
    • Added .dockerignore and Dockerfile to optimize container builds

senamakel and others added 4 commits April 1, 2026 11:14
Restructure release.yml into parallel build phases: build-desktop (matrix)
and build-docker run concurrently after create-release. Docker image is
pushed to GHCR and pull instructions are appended to release notes.
publish-release now gates on both phases succeeding.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 1, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

Adds Docker build/runtime support and CI image publishing, a .dockerignore, a Dockerfile, CI workflow changes to build/push images, and server host configuration via CLI flag and environment variable; updates server start path to bind to configurable host and port.

Changes

Cohort / File(s) Summary
Dockerfiles & Ignore
Dockerfile, .dockerignore
New multi-stage Dockerfile (builder + slim runtime) to build and run openhuman-core; .dockerignore excludes build artifacts, node/frontend outputs, IDE metadata, env files (with !.env.example), Git folders, and docs.
CI/CD Workflow
.github/workflows/release.yml
Reworked release workflow: adds packages: write, splits artifact build into build-desktop and new build-docker jobs; build-docker builds/pushes a staging GHCR image and labels it; publish-release promotes staging image to release tags and appends pull/run instructions; cleanup-failed-release removes staging image on failure.
Runtime Configuration
.env.example
Added OPENHUMAN_CORE_HOST (optional) to example env with comment default 127.0.0.1 and Docker/cloud guidance.
CLI / Server
src/core/cli.rs, src/core/jsonrpc.rs
Added --host <addr> CLI option; changed run_server signature to accept host: Option<&str>; added core_host() helper to read OPENHUMAN_CORE_HOST; bind address resolution now uses {host}:{port} and binds with TcpListener::bind((host, port)), with debug logging of resolved sources.

Sequence Diagram(s)

sequenceDiagram
    participant Dev as Developer (push tag)
    participant GH as GitHub Actions
    participant Build as Build Job
    participant Docker as Docker daemon
    participant GHCR as GHCR (Registry)
    participant Release as GitHub Release

    Dev->>GH: push tag / create release
    GH->>Build: trigger `build-docker` job
    Build->>Docker: build image from `Dockerfile`
    Docker-->>Build: image (staging:<tag>)
    Build->>GHCR: push `staging:<tag>` (with labels)
    GHCR-->>Build: ack
    GH->>Release: on success, `publish-release` promotes image to `:<tag>` and `:latest`
    Release->>GHCR: tag/promo requests
    GHCR-->>Release: image available
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐇 a rabbit's build note
I hopped and fetched the Docker chest,
Images polished, labeled, dressed;
Hosts now listen, ports aligned,
A tiny binary, neatly signed.
Hooray—containers snug and blessed!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the three main changes: Docker support (Dockerfile, .dockerignore), cloud-ready host binding configuration, and the updated release pipeline with parallel builds.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

Upstream commented out notify-discord; our branch has it as an active job
earlier in the file. Drop the commented-out block from upstream.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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: 4

🧹 Nitpick comments (1)
src/core/jsonrpc.rs (1)

426-446: Add debug/trace logging around bind resolution.

This new host precedence (CLI vs env vs default) is only visible after a successful bind. A pre-bind debug log with the resolved host/port and source would make startup failures much easier to diagnose.

As per coding guidelines, src/**/*.rs: Add substantial debug logging on new/changed flows using log/tracing at debug or trace level in Rust.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/core/jsonrpc.rs` around lines 426 - 446, Add a pre-bind debug/trace log
in run_server that reports the resolved host and port and where each value came
from (CLI arg, environment, or default) before creating bind_addr and calling
TcpListener::bind; use the existing symbols core_port, core_host, host, port,
and bind_addr to determine and log the source for each (e.g., host from CLI vs
env vs default) at debug/trace level so startup bind resolution is visible prior
to attempting the bind.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.env.example:
- Around line 26-27: The .env.example currently hardcodes
OPENHUMAN_CORE_HOST=127.0.0.1 which forces loopback when copied into .env;
update the example so it does not override the container default—either leave
OPENHUMAN_CORE_HOST unset (commented/empty) or set it to 0.0.0.0 and update the
inline comment accordingly; locate the OPENHUMAN_CORE_HOST entry and change the
value and comment so Docker users keep the image's 0.0.0.0 bind or can
explicitly set a host themselves.

In @.github/workflows/release.yml:
- Around line 790-800: The workflow currently pushes both the versioned tag and
latest in the build-docker job via docker/build-push-action, which can publish
images even if later jobs fail; change build-docker to push only a non-promoted
staging tag (e.g., ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
or a staging/${{ needs.prepare-release.outputs.tag }}) using the same
docker/build-push-action, and move the promotion to publish-release where you
retag and push the final versioned tag and latest (or use ghcr API to create the
final tags) after all steps succeed; alternatively, add a failure-path cleanup
step that deletes the GHCR images pushed by build-docker (use ghcr API or gh
cli) so incomplete releases don't leave public images.

In `@src/core/cli.rs`:
- Around line 74-78: The general help output in print_general_help() still shows
the old usage string missing the --host option; update the usage line printed by
print_general_help() to match the run subcommand usage (include "--host <addr>")
so the top-level `openhuman --help` and the `run --help` are consistent—locate
the print_general_help() function and modify its printed usage string to include
the `--host <addr>` token alongside existing `--port`, `--jsonrpc-only`, and
`--verbose`.

In `@src/core/jsonrpc.rs`:
- Around line 433-435: Replace the string join bind with a socket tuple so IPv6
works: stop building bind_addr with format!("{host}:{port}") and call
tokio::net::TcpListener::bind((host.as_str(), port)) (or equivalent) where the
current variables host, port, and listener are used; also add debug logging
before/after resolving host via core_host and before the bind to log the
resolved host and port and log the bind result/error (use the same processLogger
/ tracing logger used elsewhere) to aid diagnosing bind failures.

---

Nitpick comments:
In `@src/core/jsonrpc.rs`:
- Around line 426-446: Add a pre-bind debug/trace log in run_server that reports
the resolved host and port and where each value came from (CLI arg, environment,
or default) before creating bind_addr and calling TcpListener::bind; use the
existing symbols core_port, core_host, host, port, and bind_addr to determine
and log the source for each (e.g., host from CLI vs env vs default) at
debug/trace level so startup bind resolution is visible prior to attempting the
bind.
🪄 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: 816477b1-1b9d-4594-a22a-0ecacda58cf0

📥 Commits

Reviewing files that changed from the base of the PR and between f5b66de and 8151441.

📒 Files selected for processing (6)
  • .dockerignore
  • .env.example
  • .github/workflows/release.yml
  • Dockerfile
  • src/core/cli.rs
  • src/core/jsonrpc.rs

- .env.example: comment out OPENHUMAN_CORE_HOST so Docker's 0.0.0.0
  default isn't overridden when users copy the example file
- cli.rs: add --host to print_general_help() usage line for consistency
- jsonrpc.rs: use tuple bind (host, port) for IPv6 support, add
  debug logging with source tracking (CLI/env/default) before bind
- release.yml: push only staging tag in build-docker, promote to
  versioned + latest in publish-release after all builds succeed;
  cleanup-failed-release deletes the staging image on failure

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@senamakel senamakel merged commit 6f8b5d6 into tinyhumansai:main Apr 1, 2026
7 of 8 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.

1 participant