Vikunja is a task and project manager that you can self-host with Docker in a matter of minutes, and it now fits into a single image. In this guide you bring up the application alongside a PostgreSQL database with a single docker-compose.yml file, learn how to set the essential variables, how to organize your tasks in list, kanban, Gantt and table views, and how to publish it over HTTPS behind a reverse proxy. The same explanation is available in Spanish.

Key takeaways

  • Vikunja is an open-source task manager licensed under AGPLv3, written in Go, that replaces services like Todoist or Trello and keeps your data on your own server.
  • Since the unified release, everything lives in a single image vikunja/vikunja; you no longer have to combine vikunja/api and vikunja/frontend separately.
  • The container listens on port 3456 and runs as user 1000, so the attachments folder must belong to that UID before you start it.
  • It supports three databases (SQLite by default, MySQL/MariaDB and PostgreSQL); for serious use a PostgreSQL in its own container is best.
  • The VIKUNJA_SERVICE_PUBLICURL variable is mandatory: without the correct public URL, the frontend cannot find the API when you put it behind a proxy.

What is Vikunja?

Vikunja is an open-source application for managing tasks and projects that you host on your own infrastructure, a self-hosted replacement for tools like Todoist, Trello or Asana. Its motto sums up the idea well: it is the task manager you actually own, because the data stays on your server and not in a third party’s cloud.

It is written in Go, which means a single lightweight binary, with a Vue frontend that also works as an installable web app (PWA) on mobile. It is released under the AGPLv3 license and exposes a full REST API, so you can connect your own clients or integrate it with other tools. It ships built-in migration from Todoist, Trello and Microsoft To-Do, so moving from one of those platforms is just a matter of importing a file.

What views does it offer: list, kanban, Gantt and calendar?

The big advantage of Vikunja over a simple to-do list is that each project can be seen in several ways at once. Since the multiple-views system introduced in version 0.24, you define whichever views you want per project and switch between them with one click:

  • List: the classic view, ideal for day-to-day work and for ticking tasks off.
  • Kanban board: draggable columns (to do, in progress, done) to track the state of a workflow.
  • Gantt: a timeline perfect for planning deadlines and due dates at a glance.
  • Table: a grid with columns for priority, labels, assignees and dates.

For the calendar, Vikunja does not include a monthly calendar view as such, but it does offer CalDAV integration: you subscribe your usual calendar app (your phone’s, Thunderbird or another) to the Vikunja server and your dated tasks appear there automatically. On top of that, the new query-language filter system lets you build precise views such as "my tasks due this week".

The Vikunja docker-compose.yml with a database

Create a folder for the project, prepare the attachments folder with the right user and save this docker-compose.yml inside it. Replace each change_this_key... value with your own password and the secret with a long random string before starting:

services:
  db:
    image: postgres:17-alpine
    restart: unless-stopped
    volumes:
      - db_data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: vikunja
      POSTGRES_PASSWORD: change_this_db_key
      POSTGRES_DB: vikunja
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U vikunja"]
      interval: 30s
      timeout: 5s
      retries: 5

  vikunja:
    image: vikunja/vikunja:2.3.0
    restart: unless-stopped
    ports:
      - "3456:3456"
    depends_on:
      db:
        condition: service_healthy
    volumes:
      - ./files:/app/vikunja/files
    environment:
      VIKUNJA_SERVICE_PUBLICURL: "http://localhost:3456"
      VIKUNJA_SERVICE_SECRET: change_this_long_random_secret_key
      VIKUNJA_SERVICE_ENABLEREGISTRATION: "true"
      VIKUNJA_DATABASE_TYPE: postgres
      VIKUNJA_DATABASE_HOST: db
      VIKUNJA_DATABASE_USER: vikunja
      VIKUNJA_DATABASE_PASSWORD: change_this_db_key
      VIKUNJA_DATABASE_DATABASE: vikunja

volumes:
  db_data:

Notice a few details in the file. The application does not start until PostgreSQL passes its healthcheck, thanks to depends_on with the service_healthy condition. The container listens on port 3456 and we publish it on the same port of the host. The attachments you upload to tasks are stored in a ./files bind mount, and because Vikunja runs as UID 1000, that folder must belong to that user. Prepare it before the first boot:

