$linuxjunkies
>

Self-Host Planka (Trello Alternative)

Deploy Planka, a self-hosted Trello alternative, using Docker Compose with PostgreSQL, HTTPS via Caddy, and full support for boards, cards, comments, and attachments.

BeginnerUbuntuDebianFedoraArch9 min readUpdated June 7, 2026

Before you start

  • A Linux server with at least 1 GB RAM and internet access
  • A domain or subdomain with its DNS A record pointing to the server's IP
  • Root or sudo access on the server
  • Ports 80 and 443 open in both the host firewall and any upstream cloud security group

Planka is a fast, open-source Kanban board application that gives you everything Trello offers — cards, lists, labels, attachments, and comments — without the subscription or the data leaving your server. Deploying it with Docker Compose takes under fifteen minutes, and adding a reverse proxy gives you a proper HTTPS URL.

Prerequisites

  • A server (VPS or bare metal) with at least 1 GB RAM and Docker Engine installed
  • Docker Compose v2 (the docker compose plugin, not the legacy docker-compose binary)
  • A domain name or subdomain pointed at your server's IP — needed for the reverse proxy and for Planka's BASE_URL
  • Ports 80 and 443 reachable, or whichever port you choose for HTTP-only setups

Step 1 — Install Docker (if not already present)

Debian / Ubuntu

sudo apt update
sudo apt install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" \
  | sudo tee /etc/apt/sources.list.d/docker.list
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

Fedora / RHEL / Rocky

sudo dnf -y install dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo systemctl enable --now docker

Arch

sudo pacman -S docker docker-compose
sudo systemctl enable --now docker

Add your user to the docker group so you can run commands without sudo:

sudo usermod -aG docker $USER
newgrp docker

Step 2 — Create the Compose Project

Create a dedicated directory and a docker-compose.yml file:

mkdir -p ~/planka && cd ~/planka
cat > docker-compose.yml <<'EOF'
services:
  planka:
    image: ghcr.io/plankanban/planka:latest
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    ports:
      - "3000:1337"
    environment:
      BASE_URL: https://planka.example.com
      DATABASE_URL: postgresql://planka:planka_password@db/planka
      SECRET_KEY: "change_me_to_a_64_char_random_string"
      DEFAULT_ADMIN_EMAIL: [email protected]
      DEFAULT_ADMIN_PASSWORD: StrongAdminPass1
      DEFAULT_ADMIN_NAME: Admin
      DEFAULT_ADMIN_USERNAME: admin
    volumes:
      - planka_data:/app/public/user-avatars
      - planka_data:/app/public/project-background-images
      - planka_attachments:/app/private/attachments

  db:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: planka
      POSTGRES_USER: planka
      POSTGRES_PASSWORD: planka_password
    volumes:
      - db_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U planka"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  planka_data:
  planka_attachments:
  db_data:
EOF

