Skip to main content
Plane uses environment variables for configuration. All settings are defined in the plane.env file (Docker Compose) or Helm values (Kubernetes).

Core Configuration

Application URLs

These are the most critical settings and must be configured before first startup.
.env
# Base URL for the web application
WEB_URL="http://localhost"

# CORS allowed origins (must match WEB_URL)
CORS_ALLOWED_ORIGINS="http://localhost"

# Base URLs for different services (usually auto-configured)
ADMIN_BASE_URL="http://localhost/admin"
SPACE_BASE_URL="http://localhost/spaces"
APP_BASE_URL="http://localhost"
WEB_URL and CORS_ALLOWED_ORIGINS must match exactly, including protocol (http/https) and port. Mismatched values will cause authentication and API call failures.
Examples:
WEB_URL="http://localhost:8080"
CORS_ALLOWED_ORIGINS="http://localhost:8080"

Server Ports

.env
# HTTP port (default: 80)
LISTEN_HTTP_PORT=80

# HTTPS port (default: 443)
LISTEN_HTTPS_PORT=443

# Site address for Caddy server
SITE_ADDRESS=":80"
If port 80 is already in use, change to a different port like 8080. Remember to update WEB_URL accordingly.

Database Configuration

PostgreSQL Settings

.env
# PostgreSQL credentials
POSTGRES_USER="plane"
POSTGRES_PASSWORD="plane"  # Change in production!
POSTGRES_DB="plane"

# PostgreSQL host and port
PGHOST="plane-db"  # Service name in Docker Compose
POSTGRES_PORT="5432"

# Data directory
PGDATA="/var/lib/postgresql/data"

# Full connection string (auto-generated)
DATABASE_URL="postgresql://plane:plane@plane-db:5432/plane"
For external PostgreSQL:
.env
PGHOST="your-db-host.rds.amazonaws.com"
POSTGRES_PORT="5432"
POSTGRES_USER="plane"
POSTGRES_PASSWORD="your-secure-password"
POSTGRES_DB="plane"
DATABASE_URL="postgresql://plane:[email protected]:5432/plane"
PostgreSQL 15.7 is used with max_connections=1000 by default. Ensure your external database supports sufficient connections.

Cache & Message Queue

Redis Configuration

.env
# Redis host and port
REDIS_HOST="plane-redis"
REDIS_PORT="6379"

# Full Redis URL
REDIS_URL="redis://plane-redis:6379/"
For external Redis:
.env
REDIS_HOST="your-redis-host.cache.amazonaws.com"
REDIS_PORT="6379"
REDIS_URL="redis://your-redis-host.cache.amazonaws.com:6379/"
Plane uses Valkey 7.2 by default, a Redis-compatible alternative. Any Redis 6.0+ compatible service works.

RabbitMQ Configuration

.env
# RabbitMQ credentials
RABBITMQ_HOST="plane-mq"
RABBITMQ_PORT="5672"
RABBITMQ_USER="plane"
RABBITMQ_PASSWORD="plane"  # Change in production!
RABBITMQ_VHOST="plane"

# Full AMQP URL
AMQP_URL="amqp://plane:plane@plane-mq:5672/plane"
RabbitMQ is used for background job processing (emails, notifications, imports, etc.).

File Storage

MinIO (S3-Compatible) Settings

.env
# Enable MinIO (1 = use bundled MinIO, 0 = use external S3)
USE_MINIO=1

# MinIO credentials
AWS_ACCESS_KEY_ID="access-key"  # Change in production!
AWS_SECRET_ACCESS_KEY="secret-key"  # Change in production!

# MinIO endpoint (internal service name)
AWS_S3_ENDPOINT_URL="http://plane-minio:9000"

# Bucket name
AWS_S3_BUCKET_NAME="uploads"

# Region (not used for MinIO)
AWS_REGION=""

# SSL for MinIO endpoint (0 = disabled, 1 = enabled)
MINIO_ENDPOINT_SSL=0

# Maximum file upload size (in bytes)
FILE_SIZE_LIMIT=5242880  # 5MB default

AWS S3 Configuration

For production, use AWS S3 or compatible services:
.env
# Disable MinIO
USE_MINIO=0

# AWS credentials
AWS_REGION="us-east-1"
AWS_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE"
AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"

# S3 endpoint (empty for AWS S3)
AWS_S3_ENDPOINT_URL="https://s3.amazonaws.com"

# Bucket name (must exist)
AWS_S3_BUCKET_NAME="plane-production-uploads"

# Enable SSL
MINIO_ENDPOINT_SSL=1

