NAO_DEFAULT_PROJECT_PATH. If you want to host several projects on the same instance and domain (for example one project per team, per warehouse, or per client) and let users switch between them, run the deployment in multi-project mode.
How it works
nao organizes hosting as organization -> projects -> members:- One instance owns one organization.
- The organization owns any number of projects. Each project is the unit that holds its own context folder, data connections, chats, members, and settings.
- Users switch between the projects they belong to from the workspace switcher in the sidebar. No separate URL or subdomain per project - everything lives under the same domain.
nao deploy. Projects are identified by project_name within the organization: deploying a new name creates a project, deploying an existing name updates it in place.
Multi-project hosting reuses the same organization and project model as nao Cloud. Enabling it on your own infrastructure is a one-line switch, described below - it does not depend on nao’s hosted service.
Single-project vs multi-project
| Single-project (default) | Multi-project | |
|---|---|---|
NAO_MODE | self-hosted | cloud |
| Context source | A mounted folder or git repo (NAO_DEFAULT_PROJECT_PATH) | Pushed with nao deploy |
| Projects per instance | One | Many |
| Project switcher | Not used - always serves the default project | Users switch between projects they belong to |
Step 1: Enable multi-project mode
Set a single environment variable on your deployment:NAO_MODE=cloud, the container automatically:
- switches the context source to
api(projects arrive overnao deployinstead of a mounted folder), - unsets
NAO_DEFAULT_PROJECT_PATH, - creates a projects directory (
/app/projectsby default, configurable withNAO_PROJECTS_DIR) where each deployed project is stored in its own folder.
BETTER_AUTH_SECRET, LLM keys, and Cloud Run / container configuration are all shared across every project on the instance.
Because projects are pushed over the API rather than baked into the image, you don’t need the
COPY step or the NAO_CONTEXT_GIT_URL variables from the single-project guide. Use the stock getnao/nao image and deploy your projects afterward.Step 2: Create an organization API key
nao deploy authenticates with an organization-level API key, which can write to every project in the organization.
- Open the deployed chat UI and sign in as an admin.
- Go to Settings -> Organization -> API Keys.
- Click Create key, name it, and copy the value - it is shown only once.
Step 3: Deploy each project
From each project folder (the one containingnao_config.yaml), push it to the instance:
project_name in each project’s nao_config.yaml determines its identity in the organization:
- A new
project_namecreates a new project on the instance. - An existing
project_namereplaces that project’s context folder in place (every deploy is a full replacement, not a merge).
nao deploy reference
Full command flags, exclusions,
.naoignore, and create-vs-update behaviorStep 4: Switch between projects
Once more than one project exists, the workspace switcher appears in the sidebar. Users pick the active project there, and their chats, context, and data connections are scoped to that project. The selection is remembered per user. Deploying a new project automatically adds every existing organization member to it. To scope who can see each project, manage members per project under Settings -> Project -> Team:Organizations and projects
Manage organization members, per-project teams, and roles
Keeping projects in sync
Each project is a normal nao context folder, so the usual workflow applies: edit context locally (or in git), runnao sync, then nao deploy to push. To automate this, run nao deploy from CI on each push to the branch that holds a project.
Synchronization
Automate context sync and deploys with GitHub Actions
Notes and limitations
- One domain, no per-project URLs. Projects are not exposed as subpaths or subdomains. Selection is per user through the switcher, not the URL.
- Switching requires
NAO_MODE=cloud. In defaultself-hostedmode the server always serves the single default project, even if extra project rows exist - the switcher won’t change what’s served. - API keys are organization-scoped. One key can create or overwrite any project in the organization. Treat it as a privileged secret and rotate it from the same API Keys page.