Docker and Kubernetes Deployment Architecture for Self-Hosting Plane

Plane's self-hosted deployment uses a microservices architecture with five containerized application services (web, admin, space, api, live), three background workers (Celery, beat, migrator), and four infrastructure components (PostgreSQL, Valkey/Redis, RabbitMQ, MinIO), deployable via Docker Compose or the community Helm chart.

The makeplane/plane repository provides complete infrastructure definitions for running the project management platform on your own servers. Whether you choose Docker Compose for single-node deployments or Kubernetes for orchestrated scaling, the Docker and Kubernetes deployment architecture for self-hosting Plane maintains identical service boundaries and environment variable contracts.

Core Application Services

Plane splits its functionality across five distinct application services defined in the root docker-compose.yml. Each service builds from a dedicated Dockerfile in the apps/ directory.

Frontend Services

  • web (apps/web/Dockerfile.web): The main React-based end-user interface serving the project management dashboard on port 80.
  • admin (apps/admin/Dockerfile.admin): A separate React administration UI for system-level configuration.
  • space (apps/space/Dockerfile.space): The React "Space" UI providing distinct workspace functionality.

Backend Services

  • api (apps/api/Dockerfile.api): The Django REST API handling authentication, business logic, and CRUD operations. All frontend services depend on this component.
  • live (apps/live/Dockerfile.live): A WebSocket server that pushes real-time updates to connected clients.

In Docker Compose, these services express startup dependencies using depends_on constraints. The Kubernetes Helm chart translates these into PodAffinity rules ensuring UI pods start only after the API pod reports readiness.

Background Processing Layer

Asynchronous tasks run through Celery workers managed by three distinct deployment patterns:

  • worker (./bin/docker-entrypoint-worker.sh): Standard Celery workers processing async jobs like file uploads and email notifications. In Kubernetes, this maps to a Deployment with configurable replicas for horizontal scaling.
  • beat-worker (./bin/docker-entrypoint-beat.sh): The Celery beat scheduler for periodic tasks (cleanup, analytics). Deployed as a single-replica Deployment.
  • migrator (./bin/docker-entrypoint-migrator.sh): A one-shot database migration job that runs before application startup. In Kubernetes, this implements a Job resource that completes before the main services scale up.

All workers consume environment variables from the same .env file mounted at env_file: - ./apps/api/.env in the Compose configuration.

Data and Infrastructure Stack

Plane requires four stateful infrastructure services for persistence, caching, and messaging:

Service Docker Image Kubernetes Implementation Purpose
plane-db postgres:15.7-alpine StatefulSet + PersistentVolumeClaim (pgdata) Primary relational database for Django models
plane-redis valkey/valkey:7.2.11-alpine StatefulSet + PVC (redisdata) Caching layer and Celery result backend
plane-mq rabbitmq:3.13.6-management-alpine StatefulSet + PVC (rabbitmq_data) Message broker for Celery task queues
plane-minio minio/minio Deployment + PVC (uploads) S3-compatible object storage for file uploads
proxy Custom Nginx (apps/proxy/Dockerfile.ce) Deployment + Service Reverse proxy and TLS termination

The infrastructure services reference a top-level .env file (lines 16-22 in docker-compose.yml) for credentials and connection strings. In Kubernetes, these values migrate to ConfigMap or Secret resources mounted as environment variables.

Kubernetes Implementation with Helm

The community Helm chart located in deployments/kubernetes/community packages Plane for production Kubernetes clusters and publishes to Artifact Hub.

Key Kubernetes Mappings

Docker Compose services translate to specific workload controllers:

  • Stateless Applications (web, admin, space, api, live): Deployment + Service (ClusterIP)
  • Background Workers: Deployment with configurable replicaCount
  • Database Migrations: Job (run-once)
  • Stateful Services (PostgreSQL, Valkey, RabbitMQ): StatefulSet + PersistentVolumeClaim

