Media
Wizarr logo

How to install Wizarr with Docker

Wizarr Docker install guide cover
Difficulty: BeginnerTime: 15 minutesTested with: Wizarr 2026.9 (official image)

Wizarr is a free, open-source invitation system for your media server. Instead of creating accounts by hand and talking friends and family through which app to install, you send them one link. Wizarr creates their Jellyfin account (Plex, Emby, Audiobookshelf, Komga, Kavita and Romm work too) and walks them through getting set up, step by step.

In this guide we will run Wizarr in Docker using the official image, connect it to Jellyfin, send a first invite, and get it ready to sit behind a reverse proxy so the links work from anywhere.

💡
Note: This guide works with the current Wizarr 2026.9 release (v2026.9.1 at the time of writing) from ghcr.io/wizarrrr/wizarr.

✅ Before you start

  • A Linux host with Docker and Docker Compose v2 installed (docker compose version should work).
  • A working Jellyfin server and an admin account on it, so you can create an API key.
  • One free port, 5690, for the web UI.
  • A domain name and a reverse proxy (Traefik, Nginx Proxy Manager...), because the people you invite need to open the link from outside your network.

STEP 1: Find your user and group IDs

Wizarr should run as a normal user, not as root. Log in to your Docker host over SSH and run:

id

You will see something like uid=1000(you) gid=1000(you). Make a note of the two numbers; they become PUID and PGID below.

STEP 2: Create the folders

I like to keep every app's data under one parent folder so backups are a single job. Wizarr only needs one folder:

mkdir -p /path/to/appdata/wizarr/data

Wizarr keeps its database in a database subfolder inside it, which it creates on first start.

Finally, this guide puts the app on the shared media Docker network used by the rest of my media stack, so other containers can reach it by name. If you followed the Jellyfin guide you already have it; otherwise create it once:

docker network create media

STEP 3: The compose file

Create /path/to/appdata/wizarr/docker-compose.yml and paste in the following. Use the copy button in the top right corner of the block.

services:
  wizarr:
    image: ghcr.io/wizarrrr/wizarr:latest
    container_name: wizarr
    hostname: wizarr
    restart: unless-stopped
    environment:
      - PUID=1000                    # your user ID from STEP 1
      - PGID=1000                    # your group ID from STEP 1
      - TZ=Europe/London             # your time zone
      - DISABLE_BUILTIN_AUTH=false   # true ONLY if Authelia/Authentik protects it
    volumes:
      - /path/to/appdata/wizarr/data:/data
    ports:
      - 5690:5690                    # web UI and invite pages
    networks:
      - media

networks:
  media:
    external: true

docker-compose.yml

STEP 4: The settings explained

Setting What it does
image The official Wizarr image. latest follows stable releases.
PUID / PGID The user and group Wizarr runs as. Its database files will belong to this user.
TZ Time zone, so invite expiry times are right. List of zones.
DISABLE_BUILTIN_AUTH Leave this false. Only set it to true if another login (Authelia, Authentik and so on) already protects the admin pages, otherwise anyone could manage your invites.
/data Wizarr's database and settings, in /data/database. This is the folder to back up.
5690:5690 The admin UI and the invite pages your guests see.
networks Joins the shared media network so Wizarr can reach Jellyfin at http://jellyfin:8096.

STEP 5: Start Wizarr

From the folder containing your compose file:

cd /path/to/appdata/wizarr
docker compose up -d
docker compose logs -f

Wait until the logs settle down (press Ctrl+C to stop following them; the container keeps running), then check it is up:

docker ps --filter name=wizarr

After a minute the status should read Up ... (healthy); the image has its own health check.

STEP 6: First-run setup

First, create an API key in Jellyfin: Dashboard → API Keys → +, name it Wizarr and copy the key. Then open http://192.168.1.20:5690 in your browser (use your Docker host's IP):

  1. Create your admin account. Choose a username and a strong password such as CHANGE_ME_STRONG_PASSWORD (please do change it).
  2. Add your media server. Pick Jellyfin, enter the server URL (http://jellyfin:8096 on the shared network, or http://192.168.1.20:8096) and paste the API key. Wizarr checks the connection and lists your libraries.
  3. Create an invite. On the Invitations page, create a new invite and choose which libraries the guest gets, how long the link is valid and, if you like, an expiry for the account itself.
  4. Send the link. Copy the invite link and send it. Your guest opens it, picks a username and password, and Wizarr creates their Jellyfin account and shows them which app to install.
👍
Tip: Make the wizard yours
The steps your guests see after signing up can be edited, so you can add your own house rules, a link to Jellyseerr for requests, or a Discord invite.

STEP 7: Put Wizarr behind a reverse proxy

Wizarr is the one app in this stack that is meant to be reached from outside, because that is where your guests are. Put it behind a reverse proxy with HTTPS on its own hostname, such as join.example.com, and keep the built-in login on. Do not forward port 5690 directly.

Option A: Traefik (Docker labels)

If Traefik runs on the same Docker host and is attached to the media network, add these labels to the wizarr service. They assume your HTTPS entry point is called websecure and your certificate resolver is called cloudflare; change them to match your Traefik config.

    labels:
      - traefik.enable=true
      - traefik.http.routers.wizarr.rule=Host(`join.example.com`)
      - traefik.http.routers.wizarr.entrypoints=websecure
      - traefik.http.routers.wizarr.tls.certresolver=cloudflare
      - traefik.http.services.wizarr.loadbalancer.server.port=5690

docker-compose.yml (extra lines)

Option B: Traefik (file provider)

If Traefik runs on a different machine, add a router and service to your dynamic config file instead:

http:
  routers:
    wizarr:
      rule: Host(`join.example.com`)
      entryPoints:
        - websecure
      tls:
        certResolver: cloudflare
      service: wizarr
  services:
    wizarr:
      loadBalancer:
        servers:
          - url: http://192.168.1.20:5690

dynamic.yml

Option C: Nginx Proxy Manager

Add a Proxy Host for join.example.com with scheme http, forward hostname wizarr (if NPM is on the media network) or 192.168.1.20, and forward port 5690. Request a certificate on the SSL tab and tick Force SSL. The Wizarr docs suggest leaving Block Common Exploits off for this host.

Once the proxy works, copy invite links from Wizarr while you are browsing it on the public hostname, so the links you send out use https://join.example.com rather than your LAN IP.

Updating Wizarr

The latest tag always follows the newest stable release. To update:

cd /path/to/appdata/wizarr
docker compose pull
docker compose up -d
docker image prune -f
⚠️
Warning: Before a major upgrade: back up /path/to/appdata/wizarr/data and read the release notes.

Troubleshooting

Wizarr cannot connect to Jellyfin. Check the URL from Wizarr's point of view: use the container name on the shared network or the host IP, never localhost. Make sure you pasted an API key, not your Jellyfin password.

Invite links show your LAN address. You copied them while browsing Wizarr on its IP. Open Wizarr on the public hostname and copy the link again.

Permission errors in the logs on start. The PUID/PGID user cannot write to /path/to/appdata/wizarr/data. Fix it with sudo chown -R 1000:1000 /path/to/appdata/wizarr/data, using your IDs.

The container shows unhealthy. Run docker logs wizarr --tail 50. Database migrations on first start or after an upgrade can take a minute, so give it time.

port is already allocated when starting. Something else is using 5690. Change the left-hand side of the port mapping, for example 5691:5690.

That's it! No more setting up accounts by hand: just send a link and let Wizarr do the explaining. 🧙