Skip to content

fix(docker): fail fast when prod compose secrets are unset#5836

Open
Souptik96 wants to merge 1 commit into
simstudioai:stagingfrom
Souptik96:fix/5625-docker-prod-missing-secrets
Open

fix(docker): fail fast when prod compose secrets are unset#5836
Souptik96 wants to merge 1 commit into
simstudioai:stagingfrom
Souptik96:fix/5625-docker-prod-missing-secrets

Conversation

@Souptik96

Copy link
Copy Markdown

Summary

Running the documented prod quickstart on a fresh checkout
(docker compose -f docker-compose.prod.yml up) starts the app with empty
BETTER_AUTH_SECRET, ENCRYPTION_KEY, and INTERNAL_API_SECRET. These are passed
straight from the environment with no default (unlike POSTGRES_USER:-postgres), and
apps/sim/lib/core/config/env.ts declares all three as z.string().min(32). Because
createEnv runs with skipValidation: true, the empty values aren't rejected at boot —
they surface later (lib/core/security/encryption.ts throws on an empty ENCRYPTION_KEY,
and Better Auth can't sign sessions with an empty secret), so creating the first admin
account fails with a cleared screen and no visible error
.

Fixes #5625

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation
  • Other: ___________

Testing

Docker wasn't available in my environment, so I reproduced the failing layer — Compose
variable interpolation — directly on the real files using Compose's documented
${VAR:?err} / ${VAR:-default} semantics, under the issue's exact repro env
(OLLAMA_URL only):

Before (upstream/staging): BETTER_AUTH_SECRET, ENCRYPTION_KEY, INTERNAL_API_SECRET
all interpolate to empty strings (with Compose's "variable is not set" warning) → containers
start → signup fails.

After (this branch): docker compose up aborts before starting any container:

BETTER_AUTH_SECRET is required. Generate a 32-byte hex value with openssl rand -hex 32

docker-compose.prod.yml validated as parseable YAML. No TypeScript changed, so
type-check/lint/test are unaffected by this diff.

Please run the full docker compose -f docker-compose.prod.yml up e2e once in review to
confirm the container-level behavior end to end.

What changed

  • docker-compose.prod.yml: guard BETTER_AUTH_SECRET, ENCRYPTION_KEY, and
    INTERNAL_API_SECRET with ${VAR:?message} in both the simstudio and realtime
    services. Compose now aborts with a message naming the missing variable and how to
    generate it. No insecure defaults are introduced — the failure is made clear and
    actionable, not papered over.
  • README.md + .github/CONTRIBUTING.md (Option 2): the Docker Compose quickstart now
    generates the mandatory secrets into .env before up, matching the openssl rand -hex 32
    convention already used by the manual-setup docs.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing (N/A — compose/docs-only change; no TS/test surface)
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

Running the documented prod quickstart on a fresh checkout
(`docker compose -f docker-compose.prod.yml up`) starts the app with empty
BETTER_AUTH_SECRET, ENCRYPTION_KEY, and INTERNAL_API_SECRET. Those are passed
straight from the environment with no default (unlike POSTGRES_USER:-postgres),
and apps/sim/lib/core/config/env.ts declares all three as z.string().min(32).
Because createEnv runs with skipValidation: true, the empty values are not
rejected at boot; they surface later - ENCRYPTION_KEY throws in
lib/core/security/encryption.ts and Better Auth cannot sign sessions with an
empty secret - so creating the first admin account fails with a cleared screen
and no visible error.

Guard the three required secrets with Compose's ${VAR:?message} syntax in both
the simstudio and realtime services, so `docker compose up` aborts before
starting any container with a message naming the missing variable and how to
generate it (openssl rand -hex 32). No insecure defaults are introduced - the
failure is made clear and actionable instead of silent.

Also document the mandatory secrets in the Docker Compose quickstart in
README.md and .github/CONTRIBUTING.md (Option 2), matching the openssl
convention already used by the manual-setup instructions.

fixes simstudioai#5625
@vercel

vercel Bot commented Jul 22, 2026

Copy link
Copy Markdown

@Souptik96 is attempting to deploy a commit to the Sim Team on Vercel.

A member of the Team first needs to authorize it.

@cursor

cursor Bot commented Jul 22, 2026

Copy link
Copy Markdown

PR Summary

Low Risk
Compose and documentation only; no application code changes, though missing secrets will block docker compose up until .env is set.

Overview
Prod Docker Compose now refuses to start when BETTER_AUTH_SECRET, ENCRYPTION_KEY, or INTERNAL_API_SECRET are missing, instead of booting with empty values and breaking first-account signup with no clear error.

docker-compose.prod.yml uses Compose ${VAR:?message} interpolation on those variables for both simstudio and realtime, with messages that point to openssl rand -hex 32. No insecure defaults are added.

The README and CONTRIBUTING Docker Compose quickstarts now create a root .env with those three secrets before docker compose -f docker-compose.prod.yml up, and call out that they are mandatory.

Reviewed by Cursor Bugbot for commit a619927. Bugbot is set up for automated code reviews on this repo. Configure here.

@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR makes production Compose fail early when mandatory secrets are missing. The main changes are:

  • Adds required-variable guards to the Sim and realtime services.
  • Generates the three required secrets in the README quickstart.
  • Mirrors the secret setup in the contributor guide.

Confidence Score: 4/5

The quickstart can erase deployment settings and rotate persistent secrets when rerun in an existing checkout.

  • The Compose guards consistently cover the secrets used by each service.
  • Both documented setup commands replace the complete root .env.
  • Secret rotation can invalidate sessions and break access to encrypted data.

README.md and .github/CONTRIBUTING.md

Important Files Changed

Filename Overview
docker-compose.prod.yml Adds non-empty secret guards to both production services.
README.md Documents secret generation but replaces any existing root environment file.
.github/CONTRIBUTING.md Mirrors the quickstart and its destructive environment-file replacement.

Reviews (1): Last reviewed commit: "fix(docker): fail fast when prod compose..." | Re-trigger Greptile

Comment thread README.md
git clone https://github.com/simstudioai/sim.git && cd sim

# Generate the required secrets. Docker Compose reads them from this .env file.
cat > .env <<EOF

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Existing Environment Is Truncated

Running this step in an existing checkout replaces the entire root .env, deleting settings such as POSTGRES_PASSWORD, TRUSTED_ORIGINS, REDIS_URL, and API keys. Rerunning it also rotates persistent auth and encryption secrets, which invalidates sessions and can make previously encrypted data unreadable; generate only missing entries or stop when .env already exists. The mirrored command in .github/CONTRIBUTING.md has the same behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant