Vikunja: To-Do App and Task Manager
Simple, effective task management. Lists, labels, and filters with mobile apps.
Introduction
Vikunja is a beautiful, fast, and feature-rich open-source to-do list and task manager. Designed as a self-hosted alternative to Todoist, Wunderlist, and Microsoft To-Do, Vikunja offers an intuitive interface with powerful features including multiple views (list, kanban, table, gantt), subtasks, labels, filters, and team collaboration. With over 4,000 GitHub stars and active development, Vikunja has become the leading self-hosted task management solution.
Why Choose Vikunja?
Beautiful and Fast Interface
Vikunja provides a modern, responsive interface that works seamlessly on desktop, tablet, and mobile. The application is blazingly fast, with instant updates and smooth animations.
Multiple View Types
Switch between different views depending on your workflow: list view for traditional to-do lists, kanban boards for visual task management, table view for spreadsheet-like organization, gantt charts for timeline planning, and calendar view for date-based tasks.
Privacy-Focused
Your tasks, projects, and personal productivity data remain on your infrastructure. No third-party service tracks your activities, reads your tasks, or monetizes your data.
Cost Savings
Todoist costs $4-6/user/month. Microsoft To-Do is free but requires Microsoft account and collects data. Vikunja is completely free, open-source, and respects your privacy.
Rich Feature Set
Despite being self-hosted, Vikunja rivals commercial services with features like subtasks, reminders, recurring tasks, attachments, comments, team sharing, and comprehensive API.
Key Features:
- Multiple projects (called “namespaces” and “lists”)
- List, kanban, table, gantt, and calendar views
- Tasks with subtasks and checklists
- Labels, priorities, and assignees
- Due dates and reminders
- Recurring tasks
- File attachments
- Comments and activity feed
- Team collaboration and sharing
- Comprehensive filters and saved views
- Bulk editing
- Import from Todoist, Wunderlist, Microsoft To-Do
- CalDAV support for calendar integration
- Mobile apps (iOS and Android)
- RESTful API
- Webhooks
- Multi-language support (25+ languages)
Understanding the Architecture
Vikunja has a simple, efficient architecture:
Internet/Local Network
│
▼
┌───────────────┐
│ Reverse Proxy │ (Optional - Nginx, Caddy)
│ HTTPS/SSL │
└───────┬───────┘
│
▼
┌───────────────┐
│ Vikunja │ (Combined Frontend + Backend)
│ Port 3456 │
└───────┬───────┘
│
┌───┴────┐
│ │
▼ ▼
┌────────┐ ┌──────┐
│Database│ │Files │
│(SQLite,│ │Upload│
│ MySQL, │ │ │
│Postgres)│ │ │
└────────┘ └──────┘ Vikunja can use SQLite (no separate database needed), MySQL, or PostgreSQL.
Prerequisites
Hardware Requirements
Minimum Configuration:
- RAM: 512MB (perfect for personal use)
- CPU: 1 core
- Storage: 5GB
- Network: Standard homelab network
Recommended Configuration:
- RAM: 1GB (better for teams)
- CPU: 2 cores
- Storage: 20GB+ SSD
- Network: Gigabit ethernet
For Teams (25+ users):
- RAM: 2GB+
- CPU: 2+ cores
- Storage: 50GB+ SSD
- Dedicated database server (PostgreSQL)
Software Requirements
- Docker Engine v24+ with docker-compose
- Linux (Ubuntu 22.04/24.04 LTS recommended)
- Domain name (optional, for HTTPS and CalDAV)
- SMTP server (optional, for email reminders)
Pre-Deployment Checklist
# Verify Docker installation
docker --version
docker compose version
# Check resources
free -h
df -h
# Test network
ping -c 3 google.com Installation and Deployment
Step 1: Create Project Structure
# Create directory
mkdir -p ~/vikunja/{files,db}
cd ~/vikunja
# Set permissions
chmod 755 ~/vikunja Step 2: Choose Database Backend
Option A: SQLite (Simplest - Recommended for Personal Use)
No separate database container needed. Vikunja will create SQLite file automatically.
Option B: PostgreSQL (Recommended for Teams)
Better for multi-user environments and larger datasets.
We’ll show both configurations below.
Step 3: Create Configuration File
Create config.yml:
service:
# Service configuration
publicurl: http://YOUR-SERVER-IP:3456
maxitemsperpage: 50
enableregistration: true
enablelinksharing: true
enabletaskattachments: true
enabletaskcomments: true
enabletotp: true
enableemailreminders: true
timezone: America/New_York
database:
# For SQLite (simple, personal use)
type: sqlite
path: /db/vikunja.db
# For PostgreSQL (teams, production)
# type: postgres
# host: vikunja-db
# database: vikunja
# user: vikunja
# password: YOUR-SECURE-PASSWORD
auth:
# Authentication settings
local:
enabled: true
openid:
enabled: false
mailer:
# Email configuration (optional)
enabled: false
# host: smtp.gmail.com
# port: 587
# username: [email protected]
# password: your-app-password
# fromemail: [email protected]
# skiptlsverify: false
cors:
# CORS settings
enable: true
origins:
- http://YOUR-SERVER-IP:3456
log:
# Logging
enabled: true
standard: stdout
level: INFO
database: off
databaselevel: WARNING
files:
# File uploads
basepath: /app/vikunja/files
maxsize: 20MB
avatar:
# Avatar settings
gravatarexpiration: 3600
backgrounds:
# Enable background images for lists
enabled: true
legal:
# Legal URLs (optional)
imprinturl: ""
privacyurl: ""
migration:
# Import from other services
todoist:
enable: true
wunderlist:
enable: true
microsofttodo:
enable: true Update YOUR-SERVER-IP:
SERVER_IP=$(hostname -I | awk '{print $1}')
sed -i "s/YOUR-SERVER-IP/${SERVER_IP}/g" config.yml Step 4: Create Docker Compose Configuration
For SQLite (Simple Setup):
Create docker-compose.yml:
version: "3.8"
services:
vikunja:
image: vikunja/vikunja:latest
container_name: vikunja
restart: unless-stopped
environment:
VIKUNJA_SERVICE_PUBLICURL: http://YOUR-SERVER-IP:3456
VIKUNJA_DATABASE_TYPE: sqlite
VIKUNJA_DATABASE_PATH: /db/vikunja.db
VIKUNJA_SERVICE_TIMEZONE: America/New_York
volumes:
- ./files:/app/vikunja/files
- ./db:/db
- ./config.yml:/etc/vikunja/config.yml:ro
ports:
- "3456:3456"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3456/api/v1/info"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s For PostgreSQL (Production Setup):
Create docker-compose.yml:
version: "3.8"
services:
vikunja-db:
image: postgres:15-alpine
container_name: vikunja-db
restart: unless-stopped
environment:
POSTGRES_USER: vikunja
POSTGRES_PASSWORD: CHANGE-THIS-PASSWORD
POSTGRES_DB: vikunja
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U vikunja"]
interval: 10s
timeout: 5s
retries: 5
vikunja:
image: vikunja/vikunja:latest
container_name: vikunja
restart: unless-stopped
depends_on:
vikunja-db:
condition: service_healthy
environment:
VIKUNJA_SERVICE_PUBLICURL: http://YOUR-SERVER-IP:3456
VIKUNJA_DATABASE_TYPE: postgres
VIKUNJA_DATABASE_HOST: vikunja-db
VIKUNJA_DATABASE_USER: vikunja
VIKUNJA_DATABASE_PASSWORD: CHANGE-THIS-PASSWORD
VIKUNJA_DATABASE_DATABASE: vikunja
VIKUNJA_SERVICE_TIMEZONE: America/New_York
volumes:
- ./files:/app/vikunja/files
- ./config.yml:/etc/vikunja/config.yml:ro
ports:
- "3456:3456"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3456/api/v1/info"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
volumes:
postgres-data: Update configuration:
# Set your server IP
SERVER_IP=$(hostname -I | awk '{print $1}')
sed -i "s/YOUR-SERVER-IP/${SERVER_IP}/g" docker-compose.yml
# Generate secure password for PostgreSQL
PG_PASSWORD=$(openssl rand -base64 24)
sed -i "s/CHANGE-THIS-PASSWORD/${PG_PASSWORD}/g" docker-compose.yml
echo "PostgreSQL Password: ${PG_PASSWORD}"
echo "Save this password securely!" Step 5: Deploy Vikunja
# Pull images
docker compose pull
# Start services
docker compose up -d
# Monitor startup logs
docker compose logs -f
# Wait for "Vikunja is ready" message
# Press Ctrl+C to exit
# Verify container is running
docker compose ps Step 6: Access Vikunja
Navigate to http://YOUR-SERVER-IP:3456 in your browser.
Create your account:
- Click “Create an account”
- Enter username: your-username
- Enter email: [email protected]
- Enter password: (secure password)
- Confirm password
- Click “Sign up”
- You’re logged in and ready to go!
Initial Setup and Configuration
Create Your First Project
Vikunja organizes tasks into “Namespaces” and “Lists”:
- Namespace: Top-level container (like a workspace)
- List: Contains tasks (like a project)
Create a namespace:
1. Click "+" next to "Namespaces" in sidebar
2. Enter name: "Personal Projects"
3. Click "Create" Create a list:
1. Click the new namespace
2. Click "+ New List"
3. Enter title: "Home Renovation"
4. Description: "Tasks for home renovation project"
5. Click "Create" Configure List Settings
Click on list → Settings (gear icon):
General:
├─ Title and description
├─ Color: Choose identifying color
├─ Favorite: Pin to sidebar
└─ Archive: Hide completed list
Background:
├─ Upload custom background image
└─ Or choose from Unsplash integration
Sharing:
├─ Share with team members
├─ Share via link (read-only or editable)
└─ Make list public
Views:
├─ Default view: List, Kanban, Table, Gantt, Calendar
└─ This sets what view opens by default Create Tasks
Simple task:
1. In any list, type in the "Add a new task" box
2. Press Enter
3. Task created! Detailed task:
1. Click on a task to open details
2. Set properties:
- Description: Add detailed notes (Markdown supported)
- Due Date: When task is due
- Priority: Low, Medium, High, Urgent
- Labels: Add tags (create new or use existing)
- Assignees: Assign to team members
- Repeat: Set recurring pattern
- Color: Visual identification
- Percent Done: Track progress
3. Add subtasks:
- Click "Add a subtask"
- Create checklist of sub-items
4. Attachments:
- Drag files or click to upload
- Images, PDFs, documents
5. Relations:
- Link related tasks
- Block dependencies
6. Comments:
- Add notes and updates
- Team discussion Use Different Views
List View (Traditional To-Do List):
- Simple vertical list of tasks
- Check boxes to complete
- Quick add at top
- Filter and sort options Kanban View:
1. Click "Kanban" tab
2. Columns represent task status:
- To Do
- In Progress
- Done
3. Drag tasks between columns
4. Add new columns for custom workflow
5. Set WIP limits per column Table View:
- Spreadsheet-like interface
- Sort by any column
- Bulk edit multiple tasks
- Filter complex criteria
- Export to CSV Gantt View:
- Timeline visualization
- See task dependencies
- Drag to adjust dates
- Visual project planning
- Resource allocation Calendar View:
- Monthly/weekly calendar
- Tasks shown on due dates
- Drag to reschedule
- Integrate with CalDAV
- See all projects in one view Set Up Labels
1. Settings → Labels (in sidebar)
2. Click "+ Create Label"
3. Configure:
- Title: "urgent"
- Description: "Needs immediate attention"
- Color: Red (#ff0000)
4. Create more labels:
- home, work, personal
- bug, feature, enhancement
- waiting, blocked, in-review
5. Use labels across all lists Configure Filters
Save custom filters:
1. In any list, click "Filter"
2. Build filter:
- Priority: High or Urgent
- Due date: Next 7 days
- Assignee: Me
- Labels: work AND urgent
3. Click "Save this filter"
4. Name: "My Urgent Work Tasks"
5. Access from sidebar anytime Team Collaboration
Share Lists with Team Members
Add team member:
1. Open list
2. Click "Share" button
3. Enter email or username
4. Select permission:
- Read: View only
- Write: Create and edit tasks
- Admin: Full control including sharing
5. Click "Share"
6. User receives notification Share via Link
1. List → Share → Link Sharing
2. Click "Create share link"
3. Configure:
- Right: Read or Write
- Name: "Client Review Link"
- Password: Optional protection
4. Copy link
5. Share with anyone (no account needed)
6. Revoke link anytime Team Namespaces
1. Create namespace: "Company Projects"
2. Add all team members to namespace
3. All lists in namespace are accessible
4. Separate permissions per list
5. Great for departments or teams Comments and Activity
On any task:
1. Scroll to comments section
2. Write update or question
3. Mention team members: @username
4. They receive notification
5. View activity feed for all changes
6. Track who did what when Mobile Apps and Integrations
Mobile Apps
iOS:
Download from App Store
Login with your Vikunja URL: http://YOUR-SERVER-IP:3456
Full feature parity with web version
Offline support for viewing tasks
Push notifications (requires configuration) Android:
Download from Google Play or F-Droid
Login with server URL
Full offline support
Material Design interface
Widget support CalDAV Integration
Sync tasks with calendar apps:
CalDAV URL: http://YOUR-SERVER-IP:3456/dav/
Username: your-username
Password: your-password
Compatible with:
- Apple Calendar (macOS, iOS)
- Thunderbird
- Evolution
- Any CalDAV-compatible client
Tasks appear as calendar events
Due dates sync bidirectionally API Usage
Generate API token:
1. Settings → API Tokens
2. Click "Create a new token"
3. Label: "Automation Script"
4. Click "Create"
5. Copy token (shown once) Example API request:
# Get all tasks
curl -H "Authorization: Bearer YOUR-TOKEN" http://YOUR-SERVER-IP:3456/api/v1/tasks/all
# Create task
curl -X POST -H "Authorization: Bearer YOUR-TOKEN" -H "Content-Type: application/json" -d '{"title":"New task","list_id":1}' http://YOUR-SERVER-IP:3456/api/v1/lists/1/tasks Backup Procedures
What to Backup
| Component | Priority | Contains |
|---|---|---|
| Database | Critical | All tasks, lists, users |
| Files directory | Important | Attachments, avatars |
| config.yml | Important | Configuration |
Automated Backup Script
Create ~/vikunja/backup.sh:
#!/bin/bash
# Configuration
BACKUP_DIR="/mnt/backups/vikunja"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=30
mkdir -p "$BACKUP_DIR"
echo "Starting Vikunja backup at $(date)"
# For SQLite
if [ -f ~/vikunja/db/vikunja.db ]; then
cp ~/vikunja/db/vikunja.db "$BACKUP_DIR/vikunja-${DATE}.db"
gzip "$BACKUP_DIR/vikunja-${DATE}.db"
echo "SQLite database backed up"
fi
# For PostgreSQL
if docker ps | grep -q vikunja-db; then
docker exec vikunja-db pg_dump -U vikunja vikunja | gzip > "$BACKUP_DIR/vikunja-db-${DATE}.sql.gz"
echo "PostgreSQL database backed up"
fi
# Backup files
tar czf "$BACKUP_DIR/vikunja-files-${DATE}.tar.gz" -C ~/vikunja files/
# Backup config
cp ~/vikunja/config.yml "$BACKUP_DIR/config-${DATE}.yml"
# Clean old backups
find "$BACKUP_DIR" -name "*.gz" -mtime +$RETENTION_DAYS -delete
find "$BACKUP_DIR" -name "*.db" -mtime +$RETENTION_DAYS -delete
find "$BACKUP_DIR" -name "*.yml" -mtime +$RETENTION_DAYS -delete
echo "Backup completed at $(date)" Schedule backups:
chmod +x ~/vikunja/backup.sh
crontab -e
# Add: 0 3 * * * /home/user/vikunja/backup.sh >> /var/log/vikunja-backup.log 2>&1 Restore from Backup
SQLite:
cd ~/vikunja
docker compose down
gunzip < /mnt/backups/vikunja/vikunja-YYYYMMDD.db.gz > db/vikunja.db
tar xzf /mnt/backups/vikunja/vikunja-files-YYYYMMDD.tar.gz -C .
cp /mnt/backups/vikunja/config-YYYYMMDD.yml config.yml
docker compose up -d PostgreSQL:
cd ~/vikunja
docker compose down
docker compose up -d vikunja-db
sleep 10
gunzip < /mnt/backups/vikunja/vikunja-db-YYYYMMDD.sql.gz | docker exec -i vikunja-db psql -U vikunja vikunja
tar xzf /mnt/backups/vikunja/vikunja-files-YYYYMMDD.tar.gz -C .
docker compose up -d Troubleshooting
Issue: Can’t Access Web Interface
# Check container status
docker compose ps
# View logs
docker compose logs vikunja
# Check port availability
sudo netstat -tlnp | grep :3456
# Restart Vikunja
docker compose restart vikunja Issue: Database Connection Failed
# For SQLite - check permissions
ls -la ~/vikunja/db/
chmod 644 ~/vikunja/db/vikunja.db
# For PostgreSQL - verify database is ready
docker compose logs vikunja-db
# Test database connection
docker exec vikunja-db psql -U vikunja -c "SELECT 1"
# Restart in correct order
docker compose restart vikunja-db
sleep 10
docker compose restart vikunja Issue: File Upload Failing
# Check files directory permissions
ls -la ~/vikunja/files/
chmod 755 ~/vikunja/files/
# Check max file size in config.yml
# Should be: maxsize: 20MB or higher
# Check disk space
df -h
# Restart Vikunja
docker compose restart vikunja Issue: Mobile App Can’t Connect
# Verify Vikunja is accessible from mobile device
# From mobile browser, visit: http://YOUR-SERVER-IP:3456
# Check firewall rules
sudo ufw status
sudo ufw allow 3456/tcp
# Verify correct URL in mobile app
# Use IP address, not localhost
# For HTTPS, ensure valid certificate Issue: CalDAV Sync Not Working
# Verify CalDAV is enabled in config.yml
# Test CalDAV endpoint
curl http://YOUR-SERVER-IP:3456/dav/
# Check credentials
# Username: your-vikunja-username (not email)
# Password: your-vikunja-password
# For iOS Calendar:
# Server: YOUR-SERVER-IP:3456
# Path: /dav/
# Username: username (without @) Import from Other Services
Import from Todoist
1. Todoist → Settings → Integrations → Export
2. Download backup file
3. Vikunja → Settings → Migration
4. Select "Todoist"
5. Upload backup file
6. Click "Import"
7. All tasks, projects, labels imported Import from Microsoft To-Do
1. Settings → Migration → Microsoft To-Do
2. Click "Authenticate with Microsoft"
3. Login to Microsoft account
4. Grant permissions
5. Select lists to import
6. Click "Import" Import from Wunderlist
1. Download Wunderlist export file (if available)
2. Settings → Migration → Wunderlist
3. Upload export file
4. Map Wunderlist folders to Vikunja lists
5. Import Advanced Configuration
Enable Email Reminders
Update config.yml:
mailer:
enabled: true
host: smtp.gmail.com
port: 587
username: your-[email protected]
password: your-app-password
fromemail: [email protected]
skiptlsverify: false Restart Vikunja:
docker compose restart vikunja Configure HTTPS
Using Caddy reverse proxy:
Create Caddyfile:
vikunja.yourdomain.com {
reverse_proxy vikunja:3456
encode gzip
} Update config.yml:
service:
publicurl: https://vikunja.yourdomain.com Disable Public Registration
After creating accounts:
service:
enableregistration: false Only admin can create users via CLI:
docker exec -it vikunja ./vikunja user create --username newuser --email [email protected] --password securepass Conclusion
Vikunja provides a powerful, beautiful task management experience with complete privacy and control. Whether for personal productivity or team collaboration, Vikunja delivers enterprise features without the enterprise cost.
What You’ve Accomplished:
- Deployed Vikunja with your choice of database
- Created projects and organized tasks
- Explored multiple view types (list, kanban, gantt, calendar)
- Set up team collaboration and sharing
- Configured mobile apps and CalDAV sync
- Implemented automated backups
- Learned import from commercial services
Next Steps:
- Import existing tasks from Todoist or Microsoft To-Do
- Set up CalDAV for calendar integration
- Install mobile apps for on-the-go access
- Configure email reminders
- Set up HTTPS for secure access
- Create automation with API
- Train team on advanced features
Start managing your tasks with the freedom and simplicity of self-hosting!