---
name: dcp
description: Deploy and run DCP instances (free sandboxed mini VPS's at NAME.dcp.run) from a terminal with the dcp CLI. Use when the person wants a page, site, Node or Python app, or small database online with a real link, or wants to update, inspect, roll back or hand over one they made before.
---

# dcp: DCP instances from the terminal

A DCP instance is a sandboxed mini VPS: plain files, or a Node 22 / Python 3.12 server with its own SQLite
database, live at https://NAME.dcp.run. No account or key needed for the first deploy.

## Install
```
curl -fsSL https://dcp.run/cli/install.sh | sh
dcp doctor
```

## The commands that matter
```
dcp deploy                      # deploy this folder; first run makes the app and links the folder
dcp deploy dist --name my-shop  # a chosen name (NAME.dcp.run), from a build folder
dcp deploy --dry-run            # list files, sizes, skipped files and broken links, upload nothing
dcp push index.html img/cat.png # change single files (dcp push --rm old.html to remove)
dcp status                      # URL, state, version, claimed or not, process, env names
dcp logs -f                     # follow server output (--type request|build|deploy)
dcp env set API_KEY=- < key.txt # secrets for node/python apps, write-only, restarts the app
dcp versions                    # last 5 versions with preview links
dcp rollback 3                  # make version 3 live again (same links)
dcp claim                       # the claim link to give the person
```
More: `dcp promote V`, `dcp data COLLECTION [ls|add JSON|rm ROW]`, `dcp rules [show|set FILE]`,
`dcp brain on|off`, `dcp open`, `dcp apps`, `dcp link APP --token-stdin`, `dcp unlink`, `dcp whoami`,
`dcp init --static|--node|--python`, `dcp delete --yes`, `dcp upgrade`. `dcp help CMD` shows flags and an example.

## How an app is chosen
- `--app ID`, else `$DCP_APP`, else `./.dcp/app` (written by the first deploy; it holds only the app id).
- The token (deploy token, or owner token after claiming) lives in `~/.config/dcp/apps.json` (mode 600).
  `$DCP_TOKEN` overrides it. Tokens are never printed.
- Deploying again from a linked folder updates the same app: same links, new version.
  Do not make a new app for every fix: that gives the person new links each time.
- Add `.dcp/` to .gitignore.

## Conventions for agents
- `--json` on any command prints one JSON object on stdout (lists are wrapped, like {"apps": [...]}).
- Progress and hints go to stderr. Nothing prompts unless a person is at a terminal.
- Exit codes: 0 ok, 1 error, 2 usage, 3 auth (missing or wrong token), 4 not found.
- Errors end with `hint:` saying what to do next.

## What gets uploaded
- Skipped: .git, node_modules, .dcp, .env*, hidden files, and patterns in .dcpignore / .gitignore.
- Static sites need index.html and take html, css, js, json, txt, svg, webmanifest, png, jpg, webp, ico.
  Node/Python apps also take code and text files (py, ts, md, yaml, sql, csv, ...). Other files are skipped
  with a note. Fonts, gif, audio and video are not accepted: link them from a CDN.
- Include every file the pages link to. deploy warns when a page links a relative file that is not in the
  upload: fix those before telling the person it works.

## Apps with a server
- Listen on the PORT environment variable (bind 0.0.0.0). SQLite file at DATABASE_PATH, kept across versions.
- Node: package.json with scripts.start, or server.js. Python: main.py or app.py, requirements.txt optional.
- Keys go in `dcp env`, never in files (static files are public). The app sleeps after 5 minutes idle and
  wakes on the next request, so the first request can be slow.
- `dcp init --node` or `dcp init --python` writes a working starter.

## Gotchas
- Give the person the claim link right away (`dcp claim`). Unclaimed apps pause after 72 hours; files and
  links are kept, and claiming brings them back. The claim link stays the same across updates.
- Give only the links dcp prints (live, claim, QR). There is no manage link for you to make up: after
  claiming, the claim page gives the person their own private manage link.
- After a claim, the deploy token stops working. Ask the person for a fresh agent link from their manage
  page and run `dcp link 'https://api.dcp.run/agent#...'` (works once, within 10 minutes), or have them run
  `dcp link APP --token-stdin` with their owner token.
- Limits: 10 MB and 100 files per static app (300 for node/python), 20 changes per app per hour,
  256 MB memory, half a CPU. deploy checks size and file count before uploading.
- Something broke after an update? `dcp versions` then `dcp rollback V`, then read `dcp logs`.
- `dcp deploy --no-promote` uploads a preview version first; check its preview link, then `dcp promote V`.
- Check it really works: `curl -sI URL` and open the page, before saying it is live.

## Examples
```
dcp init --node && dcp deploy --name guestbook && dcp claim
dcp deploy --json | jq -r .url
dcp logs --type build -n 100
dcp data guestbook add '{"name":"Ann","text":"hi"}'
```
