2 minute read

What is Vikunja?

As a longtime user of Todoist, I have been eagerly awaiting an open-source and self-hosted alternative with all the features that I like. So far, it looks like Vikunja will be that replacement!

Vikunja allows me to track tasks on my dashboard and create projects that team members can access, all accessible through an easy dashboard. I use a PWA and CalDAV to access my tasks on mobile. I’d prefer a native app, but this works for now.

A screenshot of the dark theme Vikunja dashboard with some tasks and projects.

Deploying Vikunja

My Vikunja deployment depends on two servers in my homelab rack. Lavender is an Ubuntu server that handles incoming connections as an Nginx reverse proxy and Mint is a Rocky server that hosts several services including Vikunja.

Mint Configuration

Thanks to Vikunja’s fairly thorough Docker installation guide it was easy to deploy using the compose.yml I’ve included below. The configuration I settled on allows users to perform password resets and configure email reminders for tasks.

version: "3"

services:
  db:
    image: postgres:13
    environment:
      POSTGRES_PASSWORD: <secret>
      POSTGRES_USER: <secret>
    volumes:
      - ./db:/var/lib/postgresql/data
    restart: unless-stopped
  api:
    image: vikunja/api
    environment:
      VIKUNJA_DATABASE_HOST: db
      VIKUNJA_DATABASE_PASSWORD: <secret>
      VIKUNJA_DATABASE_TYPE: postgres
      VIKUNJA_DATABASE_USER: <secret>
      VIKUNJA_DATABASE_DATABASE: vikunja
      VIKUNJA_SERVICE_JWTSECRET: <secret>
      VIKUNJA_SERVICE_FRONTENDURL: https://todo.beans.team/
      VIKUNJA_SERVICE_ENABLETASKATTACHMENTS: 1
      VIKUNJA_SERVICE_ENABLEREGISTRATION: 0
      VIKUNJA_SERVICE_ENABLEEMAILREMINDERS: 1
      VIKUNJA_MAILER_ENABLED: 1
      VIKUNJA_MAILER_FORCESSL: 1
      VIKUNJA_MAILER_HOST: <secret>
      VIKUNJA_MAILER_PORT: <secret>
      VIKUNJA_MAILER_USERNAME: <secret>
      VIKUNJA_MAILER_PASSWORD: <secret>
      VIKUNJA_MAILER_FROMEMAIL: <secret>
    ports:
      - 3456:3456
    volumes:
      - ./files:/app/vikunja/files
    depends_on:
      - db
    restart: unless-stopped
  frontend:
    image: vikunja/frontend
    restart: unless-stopped
  proxy:
    image: nginx
    ports:
      - 4321:80
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      - api
      - frontend
    restart: unless-stopped

The only snag I hit on the way was attempting to handle the Nginx configuration on Lavender which caused issues with my firewall configuration. I settled on using Vikunja’s nginx.conf within the compose script to handle connections in the way that the application was expecting.

server {
    listen 80;

    location / {
        proxy_pass http://frontend:80;
    }

    location ~* ^/(api|dav|\.well-known)/ {
        proxy_pass http://api:3456;
        client_max_body_size 20M;
    }
}

Lavender Configuration

After configuring my DNS settings with my domain provider I deployed a new site configuration in Nginx to direct incoming traffic from my todo. subdomain to the correct port on Mint. Once I was able to validate the new configuration I used Certbot to issue a new certificate for the subdomain to enable HTTPS.

server {
    server_name todo.beans.team;

    location / {
        proxy_pass http://mint:4321;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/todo.beans.team/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/todo.beans.team/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

Vikunja CLI

Since I disabled self registration adding new users requires that I use the Vikunja CLI, so here are some commands that I found useful. When using docker these have to be executed from the API container.

docker exec vikunja-api-1 ./vikunja subcommand

User List

Outputs a table of all registered users.

vikunja user list

User Create

Registers a new user.

vikunja user create -e user@email.com -u username

After running this command you will be prompted to enter a password.

Dump

Creates a zip file of all Vikunja data including the full database.

vikunja dump

There are many more, but you can find them in the official documentation.