# Quickstart

Go from a folder of code to a live HTTPS URL with `deplane launch`, then deploy, watch, scale, and roll back.

You need the CLI and a login. See [Install](install.md).

## Launch

Run `deplane launch` in your project's root folder:

```sh
$ cd my-shop
$ deplane launch
Detected Next.js 15, Node 22, port 3000
Created app my-shop.
Wrote deplane.toml.
Uploading 214 files (1.3 MB)...
Build bld_4m8q2k7x9c1v5b3n6z0a queued.
Building...
...
Built 4f1c2a9e8b7d. Rolling out release v1...
Deploying: 0 of 1 instances ready.
Running: 1 of 1 instances ready.
Deployed my-shop v1: https://my-shop.deplane.dev
```

`launch` does all of this without asking you anything:

1. It works out how to build the folder and prints one line about it.
2. It creates an app named after the folder. If that name is taken, it adds a short random suffix, such as `my-shop-k3x9`. To pick the name yourself, pass `--name NAME`.
3. It writes `deplane.toml`.
4. It packs the folder and uploads it. `.gitignore` and `.dockerignore` are honored. The `.git` folder and every `.env` file are never uploaded.
5. It builds the app and streams the build log.
6. It creates release v1, starts the new instance, waits until it is healthy, and prints the URL.

Every app gets an address of the form `https://NAME.deplane.dev` with HTTPS already set up.

A first deploy takes one to two minutes. Measured end to end in October 2026: a static site 56 seconds, Express 1 minute 12 seconds, Go 1 minute 16 seconds, Flask 1 minute 17 seconds, FastAPI 1 minute 20 seconds, Next.js 2 minutes 3 seconds. Later deploys reuse the build cache and are faster.

## What launch detects

If the folder has a `Dockerfile`, Deplane builds it. Otherwise it builds the project without any configuration. It recognizes these, in this order:

| Project | Recognized by | Frameworks it names | Default port |
|---|---|---|---|
| Dockerfile | `Dockerfile` | none | the first `EXPOSE` port, else 8080 |
| Node | `package.json` | Next.js, Nuxt, Remix, SvelteKit, NestJS, Express, Fastify, Koa, Hono (3000); Astro, Angular, Create React App, Gatsby, Vite (8080) | 3000 |
| Python | `requirements.txt`, `pyproject.toml`, `Pipfile`, `setup.py`, or `uv.lock` | Django, FastAPI, Flask | 8000 |
| Go | `go.mod` | Gin, Echo, Fiber, Chi | 8080 |
| Ruby | `Gemfile` | Rails, Sinatra | 3000 |
| PHP | `composer.json` or `index.php` | Laravel, Symfony | 8080 |
| Java | `pom.xml`, `build.gradle`, or `build.gradle.kts` | Spring Boot | 8080 |
| Static site | `index.html` or `public/index.html` | none | 8080 |

The "Detected" line shows what it found, for example:

- `Detected Next.js 15, Node 22, port 3000`
- `Detected Flask 3, Python 3.12, port 8000`
- `Detected Go 1.23, port 8080`
- `Detected a Dockerfile, port 8080`
- `Detected a static site, port 8080`

Language versions come from files such as `engines.node` in `package.json`, `.nvmrc`, `.python-version`, `go.mod`, and `.ruby-version`.

