Overview
Plane is an open-source project tracker, a Jira and Linear alternative: work items, cycles, modules, roadmaps and wiki pages with a real-time collaborative editor. This template deploys Plane Community Edition with its PostgreSQL, Redis, RabbitMQ and an object store for attachments (bundled, or your own AWS S3 or S3-compatible bucket). Plane runs in exactly one location of your GVC and installs private: you claim the instance in God Mode over a port-forward, then publish.location you set must already be one of that GVC’s locations; if it is not, the Plane workloads start nothing.What Gets Created
Prerequisites
A GVC with one location, and these dictionary secrets created before you install. The database, Redis and RabbitMQ values go into connection URLs, so use letters, digits,-, _ and . only. Secret names are org-wide, so give each release its own.
Create the application keys secret
secrets.name to this name. SECRET_KEY signs sessions and encrypts the instance settings Plane stores (SMTP password, OAuth secrets), so back it up outside Control Plane and never replace it: replacing it signs everyone out and makes those settings unreadable.Create the database credentials secret
postgres.config.credentialsSecretName to this name.Create the Redis password secret
redis.credentialsSecretName to this name.Create the RabbitMQ login secret
rabbitmq.credentialsSecretName to this name. RabbitMQ reads it on its first boot only.Create the object store keys secret
storage.type: minio. accessKey needs 3 or more characters and secretKey 8 or more:storage.minio.credentialsSecretName to this name. For storage.type: s3 see Storage Setup instead.Installation
Once the secrets exist, install from the marketplace registry, pointing each key at its secret andlocation at a location of your GVC:
UI
CLI
Terraform
Pulumi
Configuration
Location and Plane
beat.resources.maxCpu sets how fast they apply. Changing plane.appUrl changes the address every sign-in provider redirects to; see Authentication.
Storage
Datastores
Access
postgres.internalAccess. With workload-list there, list //gvc/GVC_NAME/workload/RELEASE_NAME-plane, RELEASE_NAME-plane-worker and RELEASE_NAME-plane-beat in the same form.
Storage Setup
Only forstorage.type: s3. Browsers upload to and download from the bucket directly, so it needs a CORS rule for your Plane origin (replace PLANE_URL with the instance URL, scheme included):
BUCKET_NAME). Set storage.s3.bucket, region, cloudAccountName and policyName (the IAM policy’s name); leave auth.secretName empty.
storage.s3.bucket, storage.s3.endpoint and storage.s3.auth.secretName to the secret:
endpoint, so it must be a full URL that users’ browsers can reach, such as a public HTTPS endpoint. An internal *.cpln.local address serves the API but not browser uploads and downloads.
Connecting
Plane has no bootstrap credential: whoever completes/god-mode first becomes the instance admin, so the install starts private.
First Run
- Install with
publicAccess.enabled: false(the default) and wait forRELEASE_NAME-planeto become ready. - Run
cpln port-forward RELEASE_NAME-plane 8080:80 --gvc GVC_NAME, openlocalhost:8080/god-mode/in a browser and create the instance admin. Then openlocalhost:8080to create your workspace. - Set up email and sign-in methods in God Mode (below) while the instance is still private.
- Publish with
publicAccess.enabled: true; the public firewall can take a few minutes to open:
God Mode
God Mode (PLANE_URL/god-mode/) holds the instance settings. They are stored in the database, not in chart values, so they survive restarts and upgrades. Sign in with the admin you created in First Run.
SMTP_WORKLOAD_NAME.GVC_NAME.cpln.local; set the security option to match what the relay speaks (none for a plain relay). The SMTP password is encrypted with SECRET_KEY.
Authentication
Under God Mode, Authentication:- Unique codes emails a sign-in code (magic link). It needs Email to be set up first.
- Password sign-in with email and password.
- Allow anyone to sign up is on by default: an unknown email address registers itself. Turn it off to limit access to invited users.
- GitHub, Google and GitLab sign-in each need an OAuth app registered with the provider. God Mode shows the exact callback to register:
PLANE_URL/auth/github/callback/,PLANE_URL/auth/google/callback/orPLANE_URL/auth/gitlab/callback/, plus the origin URL for Google. Enter the client ID and secret in God Mode. Client secrets are stored encrypted.
plane.appUrl to a custom domain, register the new callback with each provider.
General
Under God Mode, General, set the instance name, manage instance admins and turn telemetry off. Plane sends usage telemetry totelemetry.plane.so until you do.
SECRET_KEY encrypts the settings stored here. Never replace it, or the saved SMTP password and OAuth secrets become unreadable.Webhooks and Exports
- Webhooks (workspace settings, Webhooks) must point at a public URL; internal and private addresses, including
*.cpln.localworkloads, are refused. Plane generates each webhook’s signing secret and signs the request body in thex-plane-signatureheader (HMAC-SHA256, hex, keyed with that secret). - Exports appear as download links under workspace settings, Exports. No email is sent.
- Uploads larger than
plane.fileSizeLimitare refused with HTTP 413. The limit counts the whole upload request, so the largest usable file is a couple of kilobytes smaller.
Operations
Backing Up
The bundled PostgreSQL has no scheduled backups here, because Plane runs on PostgreSQL 15 and 16 and the template backups need PostgreSQL 17. Dump the database withpg_dump from the postgresql container, and back up the object store too: attachments live there, not in the database.
username and database values from the database credentials secret. For storage.type: s3, back up the bucket with your provider’s tools; for the bundled store, snapshot its volume set:
Rotating a Secret
Secrets are read when a replica starts, and a paused deployment does not retry on its own. After creating a missing prerequisite secret late, changing one, or an upgrade that changes which secrets the release reads, runcpln workload force-redeployment with --gvc GVC_NAME on RELEASE_NAME-plane, RELEASE_NAME-plane-worker, RELEASE_NAME-plane-beat and the datastore whose secret it is (RELEASE_NAME-postgres, RELEASE_NAME-plane-redis, RELEASE_NAME-plane-mq or RELEASE_NAME-plane-minio):
SECRET_KEY.
Scaling and Availability
plane.replicas and worker.replicas scale freely; with two or more plane.replicas the UI stays up through a rolling restart. The scheduler is always one replica. PostgreSQL, Redis, RabbitMQ and the object store are single instances.
Troubleshooting
Deployment never becomes ready and the logs are empty
Deployment never becomes ready and the logs are empty
cpln helm install reported success, cpln logs returns nothing, and cpln workload get-deployments RELEASE_NAME-plane --gvc GVC_NAME -o yaml names a secret under status.versions[].message.Cause: A prerequisite secret does not exist.Fix: Create it (see Prerequisites), then force a redeployment as in Rotating a Secret.Every Plane workload reports it is deactivated
Every Plane workload reports it is deactivated
deactivated because maxScale is set to 0 and nothing is logged.Cause: location is not one of the GVC’s locations.Fix: Set location to a location your GVC already has and run cpln helm upgrade with your install values.The API stays unready for several minutes after the first install
The API stays unready for several minutes after the first install
RELEASE_NAME-plane is not ready and the api container logs Waiting for database migrations to complete....Cause: RELEASE_NAME-plane-beat applies the migrations on its first start and the API waits for it.Fix: Wait for the scheduler to finish; follow its progress with the command below. If the message never clears, the scheduler is not running: check it and its database credentials.Password authentication failed for the database
Password authentication failed for the database
RELEASE_NAME-plane-beat logs password authentication failed and the API and worker stay unready.Cause: The password in the credentials secret no longer matches the one PostgreSQL initialized with.Fix: Restore the original password in the secret and force a redeployment of RELEASE_NAME-plane, RELEASE_NAME-plane-worker and RELEASE_NAME-plane-beat.Notifications, exports and invites never arrive
Notifications, exports and invites never arrive
RELEASE_NAME-plane-worker, and raise worker.resources.maxMemory together with worker.concurrency.Uploads fail with HTTP 413
Uploads fail with HTTP 413
plane.fileSizeLimit.Fix: Raise plane.fileSizeLimit (bytes) and run cpln helm upgrade with your install values.Render refuses the install
Render refuses the install
cpln helm install fails with a message beginning plane:. The messages and their fixes:plane: `location` is required,plane: `location` must be a single location NAMEandplane: `location` must be a bare location NAME likeaws-us-east-1:locationis empty, a list, or a link form such as//location/aws-us-east-1.plane: `locations` (plural) is not a key of this chart: use the singularlocation.plane: secrets.name is required,plane: redis.credentialsSecretName is required,plane: rabbitmq.credentialsSecretName is required,plane: postgres.config.credentialsSecretName is requiredandplane: storage.minio.credentialsSecretName is required with storage.type minio: a prerequisite secret name is empty.plane: postgres.credentials is not a key of this chart: database credentials are a secret, not values.plane: beat.replicas is not a key of this chart: the scheduler is always one replica.plane: plane.replicas must be at least 1,plane: worker.replicas must be at least 1,plane: worker.concurrency must be at least 1andplane: plane.api.gunicornWorkers must be at least 1: raise the value.plane: plane.appUrl must start with https:// or http://: add the scheme.plane: storage.type must be 'minio' or 's3',plane: storage.s3.bucket is required when storage.type is s3,plane: s3 storage needs credentialsandplane: static keys (storage.s3.auth.secretName) are only for S3-compatible servers: AWS S3 usescloudAccountNameandpolicyName; an S3-compatible server usesendpointandauth.secretName.plane: internalAccess.type `none` would cut the API, worker and scheduler offandplane: postgres.internalAccess.type must not be 'none': usesame-gvcorworkload-list.plane: internalAccess.workloads may only be set when internalAccess.type is `workload-list`: remove the list or switch the type.plane: postgres.internalAccess.type is 'workload-list' but the list does not include: addRELEASE_NAME-plane,RELEASE_NAME-plane-workerandRELEASE_NAME-plane-beat.
Important Notes
- Install into a GVC with one location and set
locationto it; the bundled PostgreSQL is not pinned tolocationand starts a copy in every other location of the GVC. - Claim
/god-modeprivately first: the first visitor becomes the instance admin. - Never replace
SECRET_KEY: it encrypts the stored SMTP and OAuth settings. - Re-register OAuth callbacks whenever the instance URL changes.
- An S3-compatible
storage.s3.endpointmust be reachable from users’ browsers, and the bucket needs the CORS rule above. - No highly available database and no scheduled backups: dump the database with
pg_dumpand back up the object store yourself. - Turn telemetry off in God Mode, General, if you do not want Plane to report usage.
- Plane’s integrations service, Intake and Monitor are not part of the Community Edition.