{"id":41548476,"url":"https://github.com/prizz/opencode-cloud","last_synced_at":"2026-02-11T02:59:12.956Z","repository":{"id":333321243,"uuid":"1136904726","full_name":"pRizz/opencode-cloud","owner":"pRizz","description":"A docker container configuration and scripts for running opencode and its web ui in the cloud","archived":false,"fork":false,"pushed_at":"2026-02-06T11:18:01.000Z","size":2134,"stargazers_count":4,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-06T11:26:18.524Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pRizz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-01-18T15:17:29.000Z","updated_at":"2026-02-06T11:18:04.000Z","dependencies_parsed_at":"2026-01-31T04:02:11.750Z","dependency_job_id":null,"html_url":"https://github.com/pRizz/opencode-cloud","commit_stats":null,"previous_names":["prizz/opencode-web-service"],"tags_count":108,"template":false,"template_full_name":null,"purl":"pkg:github/pRizz/opencode-cloud","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pRizz%2Fopencode-cloud","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pRizz%2Fopencode-cloud/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pRizz%2Fopencode-cloud/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pRizz%2Fopencode-cloud/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pRizz","download_url":"https://codeload.github.com/pRizz/opencode-cloud/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pRizz%2Fopencode-cloud/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29219378,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-08T03:18:47.732Z","status":"ssl_error","status_checked_at":"2026-02-08T03:15:31.985Z","response_time":57,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-24T03:40:21.515Z","updated_at":"2026-02-11T02:59:12.949Z","avatar_url":"https://github.com/pRizz.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# opencode-cloud\n\n\u003c!-- BEGIN:opencode-cloud-readme-badges --\u003e\n[![GitHub Stars](https://img.shields.io/github/stars/pRizz/opencode-cloud)](https://github.com/pRizz/opencode-cloud)\n[![CI](https://github.com/pRizz/opencode-cloud/actions/workflows/ci.yml/badge.svg)](https://github.com/pRizz/opencode-cloud/actions/workflows/ci.yml)\n[![Mirror](https://img.shields.io/badge/mirror-gitea-blue?logo=gitea)](https://gitea.com/pRizz/opencode-cloud)\n[![crates.io](https://img.shields.io/crates/v/opencode-cloud.svg)](https://crates.io/crates/opencode-cloud)\n[![Crates Downloads](https://img.shields.io/crates/d/opencode-cloud.svg)](https://crates.io/crates/opencode-cloud)\n[![npm Downloads](https://img.shields.io/npm/dt/opencode-cloud?logo=npm)](https://www.npmjs.com/package/opencode-cloud)\n[![Docker Hub](https://img.shields.io/docker/v/prizz/opencode-cloud-sandbox?label=docker\u0026sort=semver)](https://hub.docker.com/r/prizz/opencode-cloud-sandbox)\n[![Docker Pulls](https://img.shields.io/docker/pulls/prizz/opencode-cloud-sandbox)](https://hub.docker.com/r/prizz/opencode-cloud-sandbox)\n[![GHCR](https://img.shields.io/badge/ghcr.io-sandbox-blue?logo=github)](https://github.com/pRizz/opencode-cloud/pkgs/container/opencode-cloud-sandbox)\n[![docs.rs](https://docs.rs/opencode-cloud/badge.svg)](https://docs.rs/opencode-cloud)\n[![MSRV](https://img.shields.io/badge/MSRV-1.85-blue.svg)](https://blog.rust-lang.org/2025/02/20/Rust-1.85.0.html)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\u003c!-- END:opencode-cloud-readme-badges --\u003e\n\n\u003e [!WARNING]\n\u003e This tool is still a work in progress and is rapidly evolving. Expect frequent updates and breaking changes. Follow updates at https://github.com/pRizz/opencode-cloud (mirror: https://gitea.com/pRizz/opencode-cloud). Stability will be announced at some point. Use with caution.\n\nA production-ready toolkit for deploying and managing [opencode](https://github.com/anomalyco/opencode) as a persistent cloud service, **sandboxed inside a Docker container** for isolation and security.\n\nThis project uses the opencode fork at https://github.com/pRizz/opencode, which adds **passkey-first authentication** (WebAuthn/FIDO2), two-factor authentication, and enterprise security features for cloud deployment.\n\n## Quick Deploy (Docker)\n\nDeploy opencode-cloud with one command. Installs Docker if needed (Linux), downloads or refreshes the Docker Compose config, pulls the latest `prizz/opencode-cloud-sandbox:latest` image, reconciles services, and prints the login credentials:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/pRizz/opencode-cloud/main/scripts/quick-deploy.sh | bash\n```\n\nThen open [http://localhost:3000](http://localhost:3000) and enter the Initial One-Time Password (IOTP) to complete setup.\n\n\u003e **macOS/Windows:** Install [Docker Desktop](https://www.docker.com/products/docker-desktop/) first, then run the command above.\n\n\u003e **Remote server:** SSH into the server, run the command, then access via SSH tunnel: `ssh -L 3000:localhost:3000 root@\u003cserver-ip\u003e`\n\n\u003e **Interactive mode:** Add `--interactive` to be prompted before each step: `curl -fsSL .../scripts/quick-deploy.sh | bash -s -- --interactive`\n\n\u003e **Compose refresh behavior:** By default, the script fetches the latest upstream `docker-compose.yml`. If your local file differs, it is replaced and a backup is written as `docker-compose.yml.bak.\u003ctimestamp\u003e`.\n\n\u003e **Image refresh behavior:** By default, the script runs `docker compose pull` before `docker compose up -d`, so rerunning quick deploy updates to the latest image.\n\n## Quick install (cargo)\n\n```bash\ncargo install opencode-cloud\nopencode-cloud --version\n```\n\n## Quick install (npm)\n\n```bash\nnpx opencode-cloud@latest --version\n```\n\n```bash\nbunx opencode-cloud@latest --version\n```\n\nOr install globally:\n```bash\nnpm install -g opencode-cloud\nopencode-cloud --version\n```\n\n## Deploy to AWS\n\n[![Deploy to AWS](https://s3.amazonaws.com/cloudformation-examples/cloudformation-launch-stack.png)](https://console.aws.amazon.com/cloudformation/home#/stacks/create/review?templateURL=https://opencode-cloud-templates.s3.us-east-2.amazonaws.com/cloudformation/opencode-cloud-quick.yaml)\n\nQuick deploy provisions a private EC2 instance behind a public ALB with HTTPS.\n**A domain name is required** for ACM certificate validation.\n**A Route53 hosted zone ID is required** for automated DNS validation.\n\nDocs: `docs/deploy/aws.md` (includes teardown steps and S3 hosting setup for forks)\nCredentials: `docs/deploy/aws.md#retrieving-credentials`\n\n## Deploy to Railway\n\n\u003c!-- TODO: Replace TEMPLATE_CODE with the actual Railway template code once the template is created. See docs/deploy/railway.md for template creation instructions. --\u003e\n[![Deploy on Railway](https://railway.com/button.svg)](https://railway.com/new/template/TEMPLATE_CODE)\n\nOne-click deploy provisions a Railway service with automatic HTTPS.\n\n\u003e **Important:** Attach a Railway Volume mounted to `/home/opencoder/.local/share/opencode` to prevent data loss across redeploys.\n\u003e For manual template import, use `docker-compose.railway-template-base.yml` as a Railway importer compatibility base (not as the canonical runtime compose).\n\nDocs: `docs/deploy/railway.md`\n\n## Run with Docker / Docker Desktop\n\n\u003e **Tip:** For a fully automated setup, see [Quick Deploy](#quick-deploy-docker) above.\n\nThe fastest way to run opencode-cloud locally:\n\n```bash\ndocker compose up -d\n```\n\nThis uses the included `docker-compose.yml` which configures all persistent volumes automatically.\n\nOptional `.env` overrides (same directory as `docker-compose.yml`):\n\n```bash\n# Example: expose publicly and pin a reproducible image tag\ncat \u003e .env \u003c\u003c'EOF'\nOPENCODE_PORT_MAPPING=3000:3000\nOPENCODE_IMAGE=prizz/opencode-cloud-sandbox:15.2.0\nEOF\n```\n\nBy default, Compose uses `OPENCODE_PULL_POLICY=missing`. To force-refresh to newer image layers:\n\n```bash\ndocker compose pull \u0026\u0026 docker compose up -d\n```\n\nRetrieve the Initial One-Time Password (IOTP) and open `http://localhost:3000`:\n\n```bash\ndocker compose logs | grep -F \"INITIAL ONE-TIME PASSWORD (IOTP): \" | tail -n1 | sed 's/.*INITIAL ONE-TIME PASSWORD (IOTP): //'\n```\n\nDocs: `docs/deploy/docker-desktop.md`\n\n## Deploy to DigitalOcean\n\n### Marketplace (Coming Soon)\n\nDigitalOcean Marketplace one-click deployment is in progress. Support is coming soon.\n\nDocs: `docs/deploy/digitalocean-marketplace.md`\n\n### Droplet (Manual)\n\nSSH into an Ubuntu 24.04 Droplet and run:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/pRizz/opencode-cloud/main/scripts/quick-deploy.sh | bash\n```\n\nThis installs Docker, by default refreshes the Compose file from upstream (with backup if your local copy differs), pulls the latest image, reconciles services, and prints the IOTP.\n\nAccess via SSH tunnel: `ssh -L 3000:localhost:3000 root@\u003cdroplet-ip\u003e`, then open `http://localhost:3000`.\n\nDocs: `docs/deploy/digitalocean-droplet.md`\n\n## Features\n\n- **Sandboxed execution** - opencode runs inside a Docker container, isolated from your host system\n- **Passkey-first authentication** - WebAuthn/FIDO2 passkeys as the primary login method, with username/password and TOTP 2FA as fallback options\n- **Persistent environment** - Your projects, settings, and shell history persist across restarts\n- **Cross-platform CLI** (`opencode-cloud` / `occ`) - Works on Linux and macOS\n- **Service lifecycle commands** - start, stop, restart, status, logs\n- **Platform service integration** - systemd (Linux) / launchd (macOS) for auto-start on boot\n- **Remote host management** - Manage opencode containers on remote servers via SSH\n\n## How it works\n\nopencode-cloud runs opencode inside a Docker container, providing:\n\n- **Isolation** - opencode and its AI-generated code run in a sandbox, separate from your host system\n- **Reproducibility** - The container includes a full development environment (languages, tools, runtimes)\n- **Persistence** - Docker volumes preserve your work across container restarts and updates\n- **Security** - Network exposure is opt-in; by default, the service only binds to localhost\n\nThe CLI manages the container lifecycle, so you don't need to interact with Docker directly.\n\n## Docker Images\n\nThe sandbox container image is named **`opencode-cloud-sandbox`** (not `opencode-cloud`) to clearly distinguish it from the CLI tool. The preferred way to use and manage the image is via the opencode-cloud CLI ([GitHub](https://github.com/pRizz/opencode-cloud), mirror: https://gitea.com/pRizz/opencode-cloud). It handles image pulling, container setup, and upgrades for you.\n\n**Why use the CLI?** It configures volumes, ports, and upgrades safely, so you don’t have to manage `docker run` flags or image updates yourself.\n\nThe image is published to both registries (Docker Hub is the primary distribution):\n\n| Registry | Image |\n|----------|-------|\n| Docker Hub | [`prizz/opencode-cloud-sandbox`](https://hub.docker.com/r/prizz/opencode-cloud-sandbox) |\n| GitHub Container Registry | [`ghcr.io/prizz/opencode-cloud-sandbox`](https://github.com/pRizz/opencode-cloud/pkgs/container/opencode-cloud-sandbox) |\n\nPull commands:\n\nDocker Hub:\n```bash\ndocker pull prizz/opencode-cloud-sandbox:latest\n```\n\nGitHub Container Registry:\n```bash\ndocker pull ghcr.io/prizz/opencode-cloud-sandbox:latest\n```\n\n**For most users:** Just use the CLI - it handles image pulling/building automatically:\n```bash\nocc start  # Pulls or builds the image as needed\n```\n\n**Running the image directly** (without the CLI)? Use Docker Compose or configure named volumes for persistence. See `docs/deploy/docker-desktop.md` for Docker Desktop / `docker run`, or `docs/deploy/railway.md` for Railway.\n\n## Requirements\n\n- **Rust 1.85+** - Install via [rustup](https://rustup.rs): `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`\n- **Docker** - For running the opencode container\n- **Supported platforms** - Linux and macOS\n\n## Installation\n\n### Via cargo (recommended)\n\n```bash\ncargo install opencode-cloud\nocc --version\n```\n\n### Via npm\n\n```bash\nnpx opencode-cloud@latest --version\n```\n\n```bash\nbunx opencode-cloud@latest --version\n```\n\nOr install globally:\n```bash\nnpm install -g opencode-cloud\nocc --version\n```\n\n## First run\n\n```bash\n# Install as a system service (recommended for background use)\nocc install\n\n# Start the service\nocc start\n```\n\nIf this is the first startup with no configured managed users, the container logs will print an **Initial One-Time Password (IOTP)**.\nOpen the login page, use the first-time setup panel, then continue to passkey setup where you can either enroll a passkey or choose username/password registration.\nThe IOTP is invalidated after successful passkey enrollment or successful username/password bootstrap signup.\nBuilt-in image users (for example `ubuntu`/`opencoder`) do not count as configured users for IOTP bootstrap.\n\nQuick IOTP extraction from logs:\n\n```bash\nocc logs | grep -F \"INITIAL ONE-TIME PASSWORD (IOTP): \" | tail -n1 | sed 's/.*INITIAL ONE-TIME PASSWORD (IOTP): //'\n```\n\nYou can also run the setup wizard:\n\n```bash\nocc setup\n```\n\nThe wizard now configures runtime settings (image source, bind/port, mounts), keeps authentication on IOTP-first onboarding, and attempts to auto-detect the IOTP from logs after start.\n\n### From source (install locally)\n\n```bash\n# GitHub (primary)\ngit clone https://github.com/pRizz/opencode-cloud.git\n\n# Gitea (mirror)\ngit clone https://gitea.com/pRizz/opencode-cloud.git\ncd opencode-cloud\ngit submodule update --init --recursive packages/opencode\ncargo install --path packages/cli-rust\n```\n\n### From source (development run)\n\n```bash\n# GitHub (primary)\ngit clone https://github.com/pRizz/opencode-cloud.git\n\n# Gitea (mirror)\ngit clone https://gitea.com/pRizz/opencode-cloud.git\ncd opencode-cloud\ngit submodule update --init --recursive packages/opencode\n \n# Bun is required for this repo\nbun --version\n\njust setup\njust build\njust dev    # Recommended local dev start shortcut\ncargo run -p opencode-cloud -- --version\n```\n\n## Usage\n\n```bash\n# Show version\nocc --version\n\n# Start the service (builds Docker container on first run, ~10-15 min)\nocc start\n\n# Start on a custom port\nocc start --port 8080\n\n# Start and open browser\nocc start --open\n\n# Check service status (includes broker health: Healthy/Degraded/Unhealthy)\nocc status\n\n# View logs\nocc logs\n\n# Follow logs in real-time\nocc logs -f\n\n# View opencode-broker logs (systemd/journald required)\nocc logs --broker\n\n# Troubleshoot broker health issues reported by `occ status`\nocc logs --broker --no-follow\n\n# Note: Broker logs require systemd/journald. This is enabled by default on supported Linux\n# hosts. Docker Desktop/macOS/Windows use Tini, so broker logs aren't available there.\n# Existing containers may need to be recreated after upgrading.\n\n# Stop the service\nocc stop\n\n# Restart the service\nocc restart\n\n# Check for updates and choose what to update\nocc update\n\n# Update the opencode-cloud CLI binary\nocc update cli\n\n# Update the opencode-cloud container image\nocc update container\n\n# Update opencode inside the container\nocc update opencode\n\n# Update opencode using a specific branch or commit\nocc update opencode --branch dev\nocc update opencode --commit \u003csha\u003e\n\n# Remove the container (keeps volumes)\nocc reset container\n\n# Remove container and volumes (data loss)\nocc reset container --volumes --force\n\n# Reset completed IOTP bootstrap and generate a fresh one-time password\nocc reset iotp\n\n# If bind_address is exposed (for example behind HTTPS reverse proxy), confirm intentionally\nocc reset iotp --force\n\n# Clean bind mount contents (data loss)\nocc mount clean --force\n\n# Purge bind mounts (data loss, removes config entries)\nocc mount clean --purge --force\n\n# Mount a local project into the workspace\nocc mount add /Users/\u003cusername\u003e/Desktop/opencode:/home/opencoder/workspace\n\n# Apply mount changes (you may be prompted to recreate the container)\nocc restart\n\n# Factory reset host (container, volumes, mounts, config/data)\nocc reset host --force\n\n### Workspace Mounts\n\nUse `/home/opencoder/workspace` when you want your host project folder to appear in the\nweb UI's project picker and inside the container workspace.\n\nImportant behavior:\n- `/home/opencoder/workspace` is a single mount target.\n- Adding a new mount to this same target replaces the previous mount entry.\n\nRecommended workflow:\n```bash\nocc mount add /Users/\u003cusername\u003e/Desktop/opencode:/home/opencoder/workspace\nocc restart\n```\n\nVerify the mount:\n1. Run `occ status` and check `Mounts` -\u003e `Bind mounts` includes your host path mapped to `/home/opencoder/workspace`.\n2. In the web UI, open the project picker and confirm your project files appear under `~/workspace`.\n\n### Container Mode\n\nWhen `occ` runs inside the opencode container, it will auto-detect this and switch to **container runtime**.\nOverride if needed:\n\n```bash\nocc --runtime host \u003ccommand\u003e\nOPENCODE_RUNTIME=host occ \u003ccommand\u003e\n```\n\nSupported commands in container runtime:\n- `occ status`\n- `occ logs`\n- `occ user`\n- `occ update opencode`\n\nNotes:\n- Host/Docker lifecycle commands are disabled in container runtime.\n- `occ logs` and `occ update opencode` require systemd inside the container. If systemd is not available, run those commands from the host instead.\n\n### Webapp-triggered update (command file)\n\nWhen running in foreground mode (for example via `occ install`, which uses `occ start --no-daemon`),\nthe host listens for a command file on a bind mount. The webapp can write a simple JSON payload\nto request an update.\n\nDefault paths (with default bind mounts enabled):\n- Host: `~/.local/state/opencode/opencode-cloud/commands/update-command.json`\n- Container: `/home/opencoder/.local/state/opencode/opencode-cloud/commands/update-command.json`\n\nExample payload:\n```json\n{\n  \"command\": \"update_opencode\",\n  \"request_id\": \"webapp-1234\",\n  \"branch\": \"dev\"\n}\n```\n\nThe host writes the result to:\n`~/.local/state/opencode/opencode-cloud/commands/update-command.result.json`\n\n# Install as a system service (starts on login/boot)\nocc install\n\n# Uninstall the system service\nocc uninstall\n\n# View configuration\nocc config show\n```\n\n## Authentication\n\nopencode-cloud uses **passkey-first authentication** — WebAuthn/FIDO2 passkeys are the primary login method, providing phishing-resistant, passwordless sign-in. Username/password (via PAM) and TOTP two-factor authentication are available as fallback options.\n\nSecurity details: `docs/security/passkey-registration.md`\n\nFirst boot path:\n- If no managed users are configured, startup logs print an Initial One-Time Password (IOTP).\n- Extract only the IOTP quickly: `occ logs | grep -F \"INITIAL ONE-TIME PASSWORD (IOTP): \" | tail -n1 | sed 's/.*INITIAL ONE-TIME PASSWORD (IOTP): //'`\n- `occ setup` attempts to auto-detect and print the IOTP after starting/restarting the service.\n- Enter that IOTP in the web login page first-time setup panel.\n- Continue to passkey setup, then choose one of:\n  - Enroll a passkey for the default `opencoder` account, or\n  - Use the username/password fallback to create your first managed user.\n- The IOTP is deleted after successful passkey enrollment or successful username/password bootstrap signup.\n- To restart first-time onboarding after completion, run `occ reset iotp`.\n- Built-in image users (for example `ubuntu`/`opencoder`) do not disable IOTP bootstrap.\n\nAdmin path:\n- You can always create/manage users directly via `occ user add`, `occ user passwd`, and related user commands.\n\nLogin UX:\n- **Passkey sign-in is front and center** — the login page leads with WebAuthn for fast, phishing-resistant authentication.\n- Username/password sign-in remains available as a fallback.\n- TOTP two-factor authentication can be enabled per-user from the session menu after login.\n\n### Creating Users\n\nCreate a user with a password:\n```bash\nocc user add \u003cusername\u003e\n```\n\nGenerate a random password:\n```bash\nocc user add \u003cusername\u003e --generate\n```\n\n### Managing Users\n\n- List users: `occ user list` (managed users only)\n- Change password: `occ user passwd \u003cusername\u003e`\n- Remove user: `occ user remove \u003cusername\u003e`\n- Enable/disable account: `occ user enable \u003cusername\u003e` / `occ user disable \u003cusername\u003e`\n\n### User Persistence\n\nUser accounts (including password hashes and lock status) persist across container updates and rebuilds.\nThe CLI stores user records in a managed Docker volume mounted at `/var/lib/opencode-users` inside the container.\nThis record store is the source of truth for configured users and bootstrap decisions.\nNo plaintext passwords are stored on the host.\n\n### Rebuilding the Docker Image\n\nWhen developing locally or after updating opencode-cloud, you may need to rebuild the Docker image to pick up changes in the embedded Dockerfile:\n\n```bash\n# Rebuild using Docker cache (fast - only rebuilds changed layers)\nocc start --cached-rebuild-sandbox-image\n\n# Rebuild from scratch without cache (slow - for troubleshooting)\nocc start --full-rebuild-sandbox-image\n```\n\n**`--cached-rebuild-sandbox-image`** (recommended for most cases):\n- Uses Docker layer cache for fast rebuilds\n- Only rebuilds layers that changed (e.g., if only the CMD changed, it's nearly instant)\n- Stops and removes any existing container before rebuilding\n\n**`--full-rebuild-sandbox-image`** (for troubleshooting):\n- Ignores Docker cache and rebuilds everything from scratch\n- Takes 10-15 minutes but guarantees a completely fresh image\n- Use when cached rebuild doesn't fix issues\n\n**When to rebuild:**\n- After pulling updates to opencode-cloud → use `--cached-rebuild-sandbox-image`\n- After pulling new commits in `packages/opencode` (submodule) → run `just run start --cached-rebuild-sandbox-image` once so the running container picks up the new opencode commit\n- When modifying the Dockerfile during development → use `--cached-rebuild-sandbox-image`\n- When the container fails to start due to image issues → try `--cached-rebuild-sandbox-image` first, then `--full-rebuild-sandbox-image`\n- When you want a completely fresh environment → use `--full-rebuild-sandbox-image`\n\n**Local submodule dev rebuild (no push required):**\n```bash\n# Recommended shortcut for fast rebuild using local packages/opencode checkout (including uncommitted edits)\njust dev\n\n# Equivalent long form:\njust run start --yes --local-opencode-submodule --cached-rebuild-sandbox-image\n\n# Full no-cache rebuild from local packages/opencode checkout\njust run start --full-rebuild-sandbox-image --local-opencode-submodule\n```\n- This mode is for local development/debugging only and bypasses the default remote clone path.\n- `just run status` will show commit metadata derived from your local checkout (dirty trees are marked with `-dirty`).\n- Local context packaging intentionally skips heavyweight/dev metadata folders (for example `.planning`, `.git`, `node_modules`, `target`, and `dist`).\n- Keep CI/release workflows on the default pinned remote mode.\n\n### Dockerfile Optimization Checklist\n\nFor new Docker build steps, follow this checklist:\n- Prefer BuildKit cache mounts (`RUN --mount=type=cache`) for package caches (`apt`, `bun`, `cargo`, `pip`, and `npm`).\n- For `bun install` in container builds, use a dedicated install-cache mount plus a short retry loop that clears that cache between attempts to recover from occasional corrupted/interrupted cache artifacts.\n- Create and remove temporary workdirs in the same `RUN` layer (for example `/tmp/opencode-repo`).\n- Do not defer cleanup to later layers; deleted files still exist in lower layers.\n- Keep builder-stage artifacts out of runtime layers by copying only final outputs.\n- When adding Docker build assets, update build-context inclusion logic in `packages/core/src/docker/image.rs`.\n- Keep local submodule exclude lists aligned with Dockerfile hygiene rules (`.planning`, `.git`, `node_modules`, `target`, `dist`, and similar dev metadata).\n\nThis policy is intentional for both image-size hygiene and fast local rebuilds.\n\n**Worktree-isolated sandbox profiles (opt-in):**\n```bash\n# Derive a stable instance name from the current git worktree root\njust run --sandbox-instance auto start --cached-rebuild-sandbox-image\n\n# Use an explicit instance name\njust run --sandbox-instance mytree start --cached-rebuild-sandbox-image\n```\n- Default behavior (no `--sandbox-instance`) remains the shared legacy sandbox.\n- Isolated instances use separate container names, image tags, Docker volumes, and image-state files.\n- You can also set `OPENCODE_SANDBOX_INSTANCE=\u003cname|auto\u003e` instead of passing the CLI flag every time.\n\n## Configuration\n\nConfiguration is stored at:\n- Linux/macOS: `~/.config/opencode-cloud/config.json`\n\nData (PID files, etc.) is stored at:\n- Linux/macOS: `~/.local/share/opencode-cloud/`\n\n## Development\n\n```bash\n# Bun is required for this repo\nbun --version\n\n# One-time setup (hooks + deps + submodule bootstrap)\njust setup\n\n# Build everything\njust build\n\n# Recommended local dev runtime (local submodule + cached sandbox rebuild)\njust dev\n\n# Compile and run occ (arguments automatically get passed to the binary)\njust run --version\n\n# Run tests\njust test\n\n# Format and lint\njust fmt\njust lint\n```\n\n### Visual E2E (Playwright)\n\nFrom the repository root, run UI tests in a visible browser with:\n\n```bash\nbun run --cwd packages/opencode/packages/app test:e2e:local -- --headed --project=chromium e2e/settings/settings-authentication.spec.ts\nbun run --cwd packages/opencode/packages/app test:e2e:local -- --ui e2e/settings/settings-authentication.spec.ts\nPWDEBUG=1 bun run --cwd packages/opencode/packages/app test:e2e:local -- --headed --project=chromium e2e/settings/settings-authentication.spec.ts\n```\n\nHeadless run (default Playwright mode):\n\n```bash\nbun run --cwd packages/opencode/packages/app test:e2e:local -- --project=chromium e2e/settings/settings-authentication.spec.ts\n```\n\nUse `test:e2e:local` for local harness/sandbox provisioning. Plain `test:e2e` expects a backend that is already running at the configured Playwright host/port.\n\n\u003e **Note:** The git hooks automatically sync `README.md` to npm package directories on commit.\n\n## Architecture\n\nThis is a monorepo with:\n- `packages/core` - Rust core library\n- `packages/cli-rust` - Rust CLI binary (recommended)\n- `packages/cli-node` - Node.js CLI (fully supported and in parity with the Rust CLI)\n\n### Cargo.toml Sync Requirement\n\nThe `packages/core/Cargo.toml` file must use **explicit values** rather than `workspace = true` references.\n\nWhen updating package metadata (version, edition, rust-version, etc.), keep both files in sync:\n- `Cargo.toml` (workspace root)\n- `packages/core/Cargo.toml`\n\nUse `scripts/set-all-versions.sh \u003cversion\u003e` to update versions across all files automatically.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprizz%2Fopencode-cloud","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprizz%2Fopencode-cloud","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprizz%2Fopencode-cloud/lists"}