# CLI reference

> Every command, what it reads, what it writes, and what it refuses to do.

Source: https://nextship.doodlebytestudio.in/docs/commands

```
nextship detect        Report what nextship reads from this project
nextship build         Build in Docker with the adapter injected, export the manifest
nextship package       Build, then produce the runtime image
nextship run           Package, then run the image locally
nextship doctor        Report what changes when this app leaves its current platform
nextship deploy        Show the deployment plan; add --yes to execute it
nextship rollback      Return to a previous deployment; add --yes to execute it
nextship logs          Runtime logs for the deployed app; --follow to stream
nextship env           List the runtime environment variables set on the app
nextship env push      Upload this project's env files as runtime variables
nextship env rm        Remove named variables from the app
nextship domain        List the domains attached to the app
nextship domain add    Attach a domain and print the DNS record to create
nextship domain rm     Detach a domain
nextship images        List the images pushed for this project
nextship images prune  Remove old images, keeping the recent ones
nextship destroy       Destroy the app this project created
nextship server add    Prepare a Linux server and record it as this project's target
nextship server status The server, every app on it, and what needs attention
nextship server reboot Reboot the server and wait for every app to come back healthy
nextship server move   Move this project's app to another server

  -h, --help           Show usage
  -v, --version        Show the version
```

Unknown commands and unknown flags are errors. A mistyped option is never silently
ignored.

`nextship` on its own draws the wordmark and points to `detect` and `--help`, in any
terminal at least 72 columns wide: in truecolor, 256 or 16 colours as the terminal
supports, and without colour under `NO_COLOR`. Piped, or in a narrower window, it prints
the usage above.

## Local commands

These need Docker and nothing else. No cloud account is involved.

### detect

Reads the project and reports what every later stage will act on. Runs no build and writes
nothing, so it is safe anywhere.

Everything reported is read from disk rather than from what `package.json` declares,
including packages installed transitively.

### build

Runs your own `build` script inside a Docker builder stage with the adapter injected
through `NEXT_ADAPTER_PATH`, then exports the manifest the adapter wrote to
`.nextship/output/manifest.json`.

Your `next.config.js` is never edited. Dependencies are installed inside the image, so
`next`, `sharp` and every native module are built for Linux regardless of your machine.

If the manifest comes back without the deployment id the adapter was given, the build
fails as a nextship defect rather than shipping something unverified.

### package

Builds, then assembles the runtime image: a second stage copying only the files Next.js's
own trace output lists, plus a generated launcher equivalent to the one standalone mode
writes.

```
v Image ready: acme-web:dpl-2b2c3e535f1e-4456a8b2
  platform   linux/amd64
  start it with: nextship run
```

`build` and `package` are two targets of one Dockerfile, so `package` reuses the compile
from cache rather than starting over.

### run

Packages, then starts the image locally on port 3000, loading your highest-precedence env
file so secrets stay outside the image.

### doctor

Reports what changes when an app leaves a managed platform. Most of these never stop a
build, which is exactly why they are worth surfacing. The exception is a package installed
in `node_modules` that nothing declares: that one fails the build, and is a blocker.

| Checked | Why it matters |
|---|---|
| Analytics and similar packages | They stop reporting and nothing errors |
| Cron jobs in platform config | They will simply never run |
| Routing rules in platform config | They stop applying |
| Platform URL and environment variables read in source | They become undefined |
| Packages in `node_modules` that nothing declares | They exist on your machine and not in the image, so the build fails on an import that resolves locally |
| A missing lockfile | Installs are no longer reproducible |
| The ISR cache not surviving a restart | Recorded before deploying, not after |

## Cloud commands

Each acts only on the app recorded in `nextship.json`. On DigitalOcean they need
`DIGITALOCEAN_TOKEN`; on your own server they need SSH access, and no token.

- [deploy](https://nextship.doodlebytestudio.in/md/deploying.md)
- [rollback and logs](https://nextship.doodlebytestudio.in/md/rollbacks-and-logs.md)
- [env, env push, env rm](https://nextship.doodlebytestudio.in/md/environment-variables.md)
- [domain, domain add, domain rm](https://nextship.doodlebytestudio.in/md/custom-domains.md)

### images

```bash
nextship images         # what is stored, and what it costs
nextship images prune   # remove old images, keeping recent ones
```

Registry storage is billed, and old deployment images accumulate quietly. Pruning deletes
by reachability from the tags being kept, parents before children, because deleting a tag
alone leaves the manifest and its layers behind and reclaims nothing.

On a real registry this took storage from 390.2 MiB to 286.1 MiB, freeing 104.2 MiB across
7 blobs.

### server

```bash
nextship server add root@203.0.113.10 --yes   # set a server up and record it
nextship server status                        # the server and every app on it
nextship server reboot --yes                  # reboot and wait for every app
nextship server move root@198.51.100.7 --yes  # move this app to another server
```

The server target is new in 1.1.0; see [Your own server](https://nextship.doodlebytestudio.in/md/vm.md). `deploy` on a server also
takes `--build remote|local` and `--memory`, and `logs` takes `--deployment <id>`.

### destroy

```bash
nextship destroy <app-name> --yes
```

The one command that removes a cloud resource. It requires the app name as an argument
**and** `--yes`, it only accepts the app recorded in `nextship.json`, and it is not
recoverable.