If nothing matches, launch stops with [detect_failed](errors.md#detect_failed). Run it in your project's root folder, or add a Dockerfile.

## Your app must listen on PORT

Deplane always sets the `PORT` environment variable to the app's port. Make your app listen on `0.0.0.0` at that port. Most frameworks do this already. If your app listens on `localhost` only, or on another port, the release fails with `HealthCheckFailed`.

## deplane.toml

`launch` writes `deplane.toml` the first time. The file is optional, and every field has a working default. It looks like this:

```toml
# Deplane app settings. Every field is optional: https://deplane.cloud/docs/quickstart#deplanetoml
app = "my-shop"

[service]
port = 3000             # your app must listen on 0.0.0.0 at this port; it is also in $PORT
# health_check = "/healthz"   # optional; a TCP check on the port if omitted
```

All the fields:

| Field | Default | Meaning |
|---|---|---|
| `app` | the folder name | The app this folder deploys to. |
| `port` (under `[service]`) | the detected port, else 8080 | The port your app listens on. |
| `instances` (under `[service]`) | 1 | How many instances run. |
| `size` (under `[service]`) | `small` | `small`, `medium`, or `large`. See [Limits](limits.md#instance-sizes). |
| `health_check` (under `[service]`) | none: a TCP check on the port | A path such as `/healthz` that must answer 200. |

Each `deplane deploy` applies the file. If you set `instances` or `size` here, each deploy sets the app back to these values. Leave them out if you prefer to change them with `deplane scale`. Unknown fields and bad values stop the command with [invalid_config](errors.md#invalid_config).

Commit `deplane.toml` with your code. Commands run in this folder use its `app`. Anywhere else, pass `--app NAME`.

## Deploy changes

After you change your code, run:

```sh
$ deplane deploy
Detected Next.js 15, Node 22, port 3000
Uploading 214 files (1.3 MB)...
Build bld_9t2w6r1y8u3i5o7p4a0s queued.
Building...
...
Built 0b9e7d61a2c3. Rolling out release v2...
Deploying: 0 of 1 instances ready.
Running: 1 of 1 instances ready.
Deployed my-shop v2: https://my-shop.deplane.dev
```

If the new release does not become healthy, it is marked failed and the previous release keeps serving. The command exits with code 4 and tells you why and what to do. See [Troubleshooting](errors.md).

## Check status

```sh
$ deplane status
App:       my-shop (active)
URL:       https://my-shop.deplane.dev
Release:   v2
Instances: 1 of 1 ready, size small
State:     Running
Last build: bld_9t2w6r1y8u3i5o7p4a0s, succeeded
```

When something is wrong, `status` adds a `Problem:` line and a `Fix:` line.

## Read logs

```sh
$ deplane logs
x7k2p | ready - started server on 0.0.0.0:3000
x7k2p | GET / 200 in 12ms
```

Each line starts with the short name of the instance that wrote it. `deplane logs` shows the last 100 lines of each running instance. Use `--tail N` for up to 1000 lines. Follow new lines live with `-f`, and stop with Ctrl-C:

```sh
deplane logs -f
```

## Open the app

```sh
deplane open
```

This opens the URL in your browser and prints it.

## Scale

Run more instances, change the size, or both:

```sh
$ deplane scale 2 --size medium
my-shop now runs 2 medium instance(s).
```

`deplane scale 0` stops the app without deleting it. Your plan sets how many instances and how much memory you can use. See [Limits](limits.md).

Let Deplane add instances under load, or put the app to sleep while nobody uses it:

```sh
$ deplane scale 1 --max 3 --sleep 15m
```

See [Scaling](scaling.md).

## Roll back

List releases:

```sh
$ deplane releases
VERSION  STATUS      IMAGE         CREATED           DESCRIPTION
v2       active      0b9e7d61a2c3  2026-10-13 09:41  Deploy
v1       superseded  4f1c2a9e8b7d  2026-10-13 09:12  Deploy
```

Roll back to the previous release that ran successfully, or to a version you choose:

```sh
$ deplane rollback
Roll back my-shop to the previous good release? [y/N] y
Created release v3 (Rollback to v1). Run `deplane status` to follow the rollout.
```

A rollback creates a new release with the earlier release's build and settings. Nothing is deleted.

If your app starts returning 5xx errors in a release's first 10 minutes live, Deplane rolls it back by itself and tells your team. See [Automatic rollback](cli.md#automatic-rollback); turn it off with `deplane config --auto-rollback off`.

## Destroy

```sh
$ deplane destroy
Destroy app my-shop? Its instances, releases, and secrets are deleted, and the name becomes available to others. [y/N] y
Destroyed my-shop.
```

This cannot be undone.

## Next steps

- Add configuration and API keys with [Secrets](secrets.md).
- Learn every command in the [CLI reference](cli.md).
- Deploy on every push, with a preview for every pull request: [GitHub](github.md).
- Add a Postgres database, backed up continuously: [Databases](databases.md).
- Deploy from CI with [Agents, CI, and scripts](agents.md).
- Let Claude, ChatGPT or Cursor deploy for you: [AI tools (MCP)](mcp.md).
