Nodaro Community Edition Quickstart

Two commands to a running, fully self-contained Nodaro — no cloud accounts, no API keys, nothing to configure:

git clone https://github.com/nodaroai/app.nodaro.ai.git nodaro
cd nodaro
docker compose -f docker-compose.community.yml up

The first boot downloads the prebuilt app image (~2.4 GB, so a few minutes on a typical connection) plus the bundled services — a download rather than a compile, and it does not pin your CPU. After that, boots take seconds.

Building from source instead (needed only if you change the code — PUBLIC_URL, another port or a domain, and the Supabase keys are read at runtime, so the published image serves them after a plain restart):

docker compose -f docker-compose.community.yml build

What comes up:

Service What it does Where it lives
Postgres (Supabase image) Your database — migrations apply themselves on first boot db-data volume
GoTrue Auth — email + password sign-up, no email server needed
PostgREST The data API the editor talks to
MinIO Media storage — generated images/videos land on your disk minio-data volume
Redis Job queues redis-data volume
Nodaro The app itself: editor, API, workers port 3000

1. Open the app

http://localhost:3000

Create an account with any email + password (accounts work immediately — no confirmation email on a local stack). On your first visit the dashboard seeds a Welcome Demo workflow: a finished script → image → video → voice → final-cut run with every result pre-baked, so you can explore real nodes and play the final clip before touching any configuration.

2. Check the install: /setup

http://localhost:3000/setup shows live green/red status for the database (including a dedicated “Migrations missing” state), Redis, storage, and provider keys — no login needed. On a fresh stack everything should be green except provider keys.

For a deeper check than the screen can show, run the contract probe against your own install from a clone of the repo:

node tools/community-smoke.mjs http://localhost:3000

It signs up a throwaway account, creates a workflow, submits a generation and follows the job to its end state, then reports which contracts held. Checks that do not apply to your install (you already added a provider key, for example) are reported as skipped rather than failed. The same script runs in our CI against a keyless stack on every change.

Added a KIE.ai or Replicate key already? Opt in to the success-path check too:

node tools/community-smoke.mjs http://localhost:3000 --keyed

--keyed needs a KIE.ai or Replicate key on the install (KIE_API_KEY / REPLICATE_API_TOKEN in .env, or pasted on /setup) — a nodaro.ai connection or token is the connect lane and is checked separately. It submits one real generation on the cheapest model for that key (Z-Image on KIE.ai, Flux 2 Klein on Replicate — typically under a cent of provider spend), follows it to completion, and verifies the media actually lands in your install’s own storage. Without the flag the probe never spends anything.

3. Generate for real

The demo isn’t the only free material: the dashboard’s Tutorials tab ships pre-populated — a starter set of guided walkthroughs is seeded on first boot, and browsing them costs nothing (see Tutorials).

Viewing the demo is free and works offline. To run nodes yourself you need a model provider — until you have one, the dashboard shows a dismissible “This install can’t generate yet” callout with both buttons (Connect nodaro.ai · Paste a key); it disappears on its own once a provider exists. Three ways, and they run side by side — with one rule: if this install is both connected to nodaro.ai and holds a NODARO_API_KEY, the connection is used and the token is ignored:

Paste a key in the app (no files, no restart). Two places show the same tiles: http://localhost:3000/setup → Install health (the health screen needs no login; saving a key does — create your server login first, step 1 on that page) and, once you are in the app, Integrations → Model providers. Every provider is a tile — nodaro.ai, KIE.ai, Replicate, Anthropic, Google Gemini, ElevenLabs, fal.ai, and, grouped apart as used by specific nodes, HeyGen (avatar nodes), Beeble (Relight & Switch), Apify (Web Scrape, Meta Ads, Instagram) — with a PASTE KEY field. (Connected to nodaro.ai? Then none of them is required — every tile is covered by the connection.) Paste, Save, hit Run on the demo’s Scene Image node: Z-Image, the cheapest model, answers in seconds. The key is stored encrypted in your own database (the install generates its encryption key on first boot and keeps it in the app-data volume — back that volume up with the database) and takes effect at once, no restart. Each tile says what the key powers and where to get one.

Connect nodaro.ai (no keys to manage). On the same page, step 2 → Connect nodaro.ai. Your browser opens the nodaro.ai consent screen; sign in or create a free account there (1,500 free credits on first sign-in — see Free credits), approve, and you land back on your install connected — image, video, speech and LLM models route through your nodaro.ai account — including the vendor-direct nodes (AI Avatar / Cinematic Avatar, Relight & Switch, Web Scrape, Meta Ads, Instagram), which run on the connection whenever their own key is empty. Details and the two-accounts model: Connect your instance to Nodaro Cloud.

Or keep keys in .env (infra-as-code). Create a file named .env next to the compose file:

KIE_API_KEY=...            # kie.ai — broadest model coverage
# or
REPLICATE_API_TOKEN=...    # replicate.com
# or
NODARO_API_KEY=...         # nodaro.ai as a plain provider — a personal API token
                           # from app.nodaro.ai → Settings → API (no OAuth flow)

