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.
Navigate to https://tasks.haiven.site in a browser.
Register the admin account:
Verify the deployment is functional:
./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.
Once the admin account (and any additional invited user accounts) are created, disable public self-registration:
/mnt/apps/docker/vikunja/.env:VIKUNJA_SERVICE_ENABLEREGISTRATION=false
bash
docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml restart vikunja
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.
Vikunja calls its kanban columns "buckets". Each project can switch between list view and board view.
Enable board view:
Add buckets:
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.
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:
Configure DAVx5 (Android — recommended, well-tested):
https://tasks.haiven.site/dav/Configure Apple Calendar / Reminders (iOS/macOS):
tasks.haiven.siteNote: 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 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:
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 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:
https://sso.haiven.site): create an OAuth2/OIDC Provider named "Vikunja" with redirect URI https://tasks.haiven.site/auth/openid/authentik.vikunja pointing to that provider./mnt/apps/docker/vikunja/.env:VIKUNJA_AUTH_OPENID_PROVIDERS_AUTHENTIK_CLIENTID=<client-id>
VIKUNJA_AUTH_OPENID_PROVIDERS_AUTHENTIK_CLIENTSECRET=<client-secret>bash
docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml restart vikunjaKnown limitations after OIDC is enabled:
preferred_username claim is not configured in Authentik, Vikunja assigns a random UUID as the username on first OIDC login. Configure the claim in the provider's Advanced Protocol Settings.# 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
| 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) |
docker exec vikunja-db pg_dump -U vikunja vikunja \
| gzip > /mnt/storage/backups/vikunja/vikunja-$(date +%Y%m%d_%H%M%S).sql.gz
rsync -avz /mnt/apps/docker/vikunja/files/ /mnt/storage/backups/vikunja/files/
# 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
Two items are pending from the implementation plan (Section 13):
dump_vikunja_postgres to pre-backup-dumps.sh:bash
dump_vikunja_postgres() {
dump_postgres "vikunja" "vikunja-db" "vikunja" "vikunja"
}/mnt/apps/docker/vikunja/files to the service-state location in /mnt/apps/docker/backup/autorestic.yml.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.