> Discover all available pages from the documentation index: https://mastra.ai/llms.txt

# Deploy to Mastra platform

[`mastra deploy`](https://mastra.ai/reference/cli/mastra) is the single command for releasing a Mastra application to the [Mastra platform](https://mastra.ai/docs/mastra-platform/overview).

One command builds your project and validates it before anything includes, plus creates the platform project and environment on your first run, deploys, streams build logs, and prints your public URL once the deploy is serving traffic.

```bash
mastra deploy
```

> **Note:** This page covers the unified deploy flow. The earlier split commands, [`mastra server deploy`](https://mastra.ai/docs/mastra-platform/server) and [`mastra studio deploy`](https://mastra.ai/docs/mastra-platform/studio), still work but `mastra deploy` is the recommended path.

## Before you begin

You'll need a [Mastra application](https://mastra.ai/docs) and a [Mastra platform](https://projects.mastra.ai) account. If you're not authenticated, the CLI prompts you to log in on first use.

A local `.env` file is optional. Environment variables stored on the platform are used as-is at deploy time, and managed resources like [hosted databases](https://mastra.ai/docs/mastra-platform/database) inject their own variables. Pass `--env-file` only when you want to layer local values on top.

## Your first deploy

1. From your project directory, run:

   ```bash
   mastra deploy
   ```

   On the first run the CLI prompts you to create the platform project (named after your `package.json`) and the `production` environment. Accept the prompts, or pass `--yes` to accept defaults without confirmation.

2. The CLI runs a preflight check before every deploy. Storage that would fall back to a local file path (which doesn't survive on the platform's ephemeral filesystem) would normally block the deploy:

   ```text
   file:./mastra.db will be used at runtime because TURSO_DATABASE_URL is not set
   ```

   Instead of erroring out, the CLI offers to fix it inline for you:

   ```text
   Preflight needs TURSO_DATABASE_URL for the production environment. Create a managed turso database now and attach it? (Y/n)
   ```

   Accept the prompt and provisioning takes a few seconds — the database's connection variables are injected into your deploys automatically, with nothing to copy into an `.env` file. Decline it, or run in a non-interactive shell (CI, `--yes`), and the CLI falls back to the previous behavior: it prints the exact command to run yourself.

   ```bash
   mastra env db create production --kind turso
   ```

   The environment slug (`production` above) matches the environment the CLI would have deployed to — this is important because `mastra env db create` requires an environment argument in non-interactive shells when the project has more than one environment.

   Preflight also catches database URLs that point at your local machine. A `.env` file with `REDIS_URL=redis://localhost:6379` works during development, but the deployed server can't reach your laptop — so the CLI warns and offers the same managed provisioning. If you decline, the deploy continues with your value as-is; if you accept, the managed database's connection variables take precedence at deploy time while your local `.env` keeps working for development.

   > **Note:** If preflight reports a hard-coded local path instead (`Build contains a host-local storage URL`), it can't offer the inline fix — guard the path with an environment variable first so the file is only used during local development:
   >
   > ```ts
   > new LibSQLStore({
   >   id: 'mastra-storage',
   >   // Uses the hosted database when deployed, a local file during development
   >   url: process.env.TURSO_DATABASE_URL ?? 'file:./mastra.db',
   >   authToken: process.env.TURSO_AUTH_TOKEN,
   > })
   > ```

3. Run `mastra deploy` again. Preflight passes, the build uploads, and the CLI streams build logs until the deploy is live. Expect the full build and deploy to take between 30 seconds and a few minutes. The success message prints only when the new version is serving traffic.

4. Verify your deployment at the URL printed by the CLI. Append `/api/agents` to confirm it returns a JSON list of your agents.

   > **Warning:** Set up [authentication](https://mastra.ai/docs/auth/overview) before exposing your endpoints publicly.

The first deploy writes a `.mastra-project.json` file linking your directory to the platform project. Commit it so later deploys, CI runs, and [`mastra env`](https://mastra.ai/docs/mastra-platform/environments) commands target the same project without extra flags.

## Deploy to another environment

`mastra deploy` targets the `production` environment by default. Pass `--env` to target a different one. If the environment doesn't exist yet, the CLI offers to create it:

```bash
mastra deploy --env staging
```

Each environment gets a separate URL and environment variables. It can also have its own [hosted database](https://mastra.ai/docs/mastra-platform/database).

See [Environments](https://mastra.ai/docs/mastra-platform/environments) for the full model.

## Choose a region

Pass `--region` when a deploy creates a new environment to control where it runs. Use the `us` or `eu` shorthand:

```bash
mastra deploy --env production --region eu
```

The region is fixed when the environment is created. Databases attached to an environment are placed near that environment's region automatically, and observability data is routed to the ingest region that matches the environment's residency zone. See [Regions](https://mastra.ai/docs/mastra-platform/regions) for the full list of supported regions, database placement, and observability co-location.

## Preflight checks

Preflight validates the built output before anything includes, and only flags issues in your own code:

- **Local storage paths**: A hard block. File-backed storage (for example `file:./mastra.db`) is lost on every deploy. Preflight passes when the path is guarded by an environment variable that's set locally or stored on the platform, including values provided by a managed database:

  ```ts
  import { LibSQLStore } from '@mastra/libsql'

  export const storage = new LibSQLStore({
    id: 'mastra-storage',
    // Uses the hosted database when deployed, a local file during development
    url: process.env.TURSO_DATABASE_URL ?? 'file:./mastra.db',
    authToken: process.env.TURSO_AUTH_TOKEN,
  })
  ```

- **Missing environment variables**: A warning for variables your code reads but no source provides. Variables referenced only by library code are excluded.

The recommended response to a preflight block is to fix the cause, usually by attaching a hosted database or storing the variable on the platform. `--skip-preflight` exists as an escape hatch but skips the checks that prevent broken deploys.

Run the checks without deploying:

```bash
mastra lint --preflight
```

`mastra lint` only sees your local env files. Variables stored on the platform or injected by managed databases aren't visible to it, so a deploy can pass preflight where lint still reports an error.

## Environment variables

Deploys resolve environment variables from three sources:

- **Managed variables**: Injected by platform resources like hosted databases (for example `TURSO_DATABASE_URL`). The platform defines these, and you can't edit them.
- **Stored variables**: Saved on the project or environment through the dashboard. Used as-is on every deploy with no local file needed.
- **Local env files**: Deployments layer an explicit `--env-file` or the ambient `.env` and `.env.local` files on top.

```bash
mastra deploy --env staging --env-file .env.staging
```

To change variables on a running service without a redeploy, update them in the dashboard and run [`mastra env restart`](https://mastra.ai/reference/cli/mastra).

## Private npm packages

Projects that depend on packages from a private registry install them during the deploy using the standard `NPM_TOKEN` contract.

1. Store a read-only registry token as `NPM_TOKEN` on the project or environment through the dashboard.

2. Commit a token-free `.npmrc` that points your scope at the registry and reads the token from the environment:

   ```ini
   @your-org:registry=https://npm.pkg.github.com
   //npm.pkg.github.com/:_authToken=${NPM_TOKEN}
   ```

   Keep the `${NPM_TOKEN}` reference literal. The package manager resolves it at install time, so the token itself never lands in your repository.

3. Deploy as usual:

   ```bash
   mastra deploy
   ```

In a monorepo, a `.npmrc` in your project directory takes precedence over one at the repository root.

`NPM_TOKEN` is available during dependency installation. Mastra redacts its value from the Mastra source-build logs that it streams. The generated Dockerfile receives it as a build argument, so the runtime image stays free of the token. `NPM_TOKEN` is also injected into the running service as a regular environment variable, so treat it as a secret your application can read.

Projects without a private-registry `.npmrc` need no changes. When your `.npmrc` references `${NPM_TOKEN}`, set the variable or the dependency install fails.

## Project resolution

Every deploy resolves its target project in this order:

1. The `MASTRA_PROJECT_ID` environment variable
2. The `--project <name|slug|id>` flag
3. The `.mastra-project.json` file in the current directory

In CI, set `MASTRA_PROJECT_ID` and `MASTRA_API_TOKEN` and pass `--yes`:

```bash
mastra deploy --env production --yes
```

## Related

- [Environments](https://mastra.ai/docs/mastra-platform/environments)
- [Regions](https://mastra.ai/docs/mastra-platform/regions)
- [Hosted databases](https://mastra.ai/docs/mastra-platform/database)
- [`mastra deploy` CLI reference](https://mastra.ai/reference/cli/mastra)
- [Configuration](https://mastra.ai/docs/mastra-platform/configuration)