Environment variables

Complete reference of Threatless frontend and API environment variables.

Split config: the web image is Nuxt, the API image is Spring Boot. Copy .env.example at the repo root and api/.env.example before the first boot.

Web (Nuxt)

These variables are mandatory for the frontend to talk to the API:

API_URL / NUXT_PUBLIC_API_URL

  • Type: String (URL)
  • Required: ✅ Yes in production
  • Description: Public API origin used by the browser (https://api.example.com). Baked in at Docker build as well as runtime.
  • Example: https://api.trythreatless.com

NUXT_PUBLIC_GOOGLE_OAUTH_ENABLED

  • Type: Boolean string (true / false)
  • Required: 🔶 Optional (default true in Docker)
  • Description: Shows the Google button on login/register. Must match API GOOGLE_OAUTH_ENABLED.

Stripe price IDs in the root .env.example are consumed by the API, not Nuxt. Keep them on the API service.

API (Spring Boot)

Database (required)

SPRING_DATASOURCE_URL

  • Type: JDBC URL
  • Required: ✅ Yes
  • Default: jdbc:postgresql://threatless-db:5432/threatless

SPRING_DATASOURCE_USERNAME / SPRING_DATASOURCE_PASSWORD

  • Required: ✅ Yes
  • Default: threatless / threatless

HTTP

SPRING_APP_PORT

  • Default: 8080
  • Description: Host port used only with docker-compose.local.yml. Coolify must not publish this port on the host; the proxy reaches container port 8080 on the Docker network.

On Coolify, set the API service domain to the public origin plus the container port, for example https://api.trythreatless.com:8080. Visitors still use 443; the :8080 suffix is only the internal port Traefik must target.

CLIENT_ALLOWED_ORIGINS

  • Type: Comma-separated origins
  • Required: ✅ Yes
  • Default: http://localhost:3000
  • Description: CORS allowlist for the dashboard (credentials: include). Include every web origin that will send cookies (scheme + host + port, no path). www and apex are paired automatically, so https://trythreatless.com also allows https://www.trythreatless.com. Spring also reads THREATLESS_APP_ALLOWED_ORIGINS as the same property — set one of them, not two conflicting lists.

Google OAuth

GOOGLE_OAUTH_ENABLED

  • Default: true

GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET

  • Required when OAuth is enabled

GOOGLE_REDIRECT_URI

  • Default: http://localhost:8080/web/auth/google/callback
  • Description: Must match the Google Cloud authorized redirect URI.

Stripe (paid plans)

STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=
STRIPE_PRICE_ID_STARTER=
STRIPE_PRICE_ID_PRO=
STRIPE_PRICE_ID_BUSINESS=
STRIPE_PRICE_ID_ENTERPRISE=
STRIPE_PRICE_ID_ELITE=
STRIPE_PRICE_ID_ULTIMATE=

Webhook endpoint: POST /webhooks/stripe (public, signature verified).

Without Stripe keys, checkout is unavailable and every account stays on Free (5 scans / hour).

ClamAV

Configured in application.properties (override with Spring env):

PropertyDefault
clamd.host127.0.0.1
clamd.port3310
clamd.maxfilesize10MB
spring.servlet.multipart.max-file-size10MB

The Docker image runs clamd locally inside the API container. You normally do not point these at another host.

JWT and cookies

PropertyDefaultNotes
threatless.app.jwtExpirationMs900000 (15 min)Access token
threatless.app.refreshExpirationMs1296000000 (15 days)Refresh cookie
threatless.app.cookieSecurefalseSet true behind HTTPS
threatless.app.jwtSecretsample valueOverride in production with a long random secret

Generate a secret:

terminal
openssl rand -base64 48

Mail

Spring Mail settings (spring.mail.*) send confirmation and password-reset messages. Point them at your SMTP provider. client.context.url should be the public web origin so links in emails resolve.

Do not reuse example SMTP passwords from the repo. Set real credentials via environment or a secrets manager.
Previous

Introduction

Help improve Threatless by reporting issues, suggesting features, and sending pull requests.

Next