Home Building Your Own Media Server Infrastructure: A Complete Guide
Post
Cancel

Building Your Own Media Server Infrastructure: A Complete Guide

pic01

⚠️ Responsible Use Disclaimer

This technical guide demonstrates Docker orchestration for educational purposes. By proceeding, you agree:

  • To only use content you legally own or have rights to
  • To comply with all copyright laws in your jurisdiction
  • This setup is not intended for piracy/illegal distribution

Overview

This guide will walk you through setting up a comprehensive self-hosted media server infrastructure using Docker. The setup includes media management, streaming, monitoring, and administration tools, all working together to create your personal streaming service.

Core Components

Media Server & Management

  • Jellyfin: An open-source media server for streaming your legally owned media collection
  • Jellyseerr: A request management system for Jellyfin
  • Radarr: Automated movie collection management
  • Sonarr: Automated TV shows collection management
  • Prowlarr: A indexer aggregator
  • Deluge: BitTorrent client for downloading legal content like Linux ISOs or Creative Commons material

Administration & Monitoring

  • Nginx Proxy Manager: Reverse proxy for secure access to your services
  • Filebrowser: Web-based file management interface
  • Dashdot: System monitoring dashboard
  • Homarr: Homepage for your services with Docker integration

Network Architecture

Custom Docker Network Design

The infrastructure implements a dedicated Docker network named networkflix using a bridge driver. This network is configured with a specific subnet (20.0.0.0/24) that allows for static IP assignment to each service. This design choice was made specifically to support seamless container updates and service reliability.

Table with IP and services

ServiceIP Address
Jellyfin20.0.0.2
Jellyseerr20.0.0.3
Deluge20.0.0.4
Radarr20.0.0.5
Sonarr20.0.0.6
Prowlarr20.0.0.7
Nginx Proxy20.0.0.8
Filebrowser20.0.0.9
Dahdot20.0.0.10
Homarr20.0.0.11

Cross-Service Communication

Services are configured to communicate with each other using these fixed IPs. For example:

  • Radarr connects to Deluge at 20.0.0.4:8112
  • Jellyseerr connects to Radarr at 20.0.0.5:7878
  • Sonarr connects to Prowlarr at 20.0.0.7:9696

Installation Guide

1. Prepare the Environment

First, create the necessary directories:

1
2
3
4
5
6
7
8
9
10
11
# Create base directories
mkdir -p ~/media
mkdir -p ~/jellyfin/{config,cache}
mkdir -p ~/jellyseerr/appdata/config
mkdir -p ~/deluge/config
mkdir -p ~/radarr
mkdir -p ~/sonnar
mkdir -p ~/prowlarr/data
mkdir -p ~/NginxProxyManager/{data,letsencrypt}
mkdir -p ~/filebrowser
mkdir -p ~/homarr/{configs,data,icons}

2. Configure File Permissions

Set appropriate permissions:

1
2
3
# Set user permissions (assuming your user is in the docker group)
sudo chown -R $USER:$USER ~/media
sudo chmod -R 755 ~/media

3. Create Docker Network

1
2
# Create custom Docker network with defined subnet 
docker network create --subnet=20.0.0.0/24 networkflix

4. Docker Compose [Full Config]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
version: "3"
services:
    jellyfin:
        container_name: jellyfin
        environment:
            - PUID=1000
            - PGID=1000
            - TZ=America/Chicago
        ports:
            - 8096:8096
            - 8920:8920
        volumes:
            - ~/jellyfin/config:/config
            - ~/jellyfin/cache:/cache
            - ~/media:/downloads
        networks:
            networkflix:
                ipv4_address: 20.0.0.2
        restart: unless-stopped
        image: lscr.io/linuxserver/jellyfin:latest

    jellyseerr:
        container_name: jellyseerr
        environment:
            - LOG_LEVEL=debug
            - TZ=America/Chicago
        ports:
            - 5055:5055
        volumes:
            - ~/jellyseerr/appdata/config:/app/config
        networks:
            networkflix:
                ipv4_address: 20.0.0.3
        restart: unless-stopped
        image: fallenbagel/jellyseerr:latest

    deluge:
        container_name: deluge
        environment:
            - PUID=1000
            - PGID=1000
            - TZ=America/Chicago
            - DELUGE_LOGLEVEL=error
        ports:
            - 8112:8112
            - 6881:6881
            - 6881:6881/udp
        volumes:
            - ~/deluge/config:/config
            - ~/media:/downloads
        networks:
            networkflix:
                ipv4_address: 20.0.0.4
        restart: unless-stopped
        image: lscr.io/linuxserver/deluge:latest

    radarr:
        container_name: radarr
        environment:
            - PUID=1000
            - PGID=1000
            - TZ=America/Chicago
        ports:
            - 7878:7878
        volumes:
            - ~/radarr:/config
            - ~/media:/movies
            - ~/media:/downloads
        networks:
            networkflix:
                ipv4_address: 20.0.0.5
        restart: unless-stopped
        image: lscr.io/linuxserver/radarr:latest

    sonarr:
        container_name: sonarr
        environment:
            - PUID=1000
            - PGID=1000
            - TZ=America/Chicago
        ports:
            - 8989:8989
        volumes:
            - ~/sonnar:/config
            - ~/media:/tv
            - ~/media:/downloads
        networks:
            networkflix:
                ipv4_address: 20.0.0.6
        restart: unless-stopped
        image: lscr.io/linuxserver/sonarr:latest

    prowlarr:
        container_name: prowlarr
        environment:
            - PUID=1000
            - PGID=1000
            - TZ=America/Chicago
        ports:
            - 9696:9696
        volumes:
            - ~/prowlarr/data:/config
        networks:
            networkflix:
                ipv4_address: 20.0.0.7
        restart: unless-stopped
        image: lscr.io/linuxserver/prowlarr:latest

    nginx-proxy-manager:
        container_name: nginx-proxy
        ports:
            - 443:443
            - 81:81
        volumes:
            - ~/NginxProxyManager/data:/data
            - ~/NginxProxyManager/letsencrypt:/etc/letsencrypt
        networks:
            networkflix:
                ipv4_address: 20.0.0.8
            default:
        restart: unless-stopped
        image: jc21/nginx-proxy-manager:latest

    filebrowser:
        container_name: filebrowser
        environment:
            - PUID=1000
            - PGID=1000
        ports:
            - 80:80
        volumes:
            - ~/:/srv
            - ~/filebrowser/filebrowser.db:/database/filebrowser.db
            - ~/filebrowser/settings.json:/config/settings.json
        networks:
            networkflix:
                ipv4_address: 20.0.0.9
        restart: unless-stopped
        image: filebrowser/filebrowser

    dashdot:
        container_name: dahdot
        ports:
            - 3001:3001
        volumes:
            - /:/mnt/host:ro
        privileged: true
        networks:
            networkflix:
                ipv4_address: 20.0.0.10
        restart: unless-stopped
        image: mauricenino/dashdot

    homarr:
        container_name: homarr
        ports:
            - 7575:7575
        volumes:
            - /var/run/docker.sock:/var/run/docker.sock
            - ~/homarr/configs:/app/data/configs
            - ~/homarr/data:/data
            - ~/homarr/icons:/app/public/icons
        networks:
            networkflix:
                ipv4_address: 20.0.0.11
        restart: unless-stopped
        image: ghcr.io/ajnart/homarr:latest

networks:
  networkflix:
    driver: bridge
    ipam:
      config:
        - subnet: 20.0.0.0/24
  default:
    driver: bridge

  1. Save the docker-compose.yaml file to your working directory
  2. Start the containers:
1
docker-compose up -d

5. Initial Configuration

  1. After deploying the Docker file, navigate to http://localhost:81 (or your public IP if using a VPS). Enter the default password: deluge.
    pic02
  2. After logging in, go to Preferences > Plugins, check the “Label” option, then click “Apply” and “OK”.pic
  3. In the left column, locate the “Labels” field and right-click on it.pic
  4. Add two new labels: radarr and sonarr.
    pic
  5. Now configure the other services using their respective ports:
    • Radarr: Port 7878
    • Prowlarr: Port 9696
    • Sonarr: Port 8989 For each service, create a username and password and choose your preferred authentication method. pic03

