Complete Guide to Self-Hosting Plane in Production: Key Configurations and Setup

To self-host Plane in production, configure environment variables in .env (database, Redis, RabbitMQ, MinIO credentials), deploy the multi-service Docker Compose stack, run database migrations, and optionally enable the Caddy reverse proxy for TLS termination.

Plane is an open-source project management platform developed by Makeplane. Self-hosting Plane in production requires orchestrating a full-stack architecture defined in the official docker-compose.yml from the makeplane/plane repository, including PostgreSQL, Valkey (Redis), RabbitMQ, and MinIO services.

Environment Variable Configuration

The .env.example file serves as the definitive blueprint for production settings. All sensitive credentials and endpoint URLs must be declared here before starting the stack.

Critical Secrets and Endpoints

You must define database credentials (POSTGRES_PASSWORD, POSTGRES_USER, POSTGRES_DB), object storage keys (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY), and message broker credentials (RABBITMQ_USER, RABBITMQ_PASSWORD). The SITE_ADDRESS variable is mandatory—it tells Plane which public host and port to bind to (e.g., https://plane.mycompany.com).

Feature Toggles

Set USE_MINIO=1 to utilize the bundled MinIO instance for object storage, or set it to 0 to integrate with external S3-compatible storage. The DOCKERIZED flag remains for backward compatibility with legacy deployment scripts.

Core Services Architecture

The docker-compose.yml defines twelve interconnected services that comprise the Plane application stack:

  • web: Next.js frontend application
  • admin: Django-based administrative interface
  • space: Collaboration and workspace features
  • api: Main Django REST API backend
  • worker: Background task processor
  • beat-worker: Scheduled task runner (celery beat)
  • migrator: Database migration handler (runs once)
  • live: Real-time collaboration server
  • plane-db: PostgreSQL 15.7-alpine database
  • plane-redis: Valkey (Redis fork) for caching and queues
  • plane-mq: RabbitMQ 3.13.6-management-alpine message broker
  • plane-minio: MinIO object storage server
  • proxy (optional): Caddy reverse proxy for TLS termination

Database Layer

The plane-db service runs PostgreSQL 15.7-alpine with persistent storage mounted via the pgdata Docker volume. The database name, user, and password are injected from your .env file into the container environment.

Cache and Message Queue

Valkey (a Redis fork) handles caching, session storage, and background task queues via the plane-redis service. Configure connection parameters using REDIS_HOST and REDIS_PORT environment variables. RabbitMQ manages asynchronous task processing via plane-mq, storing persistent data in the rabbitmq_data volume.

Object Storage

MinIO runs as the plane-minio service, providing S3-compatible object storage. The default bucket name is uploads. The API service uses the same AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY credentials to authenticate upload requests, while FILE_SIZE_LIMIT controls maximum upload sizes.

Reverse Proxy and TLS Termination

The optional proxy service uses Caddy (built from apps/proxy/Dockerfile.ce) to handle SSL/TLS termination. Configure automatic Let's Encrypt certificate issuance by setting CERT_EMAIL and CERT_ACME_CA in your environment. The proxy listens on ${LISTEN_HTTP_PORT} and ${LISTEN_HTTPS_PORT}, forwarding traffic to the appropriate backend services.

If you use an external reverse proxy such as Nginx or Traefik, comment out the proxy service in docker-compose.yml and expose ports 8000 (HTTP) and 8443 (HTTPS) directly from the web container.

Production Deployment Steps

Follow these steps to deploy Plane on your infrastructure:

  1. Prepare environment variables:

    cp .env.example .env
    # Edit .env to set POSTGRES_PASSWORD, AWS_ACCESS_KEY_ID, SITE_ADDRESS, CERT_EMAIL, etc.
    
  2. Launch the stack:

    docker compose -f docker-compose.yml up -d
  3. Run database migrations once the database container is healthy:

    docker compose exec api ./bin/docker-entrypoint-migrator.sh
  4. Verify the deployment by checking for the startup completion message:

    docker compose logs -f api | grep "Application Startup Complete"

For Kubernetes environments, refer to the alternative manifests in deployments/kubernetes/community/README.md.

Key Source Files

  • .env.example: Template for all required environment variables and secrets
  • docker-compose.yml: Primary production orchestration defining all services, volumes, and network configurations
  • setup.sh: Helper script displaying Docker commands for stack management
  • apps/proxy/Dockerfile.ce: Caddy reverse proxy image definition for TLS termination
  • apps/api/.env: API-specific environment configuration (generated from top-level .env)

Summary

  • Environment variables drive all configuration via .env.example, including database credentials, SITE_ADDRESS, and storage keys.
  • Docker Compose orchestrates twelve services including PostgreSQL 15, Valkey, RabbitMQ 3.13, and MinIO.
  • TLS termination is handled by the optional Caddy proxy service with automatic Let's Encrypt support, or disabled for external reverse proxies.
  • Database migrations must be executed manually via ./bin/docker-entrypoint-migrator.sh inside the API container after initial startup.
  • Object storage defaults to MinIO with the uploads bucket, configurable via USE_MINIO for external S3.

Frequently Asked Questions

How do I configure SSL certificates for a self-hosted Plane instance?

Configure the CERT_EMAIL and CERT_ACME_CA environment variables in your .env file, then enable the proxy service in docker-compose.yml. This Caddy-based service automatically provisions and renews Let's Encrypt certificates. If you prefer using Nginx or Traefik, disable the proxy service and expose ports 8000 and 8443 from the web container.

What database version does Plane require for production?

The official docker-compose.yml specifies PostgreSQL 15.7-alpine for the plane-db service. You must use this version or compatible PostgreSQL 15.x releases to ensure compatibility with Plane's schema migrations and query optimizations.

Can I use external Redis or S3 storage instead of the bundled services?

Yes. Set USE_MINIO=0 and provide your external S3 endpoint credentials (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and S3 endpoint URLs) in the .env file. For Redis, modify REDIS_HOST and REDIS_PORT to point to your external Valkey or Redis instance instead of the plane-redis service.

How do I run database migrations when upgrading Plane?

Execute the migration script inside the running API container: docker compose exec api ./bin/docker-entrypoint-migrator.sh. Run this command only once after the database container is healthy and before using the application.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →