Skip to main content

viberun CLI

Project description

viberun logo

viberun

viberun is a CLI-first, agent-native app host. Run viberun <app> locally and get dropped into an agent session inside a persistent Ubuntu container on a remote host. App data is stored under /home/viberun and survives container restarts or image updates.

Quick start (end-to-end)

You need a local machine with ssh and a reachable Ubuntu host (VM or server) that you can SSH into with sudo access.

1) Install the CLI

curl -fsSL https://viberun.sh | bash

Verify:

viberun --version

Optional overrides (advanced):

curl -fsSL https://viberun.sh | bash -s -- --nightly
curl -fsSL https://viberun.sh | bash -s -- --dir ~/.local/bin --bin viberun

Or with env vars:

curl -fsSL https://viberun.sh | VIBERUN_INSTALL_DIR=~/.local/bin VIBERUN_INSTALL_BIN=viberun bash

2) Bootstrap a host (once per VM)

Use any SSH host alias (for example, myhost in ~/.ssh/config):

viberun bootstrap myhost

Optional: set it as your default host (and agent) so you can omit @host later:

viberun config --host myhost --agent codex

3) Start your first app

viberun hello-world

If this is the first run, the server will prompt to create the container. Press Enter to accept.

Detach without stopping the agent: Ctrl-\ . Reattach later with viberun hello-world. Paste clipboard images into the session with Ctrl-V; viberun uploads the image and inserts a /tmp/viberun-clip-*.png path.

4) Hello-world prompt (paste inside the session)

Create a beautiful hello-world web app with a simple, tasteful landing page.

5) Open the app

While the session is active, viberun starts a localhost proxy to the host port. The agent will print a URL like:

http://localhost:8080

Open it in your browser. If you've configured app URLs, viberun <app> url shows the HTTPS address.

Common commands

viberun myapp
viberun myapp@hostb
viberun --forward-agent myapp
viberun myapp shell
viberun myapp snapshot
viberun myapp snapshots
viberun myapp restore latest
viberun myapp url
viberun myapp users
viberun myapp --delete -y
viberun myapp update
viberun bootstrap [<host>]
viberun proxy setup
viberun users list
viberun wipe
viberun config --host myhost --agent codex
viberun version
Table of contents

Git setup

Git, SSH, and the GitHub CLI are installed in containers. viberun seeds git config --global user.name and user.email from your local Git config into a host-managed config file that is mounted into each app container and applied on startup. This removes the common "first commit" setup step without auto-authing you.

Choose one of these auth paths:

  • SSH (agent forwarding): Run viberun --forward-agent <app>. For existing apps, run viberun <app> update once to recreate the container with the agent socket mounted. Then ssh -T git@github.com inside the container to verify access.
  • HTTPS (GitHub CLI): Run gh auth login and choose HTTPS, then gh auth setup-git. Verify with gh auth status.

If you update your local Git identity later, restart the app container (or run viberun <app> update) to re-apply the new values on startup.

Development

This repo is Go-first and uses mise for tool and task orchestration.

Setup

mise install

Build

mise exec -- go build ./cmd/viberun
mise exec -- go build ./cmd/viberun-server

Run locally

mise exec -- go run ./cmd/viberun -- --help
mise exec -- go run ./cmd/viberun-server -- --help

Test and vet

mise exec -- go test ./...
mise exec -- go vet ./...

Container image

mise run build:image
# fallback: docker build -t viberun .
# proxy image (Caddy + auth):
docker build -f Dockerfile.proxy -t viberun-proxy .

E2E and integration

bin/viberun-e2e-local
bin/viberun-integration

Bootstrap in development

When you run viberun via go run (or a dev build), bootstrap defaults to staging the local server binary and building the container image locally. This is equivalent to:

viberun bootstrap --local --local-image myhost

Under the hood, it builds a viberun:dev image for the host architecture, streams it over ssh with docker save | docker load, and tags it as viberun:latest on the host.

If you want to explicitly pass a local server binary:

mise exec -- go build -o /tmp/viberun-server ./cmd/viberun-server
viberun bootstrap --local-path /tmp/viberun-server myhost

For the full build/test/E2E flow, see DEVELOPMENT.md.

Architecture

High-level flow

viberun <app>
  -> ssh <host>
    -> viberun-server <app>
      -> docker container viberun-<app>
        -> agent session (tmux)

container port 8080
  -> host port (assigned per app)
    -> ssh -L localhost:<port>
      -> http://localhost:<port>
    -> (optional) host proxy (Caddy)
      -> https://<app>.<domain>

