Skip to content

Configure

Verify your install

Check authentication, collaboration, execution, storage, and scheduled jobs

Run these checks after installation, an upgrade, or a restore. Use a test workspace and the providers you configured. Also test optional features you enabled, such as SSO, SCIM, data drains, and remote sandboxes.

Run doctor

For Compose or a source checkout, run from the directory holding your env files:

Code
bunx sim-setup doctor

Doctor reports these groups:

GroupChecks and limits
Env filesRequired env files exist. --fix seeds missing files from examples and values already in apps/sim/.env.
SchemaRequired keys are present, no longer placeholders, and have usable formats. ENCRYPTION_KEY is checked as 64 hex characters; other required secrets have minimum lengths. Optional secrets are not shape-checked, so an invalid API_ENCRYPTION_KEY can pass this group.
ConsistencyShared secrets agree between app and realtime; the app and migrator point to the same database. --fix mirrors the app's value across split files.
CoherenceFeature flags agree with dependencies, storage configuration is complete, and server flags agree with their UI counterparts.
LiveChecks database reachability, pgvector, applied migrations, Redis, and HTTP health when their configuration is available.

Doctor reads env files, not live container configuration. Production Compose derives DATABASE_URL and Redis settings in the service definition, so those probes can be skipped when the keys are absent from .env. A standalone published package has no migration journal: it can report applied migrations, but cannot establish that they match a current checkout. Read the skipped findings and continue with the checks below.

--json prints structured findings; the command exits 1 when a check fails. --fix writes env-file repairs and reruns the checks. Review those changes and recreate the affected services to apply them; retain existing encryption secrets on upgrades and restores.

Doctor is not a Helm runtime diagnostic. For Kubernetes, use the infrastructure commands below. See Setup commands for the supported layouts and commands.

Core checks

#ActionExpected resultIf it fails
1Open the public URL and create an account. If registration is disabled, use a provisioned account.App, database, TLS, and migrations work.Read app and migrations logs.
2Sign out and sign back in.Session handling works at the configured origin.Compare NEXT_PUBLIC_APP_URL, BETTER_AUTH_URL, and the browser origin.
3Open a workflow, add blocks, and confirm the browser establishes its socket connection.Realtime is reachable.Check browser socket errors and proxy routing.
4Open that workflow in a second browser window and edit it.Edits propagate between clients.Check realtime and Redis configuration.
5Save a model API key in settings and run a two-block workflow.Credential encryption, execution, and provider egress work.Check app logs, ENCRYPTION_KEY, and outbound connectivity.
6Upload and download a small file in Files.Storage works end to end.Check signed-URL/CORS settings for cloud storage, or app/proxy logs for local storage.
7Upload a file larger than 50 MiB and confirm completion.Multipart upload works on cloud or local storage.Read part-upload and completion errors in app logs.

Two windows verify collaboration between clients. To establish cross-replica operation, also confirm their socket connections reach different realtime pods. A load balancer can send both windows to one process. Multi-replica operation requires REDIS_URL on the app and realtime services.

Cloud uploads use multipart above 50 MiB; local uploads use it above 8 MiB. Local parts pass through Sim, while cloud parts use signed provider URLs. See Object storage.

Feature checks

Run the checks for each feature you intend to use:

#ActionExpected resultPrerequisite or diagnosis
8Create a knowledge base and upload a PDF.Parsing, embeddings, and vector storage complete.Configure an embedding provider and enable pgvector.
9Invite a teammate from workspace settings.The invitation arrives and can be accepted.Configure and verify email delivery.
10Connect an OAuth integration account.The provider returns to Sim and the account is listed.Match registered callbacks to the public origin.
11Deploy a workflow with a Schedule trigger set to every minute, then wait two minutes.The workflow runs on schedule.Confirm the scheduler is running and its CRON_SECRET matches the app.
12Use a Sim API key to trigger a workflow through the public API.API-key authentication and execution work.Enable the public API and use the intended key scope.

Knowledge bases can use OpenAI, Azure OpenAI, OpenRouter, or Gemini embeddings, or an Ollama model selected by KB_EMBEDDING_MODEL=ollama/<model> with OLLAMA_URL. See Environment variables.

Infrastructure checks

For the Helm example release sim in namespace simstudio:

Code
kubectl get pods -n simstudio
kubectl logs -n simstudio deploy/sim-app -c migrations --tail=50
curl -fsS https://sim.yourdomain.com/api/health
kubectl get cronjobs -n simstudio

The migrations init container must complete before the app starts. Inspect failed CronJob pods and their logs; the presence of a schedule alone does not prove the endpoint call succeeded.

To check whether Redis is configured without printing the connection string:

Code
kubectl exec -n simstudio deploy/sim-app -- sh -c 'test -n "$REDIS_URL"'

A zero exit status only confirms a non-empty variable. It does not prove Redis answers or that cross-pod events propagate; use the collaboration check above.

For Compose:

Code
docker compose -f docker-compose.prod.yml ps -a
docker compose -f docker-compose.prod.yml logs migrations
docker compose -f docker-compose.prod.yml logs cron
curl -fsS http://localhost:3000/api/health

Expect simstudio, realtime, db, redis, and cron to be running, with migrations completed successfully. Without CRON_SECRET, the cron service exits instead of running schedules.

Read failures

FailureCheck
App does not loadDatabase connectivity and migration logs. On Helm, failed migrations block the app init sequence. On Compose, the app waits for successful migrations.
Sign-in loops or is rejectedPublic app/auth origins, scheme, and trusted origins. Confirm the app and realtime use the same BETTER_AUTH_SECRET.
Socket is unavailableWebSocket upgrades and /socket.io routing. For a separate realtime host, set NEXT_PUBLIC_SOCKET_URL and include the app origin in realtime's ALLOWED_ORIGINS.
Edits do not propagateRealtime connectivity and Redis on every replica; verify which pods hold the connections.
Workflow execution failsProvider egress, saved credentials, and app logs. A decryption error can mean the current ENCRYPTION_KEY differs from the key that encrypted the credential.
Cloud upload failsBucket CORS for the Sim origin and signed headers; server permissions to complete multipart uploads. S3 completion needs s3:ListMultipartUploadParts.
Local upload failsApp logs, writable persistent upload storage, and proxy/body limits. Bucket CORS does not apply.
Knowledge upload failsEmbedding credentials/model/width, parsing errors, and vector availability.
Email never arrivesProvider configuration and delivery dashboard. Without a provider, Sim reports success without delivery; it logs only recipient, subject, and sender at INFO.
OAuth connection failsExact callback URI, client credentials, requested scopes, and provider approval.
Schedule does not runCron service or CronJob pod logs. 401 means scheduler authentication failed; compare CRON_SECRET.

Set LOG_LEVEL=INFO and restart/recreate the app to see email no-op logs. Log-level values are uppercase; the production default is ERROR, which hides those INFO messages. Message bodies are not logged and cannot be recovered from that no-op entry.

After an upgrade

Repeat app sign-in, realtime collaboration, workflow execution, file upload/download, and scheduled-run checks at minimum. Also test each optional feature affected by the release.

After a restore

Run all applicable checks. Run a workflow using a previously saved provider key and an OAuth-backed integration to confirm the restored database and ENCRYPTION_KEY still match. An app can load and sign in while stored credentials remain unreadable.

Was this helpful?
Suggest an edit