[{"data":1,"prerenderedAt":189},["ShallowReactive",2],{"seo-verification":3,"blog-host-jellyfin-on-your-own-vps-ma-en":6,"promo-bar-likely":188},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-host-jellyfin-on-your-own-vps-ma-en",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":19,"noindex":19,"publishedAt":20,"updatedAt":21,"category":22,"categories":28,"featuredImage":30,"bgImage":31,"posterImage":32,"relatedSolution":33,"intro":36,"sections":37,"ctaTitle":127,"ctaBody":128,"ctaButton":129,"ctaUrl":130,"relatedPosts":131},84,"host-jellyfin-on-your-own-vps",{"fr":12,"en":10,"ar":13,"es":14},"heberger-jellyfin","استضافة-jellyfin-على-خادمك-الافتراضي-الخاص-vps","alojar-jellyfin-en-un-vps","Self-Hosting Jellyfin on a VPS: Complete 2026 Guide","Deploy Jellyfin on your own VPS with Docker, nginx, HTTPS, plugins, storage options and hardware transcoding. Full guide updated for 2026.",20,11,false,"2026-03-28T00:00:00+00:00","2026-11-08T01:13:14+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},7,"Self-hosting","self-hosting","bg-indigo-500\u002F10 text-indigo-400","cloud",[29],{"id":23,"name":24,"slug":25,"color":26,"icon":27},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fheberger-jellyfin-poster.svg",{"categorySlug":34,"appSlug":35},"collaboration-productivity","jellyfin","Jellyfin is the free media server Plex should have been. No subscription, no central server authenticating your devices, no data collection — just your library, on your machine, reachable from any screen. Centralised streaming platforms have raised their prices in recent years. This guide takes you from the Docker install to the nginx configuration, covering the three problems forums document most: plugins that vanish after an update, choosing storage as your library grows, and moving to a new major version whose database migration can fail to finish.",[38,42,54,57,79,82,85,88,91,94,118,121,124],{"type":39,"title":40,"body":41},"h2","Why Jellyfin in 2026","The personal media server landscape has changed in a few years. Plex raised the price of its Lifetime Pass in 2025, then tripled it on 1 July 2026 (from $249.99 to $749.99, an increase announced in May 2026), making entry expensive for family use. Emby, the other historical alternative, also runs on a freemium model — some key features such as hardware transcoding, DVR or offline downloads on mobile are reserved for Emby Premiere subscribers.\n\nJellyfin was born in 2018 as a fork of Emby, precisely to stay free. The GPLv2 licence forbids closing the code again — if a contributor reintroduces proprietary code, users can legally fork. That is a structural guarantee neither Plex nor Emby offers.\n\nAs for versions, the 12.x series has succeeded 10.11: 12.0 came out on 8 September 2026, and 12.4, published on 26 October 2026, is the latest stable release seen at the time of writing. This major version jump has a practical consequence: a database migration that can sometimes be very long, covered further down in this guide.\n\nOn features, Jellyfin covers nearly every mainstream use: adaptive streaming, software and hardware transcoding, native iOS, Android, Android TV and Roku apps, LiveTV and DVR recording, automatic subtitles, SSO authentication through OIDC and LDAP, and a plugin system that extends the application without touching the core.",{"type":43,"title":44,"items":45},"ul","What Jellyfin offers",[46,47,48,49,50,51,52,53],"**DLNA and HLS streaming** — serves films, series and music to all your devices, including TVs without a native app.","**Official apps** — iOS, Android, Android TV, Roku, Fire TV, Kodi; a responsive web interface for everything else.","**On-the-fly transcoding** — converts the source format if the target device cannot play it, in software or through a GPU.","**LiveTV and DVR recording** — plug in a USB tuner or an IPTV source to watch and record live television.","**OIDC and LDAP SSO** — plug in your existing directory or an identity provider such as Authentik or Keycloak.","**Automatic subtitles** — OpenSubtitles plugin, extraction of embedded tracks, WebVTT rendering.","**Extended plugins** — LastFM integrations, scrobbling, music metadata, trailers, collection management.","**No proprietary cloud at all** — no authentication through Plex servers, no playback data sent to a third party.",{"type":39,"title":55,"body":56},"Sizing by use case","Needs vary considerably with what you plan to do.\n\n**SD and 1080p without transcoding (direct play)**: if your devices natively play the source codec (H.264 or H.265), Jellyfin does not transcode — it serves the file like a smart file server. 2 vCPU and 2 GB of RAM are plenty for a library of several hundred titles. This is the most common use case on a VPS.\n\n**1080p with software transcoding**: when the client does not support the codec or when you cap the bitrate, Jellyfin encodes on the fly. A single 1080p H.264 stream uses 2 to 4 cores depending on the source resolution. Aim for 4 vCPU \u002F 4 GB RAM minimum for two simultaneous users.\n\n**4K HDR with software transcoding**: HDR tone-mapping (HDR→SDR conversion for screens without HDR) is extremely demanding. A single 4K HDR stream can saturate 8 cores. This use case does not suit a standard cloud VPS — prefer 4K direct play (the client must support HEVC\u002FHDR) or a dedicated server with a GPU.\n\n**GPU hardware transcoding (VAAPI\u002FNVENC)**: cuts CPU load sharply, but needs access to the `\u002Fdev\u002Fdri` device or an NVIDIA card. Standard cloud VPS do not expose a GPU; this option is reserved for dedicated servers or specialised GPU VPS.\n\n**Disk for a version upgrade**: plan enough room to hold a full copy of the configuration folder (database included) next to the original. Jellyfin's backup documentation requires at least 5 GB free for a built-in backup, and more if you include subtitles and trickplay.",{"type":58,"title":59,"steps":60},"steps","Install Jellyfin on an Ubuntu\u002FDebian VPS with Docker Compose",[61,64,67,70,73,76],{"title":62,"body":63},"Prepare the VPS and install Docker","Connect to your VPS over SSH (Ubuntu 22.04 or Debian 12). Update the system and install Docker:\n\n`apt update && apt upgrade -y`\n`curl -fsSL https:\u002F\u002Fget.docker.com | sh`\n`systemctl enable --now docker`\n\nCheck that Docker works: `docker info`. Do this update now, on a server that is still empty: later, on a machine running a package-installed Jellyfin, an `apt upgrade` can restart the service at the worst moment (see the section on version upgrades).",{"title":65,"body":66},"Create the folder tree","Choose where to keep the Jellyfin configuration and your media:\n\n`mkdir -p \u002Fopt\u002Fjellyfin\u002F{config,cache}`\n`mkdir -p \u002Fmnt\u002Fmedia\u002F{films,series,music}`\n`chown -R 1000:1000 \u002Fopt\u002Fjellyfin \u002Fmnt\u002Fmedia`\n\nUID 1000 is the one the Compose file below gives the Jellyfin container (the `user` setting, optional according to the documentation: without it, the container runs as root).",{"title":68,"body":69},"Write the docker-compose.yml file","Create `\u002Fopt\u002Fjellyfin\u002Fdocker-compose.yml`. Under `services:` then `jellyfin:` (YAML indentation of two spaces per level), put these lines:\n\n`image: jellyfin\u002Fjellyfin:12.4`\n`container_name: jellyfin`\n`user: \"1000:1000\"`\n`ports:` then, below, `- \"127.0.0.1:8096:8096\"`\n`restart: unless-stopped`\n`volumes:` then, below, `- \u002Fopt\u002Fjellyfin\u002Fconfig:\u002Fconfig`, `- \u002Fopt\u002Fjellyfin\u002Fcache:\u002Fcache` and `- \u002Fmnt\u002Fmedia:\u002Fmedia:ro`\n`environment:` then, below, `- JELLYFIN_PublishedServerUrl=https:\u002F\u002Fjellyfin.your-domain.com`\n\n**Do not write `latest`.** According to the official documentation, that tag \"always tracks the latest stable release, including through major and minor version bumps\": a plain `docker compose pull` is then enough to trigger a database migration you did not prepare. Pin a version — an `X.Y` tag (such as `12.4`) follows the fixes of that branch, an `X.Y.Z` tag freezes an exact release. Check the current tag on the image registry before copying `12.4`.\n\nThe port is published on `127.0.0.1` only: just nginx, on the same machine, reaches it, and Jellyfin cannot be reached in plain HTTP on the public IP. `network_mode: host` is only needed for DLNA discovery, according to the documentation; DLNA only works on a local network, and on a VPS that mode would expose port 8096 on every interface.",{"title":71,"body":72},"Start the container","`cd \u002Fopt\u002Fjellyfin`\n`docker compose up -d`\n`docker compose logs -f`\n\nJellyfin listens on port 8096. Wait for the `Startup complete` line in the logs before moving on.",{"title":74,"body":75},"Configure nginx as a reverse proxy","Install nginx and certbot: `apt install -y nginx certbot python3-certbot-nginx`\n\nCreate `\u002Fetc\u002Fnginx\u002Fsites-available\u002Fjellyfin` with a single `server` block, on port 80: `listen 80;`, `server_name jellyfin.your-domain.com;`, then, inside `location \u002F {`, `proxy_pass http:\u002F\u002Flocalhost:8096;`, the headers `proxy_set_header Host $host;`, `proxy_set_header X-Real-IP $remote_addr;`, `proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;` and `proxy_set_header X-Forwarded-Proto $scheme;`, then, for WebSockets, `proxy_http_version 1.1;`, `proxy_set_header Upgrade $http_upgrade;` and `proxy_set_header Connection \"upgrade\";`. Do not write a 443 block yet: its `ssl_certificate` lines would point to files that do not exist until certbot has run, and nginx would refuse to load the configuration.\n\nEnable the site, check it, then get the certificate:\n\n`ln -s \u002Fetc\u002Fnginx\u002Fsites-available\u002Fjellyfin \u002Fetc\u002Fnginx\u002Fsites-enabled\u002F`\n`nginx -t && systemctl reload nginx`\n`certbot --nginx -d jellyfin.your-domain.com`\n\nCertbot's nginx plugin obtains the certificate, stores it in `\u002Fetc\u002Fletsencrypt\u002Flive\u002Fjellyfin.your-domain.com\u002F` (`fullchain.pem` and `privkey.pem`), then installs it: it adds the 443 listener and the `ssl_certificate` and `ssl_certificate_key` lines to the block itself, along with the HTTP to HTTPS redirect, which is on by default. Check the result with `nginx -t`.\n\nIf you prefer `certbot certonly --nginx -d jellyfin.your-domain.com`, which obtains the certificate without touching the configuration, then write the 443 block yourself: `listen 443 ssl;`, the same `server_name`, `ssl_certificate \u002Fetc\u002Fletsencrypt\u002Flive\u002Fjellyfin.your-domain.com\u002Ffullchain.pem;`, `ssl_certificate_key \u002Fetc\u002Fletsencrypt\u002Flive\u002Fjellyfin.your-domain.com\u002Fprivkey.pem;` and the same `location \u002F`. Then replace the port 80 block's `location \u002F` with `return 301 https:\u002F\u002F$host$request_uri;`, and run `nginx -t && systemctl reload nginx`.",{"title":77,"body":78},"Initial setup wizard","Open `https:\u002F\u002Fjellyfin.your-domain.com` in your browser. The wizard walks you through:\n\n1. Creating the administrator account\n2. Adding your library (point to `\u002Fmedia\u002Ffilms`, `\u002Fmedia\u002Fseries`)\n3. Choosing the language and the metadata providers (TheMovieDB for films, TheTVDB for series)\n\nRun a full scan once setup is done: Dashboard > Libraries > Scan All Libraries.",{"type":39,"title":80,"body":81},"Plugins not found — check the repository","This is one of the most asked questions after a version upgrade: the plugin catalogue is empty, or every plugin shows \"An error occurred while getting the plugin details from the repository\", while the instance otherwise works.\n\n**What upstream says.** GitHub issue #16654 (\"No longer access plugins\", reported on version 10.11.8) describes this error although the reporter's repository URLs were correct. It was closed without a fix (\"not planned\") by a bot after going stale. A contributor there suggests that some countries block `raw.githubusercontent.com`, which hosts several third-party plugin manifests; one user reports fixing their case by uninstalling the plugins, restarting, then reinstalling them. No single cause is established: this guide's earlier explanation, a URL change between two versions, is not what the issue says and has been removed.\n\n**Checks, in order**:\n\n1. Go to Dashboard > Plugins > Repositories. The official stable repository must point to `https:\u002F\u002Frepo.jellyfin.org\u002Ffiles\u002Fplugin\u002Fmanifest.json`. If you had switched to the \"unstable\" repository, go back to the stable one\n2. From the VPS, check that the manifest answers: `curl -sI https:\u002F\u002Frepo.jellyfin.org\u002Ffiles\u002Fplugin\u002Fmanifest.json`. For a third-party repository hosted on GitHub, also test `curl -sI https:\u002F\u002Fraw.githubusercontent.com`\n3. Click \"Save\", then restart Jellyfin to force the metadata to reload: `docker compose -f \u002Fopt\u002Fjellyfin\u002Fdocker-compose.yml restart`\n4. As a last resort, uninstall the affected plugins, restart, reinstall them, restart again",{"type":39,"title":83,"body":84},"Storage strategy for Jellyfin on a VPS","Storage is often the main constraint. Orders of magnitude to know (standard estimates):\n\n- 1080p MKV H.264 film: 5 to 15 GB depending on length and bitrate\n- 4K HDR H.265 film: 15 to 60 GB, even more for Blu-ray remasters\n- 1080p series episode: 1 to 4 GB\n\nWorked example: 100 1080p films × 8 GB (average) = 800 GB minimum. For a collection of 300 mixed films + 10 complete series, count 3 to 5 TB.\n\n**Option 1 — Additional VPS volume (recommended to start)**: most VPS providers offer block volumes (Block Storage) that can be attached live, billed per GB per month. Mount it as ext4 on `\u002Fmnt\u002Fmedia` and pass it as a bind mount to Docker. Advantage: direct I\u002FO on a local disk, no network transit. Drawback: cost grows linearly with size.\n\nAfter attaching the volume (here `\u002Fdev\u002Fsdb`):\n\n`mkfs.ext4 \u002Fdev\u002Fsdb`\n`mount \u002Fdev\u002Fsdb \u002Fmnt\u002Fmedia`\n`echo '\u002Fdev\u002Fsdb \u002Fmnt\u002Fmedia ext4 defaults 0 2' >> \u002Fetc\u002Ffstab`\n\n**Option 2 — Hetzner Storage Box (CIFS\u002FSamba)**: a hybrid solution — your VPS stays light, storage lives on the Storage Box. Mount it over CIFS:\n\n`apt install -y cifs-utils`\n`install -m 600 \u002Fdev\u002Fnull \u002Froot\u002F.storagebox-credentials`, then write two lines in it: `username=uXXXXXX` and `password=…`\n`mount -t cifs \u002F\u002FuXXXXXX.your-storagebox.de\u002Fbackup \u002Fmnt\u002Fmedia -o seal,credentials=\u002Froot\u002F.storagebox-credentials,uid=1000,gid=1000,iocharset=utf8`\n\nThe credentials file keeps the password out of the shell history and the process list; the `seal` option encrypts the SMB connection, which is not necessarily encrypted by default. First enable SMB in the Hetzner Console, plus external reachability if your VPS is not at Hetzner.\n\nNetwork latency is acceptable for pre-buffered streaming (Jellyfin reads ahead), but unsuited to live transcoding — CIFS throughput cannot keep up.\n\n**Option 3 — Local NAS with a Tailscale or Cloudflare Tunnel**: if you already own a home NAS, you can expose your library to a remote VPS through an encrypted tunnel. Tailscale creates a virtual private network between your NAS and your VPS in under ten minutes. Streaming then flows NAS → VPS → user, with controlled latency. Keep this option for very large, already-built libraries.\n\n**Break-even point**: compare the per-TB price of your block volume with that of a Storage Box on your provider's current price lists. Beyond 500 GB, external storage is often cheaper, provided you accept the network latency.",{"type":39,"title":86,"body":87},"Hardware transcoding — VAAPI and NVENC","Software transcoding suits one or two simultaneous sessions on a good VPS. Beyond that, or for regular 4K HDR, hardware transcoding is essential.\n\n**VAAPI (Intel\u002FAMD)**: on a dedicated server with an integrated Intel GPU or an AMD GPU, the `\u002Fdev\u002Fdri\u002FrenderD128` device exposes the encoder. Add to the Docker service the lines `devices:` then `- \u002Fdev\u002Fdri\u002FrenderD128:\u002Fdev\u002Fdri\u002FrenderD128`, and `group_add:` with the ID of the host's `render` group (`getent group render | cut -d: -f3`).\n\nThen enable hardware acceleration in Dashboard > Playback > Transcoding: choose QSV (Intel Quick Sync, preferred on recent Intel GPUs under Linux) or VA-API (AMD GPUs, older Intel GPUs).\n\n**NVENC (NVIDIA)**: needs the NVIDIA driver and the NVIDIA Container Toolkit on the host (the old `nvidia-docker2` package is deprecated). Add to the service a `deploy:` > `resources:` > `reservations:` > `devices:` block containing `- driver: nvidia`, `count: 1` and `capabilities: [gpu]`.\n\n**Reminder**: standard cloud VPS do not expose a GPU or a `\u002Fdev\u002Fdri` device. This mode is reserved for dedicated servers with a graphics card or a processor with an accessible integrated GPU.",{"type":89,"body":90},"tip","Cap the load to avoid saturation: Jellyfin has no global limit on transcodes, but you can set, for each user, a maximum number of simultaneous sessions (Dashboard > Users > the user's profile) and throttle the bitrate of remote clients in the playback settings. On a 4 vCPU VPS, aim for 2 or 3 simultaneous transcodes at most — beyond that, other users see a noticeable degradation.",{"type":39,"title":92,"body":93},"Moving to a major version: what Jellyfin 12 requires","Going from 10.11 to 12.x is not a routine update. The 12.0 release notes (8 September 2026) set the frame:\n\n**Upgrade paths.** You can upgrade directly from 10.10.7 or any 10.11.x, with no intermediate step. A release older than 10.10.7 must first go through 10.10.7.\n\n**Backup.** The notes \"strongly\" recommend a full backup of the data directory, because rolling back requires a full restore. The backup documentation confirms it: Jellyfin has no downgrade mechanism.\n\n**Duration.** The migration checks the paths of every library item, which can take time depending on its size, and the first library scan will be much longer than usual.\n\n**Announced side effects.** Alternative versions that were resolved automatically (not merged by hand) are removed and come back after a full scan; some films may appear as newly added; usernames that differ only by case must be fixed before the upgrade; the legacy `\u002Femby\u002F*` and `\u002Fmediabrowser\u002F*` routes disappear, which can break older third-party clients; legacy authorisation is disabled; global subtitle settings are replaced by per-library settings.\n\nThese points come from the 12.0 notes and apply to 12.0; reread the notes of the version you are targeting.",{"type":58,"title":95,"steps":96},"A durable procedure to upgrade without losing your library",[97,100,103,106,109,112,115],{"title":98,"body":99},"Read the release notes and check the upgrade path","Open the target version's page on Jellyfin's GitHub repository and read its \"upgrade notes\". Identify your current version (`docker compose images` or the dashboard). If it is older than 10.10.7, go through 10.10.7 first. Remove plugins from third-party repositories before the migration, as the 12.0 notes ask.",{"title":101,"body":102},"Prevent any automatic update","An interrupted migration is the documented cause of the worst case (see the next section). So disable everything that can restart or replace the service without you:\n\n- Docker: pin the tag in `docker-compose.yml` (never `latest`) and turn off Watchtower or any task that runs `docker compose pull`\n- Debian\u002FUbuntu packages: list the packages with `dpkg -l | grep -i jellyfin`, hold them with `apt-mark hold \u003Cpackage>`, and check with `apt-mark showhold`. A held package is no longer updated by `apt upgrade` or `unattended-upgrades`\n- Also avoid running `apt upgrade` on the machine while the migration runs, even for other packages, until you have confirmed how your distribution behaves",{"title":104,"body":105},"Stop Jellyfin and copy the data folder","A hot copy of an open database can be unusable: the documentation states that, for a manual backup, the server must be stopped, otherwise the database may be locked and unrecoverable on restore.\n\n`cd \u002Fopt\u002Fjellyfin`\n`docker compose stop`\n`df -h \u002Fopt` and `du -sh \u002Fopt\u002Fjellyfin\u002Fconfig` to check the space\n`cp -a \u002Fopt\u002Fjellyfin \u002Fopt\u002Fjellyfin.before-upgrade`\n\nIf your configuration lives in a named volume (the case of the ServOrbit catalogue template, which mounts `jellyfin-data` on `\u002Fconfig`), copy the volume after checking its name with `docker volume ls`: `docker run --rm -v jellyfin-data:\u002Fsource:ro -v \u002Froot\u002Fjellyfin-before:\u002Fcopy alpine cp -a \u002Fsource\u002F. \u002Fcopy\u002F`.\n\nThe built-in backup (Dashboard > Backups) is an alternative, but it does not replace a folder copy when the migration itself is the risk.",{"title":107,"body":108},"Change the tag and start","Edit the `image:` line of `docker-compose.yml` to the target version, then:\n\n`docker compose pull`\n`docker compose up -d`\n\nThe server runs migrations at startup, before accepting connections. While they run, the health check repeats \"Server is still starting up.\"",{"title":110,"body":111},"Watch without touching anything","`docker compose logs -f` shows the running migration, numbered (for example \"1 of 21\"). In a second terminal, `docker stats` shows the load. Do not restart the container and do not rerun the `up` command while a migration is running: that is the gesture that blocked databases in issue #18066. Note that `restart: unless-stopped` also restarts a container that was killed (out of memory, for instance) mid-migration: if the log shows repeated starts, stop it yourself with `docker compose stop` and diagnose before resuming.",{"title":113,"body":114},"Decide: wait or restore","A slow migration uses CPU or disk; a blocked migration is inert. The reports in issue #18066 give orders of magnitude: one core at 100% for over two hours on a database of more than 3 GB before a fix existed, a full upgrade of about two hours for another user, a success after an overnight wait for a third; conversely, 0% CPU, no disk I\u002FO and idle threads for those whose migration was really blocked. Wait as long as CPU or disk are working and the counter advances. If everything has been inert for a long time, or the log no longer moves, restore.",{"title":116,"body":117},"Restore the copy if the process is inert","`docker compose down`\n`mv \u002Fopt\u002Fjellyfin \u002Fopt\u002Fjellyfin.blocked`\n`cp -a \u002Fopt\u002Fjellyfin.before-upgrade \u002Fopt\u002Fjellyfin`\n\nPut the previous exact tag back in `docker-compose.yml`, then `docker compose up -d`. Do not try to downgrade the database in place: Jellyfin has no downgrade mechanism. When the upgrade succeeds, run a full library scan, reinstall the plugins you removed, and delete the copies only after a few days of normal use.",{"type":39,"title":119,"body":120},"A migration that never finishes: the real state of issue #18066","**The symptom.** Issue jellyfin\u002Fjellyfin #18066, \"Migration ChangeOwnerIdToGuid never completes and keeps one CPU core at 100%\", was opened on 15 September 2026 on an upgrade from 10.11.11 to 12.1.0. The reporter describes a .NET thread at about 100% of one core for over two hours, a `jellyfin.db` database of about 3.2 to 3.5 GB and some 311,000 items, with almost no disk writes and no error in the log.\n\n**Second case: the restart by `apt upgrade`.** Another user reports that an `apt upgrade` restarted the service mid-migration; every later start stayed stuck on the `AddForeignKeyToOwnerId` migration, at 0% CPU, with no I\u002FO or writes. They also note that a local systemd file limiting the startup timeout (`TimeoutSec = 15`) was killing migrations. They restored the backup Jellyfin creates before migrating (the `data\u002FSQLiteBackups\u002F` folder): 12.2 then replayed the migrations in about five minutes.\n\n**What worked, what did not.** Some users succeeded after letting the migration run all night, others after restoring a pre-migration copy or reinstalling Jellyfin; some went back to 10.11.11 meanwhile. Blockages persist on 12.2 for at least two of them, while at least five report a successful upgrade there.\n\n**The upstream fix.** Pull request #18073, \"Fix ChangeOwnerIdToGuid migration performance\", was merged on 26 September 2026 into the 12.z branch (milestone v12.2) and backported on 27 September. It addresses two slow spots: a collision check that scanned the whole `UserData` table for every placeholder row, and seven indexes built on a multi-gigabyte table then discarded right away when SQLite rebuilds the table to add the foreign key.\n\n**State on 7 November 2026.** The issue is still open (`bug` label), with no root-cause analysis from a maintainer in the visible thread; the last comment dates from 17 October. Versions 12.0, 12.1, 12.2, 12.3 and 12.4 exist (12.4 of 26 October is the latest): aim for the latest 12.x rather than 12.0 or 12.1, published before this performance fix was merged.\n\nCautious reading: the fix shortens migration time, it does not guarantee that every database finishes, and nothing replaces the prior copy. A separate case in the thread, processes at 100% after a user logged in, was tied by its author to stale SQLite statistics (`sqlite_stat1`) and fixed with `ANALYZE`; its link to the migration is not confirmed.",{"type":39,"title":122,"body":123},"Troubleshooting — common errors","**Empty library after a scan**: check that the Docker bind mount is right and that permissions match. The container runs as UID 1000; if your files belong to root, Jellyfin cannot read them: `chown -R 1000:1000 \u002Fmnt\u002Fmedia`.\n\n**HTTPS broken behind nginx**: if the interface loads over HTTP although you configured HTTPS, check that the `X-Forwarded-Proto` and `X-Real-IP` headers are passed in the nginx configuration. Without them, Jellyfin generates HTTP URLs in its responses.\n\n**Slow transcoding or VAAPI error**: confirm that the container can reach the device with `docker exec jellyfin ls \u002Fdev\u002Fdri`. If the folder is missing, the device is not passed in `docker-compose.yml`, or your VPS does not expose it.\n\n**Mobile apps refuse to connect**: check that your TLS certificate is valid and not self-signed. The Jellyfin iOS and Android clients reject self-signed certificates without extra configuration. If you use Let's Encrypt, make sure automatic renewal (`certbot renew`) is active: `systemctl status certbot.timer`.\n\n**Plugins installed but inactive after a restart**: some plugins need a FULL Jellyfin restart (not a configuration reload) to activate. Use `docker compose restart` rather than the restart option in the interface if the problem persists.\n\n**\"Server is still starting up.\" in a loop after a version upgrade**: a database migration is running or blocked. Do not restart. Look at the migration counter in `docker compose logs`, the load with `docker stats`, then apply the wait-or-restore decision described above.\n\n**An old client no longer connects after 12.0**: the `\u002Femby\u002F*` and `\u002Fmediabrowser\u002F*` routes were removed. Update the client or switch to another one.",{"type":39,"title":125,"body":126},"Deploy Jellyfin from the ServOrbit Marketplace","If you prefer a preconfigured install over managing Docker by hand, Jellyfin is available in the ServOrbit Marketplace. The install automatically creates the container and, as soon as you attach a domain to the application from the client area, installs the nginx vhost and the TLS certificate. You get a ready-to-use Jellyfin, with the setup wizard on first access; media storage (additional volume, Storage Box) is still yours to mount, as described above.\n\nThe VPS stays entirely under your control: you can connect over SSH, edit `docker-compose.yml`, add volumes or move to another infrastructure at any time.\n\nMind one particularity of the template: on 7 November 2026 it references the `jellyfin\u002Fjellyfin:latest` image and mounts the `jellyfin-data` volume on `\u002Fconfig`. After deployment, pin the image tag yourself to the version you chose, then follow the upgrade procedure above before any change. This guide is provided without support for your installation.","Your Jellyfin in production in 5 minutes","Deploy Jellyfin from the ServOrbit Marketplace: automated installation, HTTPS included, configurable storage, VPS under your full control.","Deploy Jellyfin on VPS","\u002Fapplications\u002Fcollaboration-productivity\u002Fjellyfin",[132,153,171],{"id":133,"slug":134,"slugs":135,"title":139,"excerpt":140,"readTime":141,"views":142,"isPinned":19,"noindex":19,"publishedAt":143,"updatedAt":144,"category":145,"categories":150,"featuredImage":30,"bgImage":31,"posterImage":152,"relatedSolution":30},98,"jellyfin-vs-plex-which-self-hosted-media-server",{"fr":136,"en":134,"ar":137,"es":138},"jellyfin-vs-plex","jellyfin-مقابل-plex-أي-خادم-وسائط-مستضاف-ذاتيا","jellyfin-vs-plex-que-servidor-multimedia-autoalojado","Jellyfin vs Plex: Which Self-Hosted Media Server?","Jellyfin vs Plex: complete comparison to choose your self-hosted media server on a VPS — Docker deployment, troubleshooting, and Jellyfin 12 migration.",9,1,"2026-03-14T00:00:00+00:00","2026-11-08T01:13:15+00:00",{"id":146,"name":147,"slug":148,"color":149,"icon":148},5,"Comparison","comparatif","bg-info\u002F10 text-info",[151],{"id":146,"name":147,"slug":148,"color":149,"icon":148},"\u002Fblog\u002Fcovers\u002Fjellyfin-vs-plex-poster.svg",{"id":154,"slug":155,"slugs":156,"title":160,"excerpt":161,"readTime":162,"views":163,"isPinned":19,"noindex":19,"publishedAt":164,"updatedAt":165,"category":166,"categories":167,"featuredImage":30,"bgImage":31,"posterImage":169,"relatedSolution":170},292,"migrating-from-plex-to-jellyfin-after-the-july-2026-paywall",{"fr":157,"en":155,"ar":158,"es":159},"migrer-plex-vers-jellyfin-2026","الهجرة-من-plex-إلى-jellyfin-بعد-paywall-يوليو-2026","migrar-de-plex-a-jellyfin-2026","Migrating from Plex to Jellyfin after the July 2026 paywall","Plex now charges for remote streaming and patched two flaws in 2026. Move to Jellyfin (video) and Navidrome (music) on your own VPS.",16,4,"2026-08-22T00:00:00+00:00","2026-11-08T01:13:12+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[168],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Fmigrer-plex-vers-jellyfin-2026-poster.svg",{"categorySlug":34,"appSlug":35},{"id":172,"slug":173,"slugs":174,"title":178,"excerpt":179,"readTime":141,"views":163,"isPinned":19,"noindex":19,"publishedAt":180,"updatedAt":181,"category":182,"categories":183,"featuredImage":30,"bgImage":31,"posterImage":185,"relatedSolution":186},232,"host-matrix-synapse-and-element-on-your-own-vps",{"fr":175,"en":173,"ar":176,"es":177},"heberger-matrix-synapse","استضافة-matrix-synapse-وelement-على-خادم-vps-الخاص-بك","alojar-matrix-synapse-y-element-en-un-vps","Host Matrix Synapse and Element on Your Own VPS","Self-host Matrix Synapse and Element Web on a VPS: Docker, PostgreSQL, reverse proxy, bridges and history purge. Full 2026 guide.","2026-01-19T00:00:00+00:00","2026-11-08T01:13:13+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[184],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Fheberger-matrix-synapse-poster.svg",{"categorySlug":25,"appSlug":187},"matrix-synapse",true,1794270412612]