Documentation

The persistent runtime your agent deploys to — DB, storage, URL, one MCP call. Everything you need to run apps on BasicDeploy — from your first container to driving the platform from an AI agent.

Quickstart

  1. Sign in with your email — we send a magic link, so there is no password to manage.
  2. Click Create Container. You get a running container with PostgreSQL, S3-compatible storage and a public URL.
  3. Open the built-in terminal to write code, or upload a project from the Deploy page.

Core concepts

A container is the unit you work with on BasicDeploy. Each one bundles your app, a PostgreSQL database, S3-compatible object storage and a public HTTPS URL, with every credential your app needs already in its environment. The database and storage bucket are assigned per user and shared across the containers you own.

What's in a container

Your app runs inside the container and listens on port 8080. BasicDeploy's proxy maps the container's subdomain — https://your-subdomain.basicdeploy.com — to that port, so anything you serve on 0.0.0.0:8080 is live on the public URL.

Auto-sleep vs. always-on

On the Free plan, idle containers sleep to save resources and wake automatically on the next request — the first hit after sleeping may take a moment. Pro and Scale containers, and any container backed by an always-on add-on, stay running around the clock.

Plans & limits

Every plan includes PostgreSQL, object storage and a public URL on each container. Higher tiers raise the container count, memory and storage, keep containers always-on and allow custom domains.

PlanPriceContainersMemory / containerStorageAlways-onCustom domains
Free$03256 MB1 GBSleeps when idle
Pro$12/mo31 GB5 GBAlways-on1
Scale$39/mo102 GB10 GBAlways-on10

Need a Free-plan container to stay up, or an extra always-on slot on a paid plan? Add an always-on add-on for $4/mo per container.

Deploying an app

Deploy from the Deploy page in the dashboard, or POST a project archive to the API. BasicDeploy unpacks the tarball into /workspace, detects the runtime from the files it contains, installs dependencies and starts your app in the background.

Runtime detection

The runtime is chosen from the files in your project root, in this order: a Dockerfile builds from your own image; otherwise package.json runs as Node (npm install && npm start), requirements.txt as Python (pip install -r requirements.txt && python app.py), and go.mod as Go (go build && ./main).

Bind to 0.0.0.0:8080

Your app must listen on 0.0.0.0:8080 — that is the port the public URL is wired to. Binding to localhost or another port means the proxy can't reach it, and the URL shows a 'nothing listening on 8080' notice.

Python — requirements.txt + app.py

# requirements.txt
flask

# app.py
from flask import Flask

app = Flask(__name__)

@app.get("/")
def home():
    return "Hello from BasicDeploy"

# Must bind 0.0.0.0:8080 — the public URL is wired to this port.
app.run(host="0.0.0.0", port=8080)

Node — package.json + npm start

// package.json
{ "name": "app", "scripts": { "start": "node server.js" } }

// server.js
const http = require("http")

http
  .createServer((req, res) => res.end("Hello from BasicDeploy"))
  .listen(8080, "0.0.0.0") // bind 0.0.0.0:8080

Deploy logs

Startup output is captured to /workspace/deploy.log and errors to /workspace/deploy-error.log. Both are surfaced through the logs endpoint and the dashboard, so you can watch install and boot output without opening a shell.

Web terminal & exec

Every container has a built-in terminal in the dashboard for an interactive shell in /workspace. To run one-off commands from a script or agent, POST to the exec endpoint and read the command's output from the response.

curl -X POST https://basicdeploy.com/api/containers/{id}/exec \
  -H "Authorization: Bearer bd_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"command":"ls -la /workspace"}'

Database (PostgreSQL)

Each container starts with DATABASE_URL already set, pointing at your PostgreSQL database. Connect with any Postgres client or driver — no credentials to configure.

# DATABASE_URL is already in the environment.
psql "$DATABASE_URL" -c "SELECT version();"

The database is provisioned per user and shared across all of your containers, so they can read and write the same data. Use separate schemas or table prefixes if you want to keep apps isolated.

Object storage (S3)

Every container is wired to an S3-compatible bucket (MinIO) through the S3_ENDPOINT, S3_ACCESS_KEY, S3_SECRET_KEY and S3_BUCKET variables. Use any S3 client — just enable path-style addressing, which MinIO requires.

