Browse guides

Run your own copy

Run OpenKuasa on your laptop with Docker, or self-host it on your own Supabase project and any Node server.

OpenKuasa is free to self-host under AGPL-3.0. The quickest way is Docker on your own computer. You can also point it at your own Supabase project and run it on any Node server.

Run it on your laptop with Docker

Before you start

  • Docker Desktop (Mac or Windows), or Docker Engine with Compose v2.24 or newer (Linux).
  • Nothing else. No Supabase account and no Node.

Steps

git clone --depth 1 https://github.com/OpenKuasa/OpenKuasa.git
cd OpenKuasa
cp .env.example .env      # fill in your own keys (optional ones can stay blank)
docker compose up -d

Open http://localhost:58272. Sign up to get your own workspace, or press "Try the demo" to see the sample company.

Sign-up is confirmed for you locally, so you don't need email to get started. To get password-reset and invite emails, start with docker compose --profile mail up -d and read them in the mail viewer at http://localhost:58274.

Every key in .env is optional. Add OPENROUTER_API_KEY to turn on the AI chat. See AI models and keys.

Update, stop and wipe

git pull && docker compose pull && docker compose up -d   # update
docker compose down                                       # stop, keeps your data
docker compose down -v                                    # wipe, deletes all local data

Troubleshooting

  • Port already in use. The app uses ports 58272 and 58273 (and 58274 with the mail viewer). On macOS these sit in a range the system lends out briefly to other apps, so another app can hold one now and then. Find it with lsof -i :58273 (swap in the port from the error). Quit that app or restart the Mac, then run docker compose up -d again.
  • Docker isn't running. Start Docker Desktop and wait until it says it is running.
  • "dependency failed to start", or the page never loads. Run docker compose logs migrate (or docker compose logs init) to see why. Fix it, then run docker compose up -d again. It carries on from where it stopped.
  • Start over completely. Run docker compose down -v. This deletes all local data. Then run docker compose up -d.
  • Changed POSTGRES_PASSWORD after the first run. The existing database keeps its old password. Set it before the first run, or run docker compose down -v to start over.

On a cloud computer

To try it on a BoxCompute computer in Malaysia instead of your laptop, see Run it on BoxCompute.

Docker app with online Supabase

Use this path to run the app in Docker while your data lives in your own project on supabase.com, with Supabase's backups. You need only Docker on your machine.

Steps (online Supabase)

  1. Create a project on supabase.com.
  2. Copy the example settings: cp .env.example .env.
  3. In .env, fill in from the Supabase dashboard:
    • NEXT_PUBLIC_SUPABASE_URL (Project Settings → Data API), and NEXT_PUBLIC_SUPABASE_ANON_KEY and SUPABASE_SERVICE_ROLE_KEY (Project Settings → API Keys → Legacy API keys: the long anon and service_role keys that start with eyJ).
    • DATABASE_URL: press Connect, choose Session pooler, and copy the connection string with your database password in it. Use the pooler, not the direct connection: the direct address needs IPv6, which many networks and Docker setups don't have.
  4. Set up Supabase Auth once, as in step 4 of the hosted steps: site URL http://localhost:58272 (or your own address), anonymous sign-ins on if you want "Try the demo", Confirm email off unless you have set up your own email sending, and paste the email templates.
  5. Start it:
docker compose -f docker-compose.hosted.yml up -d

Open http://localhost:58272. Every start applies new database changes to your project before the app starts. If a setting is missing, docker compose -f docker-compose.hosted.yml logs init names it.

The database connection is encrypted. To also check Supabase's certificate, install its CA certificate and add ?sslmode=verify-full to DATABASE_URL.

Update: git pull && docker compose -f docker-compose.hosted.yml pull && docker compose -f docker-compose.hosted.yml up -d. Stop: docker compose -f docker-compose.hosted.yml down. Your data stays in Supabase either way.

Hosted Supabase

