Configuration

Every setting a Docker copy reads from .env, and what the important ones do.

A Docker copy reads its settings from .env next to compose.yaml (copied from .env.example). On Coolify and Dokploy they go in the deployment's environment instead. After a change, run docker compose up -d (or Redeploy): compose makes new containers, and the setup step pushes the backend's settings to Convex again.

Every setting

Version

  • CAREERBOT_VERSIONWhich CareerBot release to run. Unset: the release this compose.yaml came with. A version such as 0.8.0 stays on it until you change it here; `latest` moves to the newest release on each `docker compose pull`. Before changing it, back up and read the release notes: https://careerbot.dev/changelog

Your site

  • SITE_URLhttp://localhost:3000Where people open CareerBot, as the browser sees it. On your own computer: http://localhost:3000. On a server with a domain: its https address (https://careerbot.example.com), with your proxy or tunnel sending it to WEB_PORT.

Convex: pick one

  • NEXT_PUBLIC_CONVEX_URLhttps://your-deployment.convex.cloudA) Convex's cloud (free plan). Create a project at https://dashboard.convex.dev, then: NEXT_PUBLIC_CONVEX_URL: Settings > URL & Deploy Key, the deployment URL (https://….convex.cloud) CONVEX_DEPLOY_KEY: Settings > URL & Deploy Key, Generate Production Deploy Key CONVEX_SITE_ORIGIN isn't needed: Google and GitHub send people back to https://….convex.site. Uncomment the two lines below and comment out or delete B's four lines.
  • CONVEX_DEPLOY_KEYprod:your-deployment|…A) Convex's cloud (free plan). Create a project at https://dashboard.convex.dev, then: NEXT_PUBLIC_CONVEX_URL: Settings > URL & Deploy Key, the deployment URL (https://….convex.cloud) CONVEX_DEPLOY_KEY: Settings > URL & Deploy Key, Generate Production Deploy Key CONVEX_SITE_ORIGIN isn't needed: Google and GitHub send people back to https://….convex.site. Uncomment the two lines below and comment out or delete B's four lines.
  • COMPOSE_PROFILESself-hostedB) Self-hosted Convex, run by this compose file on this computer. Its data stays in the convex-data Docker volume. On a server with a domain, NEXT_PUBLIC_CONVEX_URL and CONVEX_SITE_ORIGIN are two https addresses of their own (https://convex.example.com, https://convex-site.example.com) that your proxy sends to CONVEX_PORT and CONVEX_SITE_PORT. CONVEX_SELF_HOSTED_URL stays as it is: the setup step reaches Convex inside compose.
  • NEXT_PUBLIC_CONVEX_URLhttp://localhost:3210B) Self-hosted Convex, run by this compose file on this computer. Its data stays in the convex-data Docker volume. On a server with a domain, NEXT_PUBLIC_CONVEX_URL and CONVEX_SITE_ORIGIN are two https addresses of their own (https://convex.example.com, https://convex-site.example.com) that your proxy sends to CONVEX_PORT and CONVEX_SITE_PORT. CONVEX_SELF_HOSTED_URL stays as it is: the setup step reaches Convex inside compose.
  • CONVEX_SITE_ORIGINhttp://localhost:3211B) Self-hosted Convex, run by this compose file on this computer. Its data stays in the convex-data Docker volume. On a server with a domain, NEXT_PUBLIC_CONVEX_URL and CONVEX_SITE_ORIGIN are two https addresses of their own (https://convex.example.com, https://convex-site.example.com) that your proxy sends to CONVEX_PORT and CONVEX_SITE_PORT. CONVEX_SELF_HOSTED_URL stays as it is: the setup step reaches Convex inside compose.
  • CONVEX_SELF_HOSTED_URLhttp://convex-backend:3210B) Self-hosted Convex, run by this compose file on this computer. Its data stays in the convex-data Docker volume. On a server with a domain, NEXT_PUBLIC_CONVEX_URL and CONVEX_SITE_ORIGIN are two https addresses of their own (https://convex.example.com, https://convex-site.example.com) that your proxy sends to CONVEX_PORT and CONVEX_SITE_PORT. CONVEX_SELF_HOSTED_URL stays as it is: the setup step reaches Convex inside compose.

Signing in

  • SIGNUP_ALLOWLISTPeople sign in with a username and password: the owner's account is made with the setup code, and the owner adds everyone else in Settings, Account. Google and GitHub are optional; the sign-in screen offers them once they're set. Who may sign in with Google or GitHub: their emails, comma-separated. Empty: nobody (password accounts don't need it). Changing the list takes effect after `docker compose up -d`; to empty it again, delete SIGNUP_ALLOWLIST in the Convex dashboard's environment variables (an empty value here leaves the one there as it is).
  • AUTH_GOOGLE_IDEach of Google and GitHub needs an OAuth app whose callback URL is your Convex HTTP actions URL plus /api/auth/callback/google (or /github): self-hosted on this computer: http://localhost:3211/api/auth/callback/google self-hosted on a server: CONVEX_SITE_ORIGIN/api/auth/callback/google (https://convex-site.example.com/…) Convex's cloud: https://your-deployment.convex.site/api/auth/callback/google Google: https://console.cloud.google.com/apis/credentials (OAuth client ID, Web application) GitHub: https://github.com/settings/developers (New OAuth App; its homepage URL is SITE_URL)
  • AUTH_GOOGLE_SECRETEach of Google and GitHub needs an OAuth app whose callback URL is your Convex HTTP actions URL plus /api/auth/callback/google (or /github): self-hosted on this computer: http://localhost:3211/api/auth/callback/google self-hosted on a server: CONVEX_SITE_ORIGIN/api/auth/callback/google (https://convex-site.example.com/…) Convex's cloud: https://your-deployment.convex.site/api/auth/callback/google Google: https://console.cloud.google.com/apis/credentials (OAuth client ID, Web application) GitHub: https://github.com/settings/developers (New OAuth App; its homepage URL is SITE_URL)
  • AUTH_GITHUB_IDEach of Google and GitHub needs an OAuth app whose callback URL is your Convex HTTP actions URL plus /api/auth/callback/google (or /github): self-hosted on this computer: http://localhost:3211/api/auth/callback/google self-hosted on a server: CONVEX_SITE_ORIGIN/api/auth/callback/google (https://convex-site.example.com/…) Convex's cloud: https://your-deployment.convex.site/api/auth/callback/google Google: https://console.cloud.google.com/apis/credentials (OAuth client ID, Web application) GitHub: https://github.com/settings/developers (New OAuth App; its homepage URL is SITE_URL)
  • AUTH_GITHUB_SECRETEach of Google and GitHub needs an OAuth app whose callback URL is your Convex HTTP actions URL plus /api/auth/callback/google (or /github): self-hosted on this computer: http://localhost:3211/api/auth/callback/google self-hosted on a server: CONVEX_SITE_ORIGIN/api/auth/callback/google (https://convex-site.example.com/…) Convex's cloud: https://your-deployment.convex.site/api/auth/callback/google Google: https://console.cloud.google.com/apis/credentials (OAuth client ID, Web application) GitHub: https://github.com/settings/developers (New OAuth App; its homepage URL is SITE_URL)

Made for you the first time

  • JWT_PRIVATE_KEYLeft empty, the first `docker compose up` makes these and keeps them in your Convex deployment's settings. Set them only to bring keys from another copy. MASTER_KEY_V1 encrypts the API keys people save in CareerBot; losing it means entering those again.
  • JWKSLeft empty, the first `docker compose up` makes these and keeps them in your Convex deployment's settings. Set them only to bring keys from another copy. MASTER_KEY_V1 encrypts the API keys people save in CareerBot; losing it means entering those again.
  • MASTER_KEY_V1Left empty, the first `docker compose up` makes these and keeps them in your Convex deployment's settings. Set them only to bring keys from another copy. MASTER_KEY_V1 encrypts the API keys people save in CareerBot; losing it means entering those again.

Optional

  • GOOGLE_PICKER_KEYChoosing a Google Drive folder in Settings (a browser API key for Google's Picker).
  • LIQUIDAI_API_KEYLiquid AI's model, for an experiment in sorting roles.
  • UPDATE_CHECKoffOnce a day this copy asks https://careerbot.dev/releases.json whether there's a newer version, and its owner sees it in Settings, Updates. Nothing about you or this copy is sent, but like any web request it shows careerbot.dev this server's IP address. off: never ask (the owner can also turn it off there).
  • WEB_PORT3000Ports on this computer, if the defaults are taken. Change SITE_URL, NEXT_PUBLIC_CONVEX_URL and CONVEX_SITE_ORIGIN to match when they're localhost addresses (behind a domain they stay as they are). Dokploy's own dashboard is on 3000: there, set WEB_PORT=3001 or another free port.
  • CONVEX_PORT3210Ports on this computer, if the defaults are taken. Change SITE_URL, NEXT_PUBLIC_CONVEX_URL and CONVEX_SITE_ORIGIN to match when they're localhost addresses (behind a domain they stay as they are). Dokploy's own dashboard is on 3000: there, set WEB_PORT=3001 or another free port.
  • CONVEX_SITE_PORT3211Ports on this computer, if the defaults are taken. Change SITE_URL, NEXT_PUBLIC_CONVEX_URL and CONVEX_SITE_ORIGIN to match when they're localhost addresses (behind a domain they stay as they are). Dokploy's own dashboard is on 3000: there, set WEB_PORT=3001 or another free port.
  • CONVEX_DASHBOARD_PORT6791Ports on this computer, if the defaults are taken. Change SITE_URL, NEXT_PUBLIC_CONVEX_URL and CONVEX_SITE_ORIGIN to match when they're localhost addresses (behind a domain they stay as they are). Dokploy's own dashboard is on 3000: there, set WEB_PORT=3001 or another free port.
  • BIND_ADDRESS127.0.0.1The address those ports are published on. 127.0.0.1 (the default): this machine only; Coolify's and Dokploy's proxies don't need them, and on a server they'd skip the proxy and its HTTPS (Docker's ports also go around ufw). Set 0.0.0.0 only to reach the ports from other machines without a proxy, never on a server facing the internet.

The ones that matter most

SITE_URL

Where people open CareerBot, as the browser sees it: http://localhost:3000 on your own computer, https://careerbot.example.com on a server. It's fixed into the web container when it starts (the image is built with a stand-in that the start script swaps), and sign-in sends people back to it. A wrong SITE_URL breaks Google and GitHub sign-in.

NEXT_PUBLIC_CONVEX_URL and CONVEX_SITE_ORIGIN

Where the browser reaches Convex: its API, and (self-hosted only) its HTTP actions, where Google and GitHub send people back after signing in. Both must be addresses the browser can open, never convex-backend. On a server, two https hostnames of their own. Compose stops with "Set NEXT_PUBLIC_CONVEX_URL in .env" when it's missing.

Neither may contain |, \ or &.

COMPOSE_PROFILES

self-hosted runs Convex in the same compose file. Leave it out for Convex's cloud. See Convex.

CONVEX_DEPLOY_KEY, CONVEX_SELF_HOSTED_URL

Which Convex the setup step deploys to. A deploy key means Convex's cloud; otherwise CONVEX_SELF_HOSTED_URL (http://convex-backend:3210) means self-hosted. With neither, the setup step stops: "Set CONVEX_DEPLOY_KEY (Convex's cloud) or CONVEX_SELF_HOSTED_URL (self-hosted Convex); see .env.example."

SIGNUP_ALLOWLIST

Who may sign in with Google or GitHub: emails, comma-separated. Empty: nobody. Password accounts don't need it. An empty value doesn't clear the list on the deployment; delete it in Convex's dashboard. See Sign-in and who can join.

AUTH_GOOGLE_ID, AUTH_GOOGLE_SECRET, AUTH_GITHUB_ID, AUTH_GITHUB_SECRET, GOOGLE_PICKER_KEY

Google and GitHub sign-in, Google Drive, and Drive's folder picker. Each sign-in button shows once both of its keys are set. See Keys and accounts.

JWT_PRIVATE_KEY, JWKS, MASTER_KEY_V1

Made by the first run and kept in the Convex deployment. Set them only to bring keys from another copy. MASTER_KEY_V1 encrypts the API keys people save in CareerBot; losing it means entering those again.

WEB_PORT, CONVEX_PORT, CONVEX_SITE_PORT, CONVEX_DASHBOARD_PORT

The ports compose publishes on the machine: 3000, 3210, 3211 and 6791. Change one when it's taken, and the localhost address that uses it. On Dokploy, set WEB_PORT=3001 (Dokploy's dashboard holds 3000). See Your own computer.

BIND_ADDRESS

The address compose publishes those ports on. Default 127.0.0.1: they open from this machine only, and a proxy in Docker (Coolify, Dokploy) doesn't need them. 0.0.0.0 opens them to other machines too; use it only on a private network without a proxy, never on a server facing the internet (Firewall).

CAREERBOT_VERSION

Which CareerBot release the web app and the setup step run, such as 0.8.0. Unset, the release compose.yaml came with; latest, the newest release each time docker compose pull runs. See Updates, backups, export.

CONVEX_RELEASE

The Convex backend and dashboard image tag for self-hosted Convex. Unset, compose.yaml's pinned release. See Upgrading self-hosted Convex.

Settings that aren't in .env

  • CAREERBOT_MODE=self-hosted: compose sets it on the Convex deployment, and the Docker image is built with it. It's what makes a copy yours: the app at /, username and password sign-in, the owner adds people. Only the Cloudflare way sets it by hand. Without it on the deployment, the sign-in screen says "This copy’s Convex isn’t set up for username and password sign-in: set CAREERBOT_MODE=self-hosted in its environment."
  • AUTH_REDIRECT_ORIGINS: more addresses, comma-separated, that sign-in may send people back to besides SITE_URL. scripts/sync-convex-env.sh sets it when it's in the environment; compose doesn't pass it, so set it with npx convex env set or in Convex's dashboard if you need it.
  • LIQUIDAI_API_KEY: in .env.example under Optional, for an experiment in sorting roles. You don't need it.
  • UPDATE_CHECK=off: in .env.example under Optional. Once a day a self-hosted copy asks https://careerbot.dev/releases.json whether there's a newer version, and its owner sees it in Settings, Updates. The request carries no account, personal data or anything about the copy or the people on it, but like any web request it shows careerbot.dev the IP address of the server the copy runs on. off stops it; the owner can also turn it off with Check for updates in Settings, Updates.
Edit this page on GitHub