ilbertt/nibrun/deploy-to-nibrun

Claude Code and agent skill by ilbertt/nibrun

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Deploy a compiled binary to nibrun and run it as an HTTPS service. Use when asked to deploy, ship, host or run a self-contained server binary (Bun, Go, Rust, Zig, C) or a folder of static assets on nibrun, when working in a repo that targets nibrun, or when deciding whether nibrun fits an app.

Install

npx vskill@latest install ilbertt/nibrun/deploy-to-nibrun

SKILL.md

Deploy to nibrun

nibrun takes one compiled binary and gives it a microVM of its own, a persistent filesystem, and an HTTPS URL. No Dockerfile, no YAML, no cluster.

Build for Linux x86_64, deploy through nibrun's MCP server or CLI, then ask the URL for something. What that path does not need is below it: copying an app, the guest contract, naming a runtime value, a second public port, cron jobs, and what nibrun does not do.

For CI deployments, start at GitHub Actions.

1. Sign in

If using a connected nibrun MCP server, use its authenticated account and skip CLI sign-in. Otherwise, check the CLI:

sh
nib apps list

Both halves in one command: command not found means the CLI is not installed, Not signed in. means it is not signed in.

sh
curl -fsSL https://nibrun.com/install.sh | sh # installs `nib` to ~/.local/bin
nib login # device flow: approve it in the browser

nib login waits on a human approving it in a browser, so an agent that finds itself signed out asks the user to run it rather than trying to drive it.

2. Build the binary

One self-contained linux-x86_64 file — static, or dynamically linked against glibc, which the rootfs carries. It has to be built for that target: a binary compiled on a Mac, or for arm64, is the most common reason a first deploy never boots.

If the repo already builds one, run its build. A project that ships a binary usually wraps more than a compiler invocation — assets embedded, constants substituted at build time, a frontend compiled first — and a hand-rolled command silently skips all of it, producing something that links and then dies on boot. bun-full-stack-starter is one such: bun run build gives backend/dist/app with the frontend and the migrations inside it, defaulting to PORT 3000 and ./data.

A Bun repo with nothing to inherit compiles one itself with bun build --compile, targeting bun-linux-x64. Embedding an asset directory, bytecode, build-time constants — all flags on that same command, and worth reading Bun's single-file executable docs for rather than recalling: a flag invented from memory is how a binary ends up missing the files it expects to carry.

Three things to read off the binary before deploying rather than after:

  • The port it listens on, and that it binds 0.0.0.0 rather than 127.0.0.1. The guest hands

the number back as NIBRUN_HTTP_PORT and PORT, so an app that reads either needs no configuration here.

  • Where it writes. Only /app/data survives a redeploy, and an app that keeps its SQLite file

and its uploads under ./data is already there.

  • What it needs from the environment, off a .env.example or whatever it loads config from. It

has to be there on the first deploy: a process that exits over a missing variable never starts serving, and the deploy fails with it.

A folder of static assets has no binary to build: nib is one, and nib serve answers for whatever folder it is given, on the port the guest hands it. So the folder goes up as the app's data/, and the CLI's own Linux build as the binary that serves it:

sh
nib run "https://github.com/ilbertt/nibrun/releases/latest/download/nib-linux-x64 serve /app/data" --name my-site --data-folder ./dist

A path naming a directory answers with its index.html, and a miss with the folder's own 404.html where it has one; serve /app/data --single-page answers every miss with the root index.html instead, for a SPA whose routes exist only in the browser. No --port: nib serve binds whichever port the guest assigns. The assets ride in as data, which goes up only as the app is created — a rebuilt site is a new app, at a new URL, and a custom domain (nib apps domains) is what keeps an address across that.

3. Deploy

With MCP

Choose the app: supply a name and optional initial config to create one, or an appId to redeploy an existing app. Initial configuration includes the environment, arguments and HTTP port needed on first boot. Existing apps reuse their saved configuration. Reuse the returned app.id as appId for subsequent deployments; a name creates a new app.

Include chatId in deploy_app when your current chat ID is available; omit it rather than guessing. Without it, nibrun records the client's _meta["openai/session"] when available. This metadata is an anonymized conversation ID and cannot be assumed to resolve to a chat URL.

Choose one binary source:

  • Native file binding: attach the compiled executable to deploy_app's binary input using

the client's file binding.

  • HTTPS download: pass url to deploy_app when the binary is already reachable over HTTPS

from nibrun. Signed download URLs work. For binary or url, an optional sha256 verifies the downloaded bytes.

  • Direct upload: if native file binding is unavailable, use prepare_deploy as described

below. This requires an agent that can read the compiled file and upload bytes over HTTP.

For a direct upload:

  1. Call prepare_deploy with the app target, the binary's filename and its actual sizeBytes.

It returns app and upload, creating the app if needed. It does not deploy anything.

  1. PUT the raw binary as the whole request body to upload.url, with Content-Length equal to

sizeBytes. The signed URL authorizes this request; send no nibrun authorization token. Wait for a successful 2xx response.

  1. Call deploy_app with appId: app.id and artifactId: upload.artifactId. nibrun finalizes and