Core components

  • Client: viberun CLI on your machine.
  • Server: viberun-server executed on the host via SSH (no long-running daemon required).
  • Container: viberun-<app> Docker container built from the viberun:latest image.
  • Agent: runs inside the container in a tmux session (default provider: codex).
  • Host RPC: local Unix socket used by the container to request snapshot/restore operations.
  • Proxy (optional): viberun-proxy (Caddy + viberun-auth) for app URLs and login.

Session lifecycle

  1. viberun <app> resolves the host (from @host or your default config) and runs viberun-server over SSH.
  2. The server creates the container if needed, or starts it if it already exists.
  3. The agent process is attached via docker exec inside a tmux session so it persists across disconnects.
  4. viberun sets up a local port forward so you can open the app on http://localhost:<port>.

Bootstrap pipeline

The bootstrap script (run on the host) does the following:

  • Verifies the host is Ubuntu.
  • Installs Docker (if missing) and enables it.
  • Installs Btrfs tools (btrfs-progs) for volume snapshots.
  • Pulls the viberun container image from GHCR (unless using local image mode).
  • Downloads and installs the viberun-server binary.

If bootstrap is run from a TTY, it will offer to set up a public domain name (same as viberun proxy setup).

Useful bootstrap overrides:

  • VIBERUN_SERVER_REPO: GitHub repo for releases (default shayne/viberun).
  • VIBERUN_SERVER_VERSION: release tag or latest.
  • VIBERUN_IMAGE: container image override.
  • VIBERUN_PROXY_IMAGE: proxy container image override (for app URLs).
  • VIBERUN_SERVER_INSTALL_DIR: install directory on the host.
  • VIBERUN_SERVER_BIN: server binary name on the host.
  • VIBERUN_SERVER_LOCAL_PATH: use a local server binary staged over SSH.
  • VIBERUN_SKIP_IMAGE_PULL: skip pulling from GHCR (used for local builds).

Networking and ports

  • Each app container exposes port 8080 internally.
  • The host port is assigned per app (starting at 8080) and stored in the host server state.
  • viberun opens an SSH local forward so http://localhost:<port> connects to the host port.
  • If the proxy is configured, apps can also be served over HTTPS at https://<app>.<domain> (or a custom domain). Access requires login by default and can be made public per app.

App URLs and proxy

viberun can optionally expose apps via a host-side proxy (Caddy + viberun-auth). Set it up once per host:

viberun proxy setup [<host>]

You'll be prompted for a base domain and public IP (for DNS), plus a primary username/password. Create an A record (or wildcard) pointing to the host's public IP.

After setup:

  • viberun <app> url shows the current URL and access status.
  • viberun <app> url --make-public or --require-login toggles access (default requires login).
  • viberun <app> url --set-domain <domain> or --reset-domain manages custom domains.
  • viberun <app> url --disable or --enable turns the URL off/on.
  • viberun <app> url --open opens the URL in your browser.
  • viberun users ... manages login accounts; viberun <app> users controls who can access the app.

If URL settings change, run viberun <app> update to refresh VIBERUN_PUBLIC_URL and VIBERUN_PUBLIC_DOMAIN inside the container.

Snapshots and restore

Snapshots are Btrfs subvolume snapshots of the app's /home/viberun volume (auto-incremented versions). On the host, each app uses a loop-backed Btrfs file under /var/lib/viberun/apps/<app>/home.btrfs.

  • viberun <app> snapshot creates the next vN snapshot.
  • viberun <app> snapshots lists versions with timestamps.
  • viberun <app> restore <vN|latest> restores from a snapshot (latest picks the highest vN).
  • viberun <app> --delete -y removes the container, the app volume + snapshots, and the host RPC directory.

Restore details:

  • The host stops the container (if running) to safely unmount the volume.
  • The current @home subvolume is replaced by a new writable snapshot of @snapshots/vN.
  • The container is started again, and s6 reloads services from /home/viberun/.local/services.

Host RPC bridge

When you open a session, the server creates a Unix socket on the host and mounts it into the container at /var/run/viberun-hostrpc. The container uses it to request snapshot and restore operations. Access is protected by a per-session token file mounted alongside the socket.

Configuration and state

Local config lives at ~/.config/viberun/config.toml (or $XDG_CONFIG_HOME/viberun/config.toml) and stores:

  • default_host
  • agent_provider
  • hosts (alias mapping)

Host server state lives at ~/.config/viberun/server-state.json (or $XDG_CONFIG_HOME/viberun/server-state.json) and stores the port mapping for each app.