MinIO client (mc)

mc alias set bd "$S3_ENDPOINT" "$S3_ACCESS_KEY" "$S3_SECRET_KEY"
mc cp ./photo.jpg "bd/$S3_BUCKET/photo.jpg"

Python — boto3

import os, boto3
from botocore.config import Config

s3 = boto3.client(
    "s3",
    endpoint_url=os.environ["S3_ENDPOINT"],
    aws_access_key_id=os.environ["S3_ACCESS_KEY"],
    aws_secret_access_key=os.environ["S3_SECRET_KEY"],
    # MinIO needs path-style addressing.
    config=Config(s3={"addressing_style": "path"}),
)
s3.upload_file("photo.jpg", os.environ["S3_BUCKET"], "photo.jpg")

The bucket is assigned per user and shared by your containers, the same way the database is.

Environment variables

Every container is started with its credentials already in the environment, so your code can connect without any configuration:

  • DATABASE_URL
  • S3_ENDPOINT
  • S3_ACCESS_KEY
  • S3_SECRET_KEY
  • S3_BUCKET

Authentication

The browser app uses a session from your magic link. For scripts and AI agents, create an API key under API Keys and send it as a Bearer token. Keys are shown once and can be revoked at any time.

curl -H "Authorization: Bearer bd_your_api_key" \
  https://basicdeploy.com/api/containers

Full keys vs. scoped guest keys

A key you create under API Keys is a full-account key: it can manage every container you own. When you share a container, BasicDeploy also issues a container-scoped guest key so an agent can work on just that one container without touching the rest of your account.

  • A scoped guest key can read its container, stream logs, run commands and upload files — for that one container only.
  • It cannot create or delete containers, deploy, manage API keys or billing, or reach any other container — everything else returns 403.

REST API

All endpoints are under https://basicdeploy.com and accept either a session token or an API key.

MethodEndpointWhat it does
POST/api/containersCreate a container with a database, storage and public URL
GET/api/containersList the containers you own or that are shared with you
GET/api/containers/{id}Fetch one container; credentials are returned to its owner only
DELETE/api/containers/{id}Permanently delete a container and everything in it
POST/api/containers/{id}/execRun a shell command inside a container
GET/api/containers/{id}/logsRead recent container logs
POST/api/containers/{id}/uploadUpload a single file into a container (streamed, up to 100 MB)
POST/api/containers/{id}/shareGive another person access by email address
DELETE/api/containers/{id}/shareRevoke a person's access to a container
POST/api/containers/{id}/sleepPut a container to sleep
POST/api/containers/{id}/wakeWake a sleeping container
POST/api/containers/{id}/always-onToggle always-on for a container
GET/api/containers/{id}/domainsList the custom domains on a container
POST/api/containers/{id}/domainsAttach a custom domain to a container
POST/api/deployUpload a project archive and run it

Every container ships with PostgreSQL, S3-compatible object storage and a public HTTPS URL. Through the API you can run commands, stream files in and out, read logs, deploy a whole project and share access — the same operations the web terminal and Deploy page use.

Create a container

curl -X POST https://basicdeploy.com/api/containers \
  -H "Authorization: Bearer bd_your_api_key"

Run a command

curl -X POST https://basicdeploy.com/api/containers/{id}/exec \
  -H "Authorization: Bearer bd_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"command":"ls -la /workspace"}'

Read recent logs

curl -H "Authorization: Bearer bd_your_api_key" \
  https://basicdeploy.com/api/containers/{id}/logs

Upload a file

curl -X POST https://basicdeploy.com/api/containers/{id}/upload \
  -H "Authorization: Bearer bd_your_api_key" \
  -F "[email protected]" -F "path=/workspace"

Deploy a project archive

tar -czf app.tgz .
curl -X POST https://basicdeploy.com/api/deploy \
  -H "Authorization: Bearer bd_your_api_key" \
  -F "[email protected]"

MCP server

BasicDeploy ships a Model Context Protocol server so an AI agent can drive your containers as tools. Add it to your agent's MCP config:

{
  "mcpServers": {
    "basicdeploy": {
      "command": "npx",
      "args": ["-y", "basicdeploy-mcp"],
      "env": {
        "BASICDEPLOY_API_KEY": "bd_your_api_key",
        "BASICDEPLOY_URL": "https://basicdeploy.com"
      }
    }
  }
}

