Kanboard: Simple Kanban Board
Minimalist Kanban project management. Swimlanes, plugins, and API access.
Introduction
Kanboard is a free, open-source kanban project management tool focused on simplicity and minimalism. Designed for teams that want to visualize their work without complexity, Kanboard provides a clean, intuitive interface with powerful features including swimlanes, analytics, automation, and integrations. With over 8,000 GitHub stars and continuous development since 2014, Kanboard has established itself as the go-to solution for straightforward kanban management.
Why Choose Kanboard?
Simplicity First
Unlike complex project management tools that require extensive configuration, Kanboard is ready to use immediately. The interface is clean, distraction-free, and focuses on what matters: getting work done.
Visual Work Management
Kanboard embraces the kanban methodology completely. Visualize work flow, identify bottlenecks, limit work-in-progress, and improve team efficiency through the power of visual management.
Lightweight and Fast
Kanboard is built with PHP and is incredibly lightweight. It runs smoothly on minimal hardware, starts instantly, and provides a snappy user experience even on older servers.
Complete Privacy
Your project data, workflow, and team activities remain on your infrastructure. Perfect for teams working on confidential projects or those who value data sovereignty.
Zero Cost, Full Features
Commercial kanban tools like Trello Business cost $10-17.50/user/month. For a team of 15, that’s $1,800-3,150 annually. Kanboard is completely free with unlimited users, boards, and features.
Key Features:
- Multiple boards and projects
- Swimlanes for grouping tasks
- Columns with WIP limits
- Task cards with descriptions, comments, attachments
- Subtasks and checklists
- Calendar and list views
- Gantt charts
- Analytics and reporting
- Burndown charts
- Automatic actions and triggers
- Custom filters and search
- Time tracking
- Budget management
- Due dates and reminders
- User groups and project roles
- LDAP and OAuth integration
- Email notifications
- Import from Trello
- Plugins for extensions
- RESTful API
- Webhooks
- RSS feeds
- iCalendar integration
Understanding the Architecture
Kanboard has a simple, monolithic architecture:
Internet/Local Network
│
▼
┌───────────────┐
│ Reverse Proxy │ (Optional - Nginx, Caddy)
│ HTTPS/SSL │
└───────┬───────┘
│
▼
┌───────────────┐
│ Kanboard │ (PHP Application - Port 80)
│ Web Server │
└───────┬───────┘
│
┌───┴────┬────────┐
│ │ │
▼ ▼ ▼
┌────────┐ ┌──────┐ ┌──────┐
│Database│ │Files │ │Plugins│
│(SQLite,│ │Upload│ │ │
│ MySQL, │ │ │ │ │
│Postgres)│ │ │ │ │
└────────┘ └──────┘ └──────┘ Kanboard supports SQLite (default), MySQL, or PostgreSQL.
Prerequisites
Hardware Requirements
Minimum Configuration:
- RAM: 256MB (sufficient for small teams)
- CPU: 1 core
- Storage: 2GB
- Network: Standard homelab network
Recommended Configuration:
- RAM: 512MB (better for teams)
- CPU: 1 core
- Storage: 10GB+ SSD
- Network: Gigabit ethernet
For Larger Teams (50+ users):
- RAM: 1GB+
- CPU: 2+ cores
- Storage: 20GB+ SSD
- PostgreSQL or MySQL database
Software Requirements
- Docker Engine v24+ with docker-compose
- Linux (Ubuntu 22.04/24.04 LTS recommended)
- Web browser (Chrome, Firefox, Safari, Edge)
- Domain name (optional, for HTTPS)
- SMTP server (optional, for notifications)
Pre-Deployment Checklist
# Verify Docker installation
docker --version
docker compose version
# Check available resources
free -h
df -h
# Test network connectivity
ping -c 3 google.com Installation and Deployment
Step 1: Create Project Directory
# Create directory structure
mkdir -p ~/kanboard/{data,plugins}
cd ~/kanboard
# Set proper permissions
chmod 755 ~/kanboard Step 2: Choose Database Configuration
Option A: SQLite (Simplest - Default)
No separate database needed. Best for small teams and personal use.
Option B: PostgreSQL (Production)
Recommended for teams with 10+ users.
Step 3: Create Docker Compose Configuration
For SQLite (Simple Setup):
Create docker-compose.yml:
version: "3.8"
services:
kanboard:
image: kanboard/kanboard:latest
container_name: kanboard
restart: unless-stopped
ports:
- "8080:80"
volumes:
- kanboard-data:/var/www/app/data
- kanboard-plugins:/var/www/app/plugins
environment:
- DATABASE_URL=sqlite:///var/www/app/data/db.sqlite
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/"]
interval: 30s
timeout: 10s
retries: 3
volumes:
kanboard-data:
kanboard-plugins: For PostgreSQL (Production Setup):
Create docker-compose.yml:
version: "3.8"
services:
kanboard-db:
image: postgres:15-alpine
container_name: kanboard-db
restart: unless-stopped
environment:
POSTGRES_USER: kanboard
POSTGRES_PASSWORD: CHANGE-THIS-PASSWORD
POSTGRES_DB: kanboard
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U kanboard"]
interval: 10s
timeout: 5s
retries: 5
kanboard:
image: kanboard/kanboard:latest
container_name: kanboard
restart: unless-stopped
depends_on:
kanboard-db:
condition: service_healthy
ports:
- "8080:80"
volumes:
- kanboard-data:/var/www/app/data
- kanboard-plugins:/var/www/app/plugins
environment:
DATABASE_URL: "postgres://kanboard:CHANGE-THIS-PASSWORD@kanboard-db/kanboard"
DB_DRIVER: postgres
DB_USERNAME: kanboard
DB_PASSWORD: CHANGE-THIS-PASSWORD
DB_HOSTNAME: kanboard-db
DB_NAME: kanboard
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/"]
interval: 30s
timeout: 10s
retries: 3
volumes:
postgres-data:
kanboard-data:
kanboard-plugins: Generate secure password for PostgreSQL:
# Generate password
PG_PASSWORD=$(openssl rand -base64 24)
# Update docker-compose.yml
sed -i "s/CHANGE-THIS-PASSWORD/${PG_PASSWORD}/g" docker-compose.yml
echo "PostgreSQL Password: ${PG_PASSWORD}"
echo "Save this securely!" Step 4: Create Custom Configuration (Optional)
Create config.php for advanced settings:
<?php
// Enable/Disable features
define('ENABLE_URL_REWRITE', false);
// Plugins directory
define('PLUGINS_DIR', '/var/www/app/plugins');
// Files directory
define('FILES_DIR', '/var/www/app/data/files');
// Email configuration
define('MAIL_FROM', '[email protected]');
define('MAIL_TRANSPORT', 'smtp');
define('MAIL_SMTP_HOSTNAME', 'smtp.gmail.com');
define('MAIL_SMTP_PORT', 587);
define('MAIL_SMTP_USERNAME', '[email protected]');
define('MAIL_SMTP_PASSWORD', 'your-app-password');
define('MAIL_SMTP_ENCRYPTION', 'tls');
// LDAP configuration (optional)
// define('LDAP_AUTH', true);
// define('LDAP_SERVER', 'ldap://dc.example.com');
// define('LDAP_PORT', 389);
// define('LDAP_BIND_TYPE', 'user');
// define('LDAP_USERNAME', 'CN=Kanboard,CN=Users,DC=example,DC=com');
// define('LDAP_PASSWORD', 'password');
// define('LDAP_USER_BASE_DN', 'OU=Users,DC=example,DC=com');
// define('LDAP_USER_FILTER', '(&(objectClass=user)(sAMAccountName=%s))');
// Session settings
define('SESSION_DURATION', 0); // 0 = until browser close
// Security
define('BRUTEFORCE_CAPTCHA', 3); // Show captcha after 3 failed login attempts
define('BRUTEFORCE_LOCKDOWN', 6); // Lock account after 6 failed attempts
define('BRUTEFORCE_LOCKDOWN_DURATION', 900); // Lock for 15 minutes
// API
define('API_AUTHENTICATION_TOKEN', 'YOUR-API-TOKEN-HERE');
// Timezone
define('TIMEZONE', 'America/New_York');
// Language
define('DEFAULT_LANGUAGE', 'en_US'); Mount config in docker-compose.yml:
volumes:
- ./config.php:/var/www/app/config.php:ro Step 5: Deploy Kanboard
# Pull images
docker compose pull
# Start services
docker compose up -d
# Monitor startup logs
docker compose logs -f
# Wait for "ready to handle connections"
# Press Ctrl+C to exit
# Verify container is running
docker compose ps Step 6: Access Kanboard
Navigate to http://YOUR-SERVER-IP:8080 in your browser.
Default credentials:
- Username:
admin - Password:
admin
IMMEDIATE SECURITY STEPS:
1. Login with default credentials
2. Click on username (top right) → My profile
3. Change username from "admin" to something unique
4. Change password to strong password (12+ characters)
5. Set your email address
6. Set timezone
7. Save Initial Setup and Configuration
Create Your First Project
1. Click "New project" in top menu
2. Fill in details:
- Name: "Website Redesign"
- Identifier: WEB (appears on tasks)
- Description: "Complete redesign project"
3. Click "Save" Configure Project Settings
Project Overview:
Settings → Edit project:
├─ Name and description
├─ Start date and end date
├─ Enable/disable email notifications
├─ Enable/disable budget tracking
└─ Enable/disable time tracking Columns Configuration:
Settings → Columns:
Default columns:
├─ Backlog
├─ Ready
├─ Work in progress
└─ Done
Customize columns:
1. Click "Add column"
2. Name: "Code Review"
3. Task limit: 3 (WIP limit)
4. Description: "Tasks waiting for code review"
5. Save
6. Drag to reorder columns Swimlanes:
Settings → Swimlanes:
Swimlanes group tasks horizontally
Examples:
├─ Frontend Tasks
├─ Backend Tasks
├─ Design Tasks
└─ Bug Fixes
To create:
1. Click "Add a new swimlane"
2. Name: "Frontend Tasks"
3. Save
4. Tasks can be assigned to swimlanes Categories:
Settings → Categories:
Create categories for task classification
Examples:
├─ Feature
├─ Bug
├─ Enhancement
├─ Documentation
└─ Security
Categories have colors for visual identification Configure Board Appearance
Settings → Board settings:
├─ Default columns: Select default column for new tasks
├─ Default swimlane: Set default swimlane
├─ Task per columns: Show task count
├─ Show task position: Display position number
└─ Highlighting: Show time spent in column Working with Tasks
Create Tasks
Quick create:
1. On board, click "+" in any column
2. Enter title: "Implement user login"
3. Press Enter
4. Task created! Detailed create:
1. Click "+ Add a new task" button
2. Fill in details:
- Title: "Implement user authentication"
- Description: Use Markdown for formatting
- Assignee: Select team member
- Category: Feature
- Color: Choose identifying color
- Column: Select starting column
- Swimlane: Select appropriate swimlane
- Priority: 0-3 (3 = highest)
- Due date: Set deadline
- Time estimated: 8 hours
3. Click "Save" Task Details and Actions
Edit task details:
Click on any task to open:
Summary Tab:
├─ Edit title and description
├─ Change assignee
├─ Set due date and priority
├─ Time tracking (time spent, estimated)
└─ Move to different column/swimlane
Activity Tab:
├─ View all changes
├─ See who did what when
└─ Full audit trail
Comments Tab:
├─ Add comments
├─ Team discussion
├─ @mention users
└─ Attach files to comments
Attachments Tab:
├─ Upload files (images, documents)
├─ Drag and drop support
└─ Screenshot paste
Subtasks Tab:
├─ Create subtasks/checklist
├─ Track completion percentage
└─ Assign subtasks to different users
Links Tab:
├─ Link related tasks
├─ Create dependencies
├─ Block/is blocked by relationships
└─ Duplicate/related links
Transitions Tab:
├─ View task movement history
├─ Time spent in each column
└─ Identify bottlenecks Manage Task Movement
Drag and drop:
- Drag tasks between columns
- Drag tasks between swimlanes
- Reorder tasks within columns
- Visual workflow management Keyboard shortcuts:
- 'n': Create new task
- 'v': Board overview
- '?': Show all shortcuts
- 'f': Focus search Use Filters
Click "Filter" button:
Filter by:
├─ Assignee: Show only my tasks
├─ Category: Show only bugs
├─ Due date: Tasks due this week
├─ Color: Tasks by color
├─ Status: Open/closed tasks
└─ Advanced: Custom queries
Save filters:
1. Apply filter
2. Click "Save custom filter"
3. Name: "My urgent tasks"
4. Access from dropdown anytime User Management
Create Users
1. Settings → Users → Add a new user
2. Fill in details:
- Username: jdoe
- Full Name: John Doe
- Email: [email protected]
- Password: (generate secure password)
- Role: User (not administrator)
3. Click "Save"
4. User receives email with credentials User Roles:
Administrator:
- Full system access
- Manage all projects
- Manage users
- Change settings
Manager:
- Create projects
- Manage own projects
- Cannot manage users
User:
- View assigned projects
- Create/edit tasks in projects
- Cannot create projects Project Members
Add members to project:
Project → Settings → Project permissions:
1. Click "Add user"
2. Select user
3. Select role:
- Project Manager: Full project control
- Project Member: Edit tasks
- Project Viewer: Read-only
4. Save User Groups
Create groups:
Settings → Groups:
1. Click "Add a new group"
2. Name: "Frontend Team"
3. Add members to group
4. Assign group to projects
5. Useful for bulk permissions Automation and Actions
Automatic Actions
Kanboard can automate repetitive tasks:
Project → Settings → Automatic actions:
Common actions:
├─ Auto-assign to category: When task contains keyword
├─ Auto-assign to user: Based on category or color
├─ Close task automatically: When moved to "Done"
├─ Move task to column: Based on assignee
└─ Send notification: When conditions met
To create:
1. Click "Add a new automatic action"
2. Select action type: "Close a task in a specific column"
3. Choose event: "Move a task to another column"
4. Add condition: Column is "Done"
5. Save
6. Tasks in "Done" column auto-close Example automations:
1. Auto-assign bugs to QA team:
- Event: Task created
- Condition: Category = Bug
- Action: Assign to user "qa-lead"
2. Send email when task is overdue:
- Event: Daily cronjob
- Condition: Due date passed
- Action: Send notification
3. Change color based on priority:
- Event: Task updated
- Condition: Priority = 3
- Action: Change color to red Analytics and Reporting
View Analytics
Project → Analytics:
Available reports:
├─ Lead and cycle time: How long tasks take
├─ Average time in columns: Identify bottlenecks
├─ Cumulative flow diagram: Work distribution
├─ Burndown chart: Sprint progress
├─ Task distribution: By assignee, category, etc.
└─ Estimated vs actual time: Accuracy tracking Cumulative Flow Diagram:
Shows work distribution over time
Identifies:
- Bottlenecks (expanding columns)
- Work in progress trends
- Flow efficiency Burndown Chart:
Track sprint/project progress
Compare:
- Work remaining vs ideal burndown
- Velocity trends
- Completion predictions Time Tracking:
Per task:
- Time estimated
- Time spent
- Remaining time
Project totals:
- Total estimated
- Total spent
- Variance Backup Procedures
What to Backup
| Component | Priority | Contains |
|---|---|---|
| Database | Critical | All tasks, projects, users |
| Data directory | Important | Attachments, uploads |
| Plugins | Important | Custom plugins |
| config.php | Important | Configuration |
Automated Backup Script
Create ~/kanboard/backup.sh:
#!/bin/bash
# Configuration
BACKUP_DIR="/mnt/backups/kanboard"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=30
mkdir -p "$BACKUP_DIR"
echo "Starting Kanboard backup at $(date)"
# Backup database (SQLite)
if docker volume inspect kanboard_kanboard-data &>/dev/null; then
docker run --rm -v kanboard_kanboard-data:/source:ro -v "$BACKUP_DIR":/backup alpine tar czf /backup/kanboard-data-${DATE}.tar.gz -C /source .
echo "SQLite database backed up"
fi
# Backup database (PostgreSQL)
if docker ps | grep -q kanboard-db; then
docker exec kanboard-db pg_dump -U kanboard kanboard | gzip > "$BACKUP_DIR/kanboard-db-${DATE}.sql.gz"
echo "PostgreSQL database backed up"
fi
# Backup plugins
docker run --rm -v kanboard_kanboard-plugins:/source:ro -v "$BACKUP_DIR":/backup alpine tar czf /backup/kanboard-plugins-${DATE}.tar.gz -C /source .
# Backup config if exists
if [ -f ~/kanboard/config.php ]; then
cp ~/kanboard/config.php "$BACKUP_DIR/config-${DATE}.php"
fi
# Create manifest
cat > "$BACKUP_DIR/manifest-${DATE}.txt" <<EOF
Kanboard Backup
Date: $(date)
Files: kanboard-data-${DATE}.tar.gz or kanboard-db-${DATE}.sql.gz
Plugins: kanboard-plugins-${DATE}.tar.gz
Config: config-${DATE}.php
EOF
# Clean old backups
find "$BACKUP_DIR" -name "*.gz" -mtime +$RETENTION_DAYS -delete
find "$BACKUP_DIR" -name "*.php" -mtime +$RETENTION_DAYS -delete
find "$BACKUP_DIR" -name "*.txt" -mtime +$RETENTION_DAYS -delete
echo "Backup completed at $(date)" Schedule backups:
chmod +x ~/kanboard/backup.sh
crontab -e
# Add: 0 2 * * * /home/user/kanboard/backup.sh >> /var/log/kanboard-backup.log 2>&1 Restore from Backup
SQLite:
cd ~/kanboard
docker compose down
docker run --rm -v kanboard_kanboard-data:/dest -v /mnt/backups/kanboard:/backup alpine tar xzf /backup/kanboard-data-YYYYMMDD.tar.gz -C /dest
docker compose up -d PostgreSQL:
cd ~/kanboard
docker compose down
docker compose up -d kanboard-db
sleep 10
gunzip < /mnt/backups/kanboard/kanboard-db-YYYYMMDD.sql.gz | docker exec -i kanboard-db psql -U kanboard kanboard
docker compose up -d Troubleshooting
Issue: Can’t Login
# Reset admin password
docker exec -it kanboard ./cli user:change-password admin newpassword
# Or reset database (CAUTION: deletes all data)
docker compose down
docker volume rm kanboard_kanboard-data
docker compose up -d Issue: File Uploads Failing
# Check data volume
docker volume inspect kanboard_kanboard-data
# Check permissions inside container
docker exec kanboard ls -la /var/www/app/data/files
# Increase PHP upload limit
# Add to config.php:
define('FILE_MAX_SIZE', 52428800); // 50MB Issue: Slow Performance
# Check database size
docker exec kanboard ls -lh /var/www/app/data/db.sqlite
# Optimize database
docker exec kanboard ./cli db:optimize
# Check resource usage
docker stats kanboard
# For PostgreSQL, run VACUUM
docker exec kanboard-db psql -U kanboard -c "VACUUM ANALYZE;" Issue: Email Not Sending
# Test email configuration
docker exec -it kanboard ./cli notification:send-test [email protected]
# Check logs
docker compose logs kanboard | grep -i mail
# Verify SMTP settings in config.php Issue: Tasks Not Appearing on Board
# Check filters
# Click "Filter" and click "Reset filters"
# Verify task status
# Closed tasks don't appear by default
# Check column assignment
# Task must be in a column to appear Advanced Features
Install Plugins
Settings → Plugins → Install from Directory:
Popular plugins:
├─ Gantt: Enhanced Gantt charts
├─ Calendar: Advanced calendar view
├─ Telegram: Telegram notifications
├─ Slack: Slack integration
└─ Custom CSS: Customize appearance
To install:
1. Click plugin name
2. Click "Install"
3. Configure plugin settings
4. Enable for projects Use REST API
Generate API token:
User profile → API access → Generate token
Copy token for use in scripts Example API calls:
# Get all projects
curl -H "Authorization: Bearer YOUR-TOKEN" http://YOUR-SERVER-IP:8080/jsonrpc.php -d '{"jsonrpc":"2.0","method":"getAllProjects","id":1}'
# Create task
curl -H "Authorization: Bearer YOUR-TOKEN" http://YOUR-SERVER-IP:8080/jsonrpc.php -d '{"jsonrpc":"2.0","method":"createTask","id":1,"params":{"title":"New task","project_id":1}}' Import from Trello
Settings → Integrations → Import from Trello:
1. Export Trello board as JSON
2. Upload JSON file
3. Map Trello lists to Kanboard columns
4. Import tasks, labels, attachments
5. Verify imported data Configure LDAP
In config.php:
define('LDAP_AUTH', true);
define('LDAP_SERVER', 'ldap://dc.example.com');
define('LDAP_PORT', 389);
define('LDAP_BIND_TYPE', 'user');
define('LDAP_USERNAME', 'CN=Kanboard,CN=Users,DC=example,DC=com');
define('LDAP_PASSWORD', 'password');
define('LDAP_USER_BASE_DN', 'OU=Users,DC=example,DC=com');
define('LDAP_USER_FILTER', '(&(objectClass=user)(sAMAccountName=%s))'); Set Up Webhooks
Project → Settings → Webhooks:
1. Click "Add webhook"
2. URL: https://your-webhook-endpoint.com
3. Select events: Task created, Task updated, etc.
4. Save
5. Kanboard sends HTTP POST on events
6. Use for Slack, Discord, custom integrations Conclusion
Kanboard provides a straightforward, powerful kanban board for teams that value simplicity and effectiveness. With visual workflow management, automation, and complete self-hosting, it’s the perfect solution for agile teams.
What You’ve Accomplished:
- Deployed Kanboard with your choice of database
- Created projects with custom workflows
- Configured columns, swimlanes, and categories
- Set up user management and permissions
- Implemented task automation
- Configured analytics and reporting
- Set up automated backups
Next Steps:
- Import existing boards from Trello
- Set up email notifications
- Configure LDAP for enterprise authentication
- Install plugins for extended functionality
- Set up webhooks for integrations
- Create automatic actions for workflow automation
- Train team on kanban methodology
Start visualizing your workflow with the simplicity and control of Kanboard!