A lightweight task manager that’s yours

If you want a simple and powerful task manager that stays entirely under your control, Vikunja is a great choice. This guide shows you how to host it on AlmaLinux 9 inside an LXC container, backed by PostgreSQL and served through Nginx with SSL under the hostname tasks.examplecorp.io.

Why self-hosting your task manager matters

Setting up your own task manager like Vikunja is more than just a technical exercise – it’s about control, privacy, and flexibility. With tasks.examplecorp.io, you now own your data, can adapt the system to your workflow, and avoid subscription lock-ins or third-party limitations.

By self-hosting, you can:

  • Keep your tasks private — no external servers, no data leaks.
  • Customize your setup — integrate with other tools or automate backups.
  • Learn and experiment — hosting your own services strengthens your IT skills and knowledge.

In short, this isn’t just a server setup; it’s an investment in productivity and autonomy. Your tasks, your rules, your environment – all lightweight, secure, and fully yours.

Preparing the LXC Container

Before installing anything, it’s important to define the basic resources for your container. A minimal but balanced setup is sufficient for Vikunja.

Recommended resources:

  • Base image: AlmaLinux 9 (LXC template)
  • CPU: 2 cores
  • Memory: 2 GB RAM
  • Storage: 10 GB (local-lvm or similar)
  • Networking: DHCP or static IP on vmbr0
  • Hostname: tasks.examplecorp.io

Once the container is created, update the system and install basic tools:

dnf update -y
dnf install -y vim wget curl git unzip net-tools nginx postgresql-server

Setting up PostgreSQL

Vikunja relies on a database to store tasks and user information. We’ll use PostgreSQL for stability and performance.

Initialize and start PostgreSQL:

postgresql-setup --initdb
systemctl enable --now postgresql

Switch to the PostgreSQL user and create a database with its own user:

sudo -u postgres psql

Inside psql:

CREATE DATABASE vikunja;
CREATE USER vikunja WITH PASSWORD 'your-strong-password';
GRANT ALL PRIVILEGES ON DATABASE vikunja TO vikunja;
\q

Adjusting PostgreSQL Authentication

By default, PostgreSQL uses ident authentication for local connections. Vikunja requires password authentication. Instead of changing defaults, we’ll add new rules specifically for the Vikunja database.

Edit pg_hba.conf:

nano /var/lib/pgsql/data/pg_hba.conf

Add these lines above the defaults:

# Custom access rules for Vikunja
host    vikunja    vikunja    127.0.0.1/32    md5
host    vikunja    vikunja    ::1/128         md5

Then restart PostgreSQL:

systemctl restart postgresql

Installing the Vikunja Backend

With the database ready, the next step is installing the backend service, which provides the API for tasks and projects.

Download and install the RPM:

wget https://dl.vikunja.io/vikunja/0.24.6/vikunja-0.24.6-x86_64.rpm
dnf install -y vikunja-0.24.6-x86_64.rpm

Backup and edit the configuration:

cp /etc/vikunja/config.yml /etc/vikunja/config.yml.default
nano /etc/vikunja/config.yml

Minimal config:

service:
  frontendurl: https://tasks.examplecorp.io

database:
  type: postgres
  host: 127.0.0.1
  user: vikunja
  password: your-strong-password
  database: vikunja

Enable and start Vikunja:

systemctl enable --now vikunja

Installing the Vikunja Frontend

The frontend delivers the user interface for your browser. We’ll place it in /var/www/vikunja.

wget https://dl.vikunja.io/frontend/vikunja-frontend-0.24.6.zip
unzip vikunja-frontend-0.24.6.zip -d vikunja-frontend
mkdir -p /var/www/vikunja
cp -r -d vikunja-frontend/* /var/www/vikunja/

Configuring Nginx with SSL

To serve Vikunja securely, configure Nginx with SSL. In this example, we assume you already have your SSL certificate and key for tasks.examplecorp.io.

Create the config file:

nano /etc/nginx/conf.d/vikunja.conf

Example configuration:

server {
    listen 80;
    server_name tasks.examplecorp.io;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name tasks.examplecorp.io;

    ssl_certificate     /etc/ssl/certs/tasks.examplecorp.io.crt;
    ssl_certificate_key /etc/ssl/private/tasks.examplecorp.io.key;

    root /var/www/vikunja;
    index index.html;

    location /api/v1/ {
        proxy_pass http://127.0.0.1:3456/api/v1/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location / {
        try_files $uri $uri/ /index.html;
    }
}

Enable Nginx:

systemctl enable --now nginx

Verifying the Installation

Once everything is running, it’s time to make sure your new task manager works.

Check listeners:

netstat -tulpen | grep -E "80|443|3456"

Verify the API:

curl -s https://tasks.examplecorp.io/api/v1/info | jq

Follow logs if needed:

journalctl -u vikunja.service -f

Bringing It All Together

Congratulations – you now have a fully functional, self-hosted task manager running at https://tasks.examplecorp.io.

Your next steps? Start creating projects, invite your team if needed, and explore integrations or automation. Every task you manage here is truly yours – a small but meaningful step toward full control over your productivity.

Self-hosting is not just a technical achievement; it’s a mindset. And with this setup, you’ve already taken the first step.