then docker compose -f docker-compose.community.yml up -d. A key set in .env takes precedence over one pasted on the screen; the tile shows set (env) and cannot be edited in place — remove the key from .env (and restart), or press Replace .env key on the tile to override it from the screen without touching the file (the nodaro.ai tile has no Replace: its .env token can only be removed from the file). Any tile with a key, .env or pasted, can also be disabled from the screen.

You pay providers directly; the Community edition has no credit system, no Nodaro fees, and no watermark.

Editing video

Any video result has an Edit video action that opens the NodarCut editor. The editor page loads from freecut.nodaro.ai; your video does not go with it — the app reads the file from your own storage and hands the bytes to the editor inside your browser, and the editing and export happen there.

It works out of the box on http://localhost:3000. If you serve this install on another origin — a LAN address, or a domain behind a reverse proxy — the browser refuses to embed the editor and the panel explains why. Two ways forward:

FREECUT_URL=https://freecut.example.internal

Restart the stack and the editor follows — no rebuild. Set FREECUT_URL=off to remove the Edit-video action entirely.

Editing audio

Audio results have an Edit audio action that opens the AudioMass editor the same way — the bytes are handed to the editor inside your browser, nothing is uploaded to it.

Unlike the video editor there is no public hosted AudioMass, so this action is inert until you configure it: with nothing set, choosing Edit audio opens a panel that explains what to set rather than an editor. Run your own AudioMass — Nodaro’s fork speaks the in-browser bridge the editor needs (vanilla AudioMass does not) — and point this install at it:

AUDIOMASS_URL=https://audiomass.example.internal

Restart the stack and the editor follows — no rebuild. AUDIOMASS_URL=off behaves the same as leaving it unset.

3D scenes

The Basic 3D lane works here: Generate 3D Scene and Edit 3D Scene author an editable clay scene with your LLM key, and Render Video exports it with the renderer that ships in this image. No Blender, no private plugin, nothing extra to install.

3D Render Pro is the other node, and it is not part of this edition — it runs on a hosted build service. This install says so consistently rather than letting you find out mid-run: GET /v1/nodes omits the type, GET /v1/3d-scene/capabilities reports pro.available: false with advanced: null, and a hand-written POST /v1/pro-3d-render is refused with 503 SCENE_CAPABILITY_UNAVAILABLE. It never silently falls back to the Basic lane.

Before exposing the stack to a network

The compose defaults are designed for local play and are public knowledge. For anything reachable by other people:

  1. Mint fresh auth keys — node tools/generate-selfhost-keys.mjs >> .env (JWT secret + anon + service keys must always come from the same run). A changed anon key needs only a restart — the container hands it to the browser at runtime (/config.js), no rebuild.
  2. Set POSTGRES_PASSWORD and a matching DATABASE_URL, and fresh MinIO credentials (R2_ACCESS_KEY_ID / R2_SECRET_ACCESS_KEY). Note the Postgres role passwords are aligned at the database’s FIRST init — if the db-data volume already exists, wipe it or update the roles manually as supabase_admin.
  3. Set PUBLIC_URL to your real https:// URL and front the stack with a reverse proxy — see Deployment.

Using managed services instead

Every bundled service can be swapped for a managed one in .env:

Updating

Every build of main publishes the image under latest and its commit <sha>; a release adds three version tags:

Tag Meaning
vX.Y.Z (e.g. v2.0.0) Immutable — exactly one build, never re-pointed. Pin this for byte-stable deploys.
vX.Y Floats across patches of one minor.
vX Floats across a whole major — features and fixes arrive, breaking changes never do.
latest Tracks main — every merged change, released or not, majors included.
<sha> One commit, never re-pointed — the other way to reproduce exactly one build.

To update, pull and restart — database migrations apply themselves on boot:

docker compose -f docker-compose.community.yml pull nodaro
docker compose -f docker-compose.community.yml up -d nodaro

Before a major version (the first number changed), read the release notes at https://github.com/nodaroai/app.nodaro.ai/releases first — majors are the only releases allowed to change env vars, compose topology, or behavior you may depend on. There is no downgrade path (migrations are forward-only): take a backup before majors and restore it if you need to go back:

tools/community-backup.sh              # everything the stack cannot regenerate, one archive
tools/community-restore.sh <archive>   # the road back — DESTRUCTIVE, asks for confirmation

On Windows run both from Git Bash (not PowerShell, not WSL). The backup prints exactly what went into the archive and warns loudly if the encryption key is missing; the restore verifies the media, the key and the app before it starts anything. Full guide: Backup & restore.

The running version is shown in the app sidebar and at /health. Click the version for the release notes — of the version you are running, or of the newest release when one is available: then a red dot appears next to it and the same dialog adds the exact upgrade commands, with the backup step first. The check is one anonymous request a day to GitHub’s API (a check that fails is tried again after five minutes, then less and less often, until one gets through); for air-gapped installs, add NODARO_UPDATE_CHECK: "off" under the nodaro service’s environment: block in docker-compose.community.yml to disable it entirely — the compose file does not pass this variable through from .env (the version then shows as plain text).

Troubleshooting