CLI reference
Every command, what it needs, and what it answers with.
Every command takes --json, never prompts, and exits with a code you can branch on. marina upgrade checks for a newer version and marina mcp serves the account to an assistant; both have their own pages (installing, MCP).
Signing in
| Command | What it does |
|---|---|
marina login | Opens a browser to approve this terminal. |
marina login --headless | Prints a code to enter elsewhere, for a machine with no browser. |
marina logout | Forgets the stored credential. |
marina whoami | Which account this terminal is on, and what it may do. |
A credential is bound to the account that issued it. MARINA_API_TOKEN overrides whatever is stored, with no keychain read at all, which is the path CI and agents should use.
Apps
marina link shop # point this directory at an app
marina deploy # ship it
marina logs --follow # watch it | Command | Notes |
|---|---|
marina status | Everything this account runs. |
marina vessels list | Apps only. |
marina vessels info | One app, in detail. |
marina vessels create <name> | From --repo, --image, or --dir to upload this directory. |
marina vessels scale | Change reserved memory. Upgrades only. |
marina vessels rollback | Put a previous deploy back. |
marina vessels builds | Deploy history. |
marina vessels delete | Needs --yes. Deleting is not something to do because a flag was forgotten. |
marina open | Open the app in a browser. |
marina unlink | Forget this directory’s link. |
marina run <command…> | A one-off command inside the app. Needs vessel:exec. |
Config vars
marina env set NODE_ENV=production
marina env pull --force pull writes the file itself rather than printing to stdout, so there is nothing to redirect; --force is what lets it overwrite an existing .env. push sends one back, and removes anything the file omits unless you pass --merge. env unset takes one or more keys and removes them.
env list and env pull need env:read, which no write scope implies and no preset grants. Being able to ship code and being able to read every secret an app holds are different powers. Config vars and secrets is the longer version.
Databases
marina db list
marina db create store --engine postgres
marina db attach store
marina db detach store | Engine | Notes |
|---|---|
postgres | Reachable from outside your apps with --external. |
mysql | Same. |
redis | Reachable from your apps only. |
sqlite | A permanent free tier at 200 MB, then billed per 100 MB. |
marina db url prints connection details and needs db:credentials, which is its own scope on purpose.
Static sites
marina sites deploy ./public --name shop
marina sites list deploy takes a directory (zipped for you), a .zip, or a single .html. Re-using a name you already own updates that site in place, free. Your first site is free permanently.
Domains
marina domains list
marina domains search myshop
marina domains buy myshop.com
marina domains order <id>
marina domains attach myshop.com --target shop Buying is the one thing here that does not finish while you wait: buy reserves the name and answers with an order. --wait polls until it settles.
If the domain came from us, attach is the whole job and the domain is live when the command returns. If you own it elsewhere, it prints the records to add and marina domains verify <id> publishes once they resolve.
domains list shows names you hold with us. domains custom shows ones you own elsewhere and pointed here, with whether each is live yet, and domains detach <id> removes one.
marina email buy example.com --tier business
marina email add hello@example.com --password '…' | Command | Notes |
|---|---|
marina email list | Plans you hold, and whether each is on. |
marina email buy <domain> | --tier starter\|business\|pro. Answers with an order; --wait blocks. |
marina email verify <domain> | Re-check the DNS records and turn the plan on. |
marina email tier <domain> <tier> | Move a domain’s plan. |
marina email mailboxes <domain> | Addresses on that domain. |
marina email add <address> | Needs --password. --quota-mb caps one mailbox. |
marina email password <address> | Change it. It cannot be read back. |
marina email remove <address> | Needs --yes. Deleting a mailbox deletes its mail. |
Webmail has no terminal equivalent; it is linked from the dashboard.
DNS
For domains bought from us or transferred in, whose DNS is already here. Zones are not something you create: dns zones lists yours and gives you the id every other command takes.
marina dns zones
marina dns records <zone>
marina dns add <zone> --type A --name @ --content 203.0.113.10
marina dns update <zone> <record> --content 203.0.113.11
marina dns remove <zone> <record> Wallet
marina wallet balance
marina wallet topup # your payment code and where to send Mobile Money
marina wallet invoices Credentials
marina tokens create ci --preset deploy | Preset | Can |
|---|---|
readonly | Look, never touch. |
deploy | Ship code to apps that already exist. Cannot create anything, and can delete. |
agent | Build, deploy, config vars, databases, and spend the wallet. |
developer | What marina login grants. |
Creating needs billing:spend, which deploy does not carry, so it cannot buy anything. Deleting needs no such thing, so it can tear an app or site down, and no narrower scope separates the two: vessel:write is create, deploy, scale and delete together. Give a CI credential --expires.
create opens a browser once to approve the scopes, then prints the token to the terminal and does not store it. marina tokens list and marina tokens revoke open the dashboard instead: a token cannot manage tokens, so there is nothing for the CLI to do here but take you somewhere signed in.
--scope takes scopes directly and combines with a preset. --spend sets a lifetime cap in GHS, which is optional: the wallet is prepaid, so it already bounds what any credential can spend. --expires sets days.
Exit codes
| Code | Meaning |
|---|---|
0 | It worked. |
1 | It failed. |
2 | The command was wrong: a flag or argument. |
3 | Not signed in. |
4 | Signed in, but this credential may not do that. |
5 | Money: an empty wallet, or a token past its cap. |
6 | Not found. |
7 | Temporary. Worth trying again. |
4 and 5 are the two worth branching on. 5 arrives with the shortfall and your payment code attached, so a script can say exactly what it needs.
