Applications Azure

Wizarr on Ubuntu 24.04 on Azure User Guide

| Product: Wizarr on Ubuntu 24.04 LTS on Azure

Overview

Wizarr is a popular open source, self hosted invitation and user onboarding manager for Jellyfin, Plex, Emby and other media servers. Administrators create time limited, permission scoped invitation links, and new users redeem them through a friendly multi step onboarding wizard that provisions their media server account and walks them through installing and using the client apps.

The cloudimg image builds Wizarr 2026.7.1 from source under /opt/wizarr, runs it as the dedicated wizarr system user with gunicorn bound to loopback 127.0.0.1:5690, and fronts it with nginx on port 80. Its datastore is an embedded SQLite database at /data/database/database.db, so nothing listens on a public interface except nginx, which is ready for your TLS certificate.

Secure by default: the image ships with no administrator and no shared secret. Your first visit lands on the create admin setup wizard where you choose your own admin username and password, then connect your media server. The Flask session signing secret (SECRET_KEY) is generated per VM on first boot and never shared between instances. A wizarr-firstboot.service oneshot generates that secret, applies the database migrations, resolves the instance URL and starts the stack, then disables itself.

What is included:

  • Wizarr 2026.7.1 (MIT) under /opt/wizarr
  • Embedded SQLite datastore at /data/database/database.db
  • wizarr.service running as wizarr, gunicorn bound to 127.0.0.1:5690
  • nginx reverse proxy on port 80, ready for TLS
  • wizarr-firstboot.service for per VM secret generation and stack start
  • uv managed Python 3.13 runtime and Node.js 22 LTS build toolchain
  • Ubuntu 24.04 LTS base, fully patched
  • 24/7 cloudimg support, 24h response SLA

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet with a subnet. Recommended VM size: Standard_B2s (Wizarr is lightweight; 4 GB RAM is comfortable). You will also need a reachable Jellyfin, Plex, Emby or other supported media server that you want to invite users onto.

Step 1: Deploy from the Azure Portal

Search the Marketplace for Wizarr on Ubuntu 24.04, choose your VM size, and attach an NSG that allows TCP 22 (SSH) from your management network and TCP 80 / 443 (the web app) from the networks that need it. Front port 80 with TLS in production (see the HTTPS section below).

Step 2: Deploy from the Azure CLI

RG="wizarr-prod"; LOCATION="eastus"; VM_NAME="wizarr-01"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/wizarr-ubuntu-24-04/versions/<version>"
SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"
az group create --name "$RG" --location "$LOCATION"
az network vnet create -g "$RG" --name wz-vnet --address-prefix 10.90.0.0/16 --subnet-name wz-subnet --subnet-prefix 10.90.1.0/24
az network nsg create -g "$RG" --name wz-nsg
az network nsg rule create -g "$RG" --nsg-name wz-nsg --name allow-ssh --priority 100 \
  --source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp
az network nsg rule create -g "$RG" --nsg-name wz-nsg --name allow-web --priority 110 \
  --source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 80 443 --access Allow --protocol Tcp
az vm create -g "$RG" --name "$VM_NAME" --image "$GALLERY_IMAGE_ID" \
  --size Standard_B2s --storage-sku StandardSSD_LRS \
  --admin-username azureuser --ssh-key-values "$SSH_KEY" \
  --vnet-name wz-vnet --subnet wz-subnet --nsg wz-nsg --public-ip-sku Standard

Step 3: Connect via SSH

ssh azureuser@<vm-ip>

Step 4: Verify the services are running

Wizarr listens on loopback only; nginx fronts the web app on port 80.

sudo systemctl is-active wizarr nginx
ss -tln | grep -E ':80 |127.0.0.1:5690'
curl -s -o /dev/null -w 'GET /setup/ -> HTTP %{http_code}\n' http://127.0.0.1/setup/

Both services report active, the gunicorn app is bound to 127.0.0.1:5690, nginx to :80, and the setup wizard returns HTTP 200 through nginx.

wizarr and nginx active, the gunicorn app bound to loopback 127.0.0.1:5690, nginx on port 80, and the setup wizard returning HTTP 200

Step 5: Secure by default, no admin and no secret ships

Nothing sensitive ships in the image. While no administrator exists, the app redirects every request to the create admin wizard, so / returns a redirect and the admin dashboard is never reachable unauthenticated. The per VM credentials note in /root is root only, and the Flask SECRET_KEY is generated on first boot; it is masked below.

