> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getnao.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy project context

> Push a local nao project to a remote nao instance with the nao deploy CLI command

The `nao deploy` command packages a local nao project and uploads it to a remote nao instance. It is the bridge between a project built locally with `nao init` / `nao sync` and a Cloud (or self-hosted) instance that will run chats, scheduled jobs, and integrations against that project.

Use it to push the same context folder you work on locally to the instance your team chats with.

## Prerequisites

* A remote nao instance URL (Cloud workspace or your self-hosted deployment).
* An organization-level API key. Create one from **Settings** -> **Organization** -> **API Keys**. See [Per-organization API keys](/nao-agent/cloud/overview#per-organization-api-keys).
* A local project that contains a valid `nao_config.yaml` with a `project_name` field.

## Command

Run from the project directory (the folder that contains `nao_config.yaml`):

```bash theme={null}
nao deploy <url> --api-key <key>
```

Or from anywhere, pointing at the project folder explicitly:

```bash theme={null}
nao deploy <url> --api-key <key> --path /path/to/project
```

### Flags

| Flag              | Description                                                                              |
| ----------------- | ---------------------------------------------------------------------------------------- |
| `<url>`           | URL of the remote nao instance (positional). For nao Cloud, use `https://app.getnao.io`. |
| `-k`, `--api-key` | Organization API key used to authenticate the upload.                                    |
| `-p`, `--path`    | Project directory. Defaults to the current working directory.                            |

## What gets uploaded

`nao deploy` builds a gzipped tarball of the project folder and uploads it to `<url>/api/deploy`. The server extracts the archive, reads `project_name` from `nao_config.yaml`, and either creates a new project in the organization or updates the existing one with the same name.

### Default exclusions

These paths are always skipped when building the archive:

* `.git`
* `.venv`
* `.env`
* `node_modules`
* `__pycache__`
* `repos`
* `*.pyc`

### `.naoignore`

Add a `.naoignore` file at the project root to exclude extra files. One pattern per line, `#` for comments. Patterns are matched against path parts (directory or file names). Example:

```
# .naoignore
dbt_packages
logs
secrets.yaml
*.parquet
```

## Create vs update

The server looks up a project by `(organization, project_name)`:

* If no project with that name exists in the organization, a new one is created and the response reports `status: "created"`.
* If a project with that name already exists, its context folder is replaced with the uploaded content and the response reports `status: "updated"`.

There is no merge. Every deploy is a full replacement of the project's context folder on the remote instance.

## Example

```bash theme={null}
$ nao deploy https://app.getnao.io --api-key nao_sk_live_...

Deploying my_project to https://app.getnao.io

Packaging project files...
Package size: 2.3 MB
Uploading...
Project my_project created
Project ID: 4f2d...
```

## Errors

* `Authentication failed. Check your API key.` - the API key is missing, revoked, or does not belong to the target organization.
* `No nao_config.yaml found in current directory` - run the command from a project root or pass `--path`.
* `nao_config.yaml is missing a 'project_name' field` - add `project_name: my_project` at the top of `nao_config.yaml`.
* `Could not connect to <url>` - check the URL and that the instance is reachable from your network.
