Database
Run a self-hosted Nodaro on the bundled Supabase stack or a managed Supabase project, apply the migrations and secure the database keys and passwords.
Nodaro keeps its database in Supabase: Postgres for the data, GoTrue for sign-in and PostgREST for the data API that the editor reads and writes. The compose stack bundles all three and applies the database migrations for you. You can instead point Nodaro at a managed Supabase project and apply the migrations yourself.
The bundled stack
| Service | Image | What it does |
|---|---|---|
db | Supabase Postgres | The database, in the db-data volume |
auth | GoTrue | Sign-up and sign-in with email and password |
rest | PostgREST | The data API |
The browser and the API reach sign-in and the data API through the app's own origin, at PUBLIC_URL/supabase. The web server in the Nodaro container forwards /supabase/auth/v1 to GoTrue and /supabase/rest/v1 to PostgREST, so no extra port or domain is needed.
The bundled stack sends no email: accounts work immediately after sign-up.
Migrations on the bundled stack
The app container applies every file in supabase/migrations/ before the API starts. It needs RUN_MIGRATIONS_ON_BOOT=true and DATABASE_URL, which the compose file sets for you.
- Applied files are remembered and skipped on the next boot.
- A half-migrated database never runs. When a migration fails, the API refuses to start, and the container log names the file.
- Fix, then start again. After you fix the cause, run
docker compose -f docker-compose.community.yml upagain. Files already applied are skipped.
Secure the bundled database
The default keys and passwords are public. Before you expose the stack to a network:
- Mint fresh auth keys with
node tools/generate-selfhost-keys.mjs >> .env. It printsSUPABASE_JWT_SECRET,SUPABASE_ANON_KEYandSUPABASE_SERVICE_ROLE_KEY. All three must come from the same run: the keys are signed with the secret. - Set
POSTGRES_PASSWORDand a matchingDATABASE_URL, such aspostgres://postgres:<new-password>@db:5432/postgres. - Apply them with
docker compose -f docker-compose.community.yml up -d.
The database aligns its internal role passwords, such as supabase_auth_admin and authenticator, with POSTGRES_PASSWORD on its first start only. If the db-data volume already exists, either delete the volume, which deletes your data, or change the role passwords by hand as supabase_admin. Otherwise sign-in fails with password authentication failed for user "supabase_auth_admin".
Use a managed Supabase project
A project on supabase.com replaces the bundled db, auth and rest services. The free tier is enough. Set these in .env:
SUPABASE_URL=https://YOUR-PROJECT.supabase.co
SUPABASE_ANON_KEY=eyJ...
SUPABASE_SERVICE_ROLE_KEY=eyJ...
FRONTEND_SUPABASE_URL=https://YOUR-PROJECT.supabase.co
RUN_MIGRATIONS_ON_BOOT=false
NODARO_ENCRYPTION_KEY=<64-character hex>FRONTEND_SUPABASE_URLis the browser's copy of the project URL. The published image is built for the bundled stack and learns another URL only from this variable, at boot.RUN_MIGRATIONS_ON_BOOT=falsedisables the migration runner. Apply the migrations yourself, as described below.NODARO_ENCRYPTION_KEYmust be set, for example withopenssl rand -hex 32. The stack generates the key for you only while the migration runner is on. Without it, pasting provider keys and connecting to Nodaro Cloud fail withEncryptionKeyMissingError.
If the install already ran on the bundled stack, reuse its key. It is in the app-data volume, at /data/nodaro/encryption-key. A new key cannot read what the old one encrypted.
Apply the migrations to a managed project
Apply every file in supabase/migrations/ in filename order. The zero-padded prefixes, such as 001_ and 002_, give the order.
- With the SQL editor. In the Supabase dashboard, open SQL editor and run each file in turn.
- With the Supabase CLI. It is faster:
supabase link --project-ref YOUR-REF
supabase db pushThe migrations can run again on an already-migrated database, except where a file says otherwise, for example for seeded data. Running them on a fresh database is always fine.
On every update, apply the new files in filename order before you restart onto the new image. A missing migration usually does not stop the API, but the features that need it answer 500 until their tables exist.
Serve a managed project through your own origin
Some networks filter every browser request by hostname and block the Supabase domain. For them, the web server in the Nodaro container can forward a managed project through the app's own origin. Set the three variables together:
SUPABASE_MANAGED_PROXY=true
FRONTEND_SUPABASE_URL=/supabase
SUPABASE_PROXY_UPSTREAM=https://YOUR-PROJECT.supabase.coSUPABASE_PROXY_UPSTREAMis an origin without a path.- Keep
SUPABASE_URLset to the project's HTTPS URL. The API keeps connecting to it directly. - The browser resolves
/supabaseagainst the page's origin. The web server forwards sign-in, REST, storage and realtime requests, including WebSocket upgrades, to the project. - Tokens and API keys pass through unchanged. The proxy adds no privileged credential.
- Several domains can use the same setup, without another custom domain on Supabase.
The compose file does not pass SUPABASE_MANAGED_PROXY or SUPABASE_PROXY_UPSTREAM from .env: add them under environment: of the nodaro service. Unset, the proxy is off and the bundled routes behave as before.
When the database is unavailable
If Postgres goes down, for a migration or a recovery, the API restarts in a loop until the database is reachable again. That is expected. Once Postgres is back, restart the Nodaro container:
docker compose -f docker-compose.community.yml restart nodaroWhat the database holds
Workflows and projects, user profiles, runs and their progress, jobs, the records of generated media, API tokens and OAuth apps, and the encrypted provider keys and social sign-in tokens. Every table enforces row-level security, so users can only see their own rows. The media files themselves are in object storage, and Redis holds only short-lived job state.
Back up the database together with the encryption key: see Backups and restore. To run two installs on one database, see Scaling.
Frequently asked questions
Which database does Nodaro use?
Supabase, which is Postgres with the GoTrue sign-in service and the PostgREST data API. The compose stack bundles all three, or you can point Nodaro at a managed project on supabase.com.
Do I have to run the database migrations myself?
Not on the bundled stack, which applies them on every boot and skips the ones already applied. With a managed Supabase project, set RUN_MIGRATIONS_ON_BOOT=false and apply supabase/migrations/ in filename order, with the SQL editor or supabase db push.
Why do pasted keys fail with EncryptionKeyMissingError on a managed Supabase project?
The stack generates the instance encryption key only while its migration runner is on. With RUN_MIGRATIONS_ON_BOOT=false, set NODARO_ENCRYPTION_KEY yourself, or reuse the key an earlier bundled install kept in its app-data volume.
Can I change POSTGRES_PASSWORD after the first start?
Only by hand. The database aligns its internal role passwords with POSTGRES_PASSWORD on its first start only. Delete the db-data volume, which deletes your data, or change the role passwords as supabase_admin.
Can migrations be rolled back?
No. Migrations only move forward. To return to an earlier version, restore the backup you took before the update.
Related
Install
Configuration
Backups and restore
Updating
Architecture
Last updated on
Provider keys
Give a self-hosted Nodaro its model provider keys on /setup or in .env, see which key powers which nodes, and send provider traffic through your own proxy.
Connect to Nodaro Cloud
Connect a self-hosted Nodaro to a Nodaro Cloud account to run standard models without your own keys and to use the Nodaro-exclusive nodes, billed in credits.