
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
@opencode-cloud/core
Advanced tools
[!WARNING] This tool is still a work in progress and is rapidly evolving. Expect bugs, frequent updates, and breaking changes. Follow updates on GitHub (Gitea mirror) and X (Twitter). Stability will be announced at some point. Use with caution.
A production-ready toolkit for deploying and managing our opencode fork (forked from anomalyco/opencode) as a persistent cloud service, sandboxed inside a Docker container for isolation and security.
This fork adds passkey-first authentication (WebAuthn/FIDO2), two-factor authentication, and enterprise security features for cloud deployment.
Deploy 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:
curl -fsSL https://raw.githubusercontent.com/pRizz/opencode-cloud/main/scripts/quick-deploy.sh | bash
Then open http://localhost:3000 and enter the Initial One-Time Password (IOTP) to complete setup.
macOS/Windows: Install Docker Desktop first, then run the command above.
Remote server: SSH into the server, run the command, then access via SSH tunnel:
ssh -L 3000:localhost:3000 root@<server-ip>
Interactive mode: Add
--interactiveto be prompted before each step:curl -fsSL .../scripts/quick-deploy.sh | bash -s -- --interactive
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 asdocker-compose.yml.bak.<timestamp>.
Image refresh behavior: By default, the script runs
docker compose pullbeforedocker compose up -d, so rerunning quick deploy updates to the latest image.
cargo install opencode-cloud
opencode-cloud --version
npx opencode-cloud@latest --version
bunx opencode-cloud@latest --version
Or install globally:
npm install -g opencode-cloud
opencode-cloud --version
Quick deploy provisions a private EC2 instance behind a public ALB with HTTPS. A domain name is required for ACM certificate validation. A Route53 hosted zone ID is required for automated DNS validation.
Docs: docs/deploy/aws.md (includes teardown steps and S3 hosting setup for forks)
Credentials: docs/deploy/aws.md#retrieving-credentials
One-click deploy provisions a Railway service with automatic HTTPS.
Important: Attach a Railway Volume mounted to
/home/opencoder/.local/share/opencodeto prevent data loss across redeploys.
Docs: docs/deploy/railway.md
Tip: For a fully automated setup, see Quick Deploy above.
The fastest way to run opencode-cloud locally:
docker compose up -d
This uses the included docker-compose.yml which configures all persistent volumes automatically.
Retrieve the Initial One-Time Password (IOTP) and open http://localhost:3000:
docker compose logs | grep -F "INITIAL ONE-TIME PASSWORD (IOTP): " | tail -n1 | sed 's/.*INITIAL ONE-TIME PASSWORD (IOTP): //'
Docs: docs/deploy/docker-desktop.md
DigitalOcean Marketplace one-click deployment is in progress. Support is coming soon.
Docs: docs/deploy/digitalocean-marketplace.md
SSH into an Ubuntu 24.04 Droplet and run:
curl -fsSL https://raw.githubusercontent.com/pRizz/opencode-cloud/main/scripts/quick-deploy.sh | bash
This 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.
Access via SSH tunnel: ssh -L 3000:localhost:3000 root@<droplet-ip>, then open http://localhost:3000.
Docs: docs/deploy/digitalocean-droplet.md
opencode-cloud / occ) - Works on Linux and macOSopencode-cloud runs opencode inside a Docker container, providing:
The CLI manages the container lifecycle, so you don't need to interact with Docker directly.
The 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, mirror: https://gitea.com/pRizz/opencode-cloud). It handles image pulling, container setup, and upgrades for you.
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.
The image is published to both registries (Docker Hub is the primary distribution):
| Registry | Image |
|---|---|
| Docker Hub | prizz/opencode-cloud-sandbox |
| GitHub Container Registry | ghcr.io/prizz/opencode-cloud-sandbox |
Pull commands:
Docker Hub:
docker pull prizz/opencode-cloud-sandbox:latest
GitHub Container Registry:
docker pull ghcr.io/prizz/opencode-cloud-sandbox:latest
For most users: Just use the CLI - it handles image pulling/building automatically:
occ start # Pulls or builds the image as needed
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.
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shcargo install opencode-cloud
occ --version
npx opencode-cloud@latest --version
bunx opencode-cloud@latest --version
Or install globally:
npm install -g opencode-cloud
occ --version
# Install as a system service (recommended for background use)
occ install
# Start the service
occ start
If this is the first startup with no configured managed users, the container logs will print an Initial One-Time Password (IOTP).
Open 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.
The IOTP is invalidated after successful passkey enrollment or successful username/password bootstrap signup.
Built-in image users (for example ubuntu/opencoder) do not count as configured users for IOTP bootstrap.
Quick IOTP extraction from logs:
occ logs | grep -F "INITIAL ONE-TIME PASSWORD (IOTP): " | tail -n1 | sed 's/.*INITIAL ONE-TIME PASSWORD (IOTP): //'
You can also run the setup wizard:
occ setup
The 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.
# GitHub (primary)
git clone https://github.com/pRizz/opencode-cloud.git
# Gitea (mirror)
git clone https://gitea.com/pRizz/opencode-cloud.git
cd opencode-cloud
git submodule update --init --recursive packages/opencode
cargo install --path packages/cli-rust
# GitHub (primary)
git clone https://github.com/pRizz/opencode-cloud.git
# Gitea (mirror)
git clone https://gitea.com/pRizz/opencode-cloud.git
cd opencode-cloud
git submodule update --init --recursive packages/opencode
# Bun is required for this repo
bun --version
just setup
just build
cargo run -p opencode-cloud -- --version
# Show version
occ --version
# Start the service (builds Docker container on first run, ~10-15 min)
occ start
# Start on a custom port
occ start --port 8080
# Start and open browser
occ start --open
# Check service status (includes broker health: Healthy/Degraded/Unhealthy)
occ status
# View logs
occ logs
# Follow logs in real-time
occ logs -f
# View opencode-broker logs (systemd/journald required)
occ logs --broker
# Troubleshoot broker health issues reported by `occ status`
occ logs --broker --no-follow
# Note: Broker logs require systemd/journald. This is enabled by default on supported Linux
# hosts. Docker Desktop/macOS/Windows use Tini, so broker logs aren't available there.
# Existing containers may need to be recreated after upgrading.
# Stop the service
occ stop
# Restart the service
occ restart
# Check for updates and choose what to update
occ update
# Update the opencode-cloud CLI binary
occ update cli
# Update the opencode-cloud container image
occ update container
# Update opencode inside the container
occ update opencode
# Update opencode using a specific branch or commit
occ update opencode --branch dev
occ update opencode --commit <sha>
# Remove the container (keeps volumes)
occ reset container
# Remove container and volumes (data loss)
occ reset container --volumes --force
# Reset completed IOTP bootstrap and generate a fresh one-time password
occ reset iotp
# If bind_address is exposed (for example behind HTTPS reverse proxy), confirm intentionally
occ reset iotp --force
# Clean bind mount contents (data loss)
occ mount clean --force
# Purge bind mounts (data loss, removes config entries)
occ mount clean --purge --force
# Mount a local project into the workspace
occ mount add /Users/<username>/Desktop/opencode:/home/opencoder/workspace
# Apply mount changes (you may be prompted to recreate the container)
occ restart
# Factory reset host (container, volumes, mounts, config/data)
occ reset host --force
### Workspace Mounts
Use `/home/opencoder/workspace` when you want your host project folder to appear in the
web UI's project picker and inside the container workspace.
Important behavior:
- `/home/opencoder/workspace` is a single mount target.
- Adding a new mount to this same target replaces the previous mount entry.
Recommended workflow:
```bash
occ mount add /Users/<username>/Desktop/opencode:/home/opencoder/workspace
occ restart
Verify the mount:
occ status and check Mounts -> Bind mounts includes your host path mapped to /home/opencoder/workspace.~/workspace.When occ runs inside the opencode container, it will auto-detect this and switch to container runtime.
Override if needed:
occ --runtime host <command>
OPENCODE_RUNTIME=host occ <command>
Supported commands in container runtime:
occ statusocc logsocc userocc update opencodeNotes:
occ logs and occ update opencode require systemd inside the container. If systemd is not available, run those commands from the host instead.When running in foreground mode (for example via occ install, which uses occ start --no-daemon),
the host listens for a command file on a bind mount. The webapp can write a simple JSON payload
to request an update.
Default paths (with default bind mounts enabled):
~/.local/state/opencode/opencode-cloud/commands/update-command.json/home/opencoder/.local/state/opencode/opencode-cloud/commands/update-command.jsonExample payload:
{
"command": "update_opencode",
"request_id": "webapp-1234",
"branch": "dev"
}
The host writes the result to:
~/.local/state/opencode/opencode-cloud/commands/update-command.result.json
occ install
occ uninstall
occ config show
## Authentication
Security details: `docs/security/passkey-registration.md` (IOTP bootstrap and passkey enrollment flow)
opencode-cloud uses **PAM (Pluggable Authentication Modules)** for authentication.
First boot path:
- If no managed users are configured, startup logs print an Initial One-Time Password (IOTP).
- Extract only the IOTP quickly: `occ logs | grep -F "INITIAL ONE-TIME PASSWORD (IOTP): " | tail -n1 | sed 's/.*INITIAL ONE-TIME PASSWORD (IOTP): //'`
- `occ setup` attempts to auto-detect and print the IOTP after starting/restarting the service.
- Enter that IOTP in the web login page first-time setup panel.
- Continue to passkey setup, then choose one of:
- Enroll a passkey for the default `opencoder` account, or
- Use the username/password fallback to create your first managed user.
- The IOTP is deleted after successful passkey enrollment or successful username/password bootstrap signup.
- To restart first-time onboarding after completion, run `occ reset iotp`.
- Built-in image users (for example `ubuntu`/`opencoder`) do not disable IOTP bootstrap.
Admin path:
- You can always create/manage users directly via `occ user add`, `occ user passwd`, and related user commands.
Login UX:
- Passkey sign-in is the primary option on the login page.
- Username/password sign-in remains available as fallback.
- 2FA setup/management is available from the upper-right session menu after login.
### Creating Users
Create a user with a password:
```bash
occ user add <username>
Generate a random password:
occ user add <username> --generate
occ user list (managed users only)occ user passwd <username>occ user remove <username>occ user enable <username> / occ user disable <username>User accounts (including password hashes and lock status) persist across container updates and rebuilds.
The CLI stores user records in a managed Docker volume mounted at /var/lib/opencode-users inside the container.
This record store is the source of truth for configured users and bootstrap decisions.
No plaintext passwords are stored on the host.
When developing locally or after updating opencode-cloud, you may need to rebuild the Docker image to pick up changes in the embedded Dockerfile:
# Rebuild using Docker cache (fast - only rebuilds changed layers)
occ start --cached-rebuild-sandbox-image
# Rebuild from scratch without cache (slow - for troubleshooting)
occ start --full-rebuild-sandbox-image
--cached-rebuild-sandbox-image (recommended for most cases):
--full-rebuild-sandbox-image (for troubleshooting):
When to rebuild:
--cached-rebuild-sandbox-imagepackages/opencode (submodule) → run just run start --cached-rebuild-sandbox-image once so the running container picks up the new opencode commit--cached-rebuild-sandbox-image--cached-rebuild-sandbox-image first, then --full-rebuild-sandbox-image--full-rebuild-sandbox-imageLocal submodule dev rebuild (no push required):
# Fast rebuild using local packages/opencode checkout (including uncommitted edits)
just run start --cached-rebuild-sandbox-image --local-opencode-submodule
# Full no-cache rebuild from local packages/opencode checkout
just run start --full-rebuild-sandbox-image --local-opencode-submodule
just run status will show commit metadata derived from your local checkout (dirty trees are marked with -dirty)..planning, .git, node_modules, target, and dist).For new Docker build steps, follow this checklist:
RUN --mount=type=cache) for package caches (apt, bun, cargo, pip, and npm).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.RUN layer (for example /tmp/opencode-repo).packages/core/src/docker/image.rs..planning, .git, node_modules, target, dist, and similar dev metadata).This policy is intentional for both image-size hygiene and fast local rebuilds.
Worktree-isolated sandbox profiles (opt-in):
# Derive a stable instance name from the current git worktree root
just run --sandbox-instance auto start --cached-rebuild-sandbox-image
# Use an explicit instance name
just run --sandbox-instance mytree start --cached-rebuild-sandbox-image
--sandbox-instance) remains the shared legacy sandbox.OPENCODE_SANDBOX_INSTANCE=<name|auto> instead of passing the CLI flag every time.Configuration is stored at:
~/.config/opencode-cloud/config.jsonData (PID files, etc.) is stored at:
~/.local/share/opencode-cloud/# Bun is required for this repo
bun --version
# One-time setup (hooks + deps + submodule bootstrap)
just setup
# Build everything
just build
# Compile and run occ (arguments automatically get passed to the binary)
just run --version
# Run tests
just test
# Format and lint
just fmt
just lint
From the repository root, run UI tests in a visible browser with:
bun run --cwd packages/opencode/packages/app test:e2e:local -- --headed --project=chromium e2e/settings/settings-authentication.spec.ts
bun run --cwd packages/opencode/packages/app test:e2e:local -- --ui e2e/settings/settings-authentication.spec.ts
PWDEBUG=1 bun run --cwd packages/opencode/packages/app test:e2e:local -- --headed --project=chromium e2e/settings/settings-authentication.spec.ts
Headless run (default Playwright mode):
bun run --cwd packages/opencode/packages/app test:e2e:local -- --project=chromium e2e/settings/settings-authentication.spec.ts
Use test:e2e:local for local harness/sandbox provisioning. Plain test:e2e expects a backend that is already running at the configured Playwright host/port.
Note: The git hooks automatically sync
README.mdto npm package directories on commit.
This is a monorepo with:
packages/core - Rust core librarypackages/cli-rust - Rust CLI binary (recommended)packages/cli-node - Node.js CLI (fully supported and in parity with the Rust CLI)The packages/core/Cargo.toml file must use explicit values rather than workspace = true references.
When updating package metadata (version, edition, rust-version, etc.), keep both files in sync:
Cargo.toml (workspace root)packages/core/Cargo.tomlUse scripts/set-all-versions.sh <version> to update versions across all files automatically.
MIT
FAQs
Core NAPI bindings for opencode-cloud (internal package)
The npm package @opencode-cloud/core receives a total of 104 weekly downloads. As such, @opencode-cloud/core popularity was classified as not popular.
We found that @opencode-cloud/core demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.