Skip to content
Feeblo Docs
Esc
navigateopen⌘Jpreview
On this page

Environment variables

Every environment variable the Feeblo server and dashboard read, grouped by concern with defaults and which ones are required.

The server reads its configuration from the process environment at boot, and the dashboard reads a smaller subset through its own Astro env schema. This page covers every variable in .env.example, grouped by concern. Each row states whether the code treats the variable as required, what default applies, and what breaks when you leave it out.

With one exception, a required mark means the process fails to start without the value. The Media group resolves its config lazily, so missing values there surface on the first upload instead of at boot.

Core

Variable Required Default What breaks without it
DATABASE_URL Yes None (compose: postgres://feeblo:password@pg:5432/feeblo) Postgres DSN for the server and the migration runner. The server config layer fails at boot. See Database.
REDIS_URL No In-memory rate-limiter store Redis DSN, optionally with username, password, and db index. Set it when running more than one server so the rate-limiter store is shared; without it every instance limits independently. The compose network defaults to redis://redis:6379/0.
APP_URL Yes None (compose: http://localhost:3001) Public URL of the dashboard. Auth redirects, cookies, and trusted origins derive from it. It must match what browsers hit, or sign-in breaks in confusing ways.
API_URL Yes None (compose: http://localhost:3000) Public URL of the API. The Slack, Discord, SES, and Polar webhook URLs all derive from it.
APP_ROOT_DOMAIN Yes None (compose: localhost) Root domain your public boards live on. Boards run on arbitrary subdomains of it, so a DNS wildcard must cover it.
APP_RELEASE No dev Release label. The server returns it from /health and the dashboard displays it. Point it at a git SHA or tag to identify a running deployment.
NO_INDEX No Unset Any non-empty value adds noindex to dashboard and board pages. An empty value disables the behavior.

Auth

Variable Required Default Notes
AUTH_ENCRYPTION_KEY Yes None At-rest key for auth tokens, verification codes, and email-subscription tokens. When the integration encryption key is unset it also encrypts integration credentials, and then it must be at least 32 bytes. Missing it, and the server refuses to start with a missing-key error; compose additionally fails fast at docker compose up. Generate one with openssl rand -hex 32.
AUTH_TRUSTED_ORIGINS No The app and API URLs, plus *.localhost:3001 in development or a {scheme}//*.{root domain} wildcard in production Comma-separated browser origins allowed to call the API (better-auth trustedOrigins). Public board subdomains need a wildcard for the root domain, for example *.feeblo.com; scheme-less patterns match both http and https hosts.
GITHUB_CLIENT_ID No None GitHub sign-in. Set it together with the client secret below.
GITHUB_CLIENT_SECRET No None GitHub OAuth secret.
GOOGLE_CLIENT_ID No None Google sign-in, paired with the secret below.
GOOGLE_CLIENT_SECRET No None Google OAuth secret.
GITHUB_EMULATOR_URL No None Points GitHub sign-in at a local OAuth emulator (vercel-labs/emulate) instead of the real provider, for example http://localhost:4000. Development only.
GOOGLE_EMULATOR_URL No None Same hook for Google, for example http://localhost:4001.

See OAuth sign-in for registering the provider apps.

Email

The mailer builds its SMTP transport from the credentials below. Defaults come from packages/transactional/src/config.ts; several differ from the sample values in .env.example.

Variable Required Default Notes
SMTP_TRANSPORT No smtp-auth Documented options are smtp-auth (default), smtp-api, and resend. The current mailer does not read this variable yet; it always uses the credentials below.
SMTP_HOST No 127.0.0.1 SMTP server host.
SMTP_PORT No 2500 SMTP port. The sample value in .env.example is 1025.
SMTP_USERNAME No None Auth user passed to nodemailer. Omit for an open relay.
SMTP_PASSWORD No None Auth secret, paired with the username.
SMTP_SECURE No false Force TLS on the connection.
SMTP_UNSAFE_IGNORE_TLS No false When true and force-TLS is off, TLS is skipped even if the server advertises STARTTLS. Meant only for broken local relays.
SMTP_FROM_NAME No None Display name for the from address. .env.example documents it, but the current mailer does not read it yet.
SMTP_FROM_ADDRESS No hello@feeblo.com Sender address. .env.example marks it required, but the code falls back to this value, so set it explicitly to a real address in production.
SMTP_PERSONAL_FROM_ADDRESS No Falls back to the default from address Dedicated sender for personal lifecycle mail (user onboarding, user feedback).
SMTP_SERVICE No None Nodemailer well-known service name, passed through to the transport.
EMAIL_PROVIDER_WEBHOOK_TOKEN No None The token alone activates the Amazon SES feedback webhook at the API path /email-provider/ses/<token>. Unset, and the route stays inert (404). Generate a dedicated one with openssl rand -hex 32; do not reuse the auth at-rest key.
EMAIL_PROVIDER_SNS_TOPIC_ARN No None ARN of the SNS topic that delivers SES feedback. Its only role is source filtering: messages signed from any other topic are rejected. Set it whenever the token is set.
EMAIL_OUTBOX_GLOBAL_DELIVERY_PAUSED No false Pauses all outbound email when true.
EMAIL_OUTBOX_MAX_CONCURRENT_SENDS No 10 Concurrency bound for the outbox send workers.
EMAIL_OUTBOX_MONTHLY_SEND_LIMIT No 100000 Once monthly send attempts reach this number, delivery stops.
EMAIL_OUTBOX_ESTIMATED_SEND_COST_MICROS No 100 Estimated cost per send in micros, used for spend tracking.
EMAIL_OUTBOX_PAUSED_WORKSPACE_IDS No Empty Comma-separated workspace IDs whose mail stays queued.

See Email for transports and the SES webhook end to end.

Media

The upload service resolves this config lazily per request, so a missing value fails the first upload rather than server boot.

Variable Required Default Notes
MEDIA_UPLOAD_REGION Yes None (compose: us-east-1) S3 region. Use auto for Cloudflare R2.
MEDIA_UPLOAD_ENDPOINT Yes None (compose: http://127.0.0.1:9002) S3-compatible endpoint. The compose default targets a local MinIO-style server; point it at your R2 or S3 endpoint.
MEDIA_UPLOAD_ACCESS_KEY_ID No None (compose: feeblo) S3 access key.
MEDIA_UPLOAD_SECRET_ACCESS_KEY No None (compose: password) S3 secret key.
MEDIA_PUBLIC_BUCKET_NAME Yes None (compose: feeblo-media-public) Public bucket that uploaded media lands in.

See Media storage for S3, R2, and MinIO setups.

Integrations

Each integration registers only when its full credential set is present; partial sets disable the provider without any error. The settings below also back the outbound webhook subsystem.

Variable Required Default Notes
INTEGRATION_ENCRYPTION_KEY No Falls back to the auth at-rest key Encrypts webhook endpoint URLs and signing secrets at rest. When it is shorter than 32 bytes, webhook create/update/rotate fails with Webhook credentials could not be encrypted.
INTEGRATION_ALLOW_PRIVATE_NETWORK No false Allows outbound webhook deliveries to private-network endpoints. The code honors it only when NODE_ENV is development; every other environment rejects private egress. Never enable it in production.
SLACK_CLIENT_ID No None Slack app credentials. The integration registers only when the client id, client secret, and signing secret are all set.
SLACK_CLIENT_SECRET No None
SLACK_SIGNING_SECRET No None Request-signing secret from the Slack app’s Basic Information page.
SLACK_OAUTH_REDIRECT_URL No The API URL plus /slack/oauth/callback OAuth redirect for the Slack install flow.
DISCORD_CLIENT_ID No None Discord app credentials. The integration registers only when the client id, client secret, bot token, and public key are all set.
DISCORD_CLIENT_SECRET No None
DISCORD_BOT_TOKEN No None Application-wide bot token; the same bot serves every guild install.
DISCORD_PUBLIC_KEY No None 64 hex characters; verifies interaction signatures.
DISCORD_OAUTH_REDIRECT_URL No The API URL plus /discord/oauth/callback OAuth redirect for the Discord install flow.
GITHUB_INTEGRATION_APP_ID No None Numeric App ID from the GitHub App’s General page, not the OAuth client ID. The two-way issue integration registers only when all six values below are set.
GITHUB_INTEGRATION_APP_SLUG No None URL-friendly app name from the public installation URL. For https://github.com/apps/feeblo the slug is feeblo.
GITHUB_INTEGRATION_CLIENT_ID No None The install flow uses it only to verify the installer can reach the selected app installation.
GITHUB_INTEGRATION_CLIENT_SECRET No None Paired with the client id above; the temporary user token is never stored.
GITHUB_INTEGRATION_PRIVATE_KEY No None PEM private key from the app’s Private keys section. Preserve the complete BEGIN/END lines and line breaks; store it as a multiline secret.
GITHUB_INTEGRATION_WEBHOOK_SECRET No None Random secret configured identically on the GitHub App. Register the fixed callback /github/app/installations/callback and webhook /github/app/webhooks under the API base; Feeblo mounts both paths itself.

The social-auth GitHub variables under Auth are separate: they only sign users into Feeblo. The integration credentials group above powers the issue integration.

Billing

Variable Required Default Notes
POLAR_MODE No sandbox Polar environment: sandbox or production.
POLAR_ACCESS_TOKEN No None Enables Polar checkout, the customer portal, and subscription synchronization. Without it the Polar client is never created and billing stays off.
POLAR_WEBHOOK_SECRET No None Verifies signed Polar webhooks. Point Polar at the webhook path /api/auth/polar/webhooks under the API base, then resend product.created and product.updated events so the local product catalog populates.

Observability & misc

Variable Required Default Notes
SENTRY_DSN No None Turns on server error tracking, tracing, logs, and metrics.
SENTRY_ENVIRONMENT No NODE_ENV Sentry environment label. Set it to staging while NODE_ENV stays production.
SENTRY_TRACES_SAMPLE_RATE No 0.1 Fraction of transactions to trace (0.0–1.0).
POSTHOG_KEY No None PostHog project API key for the dashboard. When omitted, all analytics is disabled.
POSTHOG_HOST No https://us.i.posthog.com PostHog instance host.
EMBEDDING_API_KEY No None Enables AI post embeddings and semantic suggestions; the API must implement the OpenAI embeddings endpoint. An empty value keeps the feature off.
EMBEDDING_MODEL No text-embedding-3-small Embeddings model name.
EMBEDDING_DIMENSIONS No 1536 Vector size. It must equal the post embedding column dimension (1536); reconfigure the column with db:configure-embeddings before changing it, or embedding jobs fail.
EMBEDDING_API_URL No None Override for OpenAI-compatible providers such as Hugging Face or Ollama.
PROFANITY_EXTRA_WORDS No None Comma-separated words appended to the bundled profanity dictionary. The server trims and lowercases each word.

Next steps

Was this page helpful?