# Plane project management

Source: https://docs.quake.ai/resources/iac-templates/plane-project-management
Markdown: https://docs.quake.ai/resources/iac-templates/plane-project-management.md

---

# Plane project management

This pattern composes Compute, Network, and Block Storage into a self-hosted project and work-management platform you run on infrastructure you control.

## What this template does

Provisions a single instance running [Plane](https://plane.so), an open-source project-management platform (a self-hosted alternative to Linear or Jira). Your team tracks issues, cycles, and projects on infrastructure you own:

- Compute instance that runs Plane's app, worker, and proxy containers in Docker alongside bundled PostgreSQL, Redis, RabbitMQ, and MinIO (8 vCPU and 8 GiB RAM)
- Private network, subnet, router, port, and security group; a floating IP for public access
- A block volume mounted at `/var/lib/docker`, so the database, queue, and file-upload data live on a volume you can grow rather than on the boot disk
- cloud-init installs Docker Engine, brings up PostgreSQL, Redis, RabbitMQ, and MinIO, and prepares Plane's app containers to start once you finish configuration

Plane's `SECRET_KEY`, the PostgreSQL password, the RabbitMQ password, and the MinIO root credentials are generated on first boot and written to `/opt/plane/.env`; no credential ships with this template.

## A heavier stack than the other ops tools in this library

Plane bundles four datastores (PostgreSQL, Redis, RabbitMQ, and MinIO for file uploads) plus its own six app containers (web, space, admin, api, worker, beat-worker) and a realtime service (live), fronted by Plane's own proxy container. This is a heavier footprint than the other self-hosted ops tools already in this library ([Infisical](/resources/iac-templates/infisical-secrets), [Outline](/resources/iac-templates/outline-docs), [Uptime Kuma](/resources/iac-templates/uptime-kuma)). Plane's own documentation recommends 4 vCPU and 8 GiB RAM at minimum; the default `s1a.large` flavor here provides 8 vCPU and 8 GiB RAM.

## Parameters

| Parameter | Description | Default |
| --- | --- | --- |
| `key_name` | SSH keypair name (must already exist) | No default |
| `flavor_name` | Instance size (Plane's bundled datastores plus its app and proxy containers run on 8 vCPU / 8 GiB) | `s1a.large` |
| `image_name` | Operating system image | `Ubuntu-24.04` |
| `app_name` | Display name prefix for resources | `plane` |
| `volume_size` | Block volume size in GiB, mounted at `/var/lib/docker` | `40` |
| `external_network` | External network for floating IP allocation | `PublicStatic` |
| `private_cidr` | CIDR for the private subnet | `10.51.0.0/24` |
| `app_allowed_cidr` | CIDR allowed to reach Plane's proxy on port 8080 | `10.51.0.0/24` |

## Finish setup after apply

cloud-init starts PostgreSQL, Redis, RabbitMQ, and MinIO, and writes the generated secrets to `/opt/plane/.env`. Complete the setup over SSH:

1. Point a domain's DNS A record at the floating IP and put a reverse proxy (Caddy or Nginx) in front for HTTPS on 443.
2. Edit `/opt/plane/.env`: set `WEB_URL` and `CORS_ALLOWED_ORIGINS` to your public HTTPS address.
3. Run the one-shot database migration, create the MinIO uploads bucket, then start Plane:

```bash
cd /opt/plane
docker compose run --rm migrator
docker compose exec plane-minio mc alias set local http://plane-minio:9000 plane YOUR_MINIO_PASSWORD
docker compose exec plane-minio mc mb local/uploads
docker compose up -d
```

## Access and security

Plane's proxy container listens on port 8080 over plain HTTP, remapped from its default 80/443 so a host-level reverse proxy can own those ports for the public domain. The security group restricts 8080 to `app_allowed_cidr`, which defaults to the private network only. Because Plane needs a public URL for auth callbacks and workspace links, the normal access path is a domain with HTTPS on 443 behind a reverse proxy. Ports 80 and 443 stay open for that proxy; they carry no traffic until you add one.

## When to use this pattern

Track issues, cycles, modules, and views for a team on a host you operate. The bundled PostgreSQL, Redis, RabbitMQ, and MinIO suit a single-team deployment; to run PostgreSQL separately, point Plane's `PGHOST`/`POSTGRES_*` variables at a [self-managed PostgreSQL](/resources/iac-templates/self-managed-postgres) instance and remove the bundled `plane-db` service from the compose file.

## Estimated cost

<PricingCompanion
  components={[
    { kind: "template", slug: "plane-project-management", required: true },
  ]}
/>

## Template source

<TemplateSource slug="plane-project-management" />

<TemplateResourceMap template="plane-project-management" format="opentofu" />

## Customize this pattern

- [Customize a template's image and flavor](/docs/automation/how-to/customize-template-image-flavor)
- [Add a block volume to a template](/docs/automation/how-to/add-volume-to-template)
- [Parameterize a template with a tfvars file](/docs/automation/how-to/parameterize-template-tfvars)

## See also

- [Self-managed PostgreSQL](/resources/iac-templates/self-managed-postgres)
- [Redis](/resources/iac-templates/redis-cache)
- [Infisical secrets management](/resources/iac-templates/infisical-secrets)
