Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.withnubo.com/llms.txt

Use this file to discover all available pages before exploring further.

A Frame is one deployable app - your landing page, API, Discord bot, or anything else you’d normally stand up on its own server. Each Frame gets its own domain, its own deploy history, and its own settings. Frames live inside a Space, and Spaces live inside a Project. If you’re coming from another platform: a Frame is roughly what other tools call a “service” or “app”.

Create a Frame

The fastest path is the dashboard:
  1. Open a Project, pick the Space you want (dev, staging, or production), and hit New Frame.
  2. Connect your GitHub repo and pick the branch you want Nubo to watch.
  3. Tell Nubo which port your app listens on.
  4. Hit deploy.
That’s it. Nubo takes care of building, running, and giving your Frame a URL. Prefer the API?
curl -X POST https://shuttle.withnubo.com/v2/projects/<project_id>/spaces/<space_id>/frames \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-app",
    "owner_id": "<your-user-id>",
    "git_repository": "my-repo",
    "git_repository_owner": "my-github-user",
    "git_repository_branch": "main",
    "port": 3000
  }'
To run a Frame on your own server instead of Nubo’s cloud, see Self-hosted agents.

What a Frame’s status means

Open any Frame in the dashboard and you’ll see its current state in real time:
StatusMeaning
StartingA deploy is in progress or the app is coming up.
OnlineHealthy and serving traffic.
DegradedRunning, but not all replicas are healthy.
ErrorNo healthy replicas. The dashboard will tell you why.
StoppedScaled to zero or explicitly stopped.
When a Frame is in Error, Nubo surfaces what went wrong (crash, out of memory, health-check failure, etc.) right next to the status so you don’t have to go hunting through logs. If the same Frame keeps failing - five crashes in a row, or stuck pulling its image for more than three minutes - Nubo automatically scales it to zero and shows a backoff_tripped reason so you stop seeing the same error toast over and over. The next push (or hitting Deploy) scales it back up and clears the trip, so a fresh image automatically recovers a stuck Frame.

Stop and start a Frame

Need to take a Frame offline without losing it? Hit Stop on the Frame to pause it (replicas scale to zero, or for self-hosted Agents the container is stopped). The Frame’s config, deploy history, environment variables, and domains are all kept. When you’re ready, hit Start to bring it back up. Via API:
curl -X POST https://shuttle.withnubo.com/v2/projects/<project_id>/spaces/<space_id>/frames/<frame_id>/stop \
  -H "Authorization: Bearer <your-token>"

curl -X POST https://shuttle.withnubo.com/v2/projects/<project_id>/spaces/<space_id>/frames/<frame_id>/start \
  -H "Authorization: Bearer <your-token>"
Both return 202 Accepted. The Frame moves through Stopped and back to Online as the change is applied. If the Frame is on a self-hosted Agent that is currently offline, you’ll get back 503 Service Unavailable.

Update a Frame’s settings

The Frame’s Settings tab groups everything you can change into clear sections (General, Source, Runtime, Environment variables, Custom domains, Danger zone). A sticky save bar at the bottom tracks unsaved changes so you always know if something is pending. You can:
  • Rename the Frame.
  • Switch the branch Nubo watches.
  • Change the port your app listens on.
  • Scale the replica count up or down.
  • Update environment variables.
  • Attach or remove custom domains and volumes.
Renaming, changing branches, or editing env variables doesn’t redeploy by itself. Push a commit or hit Deploy when you’re ready. Via API:
curl -X PATCH https://shuttle.withnubo.com/v2/projects/<project_id>/spaces/<space_id>/frames/<frame_id> \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-app",
    "git_repository_name": "my-repo",
    "git_repository_owner": "my-github-user",
    "git_repository_branch": "main",
    "port": 3000,
    "replica_count": 2
  }'
Changing the port re-rolls the Frame so the new value takes effect. Picks must be between 1024 and 65535.

Delete a Frame

From the dashboard: open the Frame’s Settings tab and scroll to the danger zone. Via API:
curl -X DELETE https://shuttle.withnubo.com/v2/projects/<project_id>/spaces/<space_id>/frames/<frame_id> \
  -H "Authorization: Bearer <your-token>"
Any custom domains attached to the Frame are released at the same time.

Deployments

How a push turns into a running Frame

Environment variables

Pass secrets and config into your app

Custom domains

Serve a Frame at your own hostname

Volumes

Add persistent storage to a Frame