The server reads two environment variables: BASICDEPLOY_API_KEY (a full or scoped key) and BASICDEPLOY_URL (https://basicdeploy.com). Point any MCP-capable agent — Claude, Cursor and others — at this config and it can operate your containers directly.

Available tools

list_containers
List the containers you can access.
create_container
Create a new container with a database, storage and public URL.
get_container
Fetch one container's details.
exec_command
Run a shell command inside a container and return its output.
get_logs
Read a container's recent logs.
upload_file
Stream a file into a container.
deploy_app
Upload a project archive and run it.
share_container
Share a container with someone by email.
delete_container
Permanently delete a container.

With a container-scoped guest key the same tools are available but limited to the shared container: listing shows only that container and management verbs are blocked.

Connect via SSH

SSH gives you a full interactive shell inside your container, routed through a bastion. The username is your container's subdomain, and your private key is on the container's Connect panel.

ssh [email protected] -p 2222 -i basicdeploy_key

Connect to ssh.basicdeploy.com on port 2222 — the bastion, not the app's HTTPS domain. You land in /workspace as the appuser account with your project files; use it to edit code, install packages, inspect the database or watch a process.

If the container is asleep, any REST, MCP or SSH request wakes it automatically; the first connection may take a moment.

Shared with you? Use the guest key from the container instead:

ssh [email protected] -p 2222 -i basicdeploy_guest_key

Sharing a container

Share a container to give someone else access to just that one. They get a guest link plus container-scoped API and SSH keys, so an agent or teammate can work on the shared container over REST, MCP or SSH without reaching the rest of your account.

A scoped guest key can read the container, stream logs, run commands and upload files, but cannot create or delete containers, deploy, or manage keys and billing — everything else returns 403.

Unshare at any time; the guest link and its scoped API and SSH keys are revoked immediately.

Custom domains

Pro and Scale plans let you attach your own domain, brought through Cloudflare. Add the domain to a container, then create a CNAME in Cloudflare pointing your hostname at the app's BasicDeploy URL.

# In your Cloudflare DNS, CNAME your hostname to the app URL:
app.example.com   CNAME   your-subdomain.basicdeploy.com

Set Cloudflare's SSL/TLS mode to Full. The BasicDeploy origin presents a wildcard certificate, so HTTPS works end to end once the CNAME resolves.

Custom domains are a paid-plan feature: Pro includes 1 and Scale includes 10, counted across all your containers. The Free plan has none.

Always-on, sleep & plans

Free-plan containers sleep when idle and wake automatically on the next REST, MCP, SSH or web request — expect a short delay on the first hit. Pro and Scale containers never sleep.

Need a specific container to stay up without moving your whole account to a paid plan? Add an always-on add-on at $4/mo per container. Each add-on is a paid always-on slot and raises how many of your containers can stay running.

Upgrade or add add-ons from the Billing page. Higher plans also raise your container count, memory and storage, and unlock custom domains.

API keys

Create API keys under API Keys to authenticate scripts, the MCP server and REST calls. A key is shown once at creation — copy it then — and can be revoked at any time.

Keys you create are full-account keys that manage every container you own. Sharing a container issues a container-scoped guest key limited to that one container. Send any key as a Bearer token.

Troubleshooting

My app's URL shows nothing, or a 'not listening' notice
Make sure your app binds 0.0.0.0:8080, not localhost or another port. The public URL is wired to port 8080 inside the container.
The logs are empty
Logs come from your running app plus /workspace/deploy.log and deploy-error.log. If nothing appears, the process likely exited on startup — check deploy-error.log for install or boot errors.
My container seems unreachable after being idle
Free containers sleep when idle. The next request wakes them automatically, but the first connection can take a few seconds. Move to a paid plan or add an always-on add-on to keep it running.
SSH won't connect
Connect to ssh.basicdeploy.com on port 2222 — the bastion, not the app's HTTPS domain — using your container's subdomain as the username and the key from the Connect tab.
My MCP or API key gets 403s
A container-scoped guest key only works on the container it was issued for; creating, deleting, deploying and key management are blocked. Use a full-account key for those operations.