by is the command-line client for Blockyard. It handles authentication,
deployment, app management, and administration from your terminal.
Global flags#
| Flag | Description |
|---|---|
--json | Output machine-readable JSON (all commands) |
When --json is set, all output (including errors) is printed as
pretty-printed JSON. Errors use the shape {"error": "...", "message": "..."}.
Authentication#
by login#
Store credentials interactively. Opens a browser to create a Personal Access Token, then verifies it against the server.
by login
by login --server https://blockyard.example.com| Flag | Description |
|---|---|
--server <url> | Server URL (prompts interactively if omitted) |
Credentials are saved to ~/.config/by/config.json (respects
$XDG_CONFIG_HOME) with file mode 0600.
Environment variable override. Instead of by login, you can set both
BLOCKYARD_URL and BLOCKYARD_TOKEN. When both are present they take
precedence over the config file.
Deploying#
by deploy <path>#
Deploy a Shiny app to Blockyard. This is the primary workflow command — it detects dependencies, creates a bundle archive, uploads it, and optionally waits for the build to finish.
by deploy .
by deploy ./my-app --name dashboard --pin --wait
by deploy ./my-app --yes --wait| Flag | Description |
|---|---|
--name <string> | Override app name (default: directory basename) |
--pin | Pin dependencies via renv::snapshot() (requires R + renv) |
-y, --yes | Skip the confirmation prompt |
--wait | Wait for the build to complete and stream logs |
--repositories <csv> | R package repository URLs (comma-separated) |
Dependency detection (in priority order):
manifest.jsonexists — used as-isrenv.lockexists — converted to manifest--pinflag — runsrenv::snapshot(), then convertsDESCRIPTIONexists — builds an unpinned manifest- Bare R scripts — uploaded without manifest
The command auto-detects the app entrypoint (app.R or server.R), computes
SHA-256 checksums for all files, creates a gzip tar archive, and uploads it.
If the app does not exist on the server yet, it is created automatically.
Example output:
Detected:
Name: dashboard
Mode: DESCRIPTION (entrypoint: app.R)
Deps: 3 packages
Repository: https://cran.r-project.org
Deploy? [Y/n] y
Uploading bundle... done.
App: dashboard
Bundle: b1a2b3c4 (building)
Task: t9876...
URL: https://blockyard.example.com/app/dashboard/by init <path>#
Generate a manifest.json without deploying. Useful for inspecting or
committing the resolved manifest before deploying.
by init .
by init ./my-app --pin --repositories https://cran.r-project.org| Flag | Description |
|---|---|
--pin | Pin dependencies via renv::snapshot() |
--repositories <csv> | R package repository URLs (comma-separated) |
If manifest.json already exists, validates it and exits successfully
(no new file is written). Does not support bare-script apps — at least a
DESCRIPTION is required.
App management#
by list#
List all apps. Alias: by ls.
by list
by list --deleted
by ls --json| Flag | Description |
|---|---|
--deleted | Include soft-deleted apps (admin only) |
Example output:
NAME TITLE OWNER STATUS ENABLED
dashboard Sales Dashboard alice running yes
demo Demo App bob stopped yesby get <app>#
Show details for a single app.
by get dashboard
by get dashboard --runtime| Flag | Description |
|---|---|
--runtime | Include live runtime data (workers, sessions, metrics) |
Without --runtime, shows static metadata (ID, owner, status, enabled state,
access mode, title, description, active bundle, resource limits, tags,
creation date). With --runtime, appends worker table and session/view
statistics.
by enable <app>#
Enable an app, allowing traffic to reach it.
by enable dashboardby disable <app>#
Disable an app. Blocks new traffic and drains active sessions.
by disable dashboardby delete <app>#
Soft-delete an app. Alias: by rm.
by delete demo
by rm demo --purge| Flag | Description |
|---|---|
--purge | Permanently delete (admin only; app must be soft-deleted first) |
by restore <app>#
Restore a soft-deleted app.
by restore demoby update <app>#
Update app metadata. At least one flag is required.
by update dashboard --title "Sales Dashboard v2"
by update dashboard --description "Regional sales metrics"| Flag | Description |
|---|---|
--title <string> | Display title |
--description <string> | Description text |
Bundles#
by bundles <app>#
List all bundles for an app.
by bundles dashboardExample output:
ID STATUS UPLOADED DEPLOYED BY PINNED
b1a2b3c4b1a2 success 2026-03-28T08:00:00Z alice yes
d5e6f7a8d5e6 success 2026-03-27T14:30:00Z bob noby rollback <app> <bundle-id>#
Roll back to a previous bundle.
by rollback dashboard d5e6f7a8d5e6Scaling#
by scale <app>#
Configure resource limits and autoscaling. At least one flag is required.
by scale dashboard --memory 1g --cpu 2.0
by scale dashboard --max-workers 4 --pre-warm 1| Flag | Description |
|---|---|
--memory <string> | Memory limit (e.g., 512m, 2g) |
--cpu <float> | CPU limit (e.g., 1.0, 2.5) |
--max-workers <int> | Maximum workers per app |
--max-sessions <int> | Maximum sessions per worker |
--pre-warm <int> | Pre-warmed standby workers |
Only the flags you provide are updated; omitted fields are left unchanged.
Access control#
by access show <app>#
Show the access type and ACL entries for an app.
by access show dashboardExample output:
Access type: acl
PRINCIPAL KIND ROLE GRANTED BY
alice@example.com user collaborator admin
bob@example.com user viewer adminby access set-type <app> <type>#
Set the access mode. Valid types:
| Type | Description |
|---|---|
acl | Per-user access control list |
logged_in | Any authenticated user |
public | No authentication required |
by access set-type dashboard acl
by access set-type demo publicby access grant <app> <user>#
Grant a user access to an app.
by access grant dashboard bob@example.com
by access grant dashboard bob@example.com --role collaborator| Flag | Description |
|---|---|
--role <string> | Role to grant: viewer (default) or collaborator |
by access revoke <app> <user>#
Revoke a user’s access.
by access revoke dashboard bob@example.comTags#
by tags list#
List all tags in the global pool.
by tags listby tags create <tag>#
Create a tag (admin only).
by tags create productionby tags delete <tag>#
Delete a tag (admin only). Cascades — the tag is also removed from all apps.
by tags delete stagingby tags app-list <app>#
List tags attached to an app. Hidden from by tags --help but functional.
by tags app-list dashboardby tags app-add <app> <tag>#
Attach a tag to an app. Hidden from by tags --help but functional.
by tags app-add dashboard productionby tags app-remove <app> <tag>#
Detach a tag from an app. Hidden from by tags --help but functional.
by tags app-remove dashboard stagingDependencies#
by refresh <app>#
Refresh unpinned dependencies. Triggers a background task that re-resolves packages from configured repositories and streams the task logs.
by refresh dashboard
by refresh dashboard --rollback| Flag | Description |
|---|---|
--rollback | Roll back to the previous dependency set instead |
This is useful for apps deployed from a DESCRIPTION (unpinned) — it pulls
the latest compatible package versions without requiring a new bundle upload.
Logs#
by logs <app>#
View or stream app logs.
by logs dashboard
by logs dashboard --follow
by logs dashboard --worker w-abc123 --follow| Flag | Description |
|---|---|
-f, --follow | Stream logs live (default: static snapshot) |
-w, --worker <id> | Worker ID (auto-selects most recent if omitted) |
When multiple workers exist and --worker is not specified, the most recently
started active worker is selected. If no active workers exist, the most
recently ended worker is used.
User administration#
These commands require the admin system role.
by users list#
List all users.
by users listExample output:
SUB NAME EMAIL ROLE ACTIVE
google-oauth2|abc123 Alice alice@example.com admin yes
google-oauth2|def456 Bob bob@example.com publisher yesby users update <sub>#
Update a user’s role or active status. At least one flag is required.
by users update "google-oauth2|def456" --role admin
by users update "google-oauth2|def456" --active=false| Flag | Description |
|---|---|
--role <string> | Set role: admin, publisher, or viewer |
--active <bool> | Enable or disable the user account (default: true) |
Configuration#
The CLI stores credentials in ~/.config/by/config.json (or
$XDG_CONFIG_HOME/by/config.json):
{
"server": "https://blockyard.example.com",
"token": "by_..."
}Credential resolution order:
BLOCKYARD_URL+BLOCKYARD_TOKENenvironment variables (both required)- Config file
- Error if neither is available