Integrating Deluge with Radarr

  1. In Radarr, navigate to Settings > Download Client.pic03
  2. Click on “Deluge” to add it as a download client.pic04
  3. Configure Deluge in Radarr with the following settings:
    • Host: 20.0.0.4 (Deluge’s internal IP)
    • Port: 8112 Category: radarr (This links to the label you created in Deluge)After entering the information, click “Test” to verify the connection, then click “Save”. Repeat this process for Sonarr using the same settings, except change the Category to sonarr. For Prowlarr, follow a similar process but note that it won’t have the Category option.pic04
  4. In both Sonarr and Radarr, go to Settings > Media Management.
  • In Radarr: Click “Add Root Folder” and select the movies folder
  • In Sonarr: Click “Add Root Folder” and select the tv folder. pic05

Connecting Prowlarr with Radarr and Sonarr

  1. In Prowlarr, navigate to Settings > Apps and click the “+” button to add a new application.
  2. Configure Radarr with these settings:
    • Name: Radarr
    • Sync Level: Full Sync
    • Prowlarr Server: http://20.0.0.7:9696
    • Radarr Server: http://20.0.0.5:7878
    • API Key: (Find this in Radarr under Settings > General > Security) Click “Test” to verify the connection, then click “Save”.
  3. Configure Sonarr with these settings:
    • Name: Sonarr
    • Sync Level: Full Sync
    • Prowlarr Server: http://20.0.0.7:9696
    • Sonarr Server: http://20.0.0.6:8989
    • API Key: (Find this in Sonarr under Settings > General > Security) Click “Test” to verify the connection, then click “Save”.pic06

Adding Indexers to Prowlarr

  1. In Prowlarr, click on “Indexers” and then “Add Indexer”.
  2. Select the websites you want to use, filtering by Protocol, Language, Privacy, and Categories. For each site, click “Test” and then “Save”.pic07

  3. After adding all indexers, verify in both Radarr and Sonarr that the indexers are linked by checking Settings > Indexers.pic08

Configuring Jellyfin Media Player

  1. Now that the backend automation is configured, set up Jellyfin (accessible on port 8096) by following the setup wizard.
  2. When adding your libraries for Movies and TV Shows, include the Download folder to receive content downloaded by Radarr and Sonarr.pic09

Setting Up Jellyseerr

  1. Jellyseerr provides a user-friendly interface for browsing and requesting media. Access it on port 5055.`pic10

  2. Add your Jellyfin server information:
    • IP: 20.0.0.2
    • Username and password for your Jellyfin accountpic11
  3. Add your Jellyfin API key (found in Administration > Dashboard > API keys). Create a new key specifically for Jellyseerr, add it to the API key field, then click “Sync Library” and “Continue”.pic12

  4. Add Radarr and Sonarr using their API keys (found in Settings > General > Security). Click “Test” to verify the connection.pic13

  5. After clicking “Test”, select the three new fields that appear, then click “Add Server”. Your fully automated Jellyfin ecosystem is now ready to use!pic14

Security Recommendations

  1. For enhanced security, purchase a domain and implement HTTPS encryption using the Nginx reverse proxy. The default credentials are:
    • Username: admin@example.com
    • Password: changemepic15
  2. For better security, close all ports except:
    • Port 443 (HTTPS)
    • Port 6881 (TCP and UDP for Deluge)

When configuring port forwarding, use the internal IPs listed in the Network section.pic16

Additional Services

The setup also includes these helpful utilities:

  • Filebrowser (Port 80): Works like a file explorer, allowing you to view and modify files through a web interface.
  • Homarr (Port 3001): Organizes all your links and provides basic monitoring using Dashdot.
  • Dashdot (Port 3001): Monitors server metrics such as CPU usage, memory, RAM, and other system resources.

Maintenance

Regular Updates

1
2
3
4
# Pull latest images
docker-compose pull
# Restart services
docker-compose up -d

Update with WatchTower

This container will check and update the containers every saturday 1am

1
2
3
4
5
6
7
8
9
10
docker run -d \
--name watchtower \
-v /var/run/docker.sock:/var/run/docker.sock \
-e TZ=America/Chicago \
-e WATCHTOWER_CLEANUP=true \
-e WATCHTOWER_TIMEOUT=30s \
-e WATCHTOWER_SCHEDULE="0 1 * * 6" \
--restart unless-stopped \
containrrr/watchtower \
sonarr radarr prowlarr jellyseerr jellyfin deluge dashdot homarr

Additional Resources

This post is licensed under CC BY 4.0 by the author.