# Plane.so

> Open-source project management and issue tracking for modern software teams

## Overview

| Property | Value |
|----------|-------|
| **Category** | Productivity / Project Management |
| **Host** | guava (TrueNAS Scale) |
| **Stack Name** | plane-stack |
| **Portainer ID** | 26 |
| **Status** | ✅ Active |
| **Domain** | guava.crista.home |

## Access

| Type | URL |
|------|-----|
| **HTTP** | **http://guava.crista.home:3080** ← Primary |
| **HTTPS** | https://guava.crista.home:3443 |
| **Admin** | First registered user becomes admin |

## Features

- 📋 **Issue Tracking** - Create, organize, and track issues with custom workflows
- 📊 **Multiple Views** - Kanban boards, lists, calendars, and Gantt charts
- 🔄 **Cycles** - Sprint/iteration planning and management
- 📁 **Modules** - Group related issues into feature modules
- 📄 **Pages** - Documentation and wiki functionality
- 🤖 **AI Integration** - Optional AI-powered features (requires OpenAI API key)
- 🔗 **Integrations** - GitHub, GitLab, Slack support
- 📱 **Responsive** - Works on desktop and mobile

## Architecture

```
┌─────────────────────────────────────────────────────────────────┐
│                        plane-proxy (Caddy)                      │
│                     Port 3080 (HTTP) / 3443 (HTTPS)            │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐            │
│  │plane-web│  │ space   │  │  admin  │  │  live   │            │
│  │Frontend │  │ Public  │  │  Panel  │  │Realtime │            │
│  └────┬────┘  └────┬────┘  └────┬────┘  └────┬────┘            │
│       │            │            │            │                  │
│       └────────────┴────────────┴────────────┘                  │
│                           │                                     │
│                    ┌──────┴──────┐                              │
│                    │  plane-api  │                              │
│                    │  (Django)   │                              │
│                    └──────┬──────┘                              │
│                           │                                     │
│       ┌───────────────────┼───────────────────┐                │
│       │                   │                   │                 │
│  ┌────┴────┐        ┌─────┴─────┐       ┌────┴────┐            │
│  │plane-db │        │plane-redis│       │plane-mq │            │
│  │Postgres │        │  Valkey   │       │RabbitMQ │            │
│  └─────────┘        └───────────┘       └─────────┘            │
│                           │                                     │
│                    ┌──────┴──────┐                              │
│                    │plane-minio  │                              │
│                    │ File Store  │                              │
│                    └─────────────┘                              │
└─────────────────────────────────────────────────────────────────┘
```

## Services

| Container | Image | Purpose | Health |
|-----------|-------|---------|--------|
| plane-proxy | plane-proxy:stable | Caddy reverse proxy | Up |
| plane-web | plane-frontend:stable | React frontend | Healthy |
| plane-admin | plane-admin:stable | Admin dashboard | Healthy |
| plane-space | plane-space:stable | Public issue pages | Healthy |
| plane-live | plane-live:stable | WebSocket server | Up |
| plane-api | plane-backend:stable | Django REST API | Up |
| plane-worker | plane-backend:stable | Celery worker | Up |
| plane-beat | plane-backend:stable | Celery beat scheduler | Up |
| plane-migrator | plane-backend:stable | DB migrations | Completed |
| plane-db | postgres:15.7-alpine | PostgreSQL database | Healthy |
| plane-redis | valkey:7.2.11-alpine | Cache & sessions | Up |
| plane-mq | rabbitmq:3.13.6-management | Message queue | Up |
| plane-minio | minio:latest | S3-compatible storage | Up |

## Data Persistence

All data is stored on the ZFS pool at `/mnt/data/plane-data/`:

| Directory | Purpose | Backup Priority |
|-----------|---------|-----------------|
| `postgres/` | PostgreSQL database | 🔴 Critical |
| `minio/` | File uploads & attachments | 🔴 Critical |
| `redis/` | Session cache | 🟡 Medium |
| `rabbitmq/` | Message queue state | 🟢 Low |

### Backup Recommendations

