---
title: "Jellyfin Docker Compose and one-click hosting"
description: "Jellyfin is a free media server for your films, shows and music, a self-hosted Plex alternative. Run it on your own machine in one click."
---

[← All templates](https://pethost.dev/templates/) · [Media](https://pethost.dev/templates/media/)

# Deploy Jellyfin in one click

A media server that streams your films, shows and music to any device

A self-hosted alternative to Plex and Emby.

[Deploy on Pethost](https://console.pethost.dev/?template=jellyfin)

## What is Jellyfin?

Jellyfin is a free, open-source media server that people run in place of Plex or Emby. It sorts the films, shows and music you own into libraries with posters, descriptions and cast from online metadata, and streams them to a browser, phones, tablets and TVs. Official apps exist for Android, iOS, Android TV and Fire TV, Roku, LG and Samsung TVs, Xbox and Kodi, and Jellyfin Media Player runs on desktops. Each person gets an account of their own, with their own watch progress and parental controls.

People self-host Jellyfin to watch their own media from anywhere with no account at a company and no subscription: it has no premium tier, no tracking and no central servers. This template sets it up with the administrator from the fields and three libraries, Movies, Shows and Music, over the folders of a media volume. The catch is transcoding. When a device cannot play a file as it is, Jellyfin converts it on the fly, here on the CPU, which is heavy, so files your devices play directly, such as H.264 video in MP4, are the light ones.

## Hosting Jellyfin on Pethost

1. You sign in to Pethost with a passkey, GitHub or Google. No machine yet? You pick a plan, and the link waits until it is ready.
2. New project opens at Jellyfin. You fill in what it asks for and click Create project: **Username**, **Admin password**.
3. In a minute or two Jellyfin is live at its own address with HTTPS. Its secrets are made at random, and its data is in the nightly backup.
4. It is a project like any other: you or your agent can change it, roll it back or restore it.

## Questions about Jellyfin

**Is Jellyfin really free?**

Yes. Jellyfin is free software under the GNU GPL, and its server and official apps cost nothing, with no premium tier or paid features. It is built by volunteers.

**Jellyfin vs Plex: what is the difference?**

Both stream your own media to your devices. Plex’s server is closed source, its accounts go through plex.tv, and since April 2025 watching your media away from home needs a Plex Pass or a Remote Watch Pass. Jellyfin is open source, needs no outside account and charges for nothing.

**Which devices can play from Jellyfin?**

Any modern browser, and the official apps for Android, iOS, Android TV and Fire TV, Roku, LG webOS, Samsung Tizen and Xbox. Jellyfin Media Player runs on Windows, macOS and Linux, and the JellyCon add-on brings Jellyfin into Kodi.

**How should I name my films and shows for Jellyfin?**

Give each film a folder named by its title and year, such as Big Buck Bunny (2008), with the video inside under the same name. A show gets a folder of its own with Season 01, Season 02 and so on inside, and episodes named like Show Name S01E01.mkv. Jellyfin then finds the right posters and descriptions.

**Does Jellyfin need a GPU?**

No. A GPU only speeds up transcoding, the conversion a device needs when it cannot play a file as it is; without one, Jellyfin transcodes on the CPU. HDR video is the hard case: Jellyfin’s docs say no modern consumer CPU tone-maps it in real time. Files your devices play as they are need no transcoding at all.

**How much memory and disk does Jellyfin need?**

Jellyfin takes about 250 MB of memory at rest and the disk is your library; transcoding a video runs on the CPU and is heavy. On Pethost the Starter plan is enough for it, with room for other apps beside it.

## Jellyfin Docker Compose file

The template is this compose.yaml and the variables written into the project’s .env as it is created. Pethost runs the file as it is written.

**Containers:** jellyfin (jellyfin/jellyfin:12).

**Volumes, in the nightly backup:** config, cache, media.

```
services:
  jellyfin:
    image: jellyfin/jellyfin:12
    restart: unless-stopped
    environment:
      ADMIN_USERNAME: ${ADMIN_USERNAME}
      ADMIN_PASSWORD: ${ADMIN_PASSWORD}
    # A new server's startup wizard is open to whoever comes first. So until the wizard is done,
    # Jellyfin runs on port 8097, which nobody reaches: there it is given the administrator from
    # the fields and a library for each folder of /media, and only then answers on 8096.
    entrypoint: ["/bin/sh", "-c"]
    command:
      - |
        set -e
        config=/config/config
        if ! grep -qs '<IsStartupWizardCompleted>true<' "$$config/system.xml"; then
          mkdir -p "$$config" /media/movies /media/shows /media/music
          if [ -f "$$config/network.xml" ]; then
            sed -i 's|<InternalHttpPort>[0-9]*<|<InternalHttpPort>8097<|' "$$config/network.xml"
          else
            printf '<?xml version="1.0" encoding="utf-8"?>\n<NetworkConfiguration>\n  <InternalHttpPort>8097</InternalHttpPort>\n</NetworkConfiguration>\n' > "$$config/network.xml"
          fi
          /jellyfin/jellyfin &
          setup=$$!
          api() { curl -fsS -H 'Content-Type: application/json' "$$@"; }
          # 401: an administrator with a password exists already, from a first start cut short,
          # and Jellyfin has marked its wizard done by itself.
          until wizard=$$(curl -sS -o /dev/null -w '%{http_code}' http://127.0.0.1:8097/Startup/Configuration) &&
            { [ "$$wizard" = 200 ] || [ "$$wizard" = 401 ]; }; do sleep 2; done
          if [ "$$wizard" = 200 ]; then
            api -d '{"ServerName":"Jellyfin","UICulture":"en-US","MetadataCountryCode":"US","PreferredMetadataLanguage":"en"}' http://127.0.0.1:8097/Startup/Configuration
            library() {
              api http://127.0.0.1:8097/Library/VirtualFolders | grep -q "\"Name\":\"$$1\"" ||
                api -d '{"LibraryOptions":{"EnableRealtimeMonitor":true}}' "http://127.0.0.1:8097/Library/VirtualFolders?name=$$1&collectionType=$$2&paths=/media/$$3"
            }
            library Movies movies movies
            library Shows tvshows shows
            library Music music music
            api -o /dev/null http://127.0.0.1:8097/Startup/User
            json() { printf '%s' "$$1" | sed 's/\\/\\\\/g; s/"/\\"/g'; }
            api -d "{\"Name\":\"$$(json "$$ADMIN_USERNAME")\",\"Password\":\"$$(json "$$ADMIN_PASSWORD")\"}" http://127.0.0.1:8097/Startup/User
            api -d '{"EnableRemoteAccess":true,"EnableAutomaticPortMapping":false}' http://127.0.0.1:8097/Startup/RemoteAccess
            api -X POST http://127.0.0.1:8097/Startup/Complete
          fi
          kill $$setup
          wait $$setup || true
          sed -i 's|<InternalHttpPort>8097<|<InternalHttpPort>8096<|' "$$config/network.xml"
        fi
        exec /jellyfin/jellyfin
    volumes:
      - config:/config
      - cache:/cache
      # Writable, so that films, shows and music can be copied in over SFTP.
      - media:/media

volumes:
  config:
  cache:
  media:
```

[compose.yaml](https://pethost.dev/templates/jellyfin/compose.yaml)[See it on GitHub](https://github.com/pethost-dev/templates/tree/main/jellyfin)

## [More in Media](https://pethost.dev/templates/media/)

- [**Owncast**Live video and chat on a page of your own](https://pethost.dev/templates/owncast/)
- [**Navidrome**A music server that streams your own collection](https://pethost.dev/templates/navidrome/)
- [**RomM**A library and in-browser player for your retro games](https://pethost.dev/templates/romm/)
- [**Komga**A server and web reader for your comics, manga and ebooks](https://pethost.dev/templates/komga/)
- [**Lychee**A photo gallery to upload, sort and share your photos](https://pethost.dev/templates/lychee/)
- [**Audiobookshelf**Your own audiobook and podcast server: listen in the browser or the apps, with progress kept across devices](https://pethost.dev/templates/audiobookshelf/)

Pethost · Stephan Gomer · NIP 1133096755

Pethost

- [Templates](https://pethost.dev/templates/)
- [About](https://pethost.dev/about/)
- [Docs](https://pethost.dev/docs/)
- [Blog](https://pethost.dev/blog/)
- [API](https://pethost.dev/docs/api/)
- [CLI](https://pethost.dev/docs/cli/)
- [Plugin](https://github.com/pethost-dev/plugin)
- [Terms](https://pethost.dev/terms/)
- [Privacy](https://pethost.dev/privacy/)
- [Refunds](https://pethost.dev/refunds/)
- [support@pethost.dev](mailto:support@pethost.dev)

Databases

- [Postgres](https://pethost.dev/postgres/)

Comparisons

- [Coolify vs Dokploy vs CapRover vs Dokku](https://pethost.dev/blog/coolify-vs-dokploy-vs-caprover-vs-dokku/)
- [Coolify Cloud vs Dokploy Cloud](https://pethost.dev/blog/coolify-cloud-vs-dokploy-cloud/)
- [Railway vs Render vs Fly.io pricing](https://pethost.dev/blog/railway-vs-render-vs-fly-io-pricing/)
- [Managed Docker Compose hosting](https://pethost.dev/blog/managed-docker-compose-hosting/)

Alternatives

- [Railway alternatives](https://pethost.dev/blog/railway-alternatives/)
- [Heroku alternatives](https://pethost.dev/blog/heroku-alternatives/)
- [Dokploy alternatives](https://pethost.dev/blog/dokploy-alternatives/)
- [Coolify alternatives](https://pethost.dev/blog/coolify-alternatives/)
- [Render alternatives](https://pethost.dev/blog/render-alternatives/)
- [Sliplane alternatives](https://pethost.dev/blog/sliplane-alternatives/)