# File size limit (10MB example)
FILE_SIZE_LIMIT=10485760
For other S3-compatible services:
USE_MINIO=0
AWS_REGION="nyc3"
AWS_ACCESS_KEY_ID="your-spaces-key"
AWS_SECRET_ACCESS_KEY="your-spaces-secret"
AWS_S3_ENDPOINT_URL="https://nyc3.digitaloceanspaces.com"
AWS_S3_BUCKET_NAME="plane-uploads"
MINIO_ENDPOINT_SSL=1

Security Settings

Secret Key

.env
# Django secret key (auto-generated, keep secure!)
SECRET_KEY="60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5"
Never commit the secret key to version control. Generate a new one for production using:
python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'

Live Server Secret

.env
# Secret for real-time collaboration server
LIVE_SERVER_SECRET_KEY="2FiJk1U2aiVPEQtzLehYGlTSnTnrs7LW"
Change this in production to a random 32-character string.

API Rate Limiting

.env
# Rate limit for API key requests
API_KEY_RATE_LIMIT="60/minute"
Options: 60/minute, 1000/hour, 10000/day

Trusted Proxies

.env
# CIDR ranges of trusted proxies
TRUSTED_PROXIES="0.0.0.0/0"
For production behind a load balancer:
TRUSTED_PROXIES="10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"

SSL/TLS Configuration

Let’s Encrypt

.env
# Email for Let's Encrypt notifications
CERT_EMAIL="[email protected]"

# ACME server URL
CERT_ACME_CA="https://acme-v02.api.letsencrypt.org/directory"

# For DNS challenge (optional)
CERT_ACME_DNS=""
Using DNS challenge (for wildcard certs):
.env
CERT_ACME_DNS="acme_dns cloudflare YOUR_API_TOKEN"
Supported DNS providers: Cloudflare, Route53, DigitalOcean, and more.
For testing, use Let’s Encrypt staging:
CERT_ACME_CA="https://acme-staging-v02.api.letsencrypt.org/directory"

Email Configuration (SMTP)

Required for user invitations, password resets, and notifications.
.env
# SMTP server settings
EMAIL_HOST="smtp.gmail.com"
EMAIL_PORT="587"
EMAIL_HOST_USER="[email protected]"
EMAIL_HOST_PASSWORD="your-app-password"
EMAIL_FROM="[email protected]"

# TLS/SSL settings
EMAIL_USE_TLS="1"  # For port 587
EMAIL_USE_SSL="0"  # For port 465, set to 1 and TLS to 0
Provider Examples:
EMAIL_HOST="smtp.gmail.com"
EMAIL_PORT="587"
EMAIL_HOST_USER="[email protected]"
EMAIL_HOST_PASSWORD="your-app-password"  # Use App Password, not account password
EMAIL_USE_TLS="1"
EMAIL_USE_SSL="0"
Enable 2FA and generate an App Password at myaccount.google.com/apppasswords
EMAIL_HOST="email-smtp.us-east-1.amazonaws.com"
EMAIL_PORT="587"
EMAIL_HOST_USER="your-smtp-username"
EMAIL_HOST_PASSWORD="your-smtp-password"
EMAIL_USE_TLS="1"
EMAIL_USE_SSL="0"
EMAIL_HOST="smtp.sendgrid.net"
EMAIL_PORT="587"
EMAIL_HOST_USER="apikey"
EMAIL_HOST_PASSWORD="your-sendgrid-api-key"
EMAIL_USE_TLS="1"
EMAIL_USE_SSL="0"
EMAIL_HOST="smtp.mailgun.org"
EMAIL_PORT="587"
EMAIL_HOST_USER="[email protected]"
EMAIL_HOST_PASSWORD="your-mailgun-smtp-password"
EMAIL_USE_TLS="1"
EMAIL_USE_SSL="0"

Authentication Settings

Basic Authentication

.env
# Enable user signup (1 = enabled, 0 = disabled)
ENABLE_SIGNUP="1"

# Enable email/password authentication
ENABLE_EMAIL_PASSWORD="1"

# Enable magic link login
ENABLE_MAGIC_LINK_LOGIN="1"
Set ENABLE_SIGNUP="0" to restrict new user registrations. Only admins can invite users.

Workspace Creation

.env
# Disable workspace creation for regular users
DISABLE_WORKSPACE_CREATION="0"
Set to 1 to allow only admins to create workspaces.

OAuth Providers

Google OAuth

.env
# Enable Google OAuth
IS_GOOGLE_ENABLED="1"

# Google OAuth credentials
GOOGLE_CLIENT_ID="your-client-id.apps.googleusercontent.com"
GOOGLE_CLIENT_SECRET="your-client-secret"
1

Create OAuth Credentials

2

Configure OAuth Consent Screen

Set authorized redirect URI: https://plane.example.com/auth/google/callback/
3

Copy Credentials

Add Client ID and Secret to your .env file

GitHub OAuth

