This guide will walk you through the process of setting up a Jellyfin server using Docker, Caddy, and Tailscale. It will allow you to access your server from anywhere in the world, while keeping your media private and secure.
This setup was made possible with the help of the following resources:
- Jellyfin Server Setup with Docker, Caddy, and Tailscale
- Directory Structure
- Understanding the Folders
- Setup Instructions
- Setup for
jellyfin-local
- Setup for
jellyfin-tailscale
- Running the Server
- Troubleshooting
The layout of the current folder is as follows:
.
├── README.md
├── jellyfin-local
│ └── docker-compose.yaml
├── jellyfin-server
│ ├── cache
│ └── config
└── jellyfin-tailscale
├── caddy
│ ├── Caddyfile
│ ├── config
│ └── data
├── docker-compose.yaml
└── tailscale
└── varlib
To verify that your folder is structured correctly, use the tree
command:
$ tree
The Jellyfin setup consists of three main folders:
-
jellyfin-server
: This folder contains all the information your Jellyfin server needs to run, excluding the media itself. Any changes you make to the server will be saved here. -
jellyfin-local
: This folder contains the Docker Compose file that will run your server. It's configured to restrict server access to your machine or local network, depending on your settings. This setup essentially transforms your server machine into a local media player, making it an ideal choice for situations where Tailscale connectivity is unavailable or when you want a portable laptop server. -
jellyfin-tailscale
: This folder contains the Docker Compose file that will run your server and only allow connections from devices on your Tailnet. It uses a reverse proxy through Caddy, enabling you to connect to your server over HTTPS. This folder also contains the directories that the Caddy and Tailscale containers will use to store their data while running on Docker.
Important: Both
jellyfin-tailscale
andjellyfin-local
interact with thejellyfin-server
when running in Docker. To avoid conflicts and potential data loss, these two Docker containers should not run simultaneously. If you want to switch between the two setups, stop the running container before starting the other one.
Follow these steps to set up your environment:
-
Docker Setup
- If you haven't done so already, install Docker Desktop on your system.
- If you are on Linux, you can follow the instructions here.
-
Tailscale Setup
- Register a Tailscale account. A free account can support up to 100 devices and 3 other users. More details can be found in the Tailscale pricing blog.
- Download and install Tailscale on your server and clients.
- Enable MagicDNS and HTTPS in the DNS page of the Tailscale admin console.
- Once you have authenticated your server with Tailscale, you can share access with friends.
This section will guide you through the process of setting up jellyfin-local
by modifying the docker-compose.yaml
file located in the jellyfin-local
directory.
-
Open the Docker Compose File
Navigate to thejellyfin-local
directory and open thedocker-compose.yaml
file. -
Navigate to Jellyfin Volumes
Find the sectionservices: jellyfin: volumes:
. -
Understand the File Paths
This section contains file paths, split by a colon (:
). The part before the colon is the file's location on your machine, and the part after is its location in the Docker container. The:ro
means that the files are read only, preventing the Docker container from modifying your media files. -
Replace Local File Paths
Replace the local file paths (the parts before the colon) with your own file paths.- ~/Jellyfin/jellyfin-server/config:/config - ~/Jellyfin/jellyfin-server/cache:/cache - ~/Documents/Jellyfin/Movies:/Movies:ro - ~/Documents/Jellyfin/Shows:/Shows:ro
This guide will walk you through the process of setting up jellyfin-tailscale
by modifying the docker-compose.yaml
file located in the jellyfin-tailscale
directory.
-
Open the Docker Compose File
Navigate to thejellyfin-tailscale
directory and open thedocker-compose.yaml
file. -
Configure Jellyfin Volumes
Underservices: jellyfin: volumes:
, replace the local file paths (before:
) with your own. The:ro
makes them read-only inside the Docker container.- ~/Jellyfin/jellyfin-server/config:/config - ~/Jellyfin/jellyfin-server/cache:/cache - ~/Documents/Jellyfin/Movies:/Movies:ro - ~/Documents/Jellyfin/Shows:/Shows:ro
-
Configure Caddy Volumes
Underservices: caddy: volumes:
. Replace the local file paths with your own.- ~/Jellyfin/jellyfin-tailscale/caddy/Caddyfile:/etc/caddy/Caddyfile - ~/Jellyfin/jellyfin-tailscale/caddy/data:/data - ~/Jellyfin/jellyfin-tailscale/caddy/config:/config
-
Configure Tailscale Volumes
Underservices: tailscale: volumes:
, replace the local file paths with your own.- ~/Jellyfin/jellyfin-tailscale/tailscale/varlib:/var/lib
-
Set the hostname
Underservices: tailscale: hostname:
, set the hostname. This will appear as the machine name in the Tailscale admin console. Recommended name:jellyfin
. -
Set the Tailscale authentication key
Underservices: tailscale: environment:
, replace theTS_AUTHKEY
with your key from the Tailscale admin console. Make sure the key is set toReusable
. More information can be found here. -
Setup Caddyfile:
- Navigate to the
jellyfin-tailscale/caddy
directory and open theCaddyfile
. - Replace
<machine-name>
with the hostname you set in thedocker-compose.yaml
file (e.g.,jellyfin
). - Replace
<tailnet-name>
with your tailnet name, found in the Tailscale admin console under theDNS
tab.
- Navigate to the
- Navigate to the
jellyfin-local
directory in your terminal. - Execute the command
docker-compose up -d
. - If everything is working, you should be able to access your server at
http://localhost:8096
. - Stop the server in Docker Desktop before running
jellyfin-tailscale
.
- Navigate to the
jellyfin-tailscale
directory in your terminal and execute the commanddocker-compose up -d
. - Check that the jellyfin server is connected to your tailnet by going to the Tailscale admin console.
- In the
jellyfin-tailscale
directory in your terminal, execute the commanddocker exec tailscaled tailscale --socket /tmp/tailscaled.sock cert <machine-name>.<tailnet-name>.ts.net
, replacing<machine-name>
and<tailnet-name>
with your own values. This generates a certificate for your server. - With the Docker container still running, comment out or remove the line with your authentication key in the
docker-compose.yaml
file. - Remake the
jellyfin-tailscale
Docker container by executing the commanddocker-compose up -d
. - If everything is working, you should be able to access your server at
https://<machine-name>.<tailnet-name>.ts.net
.
- Check File Paths: Ensure all the file paths in the
docker-compose.yaml
files are correct. - Check Docker Logs: If you're having trouble connecting to your server, check the logs of the Docker containers in Docker Desktop.
- Verify Tailscale Authentication Key: Make sure the Tailscale authentication key is correct and set to
Reusable
. - Check Network Connection: Verify that your network connection is stable and that the server is accessible from your network.
- Inspect Docker Services: Use
docker-compose ps
to check the status of your Docker services. All services should be in theUp
state. - Check Caddyfile Configuration: Ensure that the Caddyfile configuration is correct, and that the hostname and tailnet name match those set in the Tailscale admin console.
- Restart Docker Services: If all else fails, try restarting your Docker services with
docker-compose down
followed bydocker-compose up -d
. - USB Passthrough: Docker desktop doesn't allow for USB passthrough, so if you want to access media from a USB device, you will have to install colima