Deploy Lifecycle

Introduction

Buddo provides containerized application hosting for operators. You build a container image, push it to a supported registry, and the platform handles provisioning, networking, TLS, health monitoring, and billing. Your app runs on dedicated infrastructure (container-host-1) — isolated from the core Buddo API servers.

This guide walks through the complete deployment lifecycle: from registering your first app to monitoring, updating, and tearing down deployments. For full endpoint schemas and response details, see the Deploy API Reference.

Prerequisite: OAuth with deploy:manage scope. All deploy endpoints require an OAuth access token with the deploy:manage scope. See the OAuth PKCE guide for how to obtain one.

Overview

The deployment pipeline from creation to live traffic follows this path:

Register OAuth app          Choose a deploy tier          Create deployment
  (deploy:manage scope)        GET /api/deploy/tiers         POST /api/deploy/apps
        |                            |                            |
        v                            v                            v
  Obtain access token ----> Select tier (buddo/btc) ----> Subdomain + image + tier
                                                               |
                                                               v
                                                    Platform provisions container
                                                      (Podman on container-host-1)
                                                               |
                                                               v
                                              Caddy binds subdomain.buddocloud.com
                                                  (+ custom domain if configured)
                                                               |
                                                               v
                                              TLS auto-provisioned via Caddy/ACME
                                                               |
                                                               v
                                              Health checks begin · App is LIVE
                                                               |
                                          _____________________|_____________________
                                         |              |              |              |
                                         v              v              v              v
                                      Monitor        Restart        Update        Destroy
                                   GET .../status  POST .../restart  (redeploy)  DELETE .../

Step 1: Choose a Deploy Tier

Before creating a deployment, query the available tiers to understand the resource limits and pricing for each option.

Endpoint

GET /api/deploy/tiers

cURL Example

curl https://api.buddo.xyz/api/deploy/tiers \
  -H "Authorization: Bearer YOUR_OAUTH_TOKEN"

Response

Returns an array of DeployTier objects. Each tier includes:

FieldDescription
name / slugHuman-readable name and the slug you pass to the create endpoint
payment_methodbuddo_points or bitcoin
monthly_cost_pointsMonthly cost in Buddo points (null for Bitcoin tiers)
monthly_cost_satsMonthly cost in satoshis (null for Buddo tiers)
memory_limit_mbContainer memory cap in MB
cpu_limit_millicoresCPU allocation in millicores
custom_domain_allowedWhether this tier permits binding a custom domain
monthly_stipend_pointsBuddo points stipend included with the tier
ad_reach_multiplierMultiplier applied to ad campaign reach
Two billing tracks. Buddo offers a Buddo tier (pay with platform points) and a Bitcoin tier (pay with BTC). Bitcoin tiers include a higher monthly point stipend and elevated resource caps. Choose the tier slug that matches your preferred payment method.

Step 2: Create a Deployment

Create a new container deployment by specifying a subdomain, container image, tier, and optional configuration.

Endpoint

POST /api/deploy/apps

Request Body (JSON)

FieldRequiredDescription
subdomain Yes 1–32 characters, lowercase alphanumeric and hyphens. Your app will be reachable at <subdomain>.buddocloud.com.
image Yes Container image reference. Must start with harbor.buddo.xyz:4443/, docker.io/library/, or ghcr.io/.
tier Yes Deploy tier slug from GET /api/deploy/tiers
port No Container port to expose (default: 3000, range 1–65535)
custom_domain No Custom domain to bind (requires a tier where custom_domain_allowed is true)
env_vars No Key-value map of environment variables (max 50 keys)

cURL Example

curl -X POST https://api.buddo.xyz/api/deploy/apps \
  -H "Authorization: Bearer YOUR_OAUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "subdomain": "my-app",
    "image": "harbor.buddo.xyz:4443/operators/my-app:latest",
    "tier": "buddo-starter",
    "port": 8080,
    "env_vars": {
      "NODE_ENV": "production",
      "DATABASE_URL": "postgres://..."
    }
  }'

Success Response 201 Created

{
  "deployment": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "app_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "deploy_tier_id": "...",
    "container_name": "my-app-abc123",
    "container_image": "harbor.buddo.xyz:4443/operators/my-app:latest",
    "subdomain": "my-app",
    "status": "pending",
    "memory_limit_mb": 256,
    "cpu_limit_millicores": 250,
    "inserted_at": "2026-05-21T10:00:00Z"
  }
}

