Plane - Hardened Self-Hosted Project Management
بواسطة Lynxroute
Plane 1.4.2 - CIS Level 1 hardened project management on Ubuntu 24.04 LTS with SBOM + CIS
What is Plane
Plane is an open-source project management platform built around issues, cycles, modules, projects and pages. It covers the planning surface for software and operations teams - issues with custom properties, sprint-like cycles, multi-issue modules, kanban, list, Gantt and spreadsheet views, recurring schedules, Git and Slack integrations, and a REST API for automation. Workspaces are self-contained: invite teammates, define roles, and own the data. The stack ships a Django REST API and Celery workers, a Next.js dashboard, a public space view, an admin setup UI, a WebSocket server for collaborative page editing, plus PostgreSQL 15, Valkey 7, a task broker and an S3-compatible object store for attachments. AGPL-3.0 license, no vendor lock-in.
Why self-host Plane
Self-hosting keeps every project, issue, attachment and audit log inside your own Azure tenant - no per-seat SaaS fee, no third-party visibility into roadmap and sprint data. Suits teams with data residency requirements under HIPAA or GDPR, and engineering groups that want a Jira/Asana alternative they can extend through the REST API.
What this VM image adds
Security hardening:
- Per-instance Postgres, broker, object store, Django SECRET_KEY and Live HMAC secret generated at first boot - no shared defaults across deployments
- No admin baked into the VM - the first signup at the setup URL becomes the Instance Admin and workspace owner; a background service detects the first admin in the database and finalises instance state automatically
- All product and backing-store container images pinned by SHA-256 digest with explicit linux/amd64 platform - reproducible builds, no surprise upgrades on rebuild
- Every container binds to 127.0.0.1 only - Nginx is the sole public-facing endpoint on TCP 443
- Nginx reverse proxy with TLS - HTTP to HTTPS redirect, hardened cipher suite, WebSocket pass-through for collaborative editing, 25 MB upload limit, branded loading splash served while the stack warms up
- No provider keys baked in - configure SMTP, OAuth and webhook integrations through workspace settings after first login
- UFW firewall, fail2ban, AppArmor; CVE scan with Trivy before every release; Certbot pre-installed for Let's Encrypt
OS hardening (CIS Level 1):
- CIS Ubuntu 24.04 LTS Level 1 Benchmark via ansible-lockdown
- auditd, SSH key-only access, kernel hardening (SYN cookies, ASLR, rp_filter, TCP BBR), /tmp as tmpfs (nosuid, nodev, noexec)
- Azure IMDS endpoints - egress rules pre-configured (169.254.169.254, 168.63.129.16)
Compliance artifacts (inside the VM):
- SBOM - CycloneDX 1.6 at /etc/lynxroute/sbom.json with SHA-256 of the Plane backend image and NTIA-compliant supplier metadata
- CIS Conformance Report - OpenSCAP HTML at /etc/lynxroute/cis-report.html
- Tailored CIS profile - /usr/share/doc/lynxroute/CIS_TAILORED_PROFILE.md
- Server credentials file - /root/plane-credentials.txt with web UI URLs, backing-store passwords for operator reference, and stack-management commands
Quick Start
- Deploy VM from Azure Marketplace (Standard_D2s_v3 or larger - the eleven-container stack needs 8 GB RAM)
- Open NSG: TCP 443 from YOUR IP/32 only until you have registered the first admin; TCP 80 for Let's Encrypt; TCP 22 from your management IPs
- SSH: ssh -i key.pem azureuser@<PUBLIC_IP>; then sudo cat /root/plane-credentials.txt for web UI URLs and operator reference
- Open https://<PUBLIC_IP>/god-mode/, accept the self-signed certificate, and register with YOUR real email and a strong password - first signup becomes the Instance Admin (zxcvbn score 3 or above)
- Within ~30 seconds the setup wizard closes automatically; open https://<PUBLIC_IP>/ to create your first workspace
- In Settings -> Email configure SMTP if you need workspace invitations and password resets (registration still works without SMTP)
- Replace the self-signed TLS certificate with a CA-signed certificate using Certbot or another ACME client; after the cert is issued set WEB_URL in /opt/plane/.env to your HTTPS domain so OAuth callbacks, email links and presigned upload URLs use the new hostname
Persistent storage lives at /opt/plane/{db,redis,rabbitmq,uploads} - attach an Azure Managed Disk to any of those for production workspaces.