Deployment guide

Vikunja

Overview

Vikunja is an open source, self-hosted to-do list and project and task management application. It offers list, kanban, Gantt, table and calendar views, reminders, labels, assignees and sharing, and it is a privacy-respecting alternative to hosted task managers that you can deploy in your own virtual network.

This SecureAnyCloud image runs the Vikunja server (a single Go binary serving both the REST API and the bundled web app) behind nginx as a reverse proxy, with PostgreSQL as the datastore. The server listens on 127.0.0.1:3456 and is reached through nginx on port 80. The server and the database bind to the loopback interface only.

On the first boot of every deployed VM, a one-shot service generates a fresh session-signing secret unique to that VM and rotates the PostgreSQL password. It then runs the database migrations and creates a single administrator account with a per-VM password. Open registration is disabled. The login is written to /root/vikunja-credentials.txt with mode 0600.

What you get:

  • Vikunja 2.3 server binary at /opt/vikunja/vikunja (API and web app in one)
  • nginx reverse proxy on :80 in front of the Vikunja server (bound to loopback :3456)
  • PostgreSQL datastore, bound to loopback
  • Two dedicated Azure data disks, re-provisioned with every VM: the PostgreSQL data tier at /var/lib/postgresql, and the Vikunja binary and file attachments at /opt/vikunja
  • A per-VM administrator login generated at first boot in a root-only file, plus a per-VM session secret and database password
  • vikunja.service, postgresql.service and nginx.service as enabled, active systemd units
  • 24/7 SecureAnyCloud support

Prerequisites

You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.

Standard_B2s (2 vCPU / 4 GiB RAM) is a good starting size. Choose a larger size for larger teams.

Configure the NSG to allow inbound 22/tcp from your management network. Also allow 80/tcp (plus 443/tcp once you enable HTTPS) from the networks your users will reach Vikunja on.

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Vikunja by SecureAnyCloud, and select Create.

On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTP (80).

Review the two dedicated data disks on the Disks tab, then select Review + create and Create.

Step 2 - Deploy from the Azure CLI

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:vikunja-ubuntu-24-04:default:latest
az vm create \
  --resource-group <your-rg> \
  --name vikunja \
  --image sac1647283583153:vikunja-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name vikunja --port 80 --priority 1010

Step 3 - Connect to your VM

Connect to the VM over SSH:

ssh azureuser@<vm-public-ip>

First-boot initialization completes in under a minute. The credentials file is in place by the time SSH is ready.

Step 4 - Confirm the services are running

systemctl is-active vikunja.service postgresql.service nginx.service curl -fsS http://127.0.0.1/api/v1/info

All three services report active, and the open info endpoint returns JSON with a version. This confirms that the full stack (nginx, the Vikunja server and PostgreSQL) is serving. Both data tiers live on their own Azure data disks:

findmnt -no SOURCE,SIZE,FSTYPE,TARGET /var/lib/postgresql
findmnt -no SOURCE,SIZE,FSTYPE,TARGET /opt/vikunja

The output shows the service status, the open /api/v1/info health endpoint, and the two dedicated data disks.

Step 5 - Retrieve your administrator login

The first boot of your VM generates a unique administrator password and writes it to a root-only file:

sudo cat /root/vikunja-credentials.txt

The file contains the Vikunja URL, the administrator username (admin) and the password, plus the PostgreSQL login for the local database. From the same session, confirm that the API authenticates end to end:

PASS=$(sudo grep '^vikunja.admin.pass=' /root/vikunja-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -w 'no token -> HTTP %{http_code}\n' http://127.0.0.1/api/v1/user
curl -s -H 'Content-Type: application/json' \
  -d "{\"username\":\"admin\",\"password\":\"$PASS\"}" \
  http://127.0.0.1/api/v1/login | head -c 80; echo

The unauthenticated request returns HTTP 401, and the login call returns a JSON Web Token. This confirms the root-only credentials file and the API authentication round trip: 401 without a token, and a JWT with the per-VM password.

Step 6 - First sign-in

Open a web browser and go to http://<vm-public-ip>/. Vikunja shows its sign-in page.

Enter the username admin and the password from /root/vikunja-credentials.txt, then select Login.

Step 7 - Create projects and tasks

Select Projects, then New project. Give the project a name and open it.

Add tasks with the Add a task... box. You can set priorities, due dates, labels, assignees and reminders. Tasks with a priority are flagged in the list with an Urgent, High or Medium badge.

Step 8 - Switch views: list, kanban, Gantt, table and calendar

Use the tabs at the top of a project to view it as a List, a Gantt chart, a Table or a Kanban board.

The kanban board organizes tasks into columns such as To-Do, Doing and Done. Drag a card between columns to update its state.

Step 9 - Invite your team and use the API

Open Teams to create a team and share projects with other users. Open registration is disabled by default, so add users from the administrator account or re-enable registration in /etc/vikunja/config.yml.

Every action in the web app is also available through the REST API at http://<vm-public-ip>/api/v1/. Authenticate with POST /api/v1/login to obtain a token, then call the API with an Authorization: Bearer <token> header.

Security notes

The image ships fully patched at capture time and keeps patching itself. Ubuntu's unattended-upgrades service is enabled, so security updates are installed automatically on your running VM. Verify the state at any time:

systemctl is-enabled unattended-upgrades grep -h . /etc/apt/apt.conf.d/20auto-upgrades
sudo ss -tlnp | grep -E ':(3456|5432) ' || true

The Vikunja server (:3456) and PostgreSQL (:5432) are bound to the loopback interface only. nginx on :80 is the single network-facing entry point.

Enabling HTTPS

For any production deployment, serve Vikunja over HTTPS so that logins cannot be intercepted. The image ships with nginx, which certbot can configure automatically. The steps below assume a DNS record that points your fully qualified domain name at the VM's public IP address, and 443/tcp open in the NSG:

sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d tasks.your-domain.example \
  --non-interactive --agree-tos -m you@your-domain.example \
  --redirect

After certbot finishes, set the public URL so that generated links are correct, then restart Vikunja:

sudo sed -i 's|^ publicurl: .*| publicurl: "https://tasks.your-domain.example/"|' /etc/vikunja/config.yml
sudo systemctl restart vikunja

Backup and maintenance

Vikunja keeps all of its state (projects, tasks, users and settings) in PostgreSQL, and any uploaded file attachments under /opt/vikunja/files. Back up both regularly:

sudo -u postgres pg_dump vikunja > <backup-dir>/vikunja-db-$(date +%F).sql
sudo tar czf <backup-dir>/vikunja-files-$(date +%F).tgz -C /opt/vikunja files

The database (/var/lib/postgresql) and the application directory (/opt/vikunja) are each on their own Azure data disk, so you can also take coordinated disk snapshots in Azure.

Keep the OS patched with sudo apt update && sudo apt upgrade. To upgrade Vikunja, replace /opt/vikunja/vikunja with a newer release and restart the service. Migrations run automatically on start. See https://vikunja.io/docs/.

Support

This image is backed by 24/7 SecureAnyCloud support. Guaranteed response within 24 hours, one hour average for critical issues. Contact sales@secureanycloud.com for help with deployment, upgrades, integrations, TLS termination and database administration.

For general Vikunja questions, consult the documentation at https://vikunja.io/docs/. Vikunja is a trademark of its respective owner. Its use here is nominative and does not imply affiliation or endorsement. All product and company names are trademarks or registered trademarks of their respective holders.

Deploy on Azure

Launch Vikunja on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure