Vikunja User Guide

Operator and end-user guide for Vikunja at tasks.haiven.site. Covers first-time setup, day-to-day usage, and common operations. For deep implementation detail (OIDC internals, compose design, backup integration), see the full plan at /mnt/apps/docker/_server-setup/08/08l-vikunja-v2.md.


Table of Contents

  1. First-User Setup
  2. Lock Down Registration
  3. Kanban Boards
  4. CalDAV Setup
  5. API Token Generation
  6. OIDC Enablement (Authentik)
  7. Common Operator Commands
  8. Backup and Restore
  9. Upgrade

First-User Setup

Navigate to https://tasks.haiven.site in a browser.

Register the admin account:

  1. Click Register on the login page.
  2. Enter your email, a username, and a strong password. Store it in Bitwarden.
  3. Vikunja grants admin rights automatically to the first registered user — no manual role assignment needed.

Verify the deployment is functional:

  1. Create a project named "Inbox".
  2. Add a task with a due date and a label.
  3. Switch to kanban view to confirm the board renders.
  4. Attach a small file to a task — this verifies the ./files/ volume is writable.

Check email is working:

Trigger a test by initiating a password reset for your account. Check MailPit at https://mail.haiven.site to confirm the email arrived via smtp-relay.


Lock Down Registration

Once the admin account (and any additional invited user accounts) are created, disable public self-registration:

  1. Edit /mnt/apps/docker/vikunja/.env:

VIKUNJA_SERVICE_ENABLEREGISTRATION=false

  1. Restart Vikunja:

bash docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml restart vikunja

  1. Verify: open an incognito window and confirm the Register link is gone from the login page.

After OIDC is confirmed working, consider also disabling local auth to enforce SSO-only login:

VIKUNJA_AUTH_LOCAL_ENABLED=false

Keep at least one local admin account as a break-glass before doing this. If Authentik is unreachable and local auth is disabled, you are locked out.


Kanban Boards

Vikunja calls its kanban columns "buckets". Each project can switch between list view and board view.

Enable board view:

  1. Open a project.
  2. Click the view toggle (top-right) and select Board.

Add buckets:

  1. In board view, click + Add bucket at the right edge.
  2. Name the bucket (e.g., "To Do", "In Progress", "Done").

Drag tasks between buckets:

Swimlanes (grouping by assignee or label): available under the view options menu.

Filter by label or assignee: use the filter bar at the top of any view.


CalDAV Setup

Vikunja exposes a CalDAV endpoint at https://tasks.haiven.site/dav/. This allows task sync with DAVx5, Tasks.org, Apple Calendar, and other CalDAV clients.

Important: OIDC credentials cannot be used for CalDAV. You must generate a dedicated CalDAV token.

Generate a CalDAV token:

  1. Log into Vikunja via browser.
  2. Go to Account Settings (top-right avatar) → CalDAV.
  3. Click Create token and copy the generated token.

Configure DAVx5 (Android — recommended, well-tested):

  1. Open DAVx5 → Add accountLogin with URL and user name.
  2. Server URL: https://tasks.haiven.site/dav/
  3. Username: your Vikunja username (not email).
  4. Password: the CalDAV token you just generated.
  5. Proceed through account setup; DAVx5 discovers the task lists automatically.

Configure Apple Calendar / Reminders (iOS/macOS):

  1. Go to SettingsCalendarAccountsAdd AccountOtherAdd CalDAV Account.
  2. Server: tasks.haiven.site
  3. Username: your Vikunja username.
  4. Password: CalDAV token.

Note: Apple's native CalDAV support has known compatibility issues with some Vikunja features. If sync is unreliable, use a dedicated CalDAV app (e.g., Tasks: Todo Lists & Planner on iOS).


API Token Generation

API tokens allow access to Vikunja's REST API without using your account password. They are also the recommended auth method for mobile apps (the Vikunja mobile apps have known OIDC bugs).

Generate an API token:

  1. Log into Vikunja via browser.
  2. Go to Account SettingsAPI Tokens.
  3. Click Create Token.
  4. Set an expiry date and select the permission scopes needed.
  5. Copy the token immediately — it is shown only once. Tokens have a tk_ prefix.

Use the token:

curl -H "Authorization: Bearer tk_<your-token>" \
  https://tasks.haiven.site/api/v1/projects

Mobile app auth:

In the Vikunja Android or iOS app, choose API Token as the login method instead of username/password or OIDC. Paste the tk_ token. This bypasses the OIDC mobile bugs entirely.

Full API reference: https://tasks.haiven.site/api/v1/docs (live Swagger UI, 118 endpoints)


OIDC Enablement (Authentik)

OIDC is partially configured from launch (the env vars are set) but requires the Authentik provider and application to be created. See the full steps in the implementation plan at /mnt/apps/docker/_server-setup/08/08l-vikunja-v2.md Section 12.

Summary of what is needed:

  1. In Authentik admin (https://sso.haiven.site): create an OAuth2/OIDC Provider named "Vikunja" with redirect URI https://tasks.haiven.site/auth/openid/authentik.
  2. Create an Application with slug vikunja pointing to that provider.
  3. Copy the Client ID and Client Secret from the provider.
  4. Update /mnt/apps/docker/vikunja/.env:
    VIKUNJA_AUTH_OPENID_PROVIDERS_AUTHENTIK_CLIENTID=<client-id> VIKUNJA_AUTH_OPENID_PROVIDERS_AUTHENTIK_CLIENTSECRET=<client-secret>
  5. Restart Vikunja:
    bash docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml restart vikunja
  6. Verify: the login page shows a Log in with authentik button.

Known limitations after OIDC is enabled:


Common Operator Commands

# Start the stack
docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml up -d

# Stop the stack
docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml down

# Restart Vikunja only (not the DB)
docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml restart vikunja

# Follow live logs
docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml logs -f vikunja

# Follow DB logs
docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml logs -f vikunja-db

# Check health status
docker inspect vikunja --format='{{.State.Health.Status}}'
docker inspect vikunja-db --format='{{.State.Health.Status}}'

# API smoke test via Traefik
curl -sf https://tasks.haiven.site/api/v1/info | python3 -m json.tool

# DB shell (debugging)
docker exec -it vikunja-db psql -U vikunja -d vikunja

# List DB tables (verify migrations ran)
docker exec vikunja-db psql -U vikunja -d vikunja -c "\dt"

# Fix files volume ownership
chown -R 1000:1000 /mnt/apps/docker/vikunja/files/

# Validate compose file
docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml config > /dev/null && echo "OK"

# Check Redis is being used (index 2)
docker exec redis redis-cli -n 2 keys "*"

# Rotate JWT secret (logs everyone out)
# 1. openssl rand -hex 32
# 2. Update VIKUNJA_SERVICE_JWTSECRET in .env
# 3. docker compose restart vikunja

Backup and Restore

What to back up

Component Location Method
Database vikunja DB in vikunja-db pg_dump
Files /mnt/apps/docker/vikunja/files/ rsync
Config config.yml, docker-compose.yml git (in version control)
Secrets .env Bitwarden (do NOT commit)

Manual database backup

docker exec vikunja-db pg_dump -U vikunja vikunja \
  | gzip > /mnt/storage/backups/vikunja/vikunja-$(date +%Y%m%d_%H%M%S).sql.gz

Manual files backup

rsync -avz /mnt/apps/docker/vikunja/files/ /mnt/storage/backups/vikunja/files/

Database restore

# 1. Stop Vikunja (not the DB)
docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml stop vikunja

# 2. Drop and recreate the database
docker exec -it vikunja-db psql -U vikunja -d postgres \
  -c "DROP DATABASE vikunja WITH (FORCE);"
docker exec -it vikunja-db psql -U vikunja -d postgres \
  -c "CREATE DATABASE vikunja OWNER vikunja;"

# 3. Restore
gunzip -c /mnt/storage/backups/vikunja/<timestamp>.sql.gz \
  | docker exec -i vikunja-db psql -U vikunja -d vikunja

# 4. Start Vikunja (runs migrations automatically)
docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml start vikunja

Haiven backup integration

Two items are pending from the implementation plan (Section 13):

  1. Add dump_vikunja_postgres to pre-backup-dumps.sh:
    bash dump_vikunja_postgres() { dump_postgres "vikunja" "vikunja-db" "vikunja" "vikunja" }
  2. Add /mnt/apps/docker/vikunja/files to the service-state location in /mnt/apps/docker/backup/autorestic.yml.

Upgrade

Vikunja runs xormigrate database migrations automatically on startup. No manual schema changes are required between versions.

# 1. Review upstream changelog at kolaente.dev/vikunja/vikunja/releases
# 2. Update the image tag in docker-compose.yml (e.g., 2.3.0 -> 2.4.0)
# 3. Pull and redeploy
docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml pull
docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml up -d

# 4. Watch migration output
docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml logs -f vikunja

Look for xormigrate lines in the logs. A clean startup with no migration errors indicates a successful upgrade. If migration fails, restore from the pre-upgrade backup before retrying.