box deploy
Generate the Box’s deployment artifacts or register its public website domains with Potter.
box deploy [options]Synopsis
box deploy has two modes:
- Artifact generation (default). With no registration flags,
box deploygenerates the files needed to run the box anywhere: aDockerfile, adocker-compose.yml, a.env.deploy.example, a CI/CD workflow, Railway config-as-code, and an optionalterraform/starting point: all wired from the box’sbox configservice URLs. - Domain registration (
--register-domains). Reads thebox.ymldeploy manifest and registers its domains with Potter Website Hosting so Potter knows which Box owns each public address. Prints per-domain routing and DNS instructions and writes adns.txtfile.
Registration mode also runs when you pass any of --verify, --remove,
--backend-url, --frontend-url, or --dashboard-url (those flags imply
--register-domains).
Options
Artifact generation
| Option | Description |
|---|---|
--pipe <targets> | Artifacts to generate: a comma/space list of dockerfile, compose, github, terraform, railway, or all. Defaults to the box’s deployPipe setting, else dockerfile, compose, github, railway. |
--force | Overwrite existing generated artifacts (otherwise existing files are skipped). |
Domain registration
| Option | Description |
|---|---|
--register-domains | Register this box’s box.yml domains with the control plane. |
--backend-url <url> | Backend (engine) URL to route the domains to. Overrides box.yml. Implies --register-domains. |
--frontend-url <url> | Website frontend URL associated with the domains. Overrides box.yml. Implies --register-domains. |
--dashboard-url <origin> | Origin of the Box dashboard allowed to embed the website preview. Overrides box.yml. Implies --register-domains. |
--verify | Skip registration; check the linked status of each domain instead. |
--remove | Deregister this Box’s website domains from Potter Website Hosting. |
Flag values override the corresponding fields in box.yml. Trailing slashes are
trimmed from all URL values. --verify and --remove are mutually exclusive
with each other and with registration.
Behavior
Artifact generation (default)
Generates the selected artifacts from the box’s box config
service URLs and writes them to the box root:
| Target | Files |
|---|---|
dockerfile | Dockerfile: one multi-stage image that builds both the engine and console. |
compose | docker-compose.yml (postgres + engine + console), .env.deploy.example, and a Caddyfile when public domains are configured (auto-HTTPS reverse proxy). |
github | .github/workflows/deploy.yml: build + optional deploy CI/CD. |
terraform | cloud-init.yaml (any-VPS server configuration), terraform/main.tf, and per-provider examples (terraform/digitalocean.tf.example, terraform/hetzner.tf.example, terraform/aws.tf.example). |
railway | railway.json (engine service) and railway.console.json (console service): Railway config-as-code. Both build from the shared Dockerfile and override the start command per service; point each Railway service’s Config-as-code Path at the matching file. |
Existing files are skipped unless --force is passed. After writing, the
command prints the next steps (cp .env.deploy.example .env, docker compose up -d --build, then box deploy --register-domains once the host is live).
Set the default target set once with
box config --deploy-pipe <targets> so plain
box deploy always generates the artifacts you want. --pipe overrides it
for a single run.
Registration (--register-domains)
- Sends
POST /boxes/deployto the control plane withAuthorization: Bearer <licenseKey>and a payload of{ name, backendUrl, frontendUrl?, dashboardUrl?, domains }. - Prints per-domain routing and the DNS records you must create.
- Writes a
dns.txtfile (and a legacynameserver.txt) with the DNS instructions.
Backend URL resolution
The backend origin the domains route to is resolved in this order:
- An explicit
--backend-urlflag. backendUrlinbox.yml.engineUrlinbox.json(set viabox config --engine-url).
The last keeps a single source of truth for the engine’s public origin: whatever
the box’s own console talks to is also what the control plane resolves the
merchant website to. When the backend defaults from engineUrl, the command prints
backend defaulted from box config engineUrl → <url>. If none of the three is
set, registration fails with a clear error.
Persisted flags
After a successful registration, the flags you explicitly passed are written back into your config so later deploys don’t need them again:
--backend-url→backendUrlinbox.yml.--frontend-url→frontendUrlinbox.yml, plus the derived host is added to thebox.ymldomainslist (if not already present) and written tostorefrontDomaininbox.json.
Only flags you actually passed are persisted: omitting a flag never erases an
existing box.yml value. The YAML document model is used to update box.yml,
so your comments and formatting are preserved. The CLI prints which fields it
updated (for example, box.yml updated (backendUrl, frontendUrl)).
Consolidated DNS records
When several hosts share the same DNS target (for example, acme-bank.example
and *.acme-bank.example pointing at one CNAME value), the records are grouped
by type + value + ttl and printed once with every name that points at them,
instead of repeating the same target per host. The same consolidation is
applied to the dns.txt file and to the offered nameservers.
Verification (--verify)
- Skips registration.
- Securely checks each registered domain with Potter.
- Reports whether each domain is linked and any action still required.
Removal (--remove)
- Skips registration.
- Securely asks Potter to detach the registered domains from Website Hosting.
- Prints each detached domain and a summary when the operation completes.
- Leaves DNS records at your registrar unchanged.
--remove only disconnects the domains from Potter Website Hosting. The DNS
records you created at your registrar are not touched: you can delete them
yourself once removal succeeds.
Registration requires an authenticated box and a backend URL. Provide
--backend-url, set backendUrl in box.yml, or set engineUrl via
box config --engine-url: otherwise the command cannot register your domains.
Examples
# Generate deploy artifacts (default set: Dockerfile, compose, GitHub Actions)
box deploy
# Generate a specific set, overwriting existing files
box deploy --pipe dockerfile,compose,terraform --force
# Register domains: backend URL defaults from `box config --engine-url`
box deploy --register-domains
# Register with an explicit backend, plus frontend and dashboard origins
box deploy \
--backend-url https://api.acme-bank.example \
--frontend-url https://shop.acme-bank.example \
--dashboard-url https://admin.acme-bank.example
# Verify DNS / linkage after records propagate
box deploy --verify
# Tear down routing: deregister this box's domains from the resolver
box deploy --removeRelated configuration
Service URLs and the default artifact set come from
box.json (via
box config); the domains and public URLs registration
uses come from box.yml:
backendUrl: https://api.acme-bank.example
frontendUrl: https://shop.acme-bank.example
dashboardUrl: https://admin.acme-bank.example
domains:
- host: acme-bank.example
primary: true
- host: '*.acme-bank.example'
wildcard: trueSee also
- Live Box upgrades: update, rebuild, migrate, verify, and roll back a running Box.
box config: set the service URLs and default deploy pipe.box.ymlschema.- Concepts → DNS & website hosting.
- Control plane endpoints.