Add planka.md documentation for Planka deployment playbook

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lorentz 2026-04-07 12:55:35 -04:00
parent ed3d5833b7
commit f4d33ac457

105
playbooks/planka.md Normal file
View file

@ -0,0 +1,105 @@
# Planka Kanban Board Playbook
## Overview
`planka.yml` deploys [Planka](https://planka.app), a self-hosted kanban board application. The playbook provisions a Postgres database and the Planka app container via Docker Compose, generates and persists cryptographic secrets, and registers the stack on the `pangolin` overlay network for reverse-proxy access.
## Architecture
```
┌─────────────────────────────────┐ ┌──────────────────────────┐
│ Target Docker Host │ │ Pangolin Server │
│ │ │ pangolin.wulfconsulting │
│ ┌─────────────┐ planka_net │ │ .cloud │
│ │ planka_app │◀──────────────▶│ │ │
│ │ (planka) │ :3000→1337 │ pangolin│ Routes traffic to │
│ └──────┬──────┘ network ─────────────▶│ planka.<domain>
│ │ │ └──────────────────────────┘
│ ┌──────▼──────┐ │
│ │ planka- │ │
│ │ postgres │ │
│ │ (pg 16) │ │
│ └─────────────┘ │
│ │
│ /opt/stacks/planka/ │
│ ├── compose.yaml │
│ └── .secrets (mode 0600) │
└─────────────────────────────────┘
```
### Playbook structure
| Section | Purpose |
|---------|---------|
| **vars** | Sets stack directory, Planka version, port, base URL, admin credentials, and secret-rotation flag |
| **pre_tasks** | Validates admin password is not default, checks `planka_base_url` is set, verifies Docker is running, ensures `pangolin` Docker network exists |
| **tasks** | Creates stack directory, generates/persists/reads cryptographic secrets, renders `compose.yaml`, deploys via `docker_compose_v2`, health-checks the HTTP endpoint, prints a deployment summary |
| **handlers** | Restarts the Planka stack when `compose.yaml` changes |
Secrets (`SECRET_KEY` and `INTERNAL_ACCESS_TOKEN`) are generated on first run and stored in `/opt/stacks/planka/.secrets` (root-only, mode `0600`). Subsequent runs re-use the persisted values unless `planka_rotate_secrets: true` is passed.
## Usage
### Required extra vars
| Variable | Description |
|----------|-------------|
| `planka_admin_password` | Admin account password — must not be the default `ChangeMe123!` |
| `planka_base_url` | Public URL Planka will be accessed at (used in auth cookies and links) |
### Optional extra vars
| Variable | Default | Description |
|----------|---------|-------------|
| `planka_version` | `2.0.0-rc.3` | Planka image tag |
| `planka_port` | `3000` | Host port mapped to the Planka container |
| `planka_trust_proxy` | `false` | Set `true` when behind a reverse proxy (enables real-IP headers) |
| `planka_token_expires_in` | `365` | Session token lifetime in days |
| `planka_log_level` | `warn` | Planka log verbosity (`debug`, `info`, `warn`, `error`) |
| `planka_db_name` | `planka` | Postgres database name |
| `planka_admin_email` | `admin@example.com` | Admin account e-mail |
| `planka_admin_name` | `Planka Admin` | Admin display name |
| `planka_admin_username` | `admin` | Admin username |
| `planka_rotate_secrets` | `false` | Set `true` to force regeneration of `SECRET_KEY` and `INTERNAL_ACCESS_TOKEN` |
### Deploy to a host
```bash
ansible-playbook playbooks/planka.yml --limit myhost \
-e planka_admin_password=SuperSecret99! \
-e planka_base_url=https://planka.wulfconsulting.cloud
```
### Override image version and port
```bash
ansible-playbook playbooks/planka.yml --limit myhost \
-e planka_admin_password=SuperSecret99! \
-e planka_base_url=https://planka.wulfconsulting.cloud \
-e planka_version=latest \
-e planka_port=3001
```
### Rotate secrets on an existing deployment
```bash
ansible-playbook playbooks/planka.yml --limit myhost \
-e planka_admin_password=SuperSecret99! \
-e planka_base_url=https://planka.wulfconsulting.cloud \
-e planka_rotate_secrets=true
```
### Verify the containers are running
```bash
ansible myhost -a "docker ps --filter name=planka"
```
## Notes
- **`planka_base_url` is required.** Planka embeds this URL in auth tokens and e-mail links; an incorrect value will break logins from behind a proxy.
- **`planka_trust_proxy: true` is needed behind Pangolin/Traefik.** Without it, Planka sees the proxy's IP instead of the real client IP.
- **Admin credentials are first-run only.** `DEFAULT_ADMIN_*` env vars only take effect when Planka initialises a fresh database. Changing them after the first deploy has no effect; use the Planka UI instead.
- **Secrets are host-side persistent.** `/opt/stacks/planka/.secrets` survives container re-creation. Use `planka_rotate_secrets=true` only when intentionally invalidating all active sessions.
- **`--limit` is required.** The playbook targets `all` hosts; always scope it to the intended host.
- **Postgres data is in a named Docker volume** (`db-data`). Destroying the stack with `docker compose down -v` will wipe the database.