validates the uploaded binary, then queues the deployment.

Each deploy_app call creates a deployment and replaces the current release. The result contains app, deployment and the public url; a pending deployment is only queued. Use get_app to check the returned deployment and request the public URL before reporting success.

With the CLI

The first deploy creates the app:

sh
nib run ./my-server --name my-app --port 8080

--port is the HTTP port the binary listens on inside the guest — read it off the app rather than carrying a number over from an example. It is the number the guest hands back as NIBRUN_HTTP_PORT and PORT, and it defaults to 3000.

An app can be created with its data/ already holding something — a seeded SQLite file, a corpus, fixtures a first run would otherwise have to write:

sh
nib run ./my-server --name my-app --data-folder ./seed

--data-folder accepts a local folder, a .tar.gz or .zip file, or an HTTPS URL to either archive format. nibrun fetches remote archives directly, so there is no need to download them locally first. The URL must name the archive in its path and be reachable from nibrun; signed query strings work, so quote URLs that contain them:

sh
nib run ./my-server --name my-app --data-folder 'https://example.com/seed.tar.gz'

For every source, the root of the archive becomes the root of `data/`: a folder is packed from the inside, so ./seed/app.db arrives as /app/data/app.db, and bundling the folder rather than its contents puts every file one directory deeper than the app looks. Up to 1 GiB uploaded or fetched and 2 GiB unpacked, and only as the app is created: this and the app writing its own files are the whole of how anything gets onto the volume. A zip made anywhere but unix carries no permissions, so an executable bit does not survive one.

Try seeding first-run setup before going public

Some apps let the first visitor claim the admin account. Their public URL is reachable as soon as they boot, so check whether that setup can be seeded before deploying. This depends on what the app supports and what can run on the local machine:

  1. Look for a build for the local OS and architecture, or a supported way to run the app from

source. The Linux binary uploaded to nibrun cannot run directly on macOS. Use the same app version and check that its data can move between the local and Linux builds.

  1. If supported, seed a dedicated data folder using the app's documented initialization command,

or run the local build bound to 127.0.0.1, complete admin setup, and stop it cleanly.

  1. Deploy the seeded folder with --data-folder, using the Linux x86_64 binary. Supply any

encryption keys or other environment values the saved data needs on this first deploy.

  1. Check the public app requires the configured login and no longer offers an initial admin claim.
sh
nib run ./my-server-linux-x64 --name my-app --data-folder ./configured-data

If seeding succeeds, the app starts with its admin account already claimed. Keep the configured data folder private: it contains the app's account state.

If a compatible local build or initialization method is unavailable, check whether the app can set initial admin credentials through configuration on its first boot. If neither approach is supported, explain that seeding could not be done and that first-visitor setup will be reachable when the public URL goes live.

Redeploying

Every deploy after that must name the app, or a non-interactive shell creates a second one. nib apps list finds the name again when a later session has to redeploy:

sh
nib run ./my-server --app my-app

For a local binary, the CLI skips uploading when that app already has an artifact with the same bytes and filename. It still creates a new deployment with the configuration you supplied.

Environment variables are an edit, not a replacement — anything a deploy does not name is left alone, so secrets are set once:

sh
nib run ./my-server --app my-app --env STRIPE_SECRET_KEY=sk_live_...

Arguments for the binary go inside the quotes, not after them:

sh
nib run "./my-server serve --verbose" --app my-app

The binary may be an https url instead of a path, and nibrun fetches it rather than this machine uploading it:

sh
nib run https://github.com/me/my-app/releases/download/v1/my-server --app my-app

Changing only how the binary starts is nib apps update, which runs the one the app already has rather than asking for it again. What no flag names is left alone:

sh
nib apps update --app my-app --env LOG_LEVEL=debug
nib apps update --app my-app --args "serve --verbose"

nib run waits until the deployment is actually serving and prints the URL. Or drag the binary onto app.nibrun.com — same thing, no CLI.

Every option a deploy takes is listed by nib run anything --help — any word will do in place of the binary, because the help does not read it, and nib run --help on its own answers with the subcommand rather than the options. What is below is what --help does not say.

GitHub Actions

Deploy an existing app without an API key or nib login in CI. Use a CLI release with GitHub OIDC support. After signing in locally, configure which workflow may deploy:

sh
nib apps github-workflows set --app my-app --repository OWNER/REPO --workflow deploy.yml

Save this as .github/workflows/deploy.yml. Replace ./build.sh with the repository’s build command, ./my-server with its Linux x86_64 output, and APP_ID with the app ID from the setup command above:

yaml
name: Deploy to nibrun
on:
push:
branches: [main]
permissions:
contents: read
id-token: write
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: nibrunhq/setup-cli@v1
- run: ./build.sh
- run: nib run ./my-server --github-trusted-oidc --app-id APP_ID

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 90 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
115
Repository forks
4
7-day trend score
0

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/ilbertt/nibrun/deploy-to-nibrun/badge)](https://verified-skill.com/skills/ilbertt/nibrun/deploy-to-nibrun)

Something wrong with this skill or its page? Tell us.