The deployment starts in pending status, transitions through deploying as the container is pulled and started, and reaches running once healthy. Poll the status endpoint to track progress.

Error Responses

StatusCause
401Missing or invalid OAuth token
404Tier not found
422Validation failed — invalid subdomain pattern, unsupported image registry, or unknown tier
429Deployment limit reached for this tier or account
Rate limit: 10 create requests per minute per operator.

What happens under the hood

  1. The API validates your request (subdomain availability, image whitelist, tier existence).
  2. A deployment record is created in pending status.
  3. The platform pulls your container image on container-host-1.
  4. A Podman container is created with the tier's resource limits (memory, CPU).
  5. Caddy reverse proxy is configured to route <subdomain>.buddocloud.com to the container's exposed port.
  6. TLS is automatically provisioned via Caddy's built-in ACME integration.
  7. If a custom domain is specified, Cloudflare DNS is configured and a separate TLS certificate is provisioned.
  8. Health checks begin. Once the container responds, status transitions to running.

Step 3: Domain Binding

Every deployment automatically receives a *.buddocloud.com subdomain based on the subdomain field you provided at creation. No DNS configuration is needed for the default subdomain.

Default subdomain

Your app is reachable at https://<subdomain>.buddocloud.com immediately after the container reaches running status. TLS is handled automatically.

Custom domains

If your deploy tier allows custom domains (custom_domain_allowed: true), you can pass a custom_domain field when creating the deployment. To use a custom domain:

  1. Set the custom_domain field in the POST /api/deploy/apps request.
  2. Add a CNAME record pointing your domain to <subdomain>.buddocloud.com in your DNS provider.
  3. The platform detects the CNAME and provisions a TLS certificate automatically via Caddy's on-demand TLS.
DNS propagation. Custom domains may take a few minutes to become active while DNS propagates and the TLS certificate is issued. The default *.buddocloud.com subdomain works immediately.

Step 4: Monitor

Once your deployment is live, use the monitoring endpoints to check health, track status, and review the action audit log.

Get full deployment details

GET /api/deploy/apps/{id}

Returns the complete Deployment object including status, container info, domain configuration, health status, billing status, and timestamps.

curl https://api.buddo.xyz/api/deploy/apps/DEPLOYMENT_ID \
  -H "Authorization: Bearer YOUR_OAUTH_TOKEN"

Lightweight status polling

GET /api/deploy/apps/{id}/status

Returns only the status and health fields — optimized for frequent polling. Rate limited to 30 requests per minute.

curl https://api.buddo.xyz/api/deploy/apps/DEPLOYMENT_ID/status \
  -H "Authorization: Bearer YOUR_OAUTH_TOKEN"

Status Response

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "running",
  "subdomain": "my-app",
  "health_status": "healthy",
  "last_health_check": "2026-05-21T10:05:00Z"
}

Deployment statuses

StatusMeaning
pendingDeployment created, container not yet provisioned
deployingContainer image is being pulled and started
runningContainer is live and passing health checks
stoppedContainer has been stopped (manually or by the platform)
destroyedDeployment permanently removed

Audit logs

GET /api/deploy/apps/{id}/logs

Returns a chronological log of all actions performed on the deployment: create, deploy, stop, restart, destroy, suspend, reactivate. Each entry includes the action type, status, timestamp, and who initiated it.

curl https://api.buddo.xyz/api/deploy/apps/DEPLOYMENT_ID/logs \
  -H "Authorization: Bearer YOUR_OAUTH_TOKEN"

Log Entry Example

{
  "logs": [
    {
      "id": "...",
      "action": "create",
      "status": "completed",
      "initiated_by": "7c9e6679-...",
      "inserted_at": "2026-05-21T10:00:00Z",
      "details": null
    },
    {
      "id": "...",
      "action": "deploy",
      "status": "completed",
      "initiated_by": null,
      "inserted_at": "2026-05-21T10:00:05Z",
      "details": null
    }
  ]
}

List all deployments

GET /api/deploy/apps

Returns all deployments owned by the authenticated operator. Useful for dashboards and management UIs.

curl https://api.buddo.xyz/api/deploy/apps \
  -H "Authorization: Bearer YOUR_OAUTH_TOKEN"

Step 5: Update and Restart

To update a running application, push a new version of your container image to the registry and restart the deployment. The platform will pull the latest image and replace the running container.

Restart endpoint

POST /api/deploy/apps/{id}/restart

