To self-host Plane, create five dictionary secrets, Control Plane secrets of named key-value pairs (application keys plus the PostgreSQL, Redis, RabbitMQ and object store logins), and install the Plane template from the Template Catalog, Control Plane’s library of ready-to-install apps. You get Plane Community Edition with its database, cache, broker and attachment store, closed to the internet until you claim the admin account and turn on public access.
Plane is an open-source project tracker and a Jira and Linear alternative: work items, cycles, modules, views, roadmaps and project pages. It has more than 62,000 GitHub stars from teams that want every ticket, estimate and roadmap in a database they control. Self-hosting it is a bigger job than it looks: six HTTP services, Celery workers, a scheduler, PostgreSQL, Redis, RabbitMQ and an object store, and the first person to open /god-mode becomes the instance admin. The template installs the whole stack closed to the internet, gives you that first visit, and keeps every password out of your Helm values.
Why self-host Plane on Control Plane
- The whole tracker from one chart. Web tier, workers, scheduler, database, cache, broker and storage arrive together.
-
Nobody else can claim your instance. Plane has no bootstrap login, so the install starts with public access off. You create the admin through a
cpln port-forwardtunnel from Control Plane’scplnCLI, then publish. - Five secrets, no passwords in values. Signing keys and every datastore login sit in Control Plane secrets the chart reads by name.
-
An identity that reads only those secrets. Every Plane workload runs as one Control Plane identity, and a Control Plane policy grants it
revealon exactly the secrets this release uses, plusviewon the Global Virtual Cloud (GVC), Control Plane’s term for the set of locations a workload runs in. -
Datastores on private DNS. PostgreSQL, Redis and RabbitMQ accept no internet traffic and, by default, answer only to workloads in the same GVC, on
cpln.localnames.
Included out of the box
- Plane Community Edition v1.4.3 (AGPL-3.0)
- One workload with six containers (Caddy proxy, web, space, admin, live, api); only the proxy has a port
- Celery workers for notifications, activity, imports, exports and invites
- A one-replica scheduler that also applies the database migrations
- PostgreSQL 16, Valkey 8.1 and RabbitMQ 4.3, each on its own volume set, Control Plane’s managed persistent storage for a workload
- A single-node object store for attachments (Silo, a maintained MinIO fork), or your S3 bucket
- Built-in Control Plane logs and metrics, with tracing available to turn on
Which Plane features the Community Edition includes
Plane’s self-hosted editions are the Community Edition and the Commercial Edition, which also ships as an Airgapped Edition. The Community Edition is AGPL-3.0 and, per Plane’s docs, matches the Free tier of Plane Cloud: work items, cycles, modules, views, estimates and project pages. Paid plans (Pro, Business and Enterprise) require Plane’s closed-source Commercial Edition, which this template does not install, so features such as the workspace wiki, time tracking, dashboards and the GitHub and Slack integrations are outside it.
How to claim Plane before it goes public
Whoever opens /god-mode first becomes the admin, so publicAccess.enabled starts at false. Run cpln port-forward RELEASE_NAME-plane 8080:80 --gvc GVC_NAME, open localhost:8080/god-mode/ and create the instance admin, then create your workspace at localhost:8080.
Set up email (required for invites, notifications and sign-in codes) and sign-in methods in God Mode while the instance is still private. Check two defaults before you publish: Allow anyone to sign up is on, so any email address that reaches a public Plane can register itself, and Plane sends usage telemetry to telemetry.plane.so until you turn it off under General. Then run cpln helm upgrade with your install values plus publicAccess.enabled=true. The public firewall can take a few minutes to open.
How Plane keeps its keys and passwords
SECRET_KEY signs sessions and encrypts the SMTP password and OAuth client secrets God Mode stores. It sits in a dictionary secret with the live server’s key. Back it up outside Control Plane and never replace it: a new key signs everyone out and makes those settings unreadable.
The database, Redis and RabbitMQ logins go into connection URLs, so use only letters, digits, -, _ and .. Secrets are read when a replica starts: after changing one, run cpln workload force-redeployment on the Plane workloads and the datastore that uses it. PostgreSQL and RabbitMQ create their users on first start only, so a new password in the secret does not change the login inside the datastore.
How to store Plane attachments in S3
The bundled object store needs no cloud account. To use S3, set storage.type: s3. For AWS S3, name a Control Plane cloud account (storage.s3.cloudAccountName) and a bucket-scoped IAM policy (storage.s3.policyName); no AWS access keys go into a secret. For an S3-compatible server (MinIO, SeaweedFS, or Google Cloud Storage with an HMAC key), set storage.s3.endpoint and keep the keys in a secret. Browsers upload and download directly with presigned URLs, so the bucket needs the CORS rule from the template docs, and the endpoint must be a URL your users’ browsers can reach.
How to back up Plane
The template schedules no backups. Plane supports PostgreSQL 15 and 16, and the Template Catalog’s scheduled PostgreSQL backups and highly available PostgreSQL both need version 17, so the bundled database stays on 16 without either. Dump it with pg_dump, using the username and database values from your credentials secret:
cpln workload exec RELEASE_NAME-postgres --gvc GVC_NAME --container postgresql --quiet \
-- sh -c 'pg_dump -U USERNAME -Fc DATABASE | base64' | base64 -d > dump.pgc
Attachments are missing from that dump. Snapshot the bundled store’s volume set with cpln volumeset snapshot create, or back up an S3 bucket with your provider’s tools, and keep a copy of SECRET_KEY with your backups. The template documents no restore procedure, so test yours.
How to scale Plane on Control Plane
Set plane.replicas for the six-container HTTP tier and worker.replicas for the Celery workers. With two or more plane.replicas, Plane stays up through a rolling restart. For heavier background jobs, raise worker.concurrency together with worker.resources.maxMemory. The scheduler always runs one replica so periodic tasks do not run twice.
PostgreSQL, Redis, RabbitMQ and the object store are single instances with no failover. Plane runs in one location: install it into a GVC with one location and set location to it. The Plane workloads start nothing in other locations, but the bundled PostgreSQL is not pinned and starts a separate copy in every other location of the GVC.
How to deploy Plane on Control Plane
Sign up for Control Plane, then create a GVC with one location. Create the five dictionary secrets first: without them the deployment never turns ready and logs nothing. Then pick Plane from the Template Catalog in the Control Plane Console, or install it with the CLI:
cpln helm install RELEASE_NAME oci://ghcr.io/controlplane-com/templates/plane \
--version 1.0.0 --gvc GVC_NAME \
--set location=LOCATION_NAME \
--set secrets.name=APP_KEYS_SECRET_NAME \
--set postgres.config.credentialsSecretName=DB_CREDENTIALS_SECRET_NAME \
--set redis.credentialsSecretName=REDIS_SECRET_NAME \
--set rabbitmq.credentialsSecretName=MQ_SECRET_NAME \
--set storage.minio.credentialsSecretName=MINIO_SECRET_NAME
The first install applies the database migrations before the API turns ready, so allow several minutes. The Plane template documentation has each secret’s command and covers email, OAuth sign-in, webhooks, S3 and troubleshooting.
FAQ
Answers to common questions about running the Plane project tracker on Control Plane.
How do I self-host Plane?
Create five dictionary secrets, install the Plane template from the Template Catalog in the Control Plane Console or with cpln helm install, claim the admin account over cpln port-forward, then turn on public access.
Is Plane free to self-host?
Yes. Plane Community Edition is open source under AGPL-3.0 and needs no Plane license. You pay Control Plane for the resources the stack uses.
Does the Plane template include Plane’s paid features?
No. It runs the Community Edition, which matches Plane Cloud’s Free tier. Paid-plan features such as the workspace wiki and integrations need Plane’s closed-source Commercial Edition.
How do I create the first Plane admin securely?
With public access off, run cpln port-forward RELEASE_NAME-plane 8080:80 --gvc GVC_NAME and complete localhost:8080/god-mode/ before you publish. The first person to finish it becomes the instance admin.
How do I stop strangers from signing up to my Plane instance?
Turn off Allow anyone to sign up under God Mode, Authentication, before you set publicAccess.enabled=true. With it off, only invited users can join.
How do I back up Plane?
Run pg_dump against the bundled PostgreSQL with cpln workload exec, and back up attachments separately from the object store’s volume set or your S3 bucket. The template schedules no backups.
Can I run Plane on Kubernetes?
Yes, without operating a cluster: Control Plane runs the template’s workloads for you. It can also run workloads on a cluster you already have through Control Plane’s BYOK (bring your own Kubernetes).
Does Plane on Control Plane scale?
The web tier and workers do, through plane.replicas and worker.replicas. The scheduler and the datastores stay single instances.
Can Plane run in more than one location?
No. Plane runs in one location per install, so use a GVC with one location. A second location would start an extra copy of the bundled PostgreSQL.
Originally published on the Control Plane blog.
Top comments (0)