# Hand this document directly to your AI assistant to read. # VibeZoo - AI Agent Deployment Guide > Audience: an AI coding agent (e.g. Claude Code). This document tells you how to > (1) build/package an app this platform can deploy, and (2) deploy it through the > HTTP API or the `vibezoo` CLI. Follow it exactly. It is a deployment spec, not a tutorial. > > This guide is served by the VibeZoo platform itself. The API lives at the SAME origin > as this page. Below, replace `` with that origin (for example > `https://vibe.example.com`). This page is public and requires no login. ## 1. What VibeZoo does You give it a `.zip` of an app. VibeZoo builds it, runs it as a container, routes a public URL to it, and reports status. There are four build paths: a Dockerfile, Nixpacks (auto), Railpack (auto), or static hosting. It is meant for quick demos and internal trials, so apps run under per-app resource limits. ## 2. How to write/package the app (the rules you MUST follow) - Deliver the project as a single `.zip`. Put the project at the zip root, or inside one top-level folder (it is unwrapped automatically). - The app MUST listen on `0.0.0.0:` -- never `127.0.0.1`/`localhost`, or the platform cannot reach it. Default `containerPort` is `3000`; set it to match your app. - Choose exactly ONE build type: - `dockerfile` -- include a `Dockerfile` at the project root. Most reliable. Use `EXPOSE ` and a start command that binds `0.0.0.0:`. - `nixpacks` -- no Dockerfile; auto-detected for Node.js / Python / etc. For Python web apps (Flask/Django/FastAPI) you MUST provide a start command that binds 0.0.0.0, e.g. `gunicorn --bind 0.0.0.0:8000 app:app`. The framework dev server binds 127.0.0.1 by default and will be unreachable. - `railpack` -- alternative auto-builder with strong defaults for modern frameworks (Next.js / Remix / Django). Good when Nixpacks struggles and you do not want a Dockerfile. - `static` -- pure HTML/CSS/JS, served by nginx. No server process. Use `containerPort` 80. - The platform auto-detects build type from the ZIP contents (Dockerfile present -> dockerfile; Next/Remix/Django signals -> railpack; index.html only -> static; otherwise -> nixpacks). You can override with the `buildType` field. - Environment variables: provide as `KEY=VALUE`, one per line. - Django apps: the platform automatically injects `DJANGO_ALLOWED_HOSTS` with the deployment host. You do not need to set it manually. - Persistent storage: a writable volume is mounted at `/data`. Put SQLite databases, uploads, and any state you want to survive a redeploy under `/data`. Everything outside `/data` is ephemeral and reset on redeploy. - Outbound internet/API access may require an HTTP proxy (depends on the platform/network). If your platform provides one, set `HTTP_PROXY` / `HTTPS_PROXY` (and `NO_PROXY` for internal hosts) in the env -- the proxy address is shown in the platform UI or provided by your admin. Service-to-service traffic inside a deployment is direct. - Resource limits: each app runs under platform-/plan-configured memory and CPU limits. Keep the image and runtime lean; do not assume large memory. ## 3. Authentication -- Personal Access Token (PAT) Every API call authenticates with a PAT. Create one in the web UI: Account -> API Tokens -> Create token, with scope `deployments:write` (add `deployments:read` to read status). A token looks like `vbz_pat_...` and is shown only once. Send it on every request: Authorization: Bearer vbz_pat_xxxxxxxx ## 4. Deploy via HTTP API `POST /api/deployments` with `Content-Type: multipart/form-data`. Fields: - `name` (required) -- deployment name. - `url` (required when you may choose a host: admin / Pro / Max) -- public host or subdomain. Free tier gets an auto-assigned URL; omit it. - `zip` (required for an uploaded app) -- the project `.zip` file. - `buildType` (optional) -- `nixpacks` | `railpack` | `dockerfile` | `static`. - `containerPort` (optional) -- the port your app listens on (default 3000). - `env` (optional) -- multiline `KEY=VALUE` string. - `path` (optional) -- path prefix, default `/`. - `sourceType` (optional, default `drop`) -- where the app comes from. Tier-gated: - `drop` -- upload a `.zip` via the `zip` field (any tier). - `git` -- deploy from a Git repo (**Pro/Max only**; Free gets `403 git_requires_pro_max`). Set `sourceType=git`, `repositoryUrl`, and `repositoryBranch`. No `zip`. - `image` -- deploy a prebuilt Docker image (**Max only**; others get `403 image_requires_max`). Set `sourceType=image` and `imageRef` (e.g. `nginx:1.27` or `ghcr.io/you/app:tag`); optional `imageCommand` overrides the container CMD. No `zip` and no build step -- set `containerPort` to the port the image listens on. - `visibility` (optional) -- `public` | `private`. **New deployments default to `private`.** A `private` site is NOT openly reachable: visitors must sign in to the VibeZoo dashboard AND be on the site's allow list before the URL loads. For an openly-reachable demo you MUST pass `visibility=public`. (The deployment record echoes the current value.) - `accessEmails` (optional, only meaningful when `visibility=private`) -- a JSON array string of emails to seed the allow list at create time, e.g. `accessEmails=["a@x.com","b@y.com"]`. The owner always has access implicitly (not listed). Non-member emails get a pending invite. - Advanced (optional): `buildPath`, `publishDirectory`, `buildCommand`, `startCommand`. The call returns `202` with the deployment record (includes `id`, `phase`, and `visibility`). Poll: `GET /api/deployments/` -- `phase` progresses `queued -> scanning -> building -> ... -> ready`, or becomes `failed` (read `errorMessage`). ### Access control for `private` deployments Manage who may open a private site (the owner always has access): - `GET /api/deployments//access-entries` -- list allow-list entries. - `POST /api/deployments//access-entries` with JSON `{"email":"a@x.com"}` -- add one. A registered member becomes active immediately; a non-member gets a pending invite email and activates on sign-up. - `DELETE /api/deployments//access-entries/` -- remove one. Switch a site between public and private at any time: `PATCH /api/deployments/` with JSON `{"visibility":"public"}` (or `"private"`). ### curl example TOKEN=vbz_pat_xxxxxxxx curl -X POST /api/deployments \ -H "Authorization: Bearer $TOKEN" \ -F name=my-app \ -F url=my-app \ -F buildType=nixpacks \ -F containerPort=3000 \ -F 'env=NODE_ENV=production' \ -F zip=@./my-app.zip # poll until phase == ready curl -H "Authorization: Bearer $TOKEN" /api/deployments/ ### curl example -- Git repo (Pro/Max) curl -X POST /api/deployments \ -H "Authorization: Bearer $TOKEN" \ -F name=my-app \ -F url=my-app \ -F sourceType=git \ -F repositoryUrl=https://github.com/you/my-app \ -F repositoryBranch=main \ -F containerPort=3000 ### curl example -- Docker image (Max) curl -X POST /api/deployments \ -H "Authorization: Bearer $TOKEN" \ -F name=my-app \ -F url=my-app \ -F sourceType=image \ -F imageRef=ghcr.io/you/my-app:latest \ -F containerPort=8080 ## 5. Deploy via the vibezoo CLI npm i -g vibezoo vibezoo login --token vbz_pat_xxxxxxxx --base-url vibezoo deploy ./my-app --name my-app --url my-app --build-type nixpacks --container-port 3000 vibezoo list vibezoo logs `deploy ` accepts a directory (auto-zipped) or a `.zip` file. Options: `--name` (required), `--url` (required), `--path`, `--build-type`, `--container-port`, `--env`. The base URL can also come from the `VIBEZOO_BASE_URL` env var and the token from `VIBEZOO_TOKEN`. ## 6. Build-type decision (apply in order) 1. A `Dockerfile` exists at the project root -> use `dockerfile`. 2. Next.js (`next.config.*`), Remix, or Django (`manage.py`) -> use `railpack`. 3. Node.js (`package.json`) or Python (`requirements.txt` / `pyproject.toml`) and no Dockerfile -> use `nixpacks`. Provide a start command that binds `0.0.0.0`. 4. Only static assets (`index.html`, no build manifest) -> use `static` with `containerPort` 80. ## 7. Full API reference Interactive OpenAPI docs: `/api/docs` (raw spec at `/api/docs/json`). ## 8. Pre-deploy checklist - [ ] App listens on `0.0.0.0:`. - [ ] Anything that must persist is written under `/data`. - [ ] Correct `buildType`; Dockerfile/start command actually starts the server on the port. - [ ] Secrets passed via `env`, never hardcoded. - [ ] PAT has the `deployments:write` scope. - [ ] Poll until `phase == ready`; on `failed`, read `errorMessage`, fix, and redeploy.