Planka
Planka v2.x — Installation Guide
Section titled “Planka v2.x — Installation Guide”Platform: TrueNAS Scale, Arcane Docker Management, Keycloak OIDC
Date: 23 March 2026
Planka version: 2.1.0 (Community Edition)
Contents
Section titled “Contents”- Prerequisites
- Create TrueNAS dataset and directories
- Set permissions
- Create Keycloak client
- Docker Compose file (Arcane)
- Generate secrets
- Deploy in Arcane
- Create admin user
- Configure Pangolin reverse proxy
- Verify OIDC login
- Post-install: disable local auth (optional)
- Backup and restore
- Troubleshooting
1. Prerequisites
Section titled “1. Prerequisites”Before starting, confirm the following are in place.
- TrueNAS Scale with shell access
- Arcane installed and operational for Docker Compose management
- Keycloak running at
https://auth.wighttrash.ukwith thewighttrashrealm configured - Pangolin reverse proxy managing
planka.wighttrash.ukwith a valid TLS certificate - DNS A/CNAME record for
planka.wighttrash.ukpointing to your TrueNAS host (or Pangolin ingress)
2. Create TrueNAS dataset and directories
Section titled “2. Create TrueNAS dataset and directories”Open the TrueNAS shell (or SSH in) and run the following.
# Create the base dataset directory (if the dataset /mnt/tank/configs/planka is already created via the TrueNAS UI, skip this)mkdir -p /mnt/tank/configs/planka
# Create subdirectories for bind mountsmkdir -p /mnt/tank/configs/planka/faviconsmkdir -p /mnt/tank/configs/planka/user-avatarsmkdir -p /mnt/tank/configs/planka/background-imagesmkdir -p /mnt/tank/configs/planka/attachmentsmkdir -p /mnt/tank/configs/planka/db-data3. Set permissions
Section titled “3. Set permissions”Planka runs as the node user inside the container (UID 1000, GID 1000). PostgreSQL runs as UID 999. Both need write access to their respective directories.
# Planka application directorieschown -R 1000:1000 /mnt/tank/configs/planka/faviconschown -R 1000:1000 /mnt/tank/configs/planka/user-avatarschown -R 1000:1000 /mnt/tank/configs/planka/background-imageschown -R 1000:1000 /mnt/tank/configs/planka/attachments
# PostgreSQL data directorychown -R 999:999 /mnt/tank/configs/planka/db-dataIf you have issues with permissions after deployment, the symptom is usually a container restart loop or write errors in the logs. Recheck ownership with ls -la /mnt/tank/configs/planka/.
4. Create Keycloak client
Section titled “4. Create Keycloak client”Log in to Keycloak at https://auth.wighttrash.uk and select the wighttrash realm.
4.1 Create the client
Section titled “4.1 Create the client”- Go to Clients and click Create client.
- Set the following:
- Client type: OpenID Connect
- Client ID:
planka
- Click Next.
- On the Capability config page:
- Client authentication: On
- Authorization: Off
- Standard flow: On (checked)
- Direct access grants: Off
- Click Next.
- On the Login settings page:
- Root URL:
https://planka.wighttrash.uk - Home URL:
https://planka.wighttrash.uk - Valid redirect URIs:
https://planka.wighttrash.uk/oidc-callback - Valid post logout redirect URIs:
https://planka.wighttrash.uk - Web origins:
https://planka.wighttrash.uk
- Root URL:
- Click Save.
4.2 Copy the client secret
Section titled “4.2 Copy the client secret”- Go to the Credentials tab of the
plankaclient. - Copy the Client secret. You will need this for the Docker Compose file.
4.3 Configure the groups claim (optional but recommended)
Section titled “4.3 Configure the groups claim (optional but recommended)”This allows Planka to map Keycloak groups to Planka roles (Admin, Project Owner, Board User). If you skip this step, set OIDC_IGNORE_ROLES=true in the compose file and manage roles manually in Planka.
- Go to Clients > planka > Client scopes tab.
- Click planka-dedicated.
- Click Add mapper > By configuration > Group Membership.
- Configure the mapper:
- Name:
groups - Token Claim Name:
groups - Full group path: Off
- Add to ID token: On
- Add to access token: On
- Add to lightweight access token: Off
- Add to userinfo: On
- Add to token introspection: On
- Name:
- Click Save.
- Create Keycloak groups to match the Planka roles you want to map:
planka-admin(maps to Planka Admin)planka-project-owner(maps to Planka Project Owner)
- Add your users to the appropriate groups.
Users without a matching group claim are assigned the Board User role by default.
5. Docker Compose file (Arcane)
Section titled “5. Docker Compose file (Arcane)”This compose file uses absolute bind mount paths under /mnt/tank/configs/planka/. No relative paths, no named Docker volumes.
Replace the three placeholder values marked with CHANGE_ME before deploying.
services: planka: image: ghcr.io/plankanban/planka:latest restart: unless-stopped volumes: - /mnt/tank/configs/planka/favicons:/app/public/favicons - /mnt/tank/configs/planka/user-avatars:/app/public/user-avatars - /mnt/tank/configs/planka/background-images:/app/public/background-images - /mnt/tank/configs/planka/attachments:/app/private/attachments ports: - "3050:1337" environment: # ── Core ── - BASE_URL=https://planka.wighttrash.uk - DATABASE_URL=postgresql://planka:CHANGE_ME_DB_PASSWORD@planka-db/planka - SECRET_KEY=CHANGE_ME_SECRET_KEY - TRUST_PROXY=true
# ── OIDC (Keycloak) ── - OIDC_ISSUER=https://auth.wighttrash.uk/realms/wighttrash - OIDC_CLIENT_ID=planka - OIDC_CLIENT_SECRET=CHANGE_ME_KEYCLOAK_CLIENT_SECRET - OIDC_SCOPES=openid profile email - OIDC_ADMIN_ROLES=planka-admin - OIDC_PROJECT_OWNER_ROLES=planka-project-owner - OIDC_ROLES_ATTRIBUTE=groups - OIDC_IGNORE_USERNAME=true
# ── Optional: disable local auth once OIDC is confirmed working ── # - OIDC_ENFORCED=true
# ── Optional: debug OIDC (shows raw token payloads on login page) ── # - OIDC_DEBUG=true
# ── Optional: SMTP for email notifications ── # - SMTP_HOST=smtp.example.com # - SMTP_PORT=587 # - SMTP_SECURE=true # - SMTP_PASSWORD=your-smtp-password # - SMTP_FROM="Planka" <[email protected]> depends_on: planka-db: condition: service_healthy
planka-db: image: postgres:16-alpine restart: unless-stopped volumes: - /mnt/tank/configs/planka/db-data:/var/lib/postgresql/data environment: - POSTGRES_DB=planka - POSTGRES_USER=planka - POSTGRES_PASSWORD=CHANGE_ME_DB_PASSWORD healthcheck: test: ["CMD-SHELL", "pg_isready -U planka -d planka"] interval: 10s timeout: 5s retries: 5Important notes:
- The
planka-dbservice name is used in theDATABASE_URL. If you rename it, update the connection string. TRUST_PROXY=trueis required because Pangolin terminates TLS before forwarding to Planka.OIDC_IGNORE_USERNAME=trueis set because Keycloak’spreferred_usernamemay contain characters that Planka’s username validation rejects (e.g.,@).- The
CHANGE_ME_DB_PASSWORDmust be identical in both theplankaandplanka-dbservice environment sections.
6. Generate secrets
Section titled “6. Generate secrets”Run these commands in TrueNAS shell to generate the values needed for the compose file.
# SECRET_KEY (64-character hex string)openssl rand -hex 64
# DB password (32-character alphanumeric)openssl rand -base64 32 | tr -dc 'A-Za-z0-9' | head -c 32Copy the Keycloak client secret from section 4.2.
Replace the three CHANGE_ME placeholders in the compose file with these values.
7. Deploy in Arcane
Section titled “7. Deploy in Arcane”- Open Arcane in your browser.
- Create a new stack or compose deployment.
- Paste the compose file from section 5 (with all three secrets replaced).
- Deploy the stack.
- Wait for both containers to show as healthy. The
planka-dbcontainer must pass its healthcheck beforeplankawill start.
Check the logs if either container fails to start:
# From TrueNAS shell, if Arcane does not show logsdocker logs plankadocker logs planka-db8. Create admin user
Section titled “8. Create admin user”After the containers are running, create the initial admin user. This is a one-time step.
docker exec -it planka npm run db:create-admin-userYou will be prompted for:
Email: [email protected]Password: (choose a strong password)Name: AdminUsername (optional): adminThis local admin account is your fallback if OIDC breaks. Keep the credentials safe.
Note: If Arcane names the container differently (e.g., planka-planka-1), check with docker ps and adjust the command accordingly.
9. Configure Pangolin reverse proxy
Section titled “9. Configure Pangolin reverse proxy”Add a route in Pangolin for planka.wighttrash.uk pointing to the Planka container.
- Target:
http://<truenas-ip>:3000(or the Docker network address if Pangolin runs on the same host) - Protocol: HTTP (Pangolin handles TLS termination)
- WebSocket support: Must be enabled. Planka uses WebSockets for real-time board updates. Without this, the UI will load but cards will not sync in real time.
If Pangolin has a “WebSocket” or “Upgrade” toggle for the route, enable it. If it uses custom headers, ensure these are passed:
Upgrade: $http_upgradeConnection: "upgrade"10. Verify OIDC login
Section titled “10. Verify OIDC login”- Browse to
https://planka.wighttrash.uk. - You should see the standard Planka login form with an SSO button.
- Click SSO. You should be redirected to
https://auth.wighttrash.uk/realms/wighttrash/protocol/openid-connect/auth?... - Log in with your Keycloak credentials.
- On successful authentication, you are redirected back to Planka and logged in.
If the SSO button does not appear:
- Check the Planka container logs for OIDC errors:
docker logs planka - Verify
OIDC_ISSUERis reachable from inside the container:docker exec planka wget -qO- https://auth.wighttrash.uk/realms/wighttrash/.well-known/openid-configuration - If the container cannot reach
auth.wighttrash.uk, you may need to add a DNS entry orextra_hostsmapping in the compose file.
If login redirects but fails silently:
- Set
OIDC_DEBUG=truein the compose file, redeploy, and click the debug button on the login page to see the raw token payload. - Check that the redirect URI in Keycloak is exactly
https://planka.wighttrash.uk/oidc-callback(no trailing slash). - Check that the client secret in the compose file matches what Keycloak shows.
If the username is rejected after login:
- Confirm
OIDC_IGNORE_USERNAME=trueis set. Planka rejects usernames containing@, and Keycloak’spreferred_usernameoften includes the email address.
11. Post-install: disable local auth (optional)
Section titled “11. Post-install: disable local auth (optional)”Once you have confirmed OIDC works for both users, you can optionally force all authentication through Keycloak by uncommenting this line in the compose file:
- OIDC_ENFORCED=trueRedeploy after making this change. The local login form will be hidden and all users must authenticate via Keycloak.
Warning: If Keycloak goes down while OIDC_ENFORCED=true, nobody can log in to Planka. Keep the local admin credentials as a break-glass option. To use them, temporarily remove OIDC_ENFORCED=true and redeploy.
12. Backup and restore
Section titled “12. Backup and restore”Backup
Section titled “Backup”# Database dumpdocker exec planka-db pg_dump -U planka planka > /mnt/tank/configs/planka/backup-$(date +%Y%m%d).sql
# File attachments (already on the dataset, but tar for offsite)tar czf /mnt/tank/configs/planka/attachments-backup-$(date +%Y%m%d).tar.gz \ -C /mnt/tank/configs/planka attachments user-avatars background-images faviconsRestore
Section titled “Restore”# Stop Planka (keep database running)docker stop planka
# Restore databasecat /mnt/tank/configs/planka/backup-YYYYMMDD.sql | docker exec -i planka-db psql -U planka planka
# Restore filestar xzf /mnt/tank/configs/planka/attachments-backup-YYYYMMDD.tar.gz -C /mnt/tank/configs/planka
# Fix permissionschown -R 1000:1000 /mnt/tank/configs/planka/favicons /mnt/tank/configs/planka/user-avatars /mnt/tank/configs/planka/background-images /mnt/tank/configs/planka/attachments
# Start Plankadocker start plankaUpdate Planka
Section titled “Update Planka”# Take a backup first (see above)
# Pull latest imagedocker pull ghcr.io/plankanban/planka:latest
# Redeploy via Arcane (or docker compose up -d)13. Troubleshooting
Section titled “13. Troubleshooting”| Symptom | Likely cause | Fix |
|---|---|---|
| Container restart loop | Permission denied on bind mounts | Re-run chown commands from section 3 |
| White screen after login | WebSocket not proxied | Enable WebSocket support in Pangolin route |
| SSO button missing | OIDC env vars not set or container not restarted | Check env vars, redeploy in Arcane |
| OIDC redirect fails | Redirect URI mismatch in Keycloak | Set to exactly https://planka.wighttrash.uk/oidc-callback |
| ”Invalid username” after OIDC login | Username contains @ | Set OIDC_IGNORE_USERNAME=true |
| Container cannot reach Keycloak | DNS resolution inside container | Add extra_hosts: - "auth.wighttrash.uk:<ip>" to the planka service, or fix container DNS |
| Database connection refused | planka-db not healthy yet or password mismatch | Check healthcheck status; confirm CHANGE_ME_DB_PASSWORD matches in both services |
| Cards do not sync in real time | WebSocket blocked | Confirm Pangolin passes Upgrade and Connection headers |
OIDC_DEBUG=true shows empty groups claim | Group mapper not configured | Follow section 4.3 to add the groups mapper in Keycloak |
| Roles not mapping from Keycloak | Claims source mismatch | If groups are only in the ID token, add OIDC_CLAIMS_SOURCE=id_token to the compose file |
Useful commands
Section titled “Useful commands”# Check container statusdocker ps --filter name=planka
# View Planka logsdocker logs -f planka
# View database logsdocker logs -f planka-db
# Test OIDC discovery from inside the containerdocker exec planka wget -qO- https://auth.wighttrash.uk/realms/wighttrash/.well-known/openid-configuration
# Interactive shell inside Planka containerdocker exec -it planka sh