Install and Setup Jellyfin Docker Image

Page content

Jellyfin is a Free Software Media System that puts you in control of managing and streaming your media. It is an alternative to the proprietary Emby and Plex, to provide media from a dedicated server to end-user devices via multiple apps.

Here recorded the walkthrough of install and setup of Jellyfin docker image in a Debian bullseye/11.2 x86-64 NAS.

Jellyfin logo

1. Install Docker

1.1 Uninstall old versions of Docker (if necessary)

$ sudo apt remove docker docker-engine containerd runc

The contents of /var/lib/docker/, including images, containers, volumes, and networks, are preserved.

1.2 Install Docker using the repository

1.2.1 Setup Docker repository for Debian

  1. Update the apt package index and install packages to allow apt to use a repository over HTTPS:
$ sudo apt-get update

$ sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
  1. Add Docker’s official GPG key:
$ curl -fsSL | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
  1. Set up the stable repository of Docker
$ echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

1.2.2 Install Docker engine

  1. Update the apt package index, and install the latest version of Docker Engine and containerd:
$ sudo apt update
$ sudo apt install docker-ce docker-ce-cli
  1. Verify that Docker Engine is installed correctly by running the hello-world image.
$ sudo docker run hello-world

This command downloads a test image and runs it in a container. When the container runs, it prints a message and exits.

1.3 Manage Jellyfin Docker Image as a non-root user jellygin

The Docker daemon binds to a Unix socket instead of a TCP port. By default that Unix socket is owned by the user root and other users can only access it using sudo. The Docker daemon always runs as the root user.

If you don’t want to preface the docker command with sudo, create a Unix group called docker and add users to it. When the Docker daemon starts, it creates a Unix socket accessible by members of the docker group.


The docker group grants privileges equivalent to the root user. For details on how this impacts security in your system, see Docker Daemon Attack Surface.

First create the user jellyfin:

$ sudo adduser jellyfin

Then add user jellyfin to the docker group:

$ sudo usermod -aG docker jellyfin

Have a test:

$ docker run hello-world

For security consideration, append DenyUsers jellyfin to your sshd configuration file, then restart sshd service:

$ sudo systemctl restart ssh.service

2. Install and Setup Jellyfin Docker Image

Switch user jellyfin at first:

$ su jellyfin

2.1 Download the latest Jellyfin image

$ docker pull jellyfin/jellyfin

You may also try a special version of Jellyfin created by [nyanmisaka|], which provides full HW filtering.

$ docker pull nyanmisaka/jellyfin

2.2 Create persistent storage for configuration and cache data

As a normal user with sudo privilege, create two directories:

$ sudo mkdir -p /srv/jellyfin/config
$ sudo mkdir -p /srv/jellyfin/cache

Set full privilege of these directories to user jellyfin:

$ sudo chown -R jellyfin:jellyfin /srv/jellyfin

2.3 Create and run a Jellyfin container

Switch to user jellyfin, and run Jellyfin container in background:

$ docker run -d \
  --name jellyfin \
  --user 2000:2000 \
  --net=host \
  --volume /srv/jellyfin/config:/config \
  --volume /srv/jellyfin/cache:/cache \
  --mount type=bind,source=/mnt/warehouse,target=/media \
  --restart=unless-stopped \

Note: Here assume both of the uid and gid of user jellyfin were 2000.

2.4 Issues

Here you may encounter this error:

docker: Error response from daemon: Conflict. The container name “/jellyfin” is already in use by container “<container ID>”. You have to remove (or rename) that container to be able to reuse that name. See ‘docker run –help’.

To solve this issue, first list all containers:

$ docker container list -all

The output may like:

CONTAINER ID   IMAGE                 COMMAND                  CREATED        STATUS                    PORTS     NAMES
ea619e72b41c   nyanmisaka/jellyfin   "./jellyfin/jellyfin…"   3 hours ago    Up 3 hours (healthy)                jellyfin
30ad3712cae9   hello-world           "/hello"                 15 hours ago   Exited (0) 15 hours ago             quirky_lumiere

Next stop the running container jellyfin:

$ docker stop ea619e72b41c 

Then remove the existing container jellyfin:

$ docker rm ea619e72b41c 

Now it would be OK to run Jellyfin container again.

A. References

  1. Jellyfin project
  2. Jellyfin homepage
  3. Jellyfin documentation
  4. Jellyfin installation guide
  5. Docker Engine Manual