Taking Back Control of Your Task List
Vikunja is an open-source task and project manager that runs entirely on your own server. Think Todoist or Trello, but without subscription fees, data harvesting, or the anxiety of a company deciding to sunset the product. You get kanban boards, list views, Gantt charts, team collaboration, and a clean REST API – all hosted on hardware you control.
The case for self-hosting a task manager is stronger than it might first appear. Productivity data is surprisingly personal: it reveals your work patterns, your deadlines, your team structures, and the internal names of projects you may not want sitting on a third-party server. Vikunja keeps all of that local.
Setup takes under an hour with Docker, and the result is a full-featured project management tool that works from any browser.

What You Need Before Starting
Vikunja runs comfortably on modest hardware. A small VPS with 1GB of RAM and 10GB of storage is more than enough for personal use or a small team. For larger teams with heavy usage, 2GB RAM and a dedicated volume for database files is a smarter starting point. The application itself is lightweight – the database is where the resource demand grows over time.
You will need Docker and Docker Compose installed on your server. A domain name pointed at your server is strongly recommended, since Vikunja’s frontend and API both need stable URLs for the app to work correctly across devices. If you plan to expose the instance to the internet, an SSL certificate through Let’s Encrypt is not optional – it is what makes login sessions secure. For a private network setup without exposing anything to the public internet, running Vikunja behind a self-hosted VPN like Headscale keeps your instance accessible only to authorized devices.
You will also want a reverse proxy. Nginx Proxy Manager, Caddy, or plain Nginx all work. Caddy is the easiest for automatic HTTPS if you are not already running a proxy on your server. Pick whichever fits your existing stack and stick with it – mixing proxy configurations mid-setup creates headaches that are hard to debug.
Standing Up Vikunja with Docker Compose
Create a project directory on your server – something like /opt/vikunja – and inside it, create a docker-compose.yml file. Vikunja’s official Docker setup requires three services: the database, the API backend, and the frontend. The database can be PostgreSQL, MySQL/MariaDB, or SQLite. PostgreSQL is the right choice for anything beyond a single-user personal instance.
A working compose file looks like this:
- db – a PostgreSQL container with environment variables for your database name, user, and password, plus a named volume to persist data.
- vikunja-api – the vikunja/api image, configured with environment variables pointing to your database, a JWT secret for session signing, your public-facing frontend URL, and the email settings if you want account verification or password resets.
- vikunja-frontend – the vikunja/frontend image, which only needs to know the API URL so the browser-side app can make requests to the right endpoint.
Critical environment variables for the API container include VIKUNJA_DATABASE_TYPE, VIKUNJA_DATABASE_HOST, VIKUNJA_DATABASE_DATABASE, VIKUNJA_DATABASE_USER, VIKUNJA_DATABASE_PASSWORD, and VIKUNJA_SERVICE_JWTSECRET. Set VIKUNJA_SERVICE_FRONTENDURL to your actual domain. For the frontend, set VITE_APP_API_URL to the API’s public URL. Once your compose file is ready, run docker compose up -d and check logs with docker compose logs -f to confirm all three services started cleanly.

Reverse Proxy and HTTPS Configuration
With all three containers running, the next step is routing external traffic to them. Vikunja’s frontend runs on port 80 inside its container, and the API defaults to port 3456. Your reverse proxy needs two separate server blocks or proxy hosts: one pointing your main domain (say, tasks.yourdomain.com) to the frontend container, and a second pointing something like api.tasks.yourdomain.com to port 3456 on the API container. Some setups use a single domain with path-based routing – /api proxied to the API container and everything else to the frontend – which works but requires more precise proxy configuration to avoid stripping request headers.
If you are using Caddy, the configuration is minimal. A basic Caddyfile block for the frontend is just your domain followed by a reverse_proxy directive pointing to the container name and port. Caddy handles certificate issuance and renewal automatically. Nginx requires a server block with a proxy_pass, proxy_set_header Host, and proxy_set_header X-Real-IP at minimum, plus a Certbot call for the SSL certificate.
After the proxy is running and HTTPS is active, open your domain in a browser. The Vikunja login screen should appear. The first registered account automatically receives admin privileges, so create your account immediately after setup rather than leaving registration open. Admin controls live at /admin and let you manage users, configure OIDC login if you want single sign-on, and adjust rate limiting.
Organizing Your Work Inside Vikunja
Vikunja structures everything in a hierarchy: namespaces contain projects, projects contain tasks, and tasks support subtasks, comments, attachments, labels, due dates, priorities, assignees, and reminders. The kanban view and the Gantt view are both built in – you switch between them per-project using the view toggle at the top of the project screen. No plugins or extensions required.
For teams, you invite users to specific projects or entire namespaces and assign them one of three roles: viewer, editor, or admin. This means you can share a client-facing project board without giving that client visibility into your internal planning namespace. Task assignments send in-app notifications, and if you configured email during setup, users get email alerts for mentions, due date reminders, and assignment changes.
Vikunja also exposes a full REST API, which makes it connectable to automation tools like n8n or Zapier. You can create tasks from form submissions, push completed task data to a dashboard, or sync with calendar apps that support iCal – Vikunja generates a per-user iCal feed URL that any calendar client can subscribe to. That feed updates automatically as tasks and deadlines change.

Keeping It Running
The one thing that will catch new Vikunja operators off guard is the lack of built-in backup tooling. Your PostgreSQL volume holds everything – lose it and the instance is gone. A simple cron job running pg_dump inside the database container and pushing the output to off-site storage is the minimum acceptable backup strategy. Pair that with occasional checks of your docker compose logs output for database connection errors, and you have a self-hosted task manager that will outlast any SaaS subscription you would have otherwise signed up for.





