Environment Variables
Configuration reference
Security & Database
| Variable | Required | Description | Example |
|---|---|---|---|
JWT_SECRET | Yes | Secret key used to sign JWT tokens. Generate with openssl rand -base64 32. | s3cr3t... |
DB_PASSWORD | Yes | PostgreSQL database password. Used by the Docker Compose setup. | changeme123 |
DATABASE_URL | Yes | Full PostgreSQL connection string used by the application at runtime (typically through PgBouncer). Auto-configured in Docker. | postgresql://plunk:password@postgres:5432/plunk |
DIRECT_DATABASE_URL | Yes | Direct PostgreSQL connection string used by Prisma migrations. Must bypass any connection pooler. Auto-configured in Docker. | postgresql://plunk:password@postgres:5432/plunk |
REDIS_URL | Yes | Redis connection string. | redis://redis:6379 |
NODE_ENV | No | Application environment. Set to production for production deployments. | production |
PORT | No | Port the API server listens on. | 8080 (default) |
URLs & Domains
Set your subdomains here. The application automatically derives all internal and client-side URLs from these at container startup — you don't need to set *_URI or NEXT_PUBLIC_* variables manually.
| Variable | Required | Description | Example |
|---|---|---|---|
API_DOMAIN | Yes | Subdomain for the API server. | api.yourdomain.com |
DASHBOARD_DOMAIN | Yes | Subdomain for the dashboard app. | app.yourdomain.com |
LANDING_DOMAIN | Yes | Subdomain for the landing page. | www.yourdomain.com |
WIKI_DOMAIN | Yes | Subdomain for the documentation site. | docs.yourdomain.com |
USE_HTTPS | No | Set to true when running behind a TLS-terminating reverse proxy. Used to construct URLs with the correct protocol. | false (default) |
AWS SES
| Variable | Required | Description | Example |
|---|---|---|---|
AWS_SES_REGION | Yes | AWS region where SES is configured. | us-east-1 |
AWS_SES_ACCESS_KEY_ID | Yes | AWS access key ID with SES send permissions. | AKIA... |
AWS_SES_SECRET_ACCESS_KEY | Yes | AWS secret access key for SES. | wJalr... |
SES_CONFIGURATION_SET | No | SES configuration set name used for open/click tracking. | plunk-configuration-set (default) |
SES_CONFIGURATION_SET_NO_TRACKING | No | A second SES configuration set without tracking. When set, projects can toggle email tracking on/off. If omitted, the tracking toggle is hidden. | plunk-no-tracking-configuration-set (default) |
Storage (Minio)
The bundled Docker setup includes Minio with defaults that work out of the box. Only change these when connecting to an external S3-compatible bucket.
| Variable | Required | Description | Default |
|---|---|---|---|
MINIO_ROOT_USER | No | Minio root username (Docker Compose only). | plunk |
MINIO_ROOT_PASSWORD | No | Minio root password (Docker Compose only). | plunkminiopass |
MINIO_API_PORT | No | Port for the Minio API (Docker Compose only). | 9000 |
MINIO_CONSOLE_PORT | No | Port for the Minio console UI (Docker Compose only). | 9001 |
S3_ENDPOINT | No | S3 or Minio endpoint URL. | http://minio:9000 |
S3_ACCESS_KEY_ID | No | S3 or Minio access key. | — |
S3_ACCESS_KEY_SECRET | No | S3 or Minio secret key. | — |
S3_BUCKET | No | Bucket name for file uploads. | uploads |
S3_PUBLIC_URL | No | Publicly accessible base URL for stored files. | — |
S3_FORCE_PATH_STYLE | No | Use path-style URLs instead of virtual-hosted. Required for Minio. | true |
Attachments
Plunk supports attachments on transactional emails. AWS SES caps total message size at 40 MB; the defaults below leave headroom but can be tuned for your use case.
| Variable | Required | Description | Default |
|---|---|---|---|
MAX_ATTACHMENT_SIZE_MB | No | Maximum total attachment size in megabytes per email. Hard upper bound enforced by AWS SES is 40 MB. | 10 |
MAX_ATTACHMENTS_COUNT | No | Maximum number of attachments per email. | 10 |
SMTP Server
The optional SMTP relay lets you send emails through Plunk via the SMTP protocol.
| Variable | Required | Description | Default |
|---|---|---|---|
SMTP_DOMAIN | No | SMTP relay domain. Required when using Traefik's acme.json with multiple certificates so the correct cert can be selected. | localhost |
SMTP_ENABLED | No | Explicitly enable SMTP features in the UI. Automatically enabled when SMTP_DOMAIN is set to a non-localhost value in production. | false |
PORT_SECURE | No | SMTPS port (implicit TLS). | 465 |
PORT_SUBMISSION | No | SMTP submission port (STARTTLS). | 587 |
MAX_RECIPIENTS | No | Maximum number of recipients per email. | 5 |
OAuth
Enables social login. Register an OAuth app with each provider and add the credentials here.
| Variable | Required | Description |
|---|---|---|
GITHUB_OAUTH_CLIENT | No | GitHub OAuth app client ID. |
GITHUB_OAUTH_SECRET | No | GitHub OAuth app client secret. |
GOOGLE_OAUTH_CLIENT | No | Google OAuth app client ID. |
GOOGLE_OAUTH_SECRET | No | Google OAuth app client secret. |
Stripe
Required if you want to enable billing features. All Stripe variables must be set together for billing to activate.
| Variable | Required | Description |
| -------------------------- | -------- | --------------------------------------------------- | ------------------ |
| STRIPE_SK | No | Stripe secret key. |
| STRIPE_WEBHOOK_SECRET | No | Stripe webhook signing secret for verifying events. |
| STRIPE_PRICE_ONBOARDING | No | Stripe price ID for the one-time onboarding fee. |
| STRIPE_PRICE_EMAIL_USAGE | No | Stripe price ID for metered pay-per-email usage. |
| STRIPE_METER_EVENT_NAME | No | Stripe meter event name. | emails (default) |
Platform Emails
When configured, Plunk will send email notifications to users for critical events (e.g. project disabled, billing limits reached). Without these, only ntfy notifications are sent.
| Variable | Required | Description | Example |
|---|---|---|---|
PLUNK_API_KEY | No | API key for a Plunk instance to send transactional emails. | pk_... |
PLUNK_FROM_ADDRESS | No | From address used for platform notification emails. | noreply@yourdomain.com |
Notifications (ntfy)
Plunk bundles a self-hosted ntfy server for internal system notifications.
| Variable | Required | Description | Default |
|---|---|---|---|
NTFY_PORT | No | Port for the ntfy web UI (Docker Compose only). | 8080 |
NTFY_URL | No | ntfy topic URL. Change this to use an external ntfy.sh server or your own instance. | http://ntfy/plunk-notifications |
User Management
| Variable | Required | Description | Default |
|---|---|---|---|
DISABLE_SIGNUPS | No | When true, the signup endpoint rejects new registrations. Useful for private instances. | false |
VERIFY_EMAIL_ON_SIGNUP | No | When true, validates emails on signup — checks for disposable domains, plus-addressing, domain existence, and MX records. | false |
Security
| Variable | Required | Description | Default |
|---|---|---|---|
AUTO_PROJECT_DISABLE | No | When true, projects are automatically suspended when bounce or complaint rate thresholds are exceeded. Set to false to manage project status manually. | true |
EMAIL_RATE_LIMIT_PER_SECOND | No | Override the email sending rate limit. If not set, Plunk automatically fetches the quota from your AWS SES account. | — |
Phishing Detection
Plunk can use AI to detect and block phishing emails before they're sent. Requires an OpenRouter API key.
| Variable | Required | Description | Default |
|---|---|---|---|
OPENROUTER_API_KEY | No | OpenRouter API key. When set, enables AI-powered phishing detection. | — |
OPENROUTER_MODEL | No | LLM model to use for content analysis. See OpenRouter models. | anthropic/claude-3-haiku |
PHISHING_DETECTION_SAMPLE_RATE | No | Percentage of emails to check (0.0-1.0). For example, 0.1 means 10% of emails are analyzed. | 0.1 (10%) |
PHISHING_CONFIDENCE_THRESHOLD | No | Minimum confidence percentage (0-100) required to auto-disable a project from a single detection. | 95 |
PHISHING_CUMULATIVE_THRESHOLD | No | Number of phishing detections within the time window required to auto-disable a project. | 3 |
PHISHING_CUMULATIVE_WINDOW_MS | No | Time window in milliseconds for cumulative phishing tracking. | 3600000 (1 hour) |
How it works:
- A random sample of emails (controlled by
PHISHING_DETECTION_SAMPLE_RATE) are analyzed by the LLM for phishing content. - Projects are automatically disabled if either:
- A single email is detected with confidence ≥
PHISHING_CONFIDENCE_THRESHOLD, or PHISHING_CUMULATIVE_THRESHOLDor more emails are flagged within thePHISHING_CUMULATIVE_WINDOW_MStime window.
- A single email is detected with confidence ≥
- Detection history is stored in Redis and shared across all worker instances.