Vikunja
Vikunja manages tasks in kanban boards, lists, Gantt and table views. Two containers — a single binary serving both API and interface, and PostgreSQL.
Last run on a host 8 Nov 2026 · data restored from a backup
Pinned at 2.8.0 (released 5 Nov 2026) · the newest upstream release
In the upstream images: 1 CRITICAL · 25 HIGH with a published fix — per image
To try it: Docker, and the same build step, which the local stack runs too. See Try it locally.
To deploy it behind the proxy: Traefik running and a domain, and a build step — the image is built locally from source.
Try it locally
Section titled “Try it locally”On your own machine, with no proxy, domain or certificate. From business/vikunja/:
cp .env.local.example .env.local
# The secrets ship empty; generate the ones this stack needs{ echo "DB_PASSWORD=$(openssl rand -base64 32 | tr -d '\n')" echo "JWT_KEY=$(openssl rand -base64 48 | tr -d '\n')"} >> .env.local
docker compose -f docker-compose.local.yml --env-file .env.local builddocker compose -f docker-compose.local.yml --env-file .env.local up -dThen open http://localhost:3456. Stop it again with the same command and down.
Installation
Section titled “Installation”From business/vikunja/:
-
Copy the environment file and set
APP_TRAEFIK_HOSTandTZ:Terminal window cp .env.example .env -
Generate the secrets. The last two are placeholders that have to exist even when the features are off:
Terminal window mkdir -p .secretsopenssl rand -base64 48 | tr -d '\n' > .secrets/jwt_key.txtopenssl rand -base64 32 | tr -d '\n' > .secrets/db_pwd.txtprintf 'placeholder' > .secrets/oidc_secret.txtprintf 'placeholder' > .secrets/smtp_pwd.txt -
Build the image:
Terminal window docker compose build -
Start it:
Terminal window docker compose up -d -
Open
https://<APP_TRAEFIK_HOST>and register the first account.
Verify
Section titled “Verify”docker compose ps # two services, healthyThen create a project, add a task and attach a file. The attachment lives in a separate volume from the database, so it is the part a database-only backup would miss.
Going further
Section titled “Going further”Single sign-on through Authentik
Section titled “Single sign-on through Authentik”Vikunja can authenticate against Authentik. Two things are easy to miss: the application in Authentik needs at least one group or user binding, or the login endpoint answers 403; and the container has to be able to resolve the Authentik hostname, which is automatic with public DNS and needs a host entry on a server without it.
Replace the placeholder in .secrets/oidc_secret.txt when enabling it.
Why the healthcheck is an HTTP request
Section titled “Why the healthcheck is an HTTP request”Vikunja’s built-in vikunja healthcheck command starts without the database
password and therefore always fails. The stack checks the running server over
HTTP instead.
Named volumes rather than bind mounts
Section titled “Named volumes rather than bind mounts”Data lives in Docker named volumes, not under the stack directory. Their host
paths are /var/lib/docker/volumes/vikunja_<name>/_data.
Backup
Section titled “Backup”| Database | PostgreSQL, container vikunja-db, database vikunja, user vikunja |
| Password | .secrets/db_pwd.txt |
| State | db_data (database) · vikunja_files (task attachments) |
| Also needed | .secrets/jwt_key.txt |
| Quiescing | Not needed — the dump is consistent on its own. |
For borgmatic:
postgresql_databases: - name: vikunja username: vikunja # The server's own client, inside its container pg_dump_command: docker exec vikunja-db pg_dump pg_restore_command: docker exec -i vikunja-db pg_restore psql_command: docker exec -i vikunja-db psqljwt_key.txt signs the session tokens. Restoring without it logs everyone out —
recoverable, but it happens without explanation.
Restore order: database, then the application.
Updates
Section titled “Updates”-
Read the release notes.
-
Back up the database, the attachment volume and the key together.
-
Raise
APP_TAGin.env, then rebuild — the local layer has to be applied to the new upstream image:Terminal window docker compose build --pulldocker compose up -d -
Open a project with an attachment.
Troubleshooting
Section titled “Troubleshooting”Login through Authentik returns 403. The application in Authentik has no group or user binding.
The container cannot reach Authentik. It cannot resolve the hostname. Add it
to the Docker host’s /etc/hosts where public DNS does not cover it.
docker compose up fails with a missing image. The build step was skipped.
This stack does not pull a ready-made image.
Everyone is logged out after a restore. jwt_key.txt does not match.
Repository files
Section titled “Repository files”business/vikunja/README.md— setup, the custom build, known issuesbusiness/vikunja/UPSTREAM.md— source and upgrade checklist
Official sources
Section titled “Official sources”© 2026 SecDockBlueCode Apache-2.0Site content CC BY-NC 4.0