curl -s -o /dev/null -w 'GET / -> HTTP %{http_code} (redirect to /setup/)\n' http://127.0.0.1/
sudo stat -c '%n perms=%a owner=%U:%G' /root/wizarr-credentials.txt
sudo sed -E 's/^SECRET_KEY=.*/SECRET_KEY=**** (per-VM, generated at first boot)/' /root/wizarr-credentials.txt | grep -E '^WIZARR_URL|^SETUP_WIZARD|^SECRET_KEY|^NOTE'
curl -s -o /dev/null -w 'GET /admin (no auth) -> HTTP %{http_code} (redirect, protected)\n' http://127.0.0.1/admin

The homepage redirects to the setup wizard, the credentials note is 600 root:root, the session secret is unique to this VM, and the admin dashboard is refused without authentication.

The shipped image redirects to the create admin wizard, carries a root only per VM credentials note with the SECRET_KEY masked, and refuses the admin dashboard without authentication

Step 6: Complete the first run setup wizard

Open http://<vm-ip>/ in your browser. Because no administrator ships, Wizarr shows the create admin page: choose your own admin username and password (at least 8 characters), then submit.

The Wizarr create admin setup page, where you choose your own admin username and password; no administrator ships in the image

Step 7: Connect your media server

After creating your admin, open Settings and use the Servers and Connections tabs to connect your media server (Jellyfin, Plex, Emby, Audiobookshelf, Komga, Kavita and more) with its URL and an API key. Wizarr uses this connection to provision accounts for the users you invite.

The Wizarr Settings page, whose Servers and Connections tabs let you connect your Jellyfin, Plex or Emby media server so Wizarr can provision invited users

Step 8: Log in

Wizarr requires authentication for the admin area. Sign in at /login with the admin username and password you created during setup.

The Wizarr login page; the application requires the administrator credentials you created during setup

Step 9: Create and manage invitations

You land on the admin dashboard, where you create invitation links, scope each one to specific libraries and permissions, set expiry and usage limits, and track who has joined. New users redeem an invitation through a guided multi step onboarding experience that provisions their media server account.

The Wizarr admin dashboard, where you create time limited invitation links, scope them to libraries and permissions, and track invited users

Step 10: The runtime stack

/opt/wizarr/.venv/bin/python --version
uv --version
node -v
nginx -v
grep -m1 '^version = ' /opt/wizarr/pyproject.toml

A uv managed Python 3.13 runs the Flask app under gunicorn, Node.js 22 LTS built the front end assets, nginx fronts the app, and the pinned Wizarr release is 2026.7.1.

The uv managed Python 3.13 runtime, uv, Node.js 22 LTS, nginx and the pinned Wizarr 2026.7.1 release

Step 11: Data and persistence

All Wizarr data lives in the embedded SQLite database at /data/database/database.db, captured into the image and carried onto every instance. The first boot service applies migrations and generates the per VM secret, then disables itself.

sudo ls -la /data/database/database.db
systemctl is-enabled wizarr-firstboot.service
apt-mark showhold

The database is present, the first boot service has run and disabled itself for this instance, and there are no held packages, so the OS security baseline is intact.

The Wizarr SQLite database on disk, the first boot service state, and an intact OS patch baseline with no held packages

Step 12: Enable HTTPS

nginx already fronts Wizarr on port 80 and is ready for TLS. Point a DNS record at your VM, then obtain a certificate with certbot:

sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d <your-domain> --agree-tos -m <your-email> --redirect

certbot installs the certificate, rewrites the nginx server block for TLS, and sets up automatic renewal. Your onboarding portal is then served over HTTPS.

Managing the service

sudo systemctl status wizarr --no-pager
sudo systemctl restart wizarr
sudo journalctl -u wizarr -n 20 --no-pager

The gunicorn app logs to the journal. nginx logs are under /var/log/nginx/. The SQLite data lives under /data/database. Back up the instance by snapshotting the OS disk, or copy /data/database/database.db while the service is stopped.

Support

cloudimg provides 24/7 support for this image via email and live chat: deployment, nginx TLS termination, upgrades, media server integration and API keys, and backups. Email support@cloudimg.co.uk.

This is a repackaged open source software product with additional charges for cloudimg support services. Wizarr, Jellyfin, Plex and Emby are trademarks of their respective owners. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.