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
- Sign in with your email — we send a magic link, so there is no password to manage.
- Click Create Container. You get a running container with PostgreSQL, S3-compatible storage and a public URL.
- 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.
| Plan | Price | Containers | Memory / container | Storage | Always-on | Custom domains |
|---|---|---|---|---|---|---|
| Free | $0 | 3 | 256 MB | 1 GB | Sleeps when idle | — |
| Pro | $12/mo | 3 | 1 GB | 5 GB | Always-on | 1 |
| Scale | $39/mo | 10 | 2 GB | 10 GB | Always-on | 10 |
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:8080Deploy 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_URLS3_ENDPOINTS3_ACCESS_KEYS3_SECRET_KEYS3_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/containersFull 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.
| Method | Endpoint | What it does |
|---|---|---|
| POST | /api/containers | Create a container with a database, storage and public URL |
| GET | /api/containers | List 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}/exec | Run a shell command inside a container |
| GET | /api/containers/{id}/logs | Read recent container logs |
| POST | /api/containers/{id}/upload | Upload a single file into a container (streamed, up to 100 MB) |
| POST | /api/containers/{id}/share | Give another person access by email address |
| DELETE | /api/containers/{id}/share | Revoke a person's access to a container |
| POST | /api/containers/{id}/sleep | Put a container to sleep |
| POST | /api/containers/{id}/wake | Wake a sleeping container |
| POST | /api/containers/{id}/always-on | Toggle always-on for a container |
| GET | /api/containers/{id}/domains | List the custom domains on a container |
| POST | /api/containers/{id}/domains | Attach a custom domain to a container |
| POST | /api/deploy | Upload 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}/logsUpload 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_keyConnect 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_keyCustom 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.comSet 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.