The values.yaml file in the Helm chart mirrors the Docker Compose environment variables, allowing operators to configure POSTGRES_USER, POSTGRES_PASSWORD, AWS_ACCESS_KEY_ID, and other secrets while tuning resource limits and replica counts.

Networking and Ingress

In Docker environments, all containers share a single Docker network with the proxy container exclusively exposing ports 80 and 443. The Kubernetes chart creates a Service of type LoadBalancer (or NodePort for on-premises clusters) for the proxy deployment. An optional Ingress resource enables hostname-based routing to distinct UI services.

Persistence Configuration

Each stateful component mounts specific PVCs that survive pod restarts:

  • PostgreSQL mounts pgdata at /var/lib/postgresql/data
  • Valkey mounts redisdata at /data
  • RabbitMQ mounts rabbitmq_data at /var/lib/rabbitmq
  • MinIO mounts uploads at /export

All PVCs specify storageClassName matching the cluster's default storage class.

Architecture Flow and Request Path

Understanding the request flow clarifies how components interact in the Docker and Kubernetes deployment architecture for self-hosting Plane:

  1. Ingress/Load Balancer receives external HTTPS traffic and routes to the proxy service.
  2. Proxy terminates TLS and path-routes requests to web, admin, or space services based on URL patterns.
  3. UI Services call the api service for authentication, data access, and business logic operations.
  4. API persists data to PostgreSQL, caches in Valkey/Redis, queues tasks to RabbitMQ, and stores files in MinIO.
  5. Live service subscribes to RabbitMQ topics and pushes real-time updates via WebSockets to connected clients.
  6. Celery Workers consume background jobs from RabbitMQ (e.g., processing file uploads, sending notifications).
  7. Beat Worker schedules periodic maintenance tasks like cleanup and analytics aggregation.

Summary

  • Plane's architecture consists of five application containers (web, admin, space, api, live), three worker types (Celery, beat, migrator), and four infrastructure services (PostgreSQL 15.7, Valkey 7.2, RabbitMQ 3.13, MinIO).
  • The reference implementation uses docker-compose.yml at the repository root, while production Kubernetes deployments use the community Helm chart in deployments/kubernetes/community.
  • Stateful services require PersistentVolumeClaims with pgdata, redisdata, rabbitmq_data, and uploads volumes to ensure data persistence.
  • The proxy container (Nginx) handles external traffic, TLS termination, and internal routing to UI and API services.
  • Environment configuration is unified through .env files in Docker and ConfigMap/Secret resources in Kubernetes.

Frequently Asked Questions

What hardware requirements are needed to self-host Plane?

A minimal production deployment requires 4 vCPU cores and 8GB RAM to run the core services, PostgreSQL, and Redis comfortably. The Kubernetes Helm chart allows resource limits to be tuned per-component in values.yaml, while Docker Compose deployments should ensure the host has sufficient resources for all defined services.

How do I scale background workers in the Kubernetes deployment?

Modify the replicaCount value for the plane-worker deployment in the Helm chart's values.yaml file. The worker deployment uses the same apps/api/Dockerfile.api image but executes ./bin/docker-entrypoint-worker.sh to process Celery tasks. Horizontal scaling adds parallel job processing capacity without affecting the beat-worker or migrator jobs.

Can I use external PostgreSQL or Redis instead of the containerized versions?

Yes. Both the Docker Compose file and Helm chart support external data sources. Remove the plane-db and plane-redis service definitions from Docker Compose, or set enabled: false for these components in the Helm values.yaml. Configure the DATABASE_URL and REDIS_URL environment variables to point to your external managed services.

What is the difference between the Docker Compose and Kubernetes networking models?

Docker Compose creates an isolated bridge network where all containers communicate via internal DNS names, with only the proxy service exposing ports 80/443 to the host. Kubernetes uses ClusterIP services for internal communication, optionally exposing the proxy via LoadBalancer or NodePort services, and supports Ingress resources for HTTP/HTTPS routing based on hostnames and path prefixes.

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 →