Use this path to run OpenKuasa on a server without Docker, with your own Supabase project for data and sign-in and a host that runs Node.

Who can do this

Anyone running their own copy. You need access to a Supabase project and to the server you deploy on.

Before you start (hosted)

  • Node 22 or newer.
  • pnpm. Always use pnpm, not npm or yarn.
  • A Supabase project.

Hosted steps

1. Get the code

git clone https://github.com/OpenKuasa/OpenKuasa.git
cd OpenKuasa
pnpm install
pnpm dev

Open http://localhost:3000. With no Supabase project set, the app opens in preview mode: every visitor is a read-only "Guest" in a "Preview workspace", and the screens show sample data.

2. Point it at your Supabase project

Create a .env.local file in the project root with your project's URL and anon key. In the Supabase dashboard the URL is under Project Settings → Data API, and the anon key under Project Settings → API Keys → Legacy API keys (the long key that starts with eyJ):

NEXT_PUBLIC_SUPABASE_URL=https://<your-project-ref>.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=<your-anon-key>

The rest of the app is turned on by more variables. See Environment variables.

3. Create the tables

Run the migrations once against your project:

pnpm db:migrate --apply

It asks you to type the project ref before it writes anything. See Keep the database up to date.

4. Set up Supabase Auth

In the Supabase dashboard, under Authentication:

  • Enable Anonymous sign-ins. It powers the demo workspace and the tests.
  • Confirm email is your choice. With it off, signup signs the person in at once and lands on /command. With it on, signup stops at a "check your email" message, and the person confirms and then signs in. Either way, an already-registered address always gets that same "check your email" message, so the form never says which addresses have an account.
    • Leave it off until you set up your own email sending (Authentication → Emails → SMTP Settings). Supabase's built-in email only sends to members of your Supabase team, a few messages an hour, so anyone else who signs up never gets the confirmation email.
  • Leave hCaptcha off. The sign-in forms do not send a captcha token yet, so turning hCaptcha on breaks sign-in and signup.

The sign-in email templates are in supabase/email-templates/. They are not set by the migrations: paste each file into the matching template in the Supabase dashboard (Authentication → Emails → Templates). Every link in them points at the app's /auth/confirm route.

5. Build and run it on your server

pnpm build
pnpm start

Any host that runs Node 22 and these two commands will do. openkuasa.com runs on Railway.

6. Add the scheduler

Some background work runs only when your scheduler calls it. See Scheduled jobs.

Common problems

  • Every request answers 503 Service unavailable. A production server (pnpm start, or any host) refuses to serve when NEXT_PUBLIC_SUPABASE_URL or NEXT_PUBLIC_SUPABASE_ANON_KEY is missing. The server log names the two required variables. This is on purpose: a deployment that loses a variable fails visibly instead of turning into the sample app.
  • You want the sample-data preview on a production build. Set OPENKUASA_PREVIEW=1. It is read only when the Supabase values are missing, so it does nothing on a configured deployment. Do not set it on the deployment that serves your real data.
  • Some pages show sample data instead of yours. The database is missing a table or column that the code needs. Run pnpm db:migrate to see which migrations your project lacks.
  • Rate limits count everyone together. The app tells clients apart by the X-Real-IP header that Railway's edge sets. On a host or proxy that does not set it, every request counts against one shared counter, which has its own, wider limit. A proxy that passes on an X-Real-IP the client sent is worse: each client can pick its own counter and dodge the per-client limits. Have the proxy set the header itself, from the connection.
  • MCP limits don't add up across servers. The per-key limits on the MCP endpoint are counted in each server process's memory, so with several instances each one counts on its own, and a restart starts the count again.
  • The app stops working after a quiet week. Supabase pauses a free-plan project after about a week without activity. Open the project in the Supabase dashboard and press Restore project; your data comes back as it was.
  • Password-reset links are sometimes refused. If you run several instances or a serverless host, set AUTH_COOKIE_SECRET (32+ characters). See Environment variables.