Before starting, replace every placeholder value:

  • BASE_URL — your real domain, including scheme (https://)
  • SECRET_KEY — generate a 64-character random string (see below)
  • DEFAULT_ADMIN_PASSWORD and POSTGRES_PASSWORD — strong unique passwords
openssl rand -hex 32

Paste the output as SECRET_KEY. Keep Postgres credentials consistent between the planka and db service blocks.

Step 3 — Start Planka

docker compose up -d

Watch the logs until the app is ready (look for a line indicating the server is listening):

docker compose logs -f planka

Planka is now reachable on port 3000. Before exposing it to the internet, add the reverse proxy in the next step.

Step 4 — Reverse Proxy with Caddy (HTTPS)

Caddy is the simplest choice for automatic TLS. Install it, then write a minimal Caddyfile.

Debian / Ubuntu

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf https://dl.cloudsmith.io/public/caddy/stable/gpg.key \
  | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt \
  | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install -y caddy

Fedora / RHEL / Rocky

sudo dnf install -y 'dnf-command(copr)'
sudo dnf copr enable @caddy/caddy
sudo dnf install -y caddy

Arch

sudo pacman -S caddy

Edit /etc/caddy/Caddyfile:

sudo tee /etc/caddy/Caddyfile <<'EOF'
planka.example.com {
    reverse_proxy localhost:3000
}
EOF
sudo systemctl enable --now caddy
sudo systemctl reload caddy

Caddy fetches a Let's Encrypt certificate automatically. Your Planka instance is now available at https://planka.example.com.

If you prefer Nginx or Apache, the key settings are: proxy to http://localhost:3000, enable WebSocket upgrade headers (Upgrade and Connection), and set proxy_set_header Host $host. Planka uses WebSockets for real-time board updates.

Step 5 — Open the Firewall

ufw (Debian / Ubuntu)

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload

firewalld (Fedora / RHEL / Rocky)

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

Step 6 — Log In and Configure Boards

Open your domain in a browser and sign in with the DEFAULT_ADMIN_EMAIL and password you set. The first screen prompts you to create a Project (the top-level container, equivalent to a Trello workspace).

  • Boards — inside a project, create boards for each workflow. Click the + icon next to the project name.
  • Lists — within a board, add lists (columns) like To Do, In Progress, Done.
  • Cards — add cards to lists. Click a card to open the detail view.
  • Comments — in the card detail view, type a comment in the text field at the bottom and press Save.
  • Attachments — in the card detail view, click Attachment in the sidebar, then choose a file. Attachments are stored in the planka_attachments Docker volume at /app/private/attachments.
  • Labels and Due Dates — also accessible from the card detail sidebar.

Invite other users from Admin panel → Users → Add user, or enable open registration in the environment variables (set ALLOW_ALL_TO_CREATE_PROJECTS=true and restart the container).

Step 7 — Verify the Deployment

docker compose ps

Both planka and db should show Up (or running). Check that HTTPS works and the certificate is valid:

curl -I https://planka.example.com

You should see HTTP/2 200 (or a redirect to the login page). If WebSockets are working correctly, board changes made in one browser tab will appear instantly in another without a page refresh.

Keeping Planka Updated

cd ~/planka
docker compose pull
docker compose up -d

This pulls the latest image and recreates the container while leaving your named volumes (data, attachments, database) untouched.

Backup

Back up both the Postgres database and the attachments volume:

# Dump the database
docker compose exec db pg_dump -U planka planka > planka_backup_$(date +%F).sql

# Archive the attachments volume
docker run --rm -v planka_planka_attachments:/data -v $(pwd):/backup \
  alpine tar czf /backup/attachments_$(date +%F).tar.gz -C /data .

Troubleshooting

  • Planka container exits immediately — usually a bad DATABASE_URL or the db healthcheck hasn't passed yet. Run docker compose logs planka and docker compose logs db to confirm Postgres started cleanly.
  • Real-time updates not working — WebSocket proxying is likely misconfigured. With Nginx, ensure you have proxy_http_version 1.1, proxy_set_header Upgrade $http_upgrade, and proxy_set_header Connection "upgrade" in your location block.
  • Attachment uploads fail — verify the planka_attachments volume is mounted correctly and the container has write permission. Check with docker compose exec planka ls -la /app/private/.
  • Certificate errors — ensure ports 80 and 443 are open and DNS has propagated. Caddy logs are at journalctl -u caddy -n 50.
  • Forgot admin password — reset it via the Admin panel when logged in as another admin, or use docker compose exec planka node ./node_modules/.bin/sails run reset-password --email [email protected].
tested on:Ubuntu 24.04Debian 12Fedora 40Arch rolling

Frequently asked questions

Can I run Planka without a domain name, on a local network only?
Yes. Set BASE_URL to http://your-server-ip:3000, remove the reverse proxy, and access Planka directly on port 3000. You won't get HTTPS unless you configure a self-signed certificate or use a local CA.
How do I enable email notifications in Planka?
Add SMTP environment variables to the planka service in docker-compose.yml: SMTP_HOST, SMTP_PORT, SMTP_SECURE, SMTP_USER, SMTP_PASSWORD, and SMTP_FROM. Restart the container after saving.
Is it safe to expose Planka directly to the internet without a reverse proxy?
Not recommended. Running directly on port 3000 means no TLS and no HTTP/2. Always place a reverse proxy in front so traffic is encrypted and you can add rate-limiting or auth middleware.
How large can attachments be, and can I change the limit?
The default maximum attachment size is set by Planka's internal limits (currently around 100 MB). If you use Caddy or Nginx, also set client_max_body_size (Nginx) or request_body_max in your Caddyfile to match or exceed Planka's limit.
Can multiple people use the same Planka instance with separate accounts?
Yes. Create additional user accounts from the Admin panel under Users. Each user has their own profile and you can add them to specific projects and boards with member-level or admin-level permissions.

Related guides