Skip to main content
Build and run it yourself · Self-hosting
Self-hosting

Connect your installation

Create the owner account, apply the ordered schema, and sign in to a workspace you control.

Updated September 29, 2026 8 min read

This walkthrough turns a local demo into a connected installation you control: database, authentication, and a real owner account. You need a working checkout, a new empty Supabase project, access to its authentication settings, and a chosen owner email; complete the local quickstart first if you haven't already.

Use the installation instructions shipped with your checkout when upgrading an older version. This guide follows the repository's docs/self-hosting/SELF-HOSTING.md sequence. The setup command below changes the project you configure.

For connected setup, install PostgreSQL client tools and confirm psql --version works. The demo only needs Node.js 22.16+, npm 10+ and Git.

1. Configure your local environment

In the repository root, copy the example file:

cp .env.example .env.local

Edit .env.local in your editor. Keep it private and out of commits. Fill in the actual values from the new project:

ConfigurationPurpose
NEXT_PUBLIC_SITE_URLThe public site origin; also the workspace origin when shared
NEXT_PUBLIC_COMMAND_CENTER_ORIGIN (if separate)The workspace origin used for sign-in and recovery
NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEYPublic project connection used by the app
SUPABASE_SERVICE_ROLE_KEYServer-only database authority; never put it in a public variable
SUPABASE_PROJECT_REFThe project you intend to migrate
SUPABASE_DB_HOST, SUPABASE_DB_PORT, SUPABASE_DB_USER, SUPABASE_DB_PASSWORDThat project's database connection
ADMIN_EMAILThe platform owner email
BOOTSTRAP_BRAND_NAMEYour business name

Set BOOTSTRAP_BRAND_NAME to your business name. The guided installer derives the remaining neutral identity from that name, ADMIN_EMAIL and NEXT_PUBLIC_SITE_URL. Optional BOOTSTRAP_FOUNDER_EMAIL, if set, must match the owner email. Leave optional providers commented out.

Check the project reference and database host against the project you created. Do not use a database holding real customer records for this installation exercise.

2. Enable authentication redirects

In Supabase Authentication → URL Configuration, set the Site URL to the origin where people open the workspace. Add that origin followed by /auth/callback** to Redirect URLs. For example, if you open http://localhost:3000/admin/login, use http://localhost:3000 as the Site URL and http://localhost:3000/auth/callback** as the redirect pattern. Keep the same scheme, hostname, and port in your browser and configuration; localhost and 127.0.0.1 store separate sign-in cookies. The narrow ** pattern allows the callback query used by password recovery. These are project settings; a database key cannot configure them.

If you use a separate Command Center address, point that hostname at the same hosting project and set NEXT_PUBLIC_COMMAND_CENTER_ORIGIN to its HTTPS origin when you build and run the app. Keep NEXT_PUBLIC_SITE_URL set to the public website. Set the Supabase Auth Site URL to the app origin and allow https://your-app-domain/auth/callback**. Workspace invitations and password recovery then return to the app address, where the sign-in session is stored. If you enable Google Workspace, add the app /api/admin/google/callback URL to its OAuth client's authorized redirect URIs before connecting it. Check sign-in, recovery, invitations and sign-out on the app address before offering installation to your team.

To offer Sign in with Google, create a Google Cloud OAuth client of type Web application for this installation. Add the Command Center app origin under Authorized JavaScript origins. Under Authorized redirect URIs, add the Supabase Auth callback URL shown on your project's Authentication → Providers → Google page, then enter the client's ID and secret there and enable the provider. Keep the app's /auth/callback** pattern in Supabase's redirect list. Limit this sign-in client to identity scopes (openid, email and profile); connecting Gmail, Calendar or Drive is a separate setup. After enabling it, sign in with a Google account that already has active workspace membership and confirm it reaches the intended workspace. Accounts without membership cannot open workspace records.

Do not create the owner account in the dashboard first. The setup command below creates or reuses the configured owner, applies the ordered schema, and establishes admin membership.

3. Plan and apply workspace setup

Inspect the read-only plan:

npm run setup