```bash
# Database backup
sudo docker exec plane-db pg_dump -U plane plane > plane_backup_$(date +%Y%m%d).sql

# Full data backup
sudo tar -czf plane_data_$(date +%Y%m%d).tar.gz /mnt/data/plane-data/
```

## Configuration

### Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `WEB_URL` | http://localhost:3080 | Public URL for the application |
| `APP_DOMAIN` | localhost | Domain for cookies/CORS |
| `SECRET_KEY` | (generated) | Django secret key |
| `POSTGRES_PASSWORD` | planeSecure2024! | Database password |
| `RABBITMQ_PASSWORD` | planeRabbit2024! | Message queue password |
| `AWS_ACCESS_KEY_ID` | planeaccess | MinIO access key |
| `AWS_SECRET_ACCESS_KEY` | planesecret123 | MinIO secret key |
| `FILE_SIZE_LIMIT` | 52428800 | Max upload size (50MB) |

### Custom Domain Setup

To use a custom domain:

1. Update environment variables in Portainer:
   ```
   WEB_URL=https://plane.yourdomain.com
   APP_DOMAIN=plane.yourdomain.com
   ```

2. Configure DNS to point to guava (192.168.0.100)

3. Set up SSL certificate (Caddy auto-provisions Let's Encrypt)

## Operations

### Start/Stop via Portainer API

```bash
# Stop stack
curl -sk -X POST \
  -H 'X-API-Key: "REDACTED_API_KEY" \
  'https://192.168.0.100:31015/api/stacks/26/stop?endpointId=3'

# Start stack
curl -sk -X POST \
  -H 'X-API-Key: "REDACTED_API_KEY" \
  'https://192.168.0.100:31015/api/stacks/26/start?endpointId=3'
```

### View Logs

```bash
# Via SSH to guava
ssh guava "sudo docker logs plane-api --tail 100"
ssh guava "sudo docker logs plane-worker --tail 100"

# All containers
ssh guava "sudo docker compose -f /data/compose/26/docker-compose.yml logs -f"
```

### Update to Latest Version

1. Stop the stack in Portainer
2. Pull new images:
   ```bash
   ssh guava "sudo docker compose -f /data/compose/26/docker-compose.yml pull"
   ```
3. Start the stack in Portainer

### Health Check

```bash
# API health
curl -s http://guava.crista.home:3080/api/v1/health/

# Database connection
ssh guava "sudo docker exec plane-db pg_isready -U plane"

# Redis connection  
ssh guava "sudo docker exec plane-redis redis-cli ping"
```

## Troubleshooting

### API Not Starting

Check if migrations completed:
```bash
ssh guava "sudo docker logs plane-migrator"
```

The API waits for migrations. If stuck, check database connectivity.

### Space Service Unhealthy

This is normal during initial startup. The space service takes longer to initialize. Wait 2-3 minutes after deployment.

### File Uploads Failing

Check MinIO status:
```bash
ssh guava "sudo docker logs plane-minio"
ssh guava "curl -s http://localhost:9000/minio/health/live"
```

### Performance Issues

Plane is resource-intensive. Recommended minimums:
- 4 CPU cores
- 8GB RAM
- SSD storage

## Security Considerations

- 🔐 Default passwords should be changed for production use
- 🔒 HTTPS is available on port 3443 (self-signed cert by default)
- 🛡️ Consider putting behind Cloudflare Tunnel or reverse proxy
- 📝 First user to register becomes admin

## Related Files

- Stack Definition: [`hosts/physical/guava/plane.yaml`](../../../hosts/physical/guava/plane.yaml)
- Host Documentation: [`hosts/physical/guava/README.md`](../../../hosts/physical/guava/README.md)

## External Links

- [Plane.so Website](https://plane.so)
- [Plane GitHub](https://github.com/makeplane/plane)
- [Self-Hosting Docs](https://developers.plane.so/self-hosting)
- [Docker Compose Guide](https://developers.plane.so/self-hosting/methods/docker-compose)

---

*Deployed: February 2026 | Managed via Portainer on guava*
