Skip to main content

How to Self-Host Vikunja: Open Source Todoist and TickTick Alternative 2026

·OSSAlt Team
vikunjataskstodoproductivityself-hostingdocker2026

TL;DR

Vikunja (GPL 3.0, ~3K GitHub stars, Go + Vue) is a self-hosted task management app — a free replacement for Todoist or TickTick. It supports projects, team sharing, labels, priorities, due dates, recurring tasks, reminders, and CalDAV sync (connects to any CalDAV client for todo sync). Todoist Pro costs $4/month; TickTick Premium $2.79/month. Vikunja is free to self-host. Single Go binary + SQLite/MySQL/PostgreSQL backend.

Key Takeaways

  • Vikunja: GPL 3.0, ~3K stars — full-featured todo manager, CalDAV sync
  • CalDAV sync: Connect to iOS/macOS Reminders, Thunderbird, DAVx⁵ for bidirectional task sync
  • Team sharing: Share projects with team members, assign tasks
  • Multiple views: List, Gantt chart, table view
  • Reminders: Push notifications, email reminders
  • Labels and priorities: Organize tasks across projects

Vikunja vs Todoist vs Alternatives

FeatureVikunjaTodoist ProTasks.org (OSS)
LicenseGPL 3.0ProprietaryGPL 3.0
CostFree$4/moFree
CalDAVYesNoYes
Team projectsYesYesNo (personal)
SubtasksYesYesYes
Recurring tasksYesYesYes
LabelsYesYesYes
PrioritiesYesYesYes
Gantt chartYesNo (add-on)No
Mobile appPWA (web)iOS/AndroidAndroid only
APIYesYes
Self-hostedYesNo

Part 1: Docker Setup

# docker-compose.yml
services:
  vikunja:
    image: vikunja/vikunja:latest
    container_name: vikunja
    restart: unless-stopped
    ports:
      - "3456:3456"
    volumes:
      - vikunja_files:/app/vikunja/files
      - ./config.yml:/app/vikunja/config.yml:ro
    depends_on:
      - db
    environment:
      VIKUNJA_DATABASE_TYPE: postgres
      VIKUNJA_DATABASE_HOST: db
      VIKUNJA_DATABASE_DATABASE: vikunja
      VIKUNJA_DATABASE_USER: vikunja
      VIKUNJA_DATABASE_PASSWORD: "${POSTGRES_PASSWORD}"
      VIKUNJA_SERVICE_JWTSECRET: "${JWT_SECRET}"
      VIKUNJA_SERVICE_FRONTENDURL: "https://tasks.yourdomain.com"

  db:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: vikunja
      POSTGRES_USER: vikunja
      POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U vikunja"]
      interval: 10s

volumes:
  vikunja_files:
  postgres_data:
# .env
POSTGRES_PASSWORD=your-db-password
JWT_SECRET=$(openssl rand -hex 32)

docker compose up -d

Visit http://your-server:3456 → register your account.


Part 2: HTTPS with Caddy

tasks.yourdomain.com {
    reverse_proxy localhost:3456
}

Part 3: Configuration (config.yml)

# config.yml
service:
  JWTSecret: "${VIKUNJA_SERVICE_JWTSECRET}"
  frontendUrl: "https://tasks.yourdomain.com"
  enableRegistration: false      # Set true for initial setup, then disable
  enableEmailReminders: true
  enableTaskAttachments: true
  maxAvatarSize: 1048576         # 1MB

database:
  type: postgres
  host: db
  database: vikunja
  user: vikunja
  password: "${VIKUNJA_DATABASE_PASSWORD}"

mailer:
  enabled: true
  host: smtp.yourdomain.com
  port: 587
  username: noreply@yourdomain.com
  password: "${SMTP_PASSWORD}"
  skiptlsverify: false
  fromemail: noreply@yourdomain.com
  fromname: Vikunja

Part 4: CalDAV Sync

Vikunja exposes a CalDAV endpoint for todo sync with any CalDAV client.

CalDAV URL: https://tasks.yourdomain.com/dav/principals/USER/

iOS Reminders

  1. Settings → Reminders → Accounts → Add Account → Other
  2. Add CalDAV Account
  3. Server: https://tasks.yourdomain.com/dav/
  4. Username + password
  5. iOS Reminders now shows your Vikunja projects as lists

DAVx⁵ (Android)

  1. Install DAVx⁵
  2. Add account with base URL: https://tasks.yourdomain.com/dav/
  3. Enable CalDAV (for todo sync)
  4. Use with Tasks.org or any Android todo app

Thunderbird

  1. Install the TbSync and Provider for CalDAV extensions
  2. Add CalDAV account with the Vikunja DAV URL

Part 5: Creating and Organizing Tasks

Projects (formerly Namespaces + Lists)

My Projects/
  Work/
    Q1 Roadmap
    Bug Backlog
  Personal/
    Shopping
    Home Projects
  1. + New Project → name it
  2. Add tasks within the project

Task Properties

Each task supports:

  • Title + description (Markdown)
  • Due date + time
  • Reminders: Email or push notifications
  • Priority: Urgent / High / Medium / Low / None
  • Labels: Color-coded tags
  • Assignees: Assign to team members
  • Subtasks: Nested task hierarchy
  • Attachments: File uploads
  • Recurring: Daily/weekly/monthly/custom repeat

Bulk Operations

Select multiple tasks → bulk change due date, priority, assignee, labels.


Part 6: Team Sharing

Share a project with other users:

  1. Project → Share → Invite User
  2. Enter their username or email
  3. Set permission: Read, Write, or Admin
  4. They see the project in their dashboard

For public sharing (no account required):

  1. Project → Share → Generate Share Link
  2. Share the link — viewers can see tasks without logging in

Part 7: Views

Switch between views on any project:

  • List: Default linear task list, group by priority/due date/label
  • Gantt Chart: Timeline view for projects with due dates — see task overlaps
  • Table: Spreadsheet-like, shows all task properties as columns
  • Kanban Board: Drag-and-drop cards across status columns

Part 8: Labels

Create labels across all projects:

  1. Labels → + New Label
  2. Set name and color
  3. Apply to any task from any project

Labels are shared across all projects — useful for cross-project filtering:

  • Filter all tasks labeled #urgent across every project

Part 9: API

# Get auth token:
TOKEN=$(curl -s -X POST https://tasks.yourdomain.com/api/v1/login \
  -H "Content-Type: application/json" \
  -d '{"username":"alice","password":"your-password"}' \
  | jq -r .token)

# List all projects:
curl https://tasks.yourdomain.com/api/v1/projects \
  -H "Authorization: Bearer $TOKEN" | jq '.[].title'

# Create a task:
curl -X POST "https://tasks.yourdomain.com/api/v1/projects/42/tasks" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Review pull request",
    "description": "PR #123",
    "due_date": "2026-03-15T10:00:00Z",
    "priority": 3
  }'

# Complete a task:
curl -X POST "https://tasks.yourdomain.com/api/v1/tasks/123" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"done": true}'

Maintenance

# Update Vikunja:
docker compose pull
docker compose up -d

# Backup database:
docker exec db pg_dump -U vikunja vikunja \
  | gzip > vikunja-db-$(date +%Y%m%d).sql.gz

# Backup file attachments:
tar -czf vikunja-files-$(date +%Y%m%d).tar.gz \
  $(docker volume inspect vikunja_vikunja_files --format '{{.Mountpoint}}')

# Logs:
docker compose logs -f vikunja

See all open source productivity and task management tools at OSSAlt.com/categories/productivity.

Comments