Proxy config (when enabled) lives at /var/lib/viberun/proxy.toml (or $VIBERUN_PROXY_CONFIG_PATH) and stores the base domain, access rules, and users. When enabled, the server injects VIBERUN_PUBLIC_URL and VIBERUN_PUBLIC_DOMAIN into containers.

Agents

Supported agent providers:

  • codex (default)
  • claude
  • gemini
  • ampcode (alias: amp)
  • opencode

Custom agents can be run via npx:<pkg> or uvx:<pkg> (for example, viberun --agent npx:@sourcegraph/amp@latest <app>).

Set globally with viberun config --agent <provider> or per-run with viberun --agent <provider> <app>. To forward your local SSH agent into the container, use viberun --forward-agent <app>. For existing apps, run viberun <app> update once to recreate the container with the agent socket mounted.

Base skills are shipped in /opt/viberun/skills and symlinked into each agent's skills directory. User skills can be added directly to the agent-specific skills directory under /home/viberun.

Security model

  • All control traffic goes over SSH; the server is invoked on demand and does not expose a network port.
  • The host RPC socket is local-only and protected by filesystem permissions and a per-session token.
  • Containers are isolated by Docker and only the app port is exposed.
  • App URLs are optional: the proxy requires login by default and can be made public per app with viberun <app> url --make-public.

Wipe (safety)

viberun wipe [<host>] deletes local config and wipes all viberun data on the host. It requires a TTY and asks you to type WIPE.

On the host, wipe removes:

  • All containers named viberun-*, any containers using viberun images, and the proxy container (default viberun-proxy).
  • All viberun images (including the proxy image).
  • App data and snapshots under /var/lib/viberun (including per-app Btrfs volumes).
  • Host RPC sockets in /tmp/viberun-hostrpc and /var/run/viberun-hostrpc.
  • /etc/viberun, /etc/sudoers.d/viberun-server, and /usr/local/bin/viberun-server.

Locally, it removes ~/.config/viberun/config.toml (and legacy config if present).

Repository layout

  • cmd/: Go entrypoints (viberun, viberun-server, viberun-auth).
  • internal/: Core packages (config, server state, SSH args, target parsing, TUI helpers).
  • bin/: Helper scripts for installs, integration/E2E flows, and container utilities.
  • skills/: Codex skill definitions used inside containers.
  • config/: Shell/TMUX/Starship config, auth assets, and runtime configs.
  • Dockerfile: Base container image definition.
  • Dockerfile.proxy: Proxy image definition (Caddy + auth).

Troubleshooting

  • unsupported OS: ... expected ubuntu: bootstrap currently supports Ubuntu only.
  • docker is required but was not found in PATH: install Docker on the host or re-run bootstrap.
  • missing btrfs on host: rerun bootstrap to install btrfs-progs and ensure sudo access.
  • no host provided and no default host configured: run viberun config --host myhost or use myapp@host.
  • container image architecture mismatch: delete and recreate the app (viberun <app> --delete -y).
  • proxy is not configured: run viberun proxy setup (then retry viberun <app> url).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

viberun-0.3.5.tar.gz (38.7 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

viberun-0.3.5-py3-none-any.whl (38.8 MB view details)

Uploaded Python 3

File details

Details for the file viberun-0.3.5.tar.gz.

File metadata

  • Download URL: viberun-0.3.5.tar.gz
  • Upload date:
  • Size: 38.7 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for viberun-0.3.5.tar.gz
Algorithm Hash digest
SHA256 a8e0ecaa7626f36ee15511f972a21cc08711a72c90991c6f7a5759a5492f4d3b
MD5 981ed649561c7dab71c07b0c0391814c
BLAKE2b-256 1e661c69f0b939085abd396787e6fff6d37e5764d98052940c8c5c8ccc660055

See more details on using hashes here.

Provenance

The following attestation bundles were made for viberun-0.3.5.tar.gz:

Publisher: release.yml on shayne/viberun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file viberun-0.3.5-py3-none-any.whl.

File metadata

  • Download URL: viberun-0.3.5-py3-none-any.whl
  • Upload date:
  • Size: 38.8 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for viberun-0.3.5-py3-none-any.whl
Algorithm Hash digest
SHA256 5beea64f062936acf791517cabbd832395c7391925d3aec6d643158b2c8ac7ff
MD5 3fd4bc7f1367cabb43aa25067e1de459
BLAKE2b-256 c4fc586c9d425c5ba750ce21bd948c7654db6729b92a77a32f8c4133987e39bf

See more details on using hashes here.

Provenance

The following attestation bundles were made for viberun-0.3.5-py3-none-any.whl:

Publisher: release.yml on shayne/viberun

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page