curl -X POST https://api.buddo.xyz/api/deploy/apps/DEPLOYMENT_ID/restart \
  -H "Authorization: Bearer YOUR_OAUTH_TOKEN"

The restart action stops the current container and starts a fresh one from the latest image. The response returns the updated Deployment object. The deployment briefly transitions through deploying before returning to running.

Error Responses

StatusCause
401Missing or invalid OAuth token
403Deployment belongs to another operator
404Deployment not found
422Restart failed (e.g., deployment is already destroyed)
Rate limit: 10 restart requests per minute per operator.

Update workflow

  1. Build and push the new image to your registry (e.g., harbor.buddo.xyz:4443/operators/my-app:latest).
  2. Call POST /api/deploy/apps/{id}/restart.
  3. Poll GET /api/deploy/apps/{id}/status until status returns to running.
  4. Verify the new version is live by hitting your app's health endpoint or checking the audit logs.

Step 6: Scale and Billing

Deployment resources and costs are governed by the tier you selected at creation. Buddo uses a two-track billing model: operators choose between paying with Buddo platform points or Bitcoin.

Buddo tier (points)

Bitcoin tier

Billing cycle

Billing operates on a rolling 30-day cycle starting from deployment creation. The deployment's billing_status field reflects the current state. If payment lapses, the platform may suspend the deployment — the audit log will show a suspend action. Reactivation occurs automatically when billing is restored.

Checking tier pricing

Use GET /api/deploy/tiers at any time to review current tier definitions, pricing, and resource limits. See Step 1 for details.

Scaling up

To move to a higher-resource tier, destroy the current deployment and create a new one on the desired tier. The subdomain can be reused immediately after destruction.

Cleanup

When you no longer need a deployment, stop or destroy it to free resources and stop billing.

Stop a deployment

POST /api/deploy/apps/{id}/stop

Stops the container but preserves the deployment record. The deployment can be restarted later. Status transitions to stopped.

curl -X POST https://api.buddo.xyz/api/deploy/apps/DEPLOYMENT_ID/stop \
  -H "Authorization: Bearer YOUR_OAUTH_TOKEN"

Destroy a deployment

DELETE /api/deploy/apps/{id}

Permanently removes the deployment, its container, and all associated configuration. This action cannot be undone. Status transitions to destroyed.

curl -X DELETE https://api.buddo.xyz/api/deploy/apps/DEPLOYMENT_ID \
  -H "Authorization: Bearer YOUR_OAUTH_TOKEN"

Success Response 200 OK

{
  "message": "Deployment destroyed",
  "id": "550e8400-e29b-41d4-a716-446655440000"
}
Stop vs. Destroy. Use stop if you plan to restart later — the subdomain reservation and deployment record are preserved. Use destroy when you are done with the deployment entirely.

Architecture

Understanding the infrastructure behind Buddo deployments helps you debug issues and design your app for the environment.

Container runtime: Podman

All operator containers run on container-host-1 using Podman (rootless, daemonless). Each deployment gets its own isolated container with resource limits (memory and CPU) enforced by the selected tier. Containers are not co-located with the core Buddo API — they run on dedicated hosting infrastructure.

Reverse proxy: Caddy

Caddy acts as the reverse proxy in front of all deployed containers. It handles:

DNS: Cloudflare

The buddocloud.com zone is managed on Cloudflare. Wildcard DNS (*.buddocloud.com) points to container-host-1. Custom domains require the operator to add a CNAME record in their own DNS pointing to <subdomain>.buddocloud.com.

Health checks

The platform periodically probes each running container. The health_status and last_health_check fields on the deployment object reflect the current state. If a container becomes unresponsive, the platform may restart it automatically.

Image registries

Deployments accept images from three whitelisted registries:

API Quick Reference

All deploy endpoints require OAuth with deploy:manage scope. For full request/response schemas, see the Deploy API Reference.

EndpointDescriptionRate Limit
GET /api/deploy/tiers List available deployment tiers with pricing 30/min
POST /api/deploy/apps Create a new deployment 10/min
GET /api/deploy/apps List all operator deployments 30/min
GET /api/deploy/apps/{id} Get full deployment details 30/min
GET /api/deploy/apps/{id}/status Lightweight status poll 30/min
GET /api/deploy/apps/{id}/logs Deployment audit log 30/min
POST /api/deploy/apps/{id}/restart Restart deployment container 10/min
POST /api/deploy/apps/{id}/stop Stop a running deployment 10/min
DELETE /api/deploy/apps/{id} Permanently destroy a deployment 10/min

Further Reading