.env
# Enable GitHub OAuth
IS_GITHUB_ENABLED="1"

# GitHub OAuth credentials
GITHUB_CLIENT_ID="your-github-client-id"
GITHUB_CLIENT_SECRET="your-github-client-secret"

# GitHub App name (optional)
GITHUB_APP_NAME=""
1

Create OAuth App

2

Set Callback URL

Authorization callback URL: https://plane.example.com/auth/github/callback/
3

Copy Credentials

Add Client ID and Secret to your .env file

GitLab OAuth

.env
# Enable GitLab OAuth
IS_GITLAB_ENABLED="1"

# GitLab OAuth credentials
GITLAB_CLIENT_ID="your-gitlab-client-id"
GITLAB_CLIENT_SECRET="your-gitlab-client-secret"
GITLAB_HOST="https://gitlab.com"  # Or your self-hosted GitLab URL

Integrations

Slack Integration

.env
# Slack OAuth credentials
SLACK_CLIENT_ID="your-slack-client-id"
SLACK_CLIENT_SECRET="your-slack-client-secret"

Unsplash Integration

For cover images:
.env
# Unsplash API key
UNSPLASH_ACCESS_KEY="your-unsplash-access-key"
Get an API key at unsplash.com/developers

AI Features (LLM)

For AI-powered features:
.env
# OpenAI API key
LLM_API_KEY="sk-your-openai-api-key"

# API base URL (optional, for custom endpoints)
OPENAI_API_BASE="https://api.openai.com/v1"

# Model selection (deprecated)
GPT_ENGINE="gpt-3.5-turbo"
OPENAI_API_KEY, OPENAI_API_BASE, and GPT_ENGINE are deprecated but still supported. Use LLM_API_KEY for new deployments.

Analytics & Monitoring

PostHog (Product Analytics)

.env
# PostHog API key
POSTHOG_API_KEY="phc_your_api_key"

# PostHog host (default: PostHog Cloud)
POSTHOG_HOST="https://app.posthog.com"
For self-hosted PostHog:
POSTHOG_HOST="https://posthog.example.com"

Intercom (Customer Support)

.env
# Enable Intercom widget
IS_INTERCOM_ENABLED="1"

# Intercom App ID
INTERCOM_APP_ID="your-intercom-app-id"

Performance Settings

Gunicorn Workers

.env
# Number of Gunicorn worker processes
GUNICORN_WORKERS=1
Recommended: (2 x CPU_CORES) + 1

Debug Mode

.env
# Enable debug mode (0 = disabled, 1 = enabled)
DEBUG=0
Never enable debug mode in production. It exposes sensitive information and impacts performance.

Deprecated Settings

These settings are kept for backward compatibility:
.env
# Deprecated - Docker environment indicator
DOCKERIZED=1

# Deprecated - Use LLM_API_KEY instead
OPENAI_API_KEY="sk-"
OPENAI_API_BASE="https://api.openai.com/v1"
GPT_ENGINE="gpt-3.5-turbo"

Environment Variables Reference Table

VariableRequiredDefaultDescription
WEB_URLYeshttp://localhostBase URL for web app
CORS_ALLOWED_ORIGINSYeshttp://localhostCORS origins (must match WEB_URL)
POSTGRES_PASSWORDYesplanePostgreSQL password
POSTGRES_USERNoplanePostgreSQL username
POSTGRES_DBNoplanePostgreSQL database name
REDIS_HOSTNoplane-redisRedis hostname
SECRET_KEYYesAuto-generatedDjango secret key
USE_MINIONo1Use bundled MinIO (1) or external S3 (0)
AWS_ACCESS_KEY_IDYesaccess-keyS3/MinIO access key
AWS_SECRET_ACCESS_KEYYessecret-keyS3/MinIO secret key
EMAIL_HOSTNoEmptySMTP server hostname
ENABLE_SIGNUPNo1Allow new user registrations
IS_GOOGLE_ENABLEDNo0Enable Google OAuth
IS_GITHUB_ENABLEDNo0Enable GitHub OAuth
FILE_SIZE_LIMITNo5242880Max file size (bytes)
LISTEN_HTTP_PORTNo80HTTP port
LISTEN_HTTPS_PORTNo443HTTPS port

Applying Configuration Changes

1

Edit Configuration

nano plane-app/plane.env
2

Restart Services

Docker Compose:
./setup.sh
# Select option 4 (Restart)
Or directly:
cd plane-app
docker compose down
docker compose up -d
Kubernetes:
# Update values.yaml, then:
helm upgrade plane makeplane/plane-ce -n plane -f values.yaml
3

Verify Changes

Check logs:
docker compose logs api | grep "loaded with value"

Next Steps

Instance Admin

Learn how to set up and manage instance administrators

Build docs developers (and LLMs) love