Missing or placeholder configuration returns named fixes without making changes. A configured plan checks the database target and migration ledger and looks up the owner. It never prints passwords or service keys.

To create a new owner, set SETUP_OWNER_PASSWORD in your private local environment (12 to 1024 characters). Do not put the password in command arguments, Git, or a shared transcript.

Apply to the exact project reference displayed by the plan:

npm run setup -- --apply --project your-project-reference

The command reuses an existing confirmed, active owner or creates the configured owner with a confirmed email and password. It sends no invitation email. Existing passwords are never reset. It verifies that the Auth owner also exists in the configured database, applies the existing migration ledger, then verifies the matching bootstrap workspace and active admin membership.

Auth account creation and database migration are separate operations. If a later step fails, rerun the same command: the owner is reused and completed migration transactions are skipped. Setup does not delete partial installations. Remove SETUP_OWNER_PASSWORD after completion.

A failed migration file rolls back. Do not edit recorded migrations or remove the ledger to force replay. An existing database without a migration ledger needs reviewed baseline adoption. Stop rather than treating that refusal as a fresh installation failure.

The lower-level npm run verify:migrations, npm run db:migrate:all, npm run db:verify-schema, and npm run verify:bootstrap-identity commands remain available for migration-only operations. The guided command supplies the owner and membership steps those commands do not.

4. Sign in and check the workspace

Restart your local development server after editing environment configuration. Sign in at /admin with the owner account. Confirm the intended business identity and workspace, then open Setup.

Before inviting anyone else, sign out and request a password reset from /admin/login. Open the message in the owner inbox, set a new password, and sign in again on the same hostname. Without RESEND_API_KEY, the app sends recovery through Supabase Auth email; check its delivery settings or configure SMTP if the message does not arrive. When Resend is configured, check its verified sender instead. If the link opens the public site or loses your session, check the Auth Site URL, callback pattern, and NEXT_PUBLIC_COMMAND_CENTER_ORIGIN above.

If authentication succeeds but workspace access fails, inspect the owner email match, account creation order, membership, and workspace status. Do not weaken authentication or manually grant broad access to hide a setup error.

Changing BOOTSTRAP_* later does not rewrite an existing workspace. Use Branding and the supported tenant configuration path for subsequent identity changes.

5. Save your first useful result

Before connecting providers, create a fictional contact and a task for its next action in your workspace. Reload the page, reopen the task and confirm the saved details and activity. Complete the task and verify its completed state after another reload. This proves a recorded business workflow without email or AI credentials. The fictional demo uses browser storage; it does not prove your database installation.

6. Connect one workflow

Add the provider required for your first workflow through the documented connection path. Email sending needs a verified sending setup; AI workloads need the configured AI connection. See Integrations.

Check Setup, then run a controlled workflow with fictional records and a destination you control. Inspect the resulting activity and provider outcome. Saved credentials alone are not a successful connection test.

7. Establish readiness before real use

Follow the verification sequence in your checkout's docs/self-hosting/SELF-HOSTING.md, including tenant isolation checks with fictional workspaces. Run heavy checks sequentially through the repository's resource gate or in CI.

Before importing real data, establish backup and restore ownership, update procedures, and failure reporting. Hosting requires configuring secrets in your own hosting project and verifying authentication and the canonical domain after release. A working local demo does not establish production readiness.

Next: Run a business pilot, or onboard agency clients. For failures, see Troubleshooting.

Deploy the complete app package

For the app with the bundled Social Marketing runtime, set APP_HOST in .env and set SOCIAL_MARKETING_ENABLED=true before running npm run stack:up. The root Docker Compose package builds both services and routes them through one HTTPS proxy. Postiz requires no second installation. See the repository deployment/README.md for DNS, updates and retained data.

Protect your saved work

Before importing customer records, keep recovery copies of the database, uploaded files and encryption configuration, then test restoring them into an isolated installation. Follow the repository's backup and recovery guide and record the result so the next maintainer can repeat it.

Protected actions share request limits across server instances. A 429 response means the limit was reached; wait for the indicated retry time. A 503 means the action is temporarily unavailable, so check Setup, the migration catalog and server configuration before retrying. The request stops before sending messages or starting the protected action.