mkdir -p files
sudo chown 1000:1000 files
docker compose up -d
docker compose ps

When the log stops moving, open http://localhost:3456 in the browser. You will see Vikunja’s welcome screen ready to create the first account.

Key configuration variables

Vikunja is configured entirely with environment variables prefixed VIKUNJA_. Three of them are worth understanding well:

  • VIKUNJA_SERVICE_PUBLICURL is the most important: it must match the exact URL through which users reach the application (with its https:// scheme and no extra trailing slash). If you set it wrong, the frontend will load but cannot talk to the API and you will see network errors when signing in.
  • VIKUNJA_SERVICE_SECRET is the secret used to sign the JWT session tokens. Generate a long, random string; if you change this value, all open sessions are invalidated. The old VIKUNJA_SERVICE_JWTSECRET still works but is deprecated.
  • VIKUNJA_SERVICE_ENABLEREGISTRATION defaults to true. Leave it that way just long enough to create your user, then set it to false and recreate the container; otherwise anyone who reaches your instance could register.

A good practice is to move these values into a .env file rather than writing them directly in the Compose file; it is the same pattern other tools in this series use, such as Firefly III for your personal finances. To start from scratch, you first need Docker installed; follow the guide to install Docker on Ubuntu 24.04 if that is your case.

How do you publish it with a reverse proxy and HTTPS?

Serving Vikunja over plain HTTP is only fine for tests on your local network. To take it to the Internet with a valid certificate, place it behind a reverse proxy that handles TLS. With Nginx Proxy Manager you just create a "proxy host" pointing to the container on port 3456 and request a Let’s Encrypt certificate from its interface.

If you prefer Traefik, remove the ports section from the vikunja service, connect it to the proxy network and add these labels:

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.vikunja.rule=Host(`tasks.mydomain.com`)"
      - "traefik.http.routers.vikunja.entrypoints=websecure"
      - "traefik.http.routers.vikunja.tls.certresolver=le"
      - "traefik.http.services.vikunja.loadbalancer.server.port=3456"

The step you must not forget: update VIKUNJA_SERVICE_PUBLICURL to your real domain with HTTPS (for example https://tasks.mydomain.com) and recreate the container. It is the most common mistake when publishing Vikunja: the proxy works, but the frontend still points to localhost and login fails.

Frequently asked questions

Do I really need PostgreSQL or is SQLite enough?

For a personal, low-use instance, SQLite (the default backend) works with no configuration: it is stored in a file inside the volume. But if you are going to be several users, or you want more robust backups and better performance with many tasks, a PostgreSQL database in its own container is the recommended option, and it is the one we used in the docker-compose.yml above.

Why should I not use the image’s latest tag?

Because :latest changes without warning, and a major update could introduce database migrations or configuration changes during a simple restart. By pinning vikunja/vikunja:2.3.0 you decide when you update: you read the release notes first, take a backup and only then bump the tag. Version 2.3.0 was released in April 2026 with 277 commits and several security fixes.

How do I back up Vikunja?

You need two pieces: the database dump and the attachments folder. Export PostgreSQL with pg_dump and copy the ./files bind mount, where the files you attach to tasks live:

docker compose exec db pg_dump -U vikunja vikunja > vikunja-db.sql
tar czf vikunja-files.tar.gz files

With those two elements you can restore the whole instance on another server.

Conclusion

With a single docker-compose.yml you have a complete, private task manager: application and database, with list, kanban, Gantt and table views, and all the data on your server. The logical next step is to publish it securely behind Nginx Proxy Manager or Traefik, set VIKUNJA_SERVICE_PUBLICURL to your domain and schedule backups of the database and attachments. From there, import your tasks from Todoist or Trello and organize your projects your way.

Sources

  1. Official Vikunja documentation
  2. go-vikunja/vikunja repository on GitHub
  3. Official vikunja image on Docker Hub

Route: Self-hosted docs and productivity with Docker