42 |
43 | - type: repository
44 | repository: TechHutTV/homelab
45 | pull-requests-limit: 5
46 | issues-limit: 3
47 | commits-limit: 3
48 |
49 | - size: full
50 | widgets:
51 | - type: search
52 | autofocus: true
53 | search-engine: google
54 | new-tab: true
55 | bangs:
56 | - title: YouTube
57 | shortcut: "!yt"
58 | url: https://www.youtube.com/results?search_query={QUERY}
59 | - title: Github
60 | shortcut: "!gh"
61 | url: https://github.com/search?q={QUERY}&type=repositories
62 |
63 | - type: monitor
64 | cache: 1m
65 | title: Services
66 | sites:
67 | - title: Proxmox
68 | url: https://proxmox.hopki.net/
69 | check-url: https://10.0.0.80:8006
70 | allow-insecure: true
71 | icon: di:proxmox
72 | - title: Plex
73 | url: https://plex.hopki.net/
74 | check-url: http://10.0.0.100:32400
75 | icon: di:plex
76 | alt-status-codes:
77 | - 401
78 | - 403
79 | - title: Nextcloud
80 | url: https://cloud.hopki.net/
81 | check-url: http://10.0.0.104:11000
82 | icon: di:nextcloud
83 | - title: Immich
84 | url: https://immich.hopki.net/
85 | check-url: http://10.0.0.104:2283
86 | icon: di:immich
87 | - title: Pi-Hole
88 | url: https://pihole.hopki.net/admin
89 | check-url: http://10.0.0.103:80
90 | icon: di:pi-hole
91 | - title: Vaultwarden
92 | url: https://warden.hopki.net/
93 | check-url: http://10.0.0.109:8000
94 | icon: di:vaultwarden-light
95 | - title: Home Assistant
96 | url: https://hass.hopki.net/
97 | check-url: http://10.0.0.250:8123
98 | icon: di:home-assistant
99 | - title: Frigate
100 | url: https://frigate.hopki.net/
101 | check-url: http://10.0.0.107:5000
102 | icon: di:frigate-light
103 | - title: Zigbee2MQTT
104 | url: https://zigbee.hopki.net/
105 | check-url: http://10.0.0.106:9442
106 | icon: di:zigbee2mqtt
107 | - title: NGINX Proxy Manager
108 | url: https://proxy.hopki.net/
109 | check-url: http://10.0.0.102:81
110 | icon: di:nginx
111 | - title: Docmost
112 | url: https://doc.hopki.net/
113 | check-url: http://10.0.0.104:3001
114 | icon: di:notion
115 | - title: Hoarder
116 | url: https://hoarder.hopki.net/
117 | check-url: http://10.0.0.104:3000
118 | icon: di:hoarder-light
119 | - title: Tautulli
120 | url: https://tautulli.hopki.net/
121 | check-url: http://10.0.0.201:8181
122 | icon: di:tautulli
123 | - title: Jellyfin
124 | url: https://jellyfin.hopki.net/
125 | check-url: http://10.0.0.100:8096
126 | icon: di:jellyfin
127 | - title: TeslaMate
128 | url: https://tesla.hopki.net/
129 | check-url: http://10.0.0.101:4000
130 | icon: di:teslamate-light
131 | - title: Grafana
132 | url: https://grafana.hopki.net/
133 | check-url: http://10.0.0.101:3001
134 | icon: di:grafana
135 | - title: OctoPrint
136 | url: https://3d.hopki.net/
137 | check-url: http://10.0.0.71
138 | icon: di:octoprint
139 | - title: Proxmox Backup Server
140 | url: https://backup.hopki.net/
141 | check-url: https://10.0.0.251:8007
142 | icon: di:proxmox-light
143 | alt-status-codes:
144 | - 401
145 | - 403
146 |
147 | - type: monitor
148 | cache: 1m
149 | title: Servarr
150 | sites:
151 | - title: Overseerr
152 | url: https://request.hopki.net
153 | check-url: http://10.0.0.202:5055
154 | icon: di:overseerr
155 | - title: Radarr
156 | url: https://arr.hopki.net/radarr
157 | check-url: http://10.0.0.100:7878
158 | icon: di:radarr
159 | - title: Sonarr
160 | url: https://arr.hopki.net/sonarr
161 | check-url: http://10.0.0.100:8989
162 | icon: di:sonarr
163 | - title: Lidarr
164 | url: https://arr.hopki.net/lidarr
165 | check-url: http://10.0.0.100:8686
166 | icon: di:lidarr
167 | - title: Bazarr
168 | url: https://arr.hopki.net/bazarr
169 | check-url: http://10.0.0.100:6767
170 | icon: di:bazarr
171 | - title: Prowlarr
172 | url: https://arr.hopki.net/prowlarr
173 | check-url: http://10.0.0.100:9696
174 | icon: di:prowlarr
175 | - title: qBittorrent
176 | url: https://torrent.hopki.net/
177 | check-url: http://10.0.0.100:8080
178 | icon: di:qbittorrent
179 | - title: NZBGet
180 | url: https://nzbget.hopki.net/
181 | check-url: http://10.0.0.100:6789
182 | icon: di:nzbget
183 | alt-status-codes:
184 | - 401
185 | - 403
186 | - title: File Browser
187 | url: https://arrfiles.hopki.net/
188 | icon: di:filebrowser
189 | - title: Portainer
190 | url: https://arr.hopki.net/
191 | check-url: http://10.0.0.100:80
192 | icon: di:portainer
193 |
194 | - name: Home
195 | # Optionally, if you only have a single page you can hide the desktop navigation for a cleaner look
196 | # hide-desktop-navigation: true
197 | columns:
198 | - size: small
199 | widgets:
200 | - type: calendar
201 | first-day-of-week: monday
202 |
203 | - type: rss
204 | limit: 10
205 | collapse-after: 3
206 | cache: 12h
207 | feeds:
208 | - url: https://omgubuntu.co.uk/feed
209 | title: OmgUbuntu
210 | limit: 4
211 | - url: https://9to5linux.com/feed/atom
212 | title: 9to5Linux
213 | limit: 4
214 |
215 | - type: twitch-channels
216 | channels:
217 | - technotim
218 | - piratesoftware
219 |
220 | - size: full
221 | widgets:
222 | - type: group
223 | widgets:
224 | - type: hacker-news
225 | - type: lobsters
226 |
227 | - type: videos
228 | channels:
229 | - UCXuqSBlHAE6Xw-yeJA0Tunw # Linus Tech Tips
230 | - UCR-DXc1voovS8nhAvccRZhg # Jeff Geerling
231 | - UCsBjURrPoezykLs9EqgamOA # Fireship
232 | - UCBJycsmduvYEL83R_U4JriQ # Marques Brownlee
233 |
234 | - type: group
235 | widgets:
236 | - type: reddit
237 | subreddit: technology
238 | show-thumbnails: true
239 | - type: reddit
240 | subreddit: selfhosted
241 | show-thumbnails: true
242 |
243 | - size: small
244 | widgets:
245 | - type: weather
246 | location: 98664
247 | units: imperial
248 | hour-format: 12h # alternatively "24h"
249 | # Optionally hide the location from being displayed in the widget
250 | # hide-location: true
251 |
252 | - type: markets
253 | # The link to go to when clicking on the symbol in the UI,
254 | # {SYMBOL} will be substituded with the symbol for each market
255 | symbol-link-template: https://www.tradingview.com/symbols/{SYMBOL}/news
256 | markets:
257 | - symbol: LTC-USD
258 | name: Litecoin
259 | - symbol: XRP-USD
260 | name: Ripple
261 | - symbol: AAPL
262 | name: Apple
263 | - symbol: MSFT
264 | name: Microsoft
265 |
266 | - type: releases
267 | cache: 1d
268 | # Without authentication the Github API allows for up to 60 requests per hour. You can create a
269 | # read-only token from your Github account settings and use it here to increase the limit.
270 | # token: ...
271 | repositories:
272 | - glanceapp/glance
273 | - TechHutTV/homelab
274 | - immich-app/immich
275 |
276 | # Add more pages here:
277 | # - name: Your page name
278 | # columns:
279 | # - size: small
280 | # widgets:
281 | # # Add widgets here
282 |
283 | # - size: full
284 | # widgets:
285 | # # Add widgets here
286 |
287 | # - size: small
288 | # widgets:
289 | # # Add widgets here
290 |
--------------------------------------------------------------------------------
/storage/README.md:
--------------------------------------------------------------------------------
1 | # Storage and Backup
2 | In this repo I will layout my storage and backup solutions for all of the services and platforms running on my homelab. Currently, I manage everything with Proxmox and Proxmox Backup Server. While solutions like Unraid and TrueNAS are awesome, I have found over the years the Proxmox is actually an amazing solution for managing storage, network shares, and backups.
3 |
4 | > [!NOTE]
5 | > I've recently switched to using Unraid on a seperate machine for my shares and primary file storage; however, this guide still works great for a all-Proxmox solution. I will make chages to this page in the next few weeks to reflect additional storage options and the best ways to mount nfs shares in Proxmox.
6 |
7 | ## Video Guides
8 | This readme is a companion to my official walkthrough guide!
9 |
10 | [](https://youtu.be/qmSizZUbCOA)
11 |
12 | ## Navigation
13 | * [Apps](https://github.com/TechHutTV/homelab/tree/main/apps) - List of all the apps and services.
14 | * [Home Assistant](https://github.com/TechHutTV/homelab/tree/main/homeassistant) - Smart home services and automation.
15 | * [Media Server](https://github.com/TechHutTV/homelab/tree/main/media) - Plex, Jellyfin, *arr stack, and more.
16 | * [Server Monitoring](https://github.com/TechHutTV/homelab/tree/main/monitoring) - Graphs and Visualizations for Unraid, Proxmox, and more.
17 | * [Surveillance System](https://github.com/TechHutTV/homelab/tree/main/surveillance) - Frigate NVR Solution with Coral TPU.
18 | * **Storage** - Current Storage and Backup Solution.
19 | * [Proxy Management](https://github.com/TechHutTV/homelab/tree/main/proxy) - NGINX Proxy Manager, DDNS with Cloudflare, Local Domains, and more.
20 |
21 | ## Proxmox as a NAS
22 | My current setup involves a single server with x3 NVME drives and a bunch of hard drives in a ZFS configuration. These are combined into separate ZFS pools for the HDDs (vault) and the SSDs (flash). Vault is used as a large data storage pool and Flash is used for containers and virtual machine disks. No matter your configuration you can follow this guide. However, I would recommend at least one NVME SSD for your boot drive, and at least 512gb if you don't have any other NVME SSDs and at least x2 HDDs for file storage.
23 |
24 | ### Post Install Steps (optional)
25 |
26 | #### Removing Proxmox Subscription Notice
27 | (not currently working)
28 |
29 | #### Disable Enterprise Repositories
30 | 1. Navigate to _Node > Repositories_ Disable the enterprise repositories.
31 | 2. Now click Add and enable the no subscription repository. Finally, go _Updates > Refresh_.
32 | 3. Upgrade your system by clicking _Upgrade_ above the repository setting page.
33 |
34 | 
35 |
36 | #### Delete local-lvm and Resize local (fresh install)
37 |
38 | > [!WARNING]
39 | > This assumes a fresh installation without advanced storage settings during the installation. See this [issue](https://github.com/TechHutTV/homelab/issues/19).
40 |
41 | My boot drive is small and I run all my containers and virtual machine disks on a separate storage pool. So the LVM partition is not necessary for me and goes unused. If you're running everything off the same boot drive for fast storage skips this. Also you should check out this [video](https://www.youtube.com/watch?v=czQuRgoBrmM) to learn more about LVM before doing anything.
42 | 1. Delete local-lvm manually from web interface under _Datacenter > Storage_.
43 | 2. Run the following commands within _Node > Shell_.
44 | ```bash
45 | lvremove /dev/pve/data
46 | lvresize -l +100%FREE /dev/pve/root
47 | resize2fs /dev/mapper/pve-root
48 | ```
49 | 3. Check to ensure your local storage partition is using all available space. Reassign storage for containers and VM if needed.
50 |
51 | #### Ensure IOMMU is enabled
52 | Enable IOMMU on in grub configuration within _Node > Shell_.
53 | ```bash
54 | nano /etc/default/grub
55 | ```
56 | You will see the line with `GRUB_CMDLINE_LINUX_DEFAULT="quiet"`, all you need to do is add `intel_iommu=on` or `amd_iommu=on` depending on your system.
57 | ```
58 | # Should look like this
59 | GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on"
60 | ```
61 |
62 | 
63 |
64 | Next run the following commands and reboot your system.
65 | ```bash
66 | update-grub
67 | ```
68 | Now check to make sure everything is enabled.
69 | ```bash
70 | dmesg | grep -e DMAR -e IOMMU
71 | dmesg | grep 'remapping'
72 | ```
73 | Learn about enabling PCI Passthrough [here](https://pve.proxmox.com/wiki/PCI_Passthrough)
74 |
75 | ### 2. Create ZFS Pools
76 |
77 | First, we are going to setup two ZFS Pools. A _tank_ pool which is used for larger stored data sets such as media, images and archives. We also will make a _flash_ pool which is used for virtual machine and container root file systems. This is what I name them for my setup. You can name these however you'd like.
78 |
79 | First, checkout you disks and make sure that they're all there. Find this under _Node > Disks_. Make sure you wipe all the disks you plan on using and do note this will wipe any data on the disks, so make sure there is no important data on them and back up if needed.
80 |
81 | 
82 |
83 | Now, on the Proxmox sidebar for your datacenter, go to _Disks > ZFS > Create: ZFS_. This will pop up the screen to create a ZFS pool.
84 |
85 | From this screen, it should show all of your drives, so select the ones you want in your pool, and select your RAID level (in my case RAIDZ for my vault pool and mirror for my flash pool) and compression, (in my case I keep it at on). Make sure you check the box that says __Add to Storage__. This will make the pools immediately available and will prevent using .raw files as opposed to my previous setup when I added directories.
86 |
87 | 
88 |
89 | ### 3. Creating Containers using ZFS Pools
90 |
91 | Now time to put these new storage pools in use. For this, we are going to create our first LXC. In this example the LXC is going to be in charge of managing our media server. First we need a operating system image. Click on your local storage in the sidebar and click on CT Templates then the Templates button. From there search for Ubuntu and download the ubuntu-22.04-standard template.
92 |
93 | Now in the top right click on Create CT. The "Create: LXC Container" prompt should show up. On the general tab I set my CT ID to 100 (later I will match this to a local IP for organization) and I set the hostname to "servarr", you can name it anything like media, jellyfin, or whatever. Set your password, keep the container and unprivileged and click Next. Select your downloaded Ubuntu template and click next. Under disk you can select your storage location. If you created the flash pool like we did earlier select it, otherwise local is fine. For storage I picked 64gb as my media server is quite large. Click next as we will add the data and docker directory later. Give it as many CPU cores and ram as you need, for my setup I gave it 6 cores and 8gb of memory.
94 |
95 | Under network we will leave most everything, but I like to give it a static IP here. If you want to manage this with your router select DHCP. Under IPv4 I set the IPv4/CIDR to `10.0.0.100/24` and the gateway to `10.0.0.1` your local IP may be different. Keep DNS as is and confirm the installation.
96 |
97 | ### 4. Adding Mount Points
98 |
99 | Now that our container is created I want to add some storage and mount the data and docker directories on my system. Click on your newly created LXC and then click on Resources. From there click the Add button and select mount point. The first one I'll add is going to be for the bulk file storage or I will change the option under storage to tank. For path I will set this to /data and uncheck backup. We will set up backups later. I want to dedicate a ton of room to this so I 26078 GiB (28 TB). Set this to what works best your how much media you'd like to store there. I keep everything else as is and click create. For the docker mount I repeated all these steps, but set the storage to flash, mount point to /docker, and gave it about 128gb of space.
100 |
101 | ### 5. Creating SMB Shares
102 |
103 | In our new LXC we first need to run some general updates and user creation.
104 |
105 | 1. Update your system
106 | ```bash
107 | apt update && apt upgrade -y
108 | ```
109 | 2. Create your user
110 | ```bash
111 | adduser brandon
112 | adduser brandon sudo
113 | ```
114 |
115 | Great [video resource by KeepItTechie](https://www.youtube.com/watch?v=2gW4rWhurUs), [source](https://gist.github.com/pjobson/3811b73740a3a09597511c18be845a6c)
116 | 3. Switch to your new user
117 | ```bash
118 | su - brandon
119 | ```
120 | 4. Set permissions of mount points created earlier.
121 | ```bash
122 | sudo chown -R brandon:brandon /data
123 | sudo chown -R brandon:brandon /docker
124 | ```
125 | 5. Install Samba
126 | ```bash
127 | sudo apt install samba
128 | ```
129 | 6. Create a backup of the default configuration
130 | ```bash
131 | cd /etc/samba
132 | sudo mv smb.conf smb.conf.old
133 | ```
134 | 7. Edit the samba config
135 | ```bash
136 | sudo nano smb.conf
137 | ```
138 | This is my configuration (see [issue 51](https://github.com/TechHutTV/homelab/issues/51) for more info on subnets.)
139 | ```
140 | [global]
141 | server string = Servarr
142 | workgroup = WORKGROUP
143 | security = user
144 | map to guest = Bad User
145 | name resolve order = bcast host
146 | hosts allow = 10.0.0.0/24
147 | hosts deny = 0.0.0.0/0
148 | [data]
149 | path = /data
150 | force user = brandon
151 | force group = brandon
152 | create mask = 0774
153 | force create mode = 0774
154 | directory mask = 0775
155 | force directory mode = 0775
156 | browseable = yes
157 | writable = yes
158 | read only = no
159 | guest ok = no
160 | [docker]
161 | path = /docker
162 | force user = brandon
163 | force group = brandon
164 | create mask = 0774
165 | force create mode = 0774
166 | directory mask = 0775
167 | force directory mode = 0775
168 | browseable = yes
169 | writable = yes
170 | read only = no
171 | guest ok = no
172 | ```
173 | 8. Add your samba user
174 | ```bash
175 | sudo smbpasswd -a [username]
176 | ```
177 | 9. Set services to auto start on reboot
178 | ```bash
179 | sudo systemctl enable smbd
180 | sudo systemctl enable nmbd
181 | sudo systemctl restart smbd
182 | sudo systemctl restart nmbd
183 | ```
184 | 10. Install wsdd for Windows discovery
185 | ```bash
186 | sudo apt install wsdd
187 | sudo apt install wsdd-server
188 | ```
189 | 11. Allow services on firewall if you run into any issues.
190 | ```bash
191 | sudo ufw allow OpenSSH
192 | sudo ufw allow Samba
193 | # following 3 are needed for wsdd
194 | sudo ufw allow 3702/udp
195 | sudo ufw allow 5357/tcp
196 | sudo ufw allow 5358/tcp
197 | # Check ufw status
198 | sudo ufw status
199 | ```
200 | Optionally, enable the firewall.
201 | ```bash
202 | sudo ufw enable
203 | ```
204 |
205 | # Backups
206 | Work in Progress
207 |
--------------------------------------------------------------------------------
/media/jellyfin/README.md:
--------------------------------------------------------------------------------
1 | # Jellyfin Setup Guide
2 | Welcome to the ultimate Jellyfin setup guide.
3 |
4 | > [!NOTE]
5 | > For simplicity and compatibility it is recommended to install Jellyfin with Docker in a __virtual machine__ if you're running Proxmox. See more information [here](https://pve.proxmox.com/pve-docs/pve-admin-guide.html#chapter_pct).
6 | >
7 |
8 | ## Data Directory
9 | ### Folder Mapping
10 | It's good practice to give all containers the same access to the same root directory or share. This is why all containers in the compose file have the bind volume mount `/data:/data`. It makes everything easier, plus passing in two volumes such as the commonly suggested `/tv`, `/movies`, and `/downloads` makes them look like two different file systems, even if they are a single file system outside the container. See my current setup below.
11 | ```
12 | data
13 | ├── movies
14 | ├── music
15 | └── shows
16 | docker
17 | └── jellyfin
18 | ├── config
19 | ├── jellyseerr
20 | └── jellystat
21 | ```
22 |
23 | ### Network Share (VM)
24 | I generally install Docker on the same LXC that I have my media server on as well as all my data. This, however, is [not recommended by Proxmox](https://www.reddit.com/r/Proxmox/comments/1afslhs/should_i_use_lxc_or_vm_for_running_docker/). Going forward you should create a separate VM for all your docker containers and mount the data directory we created in the storage guide with the share.
25 |
26 | Within the VM install `cifs-utils`
27 | ```bash
28 | sudo apt install cifs-utils
29 | ```
30 | Now, edit the `fstab` file and add the following lines editing them to match your information.
31 | ```bash
32 | sudo nano /etc/fstab
33 | ```
34 | ```
35 | //10.0.0.100/data /data cifs uid=1000,gid=1000,username=user,password=password,iocharset=utf8 0 0
36 | ```
37 | Storing the user credentials within this file isn't the best idea. Check out [this question](https://unix.stackexchange.com/questions/178187/how-to-edit-etc-fstab-properly-for-network-drive) on Stack Exchange to learn more.
38 |
39 | Now reload the configuration and mount the shares with the following commands.
40 | ```bash
41 | sudo systemctl daemon-reload
42 | sudo mount -a
43 | ```
44 |
45 | ## User Permissions
46 | Using bind mounts (`path/to/config:/config`) may lead to permission conflicts between the host operating system and the container. To avoid this problem, you can specify the user ID (`PUID`) and group ID (`PGID`) to use within some of the containers. This will give your user permissions to read and write configuration files, etc.
47 |
48 | In the compose file I use `PUID=1000` and `PGID=1000`, as those are generally the default IDs in most Linux systems, but depending on your setup you may need to change this.
49 |
50 | ```bash
51 | id your_user
52 | ```
53 | This command will return something like the following:
54 | ```
55 | uid=1000(brandon),gid=1003(brandon),groups=1000(data-share),988(docker)
56 | ```
57 | In the example output above, if using a network share I would need to edit the `compose.yaml` with `PGID=1003`. If you are using a network share mounted though `/etc/fstab` match the permissions there. I use Cockpit with a custom group for shares so my permissions are `uid=1000(brandon),gid=1000(data-share)`.
58 | If you run into errors after creating all the folders you can assign the permissions using `chown`. For example:
59 | ```bash
60 | sudo chown -R 1000:1000 /data
61 | sudo chown -R 1000:1000 /docker
62 | ```
63 |
64 | ## Installation
65 | There are two options for installing Jellyfin. Both work great and it's all a matter of preference. I generally install Jellyfin directly on the LXC within Proxmox that contains all my data.
66 |
67 | ### Docker Setup (Recommended)
68 | Docker is another option to install and run Jellyfin. Check out the `compose.yaml` file or the full stack.
69 |
70 | ```yaml
71 | services:
72 | jellyfin:
73 | image: lscr.io/linuxserver/jellyfin:latest
74 | container_name: jellyfin
75 | environment:
76 | - PUID=1000
77 | - PGID=1000
78 | - TZ=America/Los_Angeles
79 | - JELLYFIN_PublishedServerUrl=http://10.0.0.101 #optional
80 | volumes:
81 | - ./config:/config
82 | - /data:/data
83 | devices:
84 | - /dev/dri:/dev/dri #Use for Intel QuickSync
85 | ports:
86 | - 8096:8096
87 | - 7359:7359/udp #Service Discovery
88 | - 1900:1900/udp #Client Discovery
89 | restart: unless-stopped
90 | ```
91 |
92 | ### System Installation (NOT Recommended)
93 | Run the following command on your Ubuntu system, VM, or Proxmox LXC. You can learn about how to verify the script integrity [here](https://jellyfin.org/docs/general/installation/linux/).
94 | ```bash
95 | curl https://repo.jellyfin.org/install-debuntu.sh | sudo bash
96 | ```
97 |
98 | #### Permissions
99 | If you're running this with docker, you can skip these steps!
100 |
101 | Stop the Jellyfin service.
102 | ```bash
103 | sudo systemctl jellyfin stop
104 | ```
105 | Edit the Jellyfin service configuration to reflect your user.
106 | ```bash
107 | sudo nano /lib/systemd/system/jellyfin.service
108 | ```
109 | Now change the `User` and `Group` settings to your main user. You can run the `id` command if you're unsure.
110 | ```ini
111 | [Unit]
112 | Description = Jellyfin Media Server
113 | After = network-online.target
114 |
115 | [Service]
116 | Type = simple
117 | EnvironmentFile = /etc/default/jellyfin
118 | User = brandon
119 | Group = brandon
120 | WorkingDirectory = /var/lib/jellyfin
121 | ExecStart = /usr/bin/jellyfin $JELLYFIN_WEB_OPT $JELLYFIN_FFMPEG_OPT $JELLYFIN_SERVICE_OPT
122 | Restart = on-failure
123 | TimeoutSec = 15
124 | SuccessExitStatus=0 143
125 |
126 | [Install]
127 | WantedBy = multi-user.target
128 | ```
129 | Now change the permissions of the Jellyfin files and folders
130 | ```bash
131 | sudo chown -R brandon:brandon /etc/default/jellyfin
132 | sudo chown -R brandon:brandon /usr/bin/jellyfin
133 | sudo chown -R brandon:brandon /var/lib/jellyfin/
134 | sudo chown -R brandon:brandon /etc/jellyfin/
135 | sudo chown -R brandon:brandon /var/log/jellyfin/
136 | sudo chown -R brandon:brandon /var/cache/jellyfin/
137 | sudo chown -R brandon:brandon /usr/share/jellyfin
138 | sudo chown -R brandon:brandon /usr/share/jellyfin-ffmpeg
139 | sudo chown -R brandon:brandon /usr/lib/jellyfin/
140 | sudo chown -R brandon:brandon /usr/lib/jellyfin-ffmpeg/
141 | ```
142 | Reload the daemon and restart jellyfin
143 | ```bash
144 | sudo systemctl daemon-reload
145 | sudo systemctl restart jellyfin
146 | ```
147 | Check the user that is running Jellyfin
148 | ```bash
149 | ps -aux | grep jellyfin
150 | ```
151 | Source: [https://github.com/tteck/Proxmox/discussions/286](https://github.com/tteck/Proxmox/discussions/286)
152 |
153 | #### Hardware Transcoding
154 | For the System Installation only, install the `jellyfin-ffmpeg7`. Remove the deprecated jellyfin meta package if it breaks the dependencies.
155 | ```bash
156 | sudo apt update && sudo apt install -y jellyfin-ffmpeg7
157 | ```
158 | Continue with the steps below...
159 |
160 | ## Hardware Transcoding
161 | This focuses on transcoding with Intel QuickSync. In my experience it is simply the best option. If you're running a AMD CPU you can pickup a Intel Arc GPU fairly cheap. If you have any issues or don't have access to a Intel CPU or an Arc GPU be sure to checkout the official docs [here](https://jellyfin.org/docs/general/administration/hardware-acceleration/). If you're not doing this on Proxmox you can skip to the Ubuntu setup.
162 |
163 | ### Proxmox Passthrough
164 |
165 | > [!NOTE]
166 | > Running Jellyfin with Docker on a VM is highly recommended. This eliminates permission issues with running Jellyfin on the system and running Docker on a VM is what is recommended by the Proxmox team.
167 | >
168 |
169 | #### Running on a VM (Recommended)
170 | In the Proxmox UI, under your virtual machine, click the **Hardware** option in the sidebar. From there select _Add > PCI Device_. Then select **Raw** and pick the device that we will use for Quicksync or another GPU if you're not using Quicksync. For Quicksync it's often the very first Intel device that will say something like "Alderlake" in the name.
171 |
172 | #### Running on an Unprivileged LXC
173 | If you're running Jellyfin directly on the LXC that houses all your media, you will need to manually add the following to you LXC configuration. Add the lines below to the configuration of your container below. Don't forget to change the ID to match the container you've installed Jellyfin on.
174 | ```bash
175 | nano /etc/pve/lxc/100.conf
176 | ```
177 | ```
178 | #Add these for Intel QuickSync
179 | dev0: /dev/dri/card0,gid=44
180 | dev1: /dev/dri/renderD128,gid=104
181 | ```
182 | ### Ubuntu Setup
183 | The following steps are necessary when running Jellyfin on an Ubuntu server, virtual machine or Proxmox LXC. Add user `jellyfin` and the user you're running jellyfin as to the `render` group.
184 | ```bash
185 | sudo usermod -aG render jellyfin
186 | sudo usermod -aG render brandon # since I'm running jellyfin as my user
187 | sudo systemctl restart jellyfin
188 | ```
189 | Now we can confirm hardware transcoding is ready by installing the `intel-gpu-tools` package and running the command `intel_gpu_top`.
190 | ```bash
191 | sudo apt install intel-gpu-tools
192 | intel_gpu_top
193 | ```
194 |
195 | ## Configuring Jellyfin
196 | Open your web browser and navigate to your installed instance of Jellyfin using `http://IP:8096` and once there you can power through the initial setup by selecting your preferred language, then create an admin account with a secure username and password. Next, set up your media libraries by adding folders for movies, TV shows, or music. I tend to keep everything in my `/data` directory as shown in the media page on this repo.
197 |
198 | ## Plugins
199 | Below are the plugins I'm currently testing. I'd recommend checking out [Awesome Jellyfin](https://github.com/awesome-jellyfin/awesome-jellyfin) for much more.
200 |
201 | 1. [Intro Skipper](https://github.com/intro-skipper/intro-skipper)
202 | 2. [Fan Art](https://github.com/jellyfin/jellyfin-plugin-fanart)
203 | 3. [Jellyfin Newsletter](https://github.com/Cloud9Developer/Jellyfin-Newsletter-Plugin)
204 | 4. [TMDb Box Sets](https://github.com/jellyfin/jellyfin-plugin-tmdbboxsets)
205 | 5. [TheTVDB](https://github.com/jellyfin/jellyfin-plugin-tvdb)
206 | 6. [SkinManager](https://github.com/danieladov/jellyfin-plugin-skin-manager)
207 | 7. [Media Bar](https://github.com/IAmParadox27/jellyfin-plugin-media-bar)
208 |
209 | ## Other Tools
210 | Now to expand the functionality of Jellyfin I recommend these 3rd party tools that integrate well with Jellyfin.
211 |
212 | ### Jellystat
213 | Find it [here](https://github.com/CyferShepard/Jellystat)
214 |
215 | ### Jellyseerr
216 | Find it [here](https://github.com/fallenbagel/jellyseerr)
217 |
218 | ## DVR and Live TV
219 |
220 | ### Live TV
221 | This will require some extra hardware and a paid service for the guide data. HDHomeRun is great and it's what I use. Go to _Dashboard → Live TV → TV Sources → Add Tuner Device_. Select your tuner type _HDHomeRun_. Enter the tuner’s IP address and click **Save**.
222 |
223 | Next you want to setup guide data. _Guide Providers → Add Guide Provider_. Schedules Direct is a paid service, but they're awesome. It's a non-profit and they commit to the Jellyfin code directly. Create an account and you can use it for free for a week. Input your username and password and give it some time to update the data. I didn't need to but you can map the channels by going to _Channels → Map Channels_.
224 |
225 | ### DVR
226 |
227 | > [!NOTE]
228 | > This is a work in progress. Don't quite have it working yet.
229 | >
230 |
231 | ## Remote Connections
232 |
233 | > [!NOTE]
234 | > This is a work in progress.
235 |
236 | In the meantime checkout [this](https://youtu.be/79e6KBYcVmQ?si=0yTkdD5UtDVs-jNX) video.
237 |
--------------------------------------------------------------------------------
/media/README.md:
--------------------------------------------------------------------------------
1 | # Self-Hosted Media Server and Aggregation
2 |
3 | Make sure to review everything here and if you have any issues please submit it as an issue. Also, we are more than open to any suggests or edits. Also, checkout the [Servarr Docker Setup](https://wiki.servarr.com/docker-guide) for more details on installing the stack.
4 |
5 | > [!CAUTION]
6 | > Some MAJOR Updates! Moved the VPN configuration and some of the env variables to a `.env` file. If you're watching the current live video it's a huge change. Will be uploading a new one in the next few days.
7 |
8 | ## Navigation
9 | * [Apps](https://github.com/TechHutTV/homelab/tree/main/apps)
10 | * [Home Assistant](https://github.com/TechHutTV/homelab/tree/main/homeassistant)
11 | * [__Media Server__](https://github.com/TechHutTV/homelab/tree/main/media)
12 | - [Companion Video](#companion-video)
13 | * [Updates Since Video Publish](#updates-since-video-publish)
14 | - [Media Server](#media-server)
15 | * [Jellyfin](https://github.com/TechHutTV/homelab/tree/main/media/jellyfin)
16 | * [Plex](https://github.com/TechHutTV/homelab/tree/main/media/plex)
17 | - [Data Directory](#data-directory)
18 | * [Folder Mapping](#folder-mapping)
19 | * [Network Share](#network-share)
20 | - [User Permissions](#user-permissions)
21 | - [Docker Compose and .env](#docker-compose-and-env)
22 | - [Gluetun VPN](#gluetun-vpn)
23 | * [Setup and Configuration](#setup-and-configuration)
24 | * [Testing Gluetun Connectivity](#testing-gluetun-connectivity)
25 | * [Passing Through Containers](#passing-through-containers)
26 | * [External Container to Gluetun](#external-container-to-gluetun)
27 | * [Gluetun Proxmox LXC Setup](#gluetun-proxmox-fix)
28 | * [Reduce Gluetun Ram Usage](#reduce-gluetun-ram-usage)
29 | - [Download Clients](#download-clients)
30 | * [NZBGet](#nzbget)
31 | + [NZBGet Login Credentials](#nzbget-login-credentials)
32 | + [Download Directories Mapping](#nzbget-download-directories)
33 | + [Fix "directory does not appear" error in Sonarr/Radarr](#fix-directory-does-not-appear-to-exist-inside-the-container-error)
34 | * [qBittorrent](#qbittorrent)
35 | + [qBittorrent Login Credentials](#qbittorrent-login-credentials)
36 | + [Download Directories Mapping](#qbittorrent-download-directories)
37 | + [qBittorrent Stalls with VPN Timeout](#qbittorrent-stalls-with-vpn-timeout)
38 | - [*arr Apps](#arr-apps)
39 | * [Server Monitoring](https://github.com/TechHutTV/homelab/tree/main/monitoring)
40 | * [Surveillance System](https://github.com/TechHutTV/homelab/tree/main/surveillance)
41 | * [Storage](https://github.com/TechHutTV/homelab/tree/main/storage)
42 | * [Proxy Management](https://github.com/TechHutTV/homelab/tree/main/proxy)
43 |
44 | ## Companion Video
45 | ```
46 | # Updated video coming soon
47 | [](video link)
48 | ```
49 | ### Updates Since Video Publish
50 | * Added [ytdl-sub](https://ytdl-sub.readthedocs.io/en/latest/) to the `compose.yaml`. Remove if unwanted.
51 |
52 | ## Media Server
53 | Media Servers have their own guides! Check the link below and it will take you to the folder for the guides.
54 |
55 | - [Jellyfin](https://github.com/TechHutTV/homelab/tree/main/media/jellyfin)
56 | - [Plex](https://github.com/TechHutTV/homelab/tree/main/media/plex)
57 |
58 | ## Data Directory
59 | ### Folder Mapping
60 | It's good practice to give all containers the same access to the same root directory or share. This is why all containers in the compose file have the bind volume mount `/data:/data`. It makes everything easier, plus passing in two volumes such as the commonly suggested `/tv`, `/movies`, and `/downloads` makes them look like two different file systems, even if they are a single file system outside the container. See my current setup below.
61 | ```
62 | data
63 | ├── books
64 | ├── downloads
65 | │ ├── qbittorrent
66 | │ │ ├── completed
67 | │ │ ├── incomplete
68 | │ │ └── torrents
69 | │ └── nzbget
70 | │ ├── completed
71 | │ ├── intermediate
72 | │ ├── nzb
73 | │ ├── queue
74 | │ └── tmp
75 | ├── movies
76 | ├── music
77 | ├── shows
78 | └── youtube
79 | ```
80 | Here is a easy command to create the download directory scheme. Run within the `/data` directory.
81 | ```bash
82 | mkdir -p downloads/qbittorrent/{completed,incomplete,torrents} && mkdir -p downloads/nzbget/{completed,intermediate,nzb,queue,tmp}
83 | ```
84 |
85 | ### Network Share
86 | I generally install Docker on the same LXC that I have my media server on as well as all my data. This, however, is [not recommended by Proxmox](https://pve.proxmox.com/pve-docs/pve-admin-guide.html#chapter_pct). Going forward you should create a separate VM for all your docker containers and mount the data directory we created in the [storage guide](https://github.com/TechHutTV/homelab/tree/main/storage) with the share. You can also use this method if you're using a separate share on another machine running something like Unraid or TrueNAS.
87 |
88 | Within the VM install `cifs-utils`
89 | ```bash
90 | sudo apt install cifs-utils
91 | ```
92 | Now, edit the `fstab` file and add the following lines editing them to match your information:
93 | ```bash
94 | sudo nano /etc/fstab
95 | ```
96 | ```
97 | //10.0.0.100/data /data cifs uid=1000,gid=1000,username=user,password=password,iocharset=utf8 0 0
98 | ```
99 | Storing the user credentials within this file isn't the best idea. Check out [this question](https://unix.stackexchange.com/questions/178187/how-to-edit-etc-fstab-properly-for-network-drive) on Stack Exchange to learn more.
100 |
101 | Now reload the configuration and mount the shares with the following commands.
102 | ```bash
103 | sudo systemctl daemon-reload
104 | sudo mount -a
105 | ```
106 |
107 | ## User Permissions
108 | Using bind mounts (`path/to/config:/config`) may lead to permission conflicts between the host operating system and the container. To avoid this problem, you can specify the user ID (`PUID`) and group ID (`PGID`) to use within some of the containers. This will give your user permissions to read and write configuration files, etc.
109 |
110 | In the compose file I use `PUID=1000` and `PGID=1000`, as those are generally the default IDs in most Linux systems, but depending on your setup you may need to change this.
111 |
112 | ```bash
113 | id your_user
114 | ```
115 | This command will return something like the following:
116 | ```
117 | uid=1000(your_user) gid=1000(your_user) groups=1000(your_user),27(sudo),24(cdrom),30(dip),46(plugdev),108(lxd)
118 | ```
119 | If you are using a network share mounted though `/etc/fstab` match the permissions there. Learn more above.
120 |
121 | If you run into errors after creating all the folders you can assign the permissions using `chown`. For example:
122 | ```bash
123 | sudo chown -R 1000:1000 /data
124 | ```
125 | Also, I like to store all my Docker configurations in a root `/docker` directory on my Linux system. These can go wherever you prefer whether that be your home directory or somewhere else. Do note, many Docker apps may have issues if you're trying to store you Docker configurations in a SMB network share.
126 | ```bash
127 | mkdir /docker
128 | sudo chown -R 1000:1000 /docker
129 | ```
130 | ## Docker Compose and .env
131 | Navigate to the directory you want to spin up the servarr stack in. I run mine from `/docker/servarr` but you can run it from anywhere you'd like such as `/home/user/docker/servarr`. Then download the `compose.yaml` and `.env` files from this repo.
132 | ```bash
133 | wget https://github.com/TechHutTV/homelab/raw/refs/heads/main/media/compose.yaml && wget https://github.com/TechHutTV/homelab/raw/refs/heads/main/media/.env
134 | ```
135 | Most of our editing is going to be done in the `.env` file. Here you change your `UID` and `GID`, timezone, and add all your VPN keys and info. You can also make edits to the `compose.yaml` file such as the mount point locations, for example, if you are using something other than `/data:/data` or even changing the docker network IP addresses for your services.
136 |
137 | ## Gluetun VPN
138 |
139 | ### Setup and Configuration
140 | I like to set this out with [AirVPN](https://airvpn.org/?referred_by=673908) (referral link). I'm not affiliated with them in any way other than the referral link. I've tried a few other providers and they're my preference. If you already have a VPN checkout the [providers](https://github.com/qdm12/gluetun-wiki/tree/main/setup/providers) page on their wiki.
141 |
142 | On AirVPN navigate to the **Client Area** from here select the **Config Generator**. Now in the options select **Linux** then toggle the **WireGuard** option. Select **New device** and then scroll down to **By single server** and select a server that is best for you. For example, _Titawin (Vancouver)_ was my selection because, at the time, it had the fewest users with good speeds. Scroll all the way to the bottom and select **Generate**. This will download a conf file with all of your information.
143 |
144 | Back in AirVPN navigate to the **Client Area** from here select **Manage** under **Ports**. If you already have a port open click on **Test open** otherwise click the plus button under **Add a new port** then click **Test open** for that port. Here you will find the specific servers that you can use your port on. If there is a `Connection refused` warning next the server you generated your configuration for change the port until the warning goes away. For example, in my case the _'Titawin (Vancouver)_ server that I selected with my port is good to use.
145 |
146 | > [!CAUTION]
147 | > Do NOT forward on your router the same ports you use on your listening services while connected to the VPN.
148 |
149 | Now, in the same directory as your docker `compose.yaml` file create a `.env` file. Paste in the variables below and then add all the information from your downloaded `.conf` file.
150 |
151 | ```bash
152 | nano .env
153 | ```
154 | ```bash
155 | # General UID/GIU and Timezone
156 | TZ=America/Los_Angeles
157 | PUID=1000
158 | PGID=1000
159 |
160 | # Input your VPN provider and type here
161 | VPN_SERVICE_PROVIDER=airvpn
162 | VPN_TYPE=wireguard
163 |
164 | # Mandatory, airvpn forwarded port
165 | FIREWALL_VPN_INPUT_PORTS=port # mandatory, airvpn forwarded port
166 |
167 | # Copy all these variables from your generated configuration file
168 | WIREGUARD_PUBLIC_KEY=key
169 | WIREGUARD_PRIVATE_KEY=key
170 | WIREGUARD_PRESHARED_KEY=key
171 | WIREGUARD_ADDRESSES=ipv4
172 |
173 | # Optional location variables, comma separated list, no spaces after commas, make sure it matches the config you created
174 | SERVER_COUNTRIES=country
175 | SERVER_CITIES=city
176 |
177 | # Heath check duration
178 | HEALTH_VPN_DURATION_INITIAL=120s
179 | ```
180 |
181 | ### Testing Gluetun Connectivity
182 | Once your containers are up and running, you can test your connection is correct and secured. This assumes you keep the `gluetun` container name. Learn more at the [gluetun wiki](https://github.com/qdm12/gluetun-wiki/blob/main/setup/test-your-setup.md).
183 |
184 | > [!Note]
185 | > If you run into issues try restarting the stack with `docker compose restart`.
186 | ```bash
187 | docker run --rm --network=container:gluetun alpine:3.18 sh -c "apk add wget && wget -qO- https://ipinfo.io"
188 | ```
189 | If you'd like to test Gluetun connectivity from a container using the service jump into the `docker compose exec` console and run the `wget` command below. Tested with `nzbget`, `qbittorrent`, and `prowlarr` containers. Ensure you open the ports through the the `gluetun` container.
190 | ```bash
191 | docker exec -it container_name bash
192 | wget -qO- https://ipinfo.io
193 | ```
194 | ### Passing Through Containers
195 | When containers are in the same docker compose they all you need to add is a `network_mode: service:container_name` and open the ports through the the gluetun container. See example with a different torrent client below.
196 | ```yaml
197 | services:
198 | gluetun:
199 | image: qmcgaw/gluetun
200 | container_name: gluetun
201 | ...
202 | ports:
203 | - 8888:8112 # deluge web interface
204 | - 58846:58846 # deluge RPC
205 | deluge:
206 | image: linuxserver/deluge:latest
207 | container_name: deluge
208 | ...
209 | network_mode: service:gluetun
210 | ```
211 | ### External Container to Gluetun
212 | Add the following when launching the container, provided Gluetun is already running on the same machine.
213 | ```
214 | --network=container:gluetun
215 | ```
216 | If the container is in another docker `compose.yaml`, assuming Gluetun is already running add the following network mode. Ensure you open the ports through the the gluetun container.
217 | ```yaml
218 | network_mode: "container:gluetun"
219 | ```
220 |
221 | ### Gluetun Proxmox LXC Setup
222 |
223 | Errors like `cannot Unix Open TUN device file: operation not permitted` and `cannot create TUN device file node: operation not permitted` may happen if you're running this on LXC containers.
224 |
225 | Find your container number, for example mine is 101
226 |
227 | Edit `/etc/pve/lxc/101.conf` and add:
228 | ```
229 | lxc.cgroup2.devices.allow: c 10:200 rwm
230 | lxc.mount.entry: /dev/net dev/net none bind,create=dir
231 | lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
232 | ```
233 | Make sure you pass through the tun device (`/dev/net/tun:/dev/net/tun`) as shown in my compose file.
234 |
235 | ### Reduce Gluetun Ram Usage
236 | As mentioned in this [issue](https://github.com/TechHutTV/homelab/issues/12) there is a [feature request](https://github.com/qdm12/gluetun/issues/765#issuecomment-1019367595) on the Gluetun Github page to help reduce ram usage. Gluetun bundles a recursive caching DNS resolver called `unbound` for handling domain name requests securely. Over time the cache size, which rests in RAM, can balloon to gigabytes.
237 |
238 | You can do this by adding the following to your docker `compose.yaml` file under the `gluetun` environment variables.
239 | ```yaml
240 | gluetun:
241 | ...
242 | environment:
243 | - BLOCK_MALICIOUS=off # Disable unbound DNS resolver
244 | ```
245 | This may not be an issue as [DNS over HTTPS in Go to replace Unbound](https://github.com/qdm12/gluetun/issues/137) is implemented, but it's worth the mention.
246 |
247 | ## Download Clients
248 |
249 | ### NZBGet
250 |
251 | #### NZBGet Login Credentials
252 | The default credentials for NZBGet are a username of `nzbget` and a password of `tegbzn6789`. It's strongly recommended to change these default credentials for security reasons. This can be done under _Settings > SECURITY_, then change the ControlUsername and ControlPassword.
253 |
254 | #### NZBGet Download Directories
255 | If following the `/data:/data` directory scheme and used the command to setup the download directories open the qBittorent Web UI and do under _Settings > PATHS_ and change the paths.
256 |
257 | _MainDir:_ `/data/downloads/nzbget`
258 |
259 | _DestDir:_ `${MainDir}/completed`
260 |
261 | _InterDir:_ `${MainDir}/intermediate`
262 |
263 | And keep everything else as is.
264 |
265 | #### Fix directory does not appear to exist inside the container error
266 | This error may appear within Sonarr and Radarr. Once NZBGet is setup go to settings and under **INCOMING NZBS** change the **AppendCategoryDir** to **No**. This will prevent some potential mapping issues and save on unnecessary directories.
267 |
268 | ### qBittorrent
269 |
270 | #### qBittorrent Login Credentials
271 | When you first launch qBittorrent it will generate a random password. To find this password you can view the logs to see what the password is.
272 | ```bash
273 | docker container logs qbittorrent
274 | ```
275 | Now, go to your settings and setup a new username and password under _WebUI > Authentication_.
276 |
277 | #### Qbittorrent Download Directories
278 | If following the `/data:/data` directory scheme and used the command to setup the download directories open the qBittorent Web UI and do under _Settings > Downloads_ and change the paths.
279 |
280 | _Default Save Path:_ `/data/downloads/qbittorrent/completed`
281 |
282 | _Keep incomplete torrents in:_ `/data/downloads/qbittorrent/incomplete`
283 |
284 | _Copy .torrent files to:_ `/data/downloads/qbittorrent/torrents`
285 |
286 | #### qBittorrent Stalls with VPN Timeout
287 | qBittorrent stalls out if there is a timeout or any type of interruption on the VPN. This is good because it drops connection, but we need it to fire back up when the connection is restored without manually restarting the container.
288 |
289 | __Solution #1:__ Within the WebUI of qBittorrent head over to advanced options and select `tun0` as the networking interface. See image below for example.
290 |
291 | 
292 |
293 | Next, I added `HEALTH_VPN_DURATION_INITIAL=120s` to my gluetun environment variables as [per this issue](https://github.com/qdm12/gluetun/issues/1832). I updated my `compose.yaml` above with this variable so you may already have this enabled. You can learn more about this on their [wiki](https://github.com/qdm12/gluetun-wiki/blob/main/faq/healthcheck.md). If you continue to have issues continue to next solution.
294 |
295 | __Solution #2:__ Another solution, that can be used in conjunction with __Solution #1__ is using the [deunhealth](https://github.com/qdm12/deunhealth/tree/main) container to automatically restart qBittorrent when it gives an unhealthy status. We've added this to our `compose.yaml` for this stack.
296 | ```yaml
297 | deunhealth:
298 | image: qmcgaw/deunhealth
299 | container_name: deunhealth
300 | network_mode: "none"
301 | environment:
302 | - LOG_LEVEL=info
303 | - HEALTH_SERVER_ADDRESS=127.0.0.1:9999
304 | - TZ=America/Los_Angeles
305 | restart: always
306 | volumes:
307 | - /var/run/docker.sock:/var/run/docker.sock
308 | ```
309 |
310 | Next we need to add a health check and label to our `qbittorrent` container. We add `deunhealth.restart.on.unhealthy=true` as a label and a simple ping health check as shown below.
311 |
312 | ```yaml
313 | qbittorrent:
314 | image: lscr.io/linuxserver/qbittorrent:latest
315 | container_name: qbittorrent
316 | restart: unless-stopped
317 | labels:
318 | deunhealth.restart.on.unhealthy=true # Label added for deunhealth monitoring
319 | ...
320 | ```
321 | Relevant Resources: [DBTech video on deunhealth](https://www.youtube.com/watch?v=Oeo-mrtwRgE), [gluetun/issues/2442](https://github.com/qdm12/gluetun/issues/2442) and [gluetun/issues/1277](https://github.com/qdm12/gluetun/issues/1277#issuecomment-1352009151)
322 |
323 | ## *arr Apps
324 |
325 | When connecting your *arr applications be sure to use the new configured IP addresses in the `servarrnetwork`. We will soon update this section with more text documentation.
326 |
--------------------------------------------------------------------------------
/proxy/README.md:
--------------------------------------------------------------------------------
1 | # External Proxy and Internal Top-Level Domains
2 |
3 | This is going to be an overview of my setup for connecting to specific services through a proxy and DDNS combo, local top-level domain names, and how I connect to the internal home network remotely with Twingate.
4 |
5 | This is done on Proxmox with an LXC running Ubuntu 22.04 and Docker. However, these steps will work with any Docker installation. If you want details on installing Docker and a brief overview of all the basics you need to know to get started checkout our [7 Docker Basics for Beginners](https://techhut.tv/7-docker-basics-for-beginners).
6 |
7 | ## Navigation
8 | * [Apps](https://github.com/TechHutTV/homelab/tree/main/apps) - List of all the apps and services.
9 | * [Home Assistant](https://github.com/TechHutTV/homelab/tree/main/homeassistant) - Smart home services and automation.
10 | * [Media Server](https://github.com/TechHutTV/homelab/tree/main/media) - Plex, Jellyfin, *arr stack, and more.
11 | * [Server Monitoring](https://github.com/TechHutTV/homelab/tree/main/monitoring) - Graphs and Visualizations for Unriad, Proxmox, and more.
12 | * [Surveillance System](https://github.com/TechHutTV/homelab/tree/main/surveillance) - Frigate NVR Solution with Coral TPU.
13 | * [Storage](https://github.com/TechHutTV/homelab/tree/main/storage) - Current Storage and Backup Solution.
14 | * [__Proxy Managment__](https://github.com/TechHutTV/homelab/tree/main/proxy) - NGINX Proxy Manager, DDNS with Cloudflare, Local Domains, and more.
15 |
16 |
17 | ## Installing NGINX Proxy Manager
18 | This is done with the [Docker Compose file](https://github.com/TechHutTV/homelab/blob/main/proxy/compose.yaml) within this repository. Do note, I made some customizations for how I specifically like to set it up. I've changed some of the external ports to access 80, 443, and the GUI for NGINX Proxy Manager as well as placing the storage within [volumes](https://docs.docker.com/engine/storage/volumes/). Please change these as needed or use the [official compose file](https://github.com/NginxProxyManager/nginx-proxy-manager) as seen below. Additionally, I've added the container [cloudflare-dynamic-dns](https://github.com/favonia/cloudflare-ddns) as my IP address changes randomly. If you don't have a dynamic IP address or don't have intention on exposing a service to the internet you can remove this container from the compose file.
19 |
20 | ### NGINX Proxy Manager Compose (customized)
21 |
22 | ```
23 | services:
24 | proxy:
25 | image: 'jc21/nginx-proxy-manager:latest'
26 | container_name: nginx-proxy-manager
27 | restart: unless-stopped
28 | network_mode: host
29 | volumes:
30 | - proxy-data:/data
31 | - proxy-letsencrypt:/etc/letsencrypt
32 | healthcheck:
33 | test: ["CMD", "/usr/bin/check-health"]
34 | interval: 10s
35 | timeout: 3s
36 | volumes:
37 | proxy-data:
38 | proxy-letsencrypt:
39 | ```
40 |
41 | This is setup as a host network to allow localhost and local networking connections without needing to add ports for all the services to the container.
42 |
43 | _Below is a basic compose template from NGINX if you don't want to use [mine](https://github.com/TechHutTV/homelab/blob/main/proxy/compose.yaml)._
44 |
45 | #### Official Compose from NginxProxyManager/nginx-proxy-manager
46 |
47 | Checkout the [quick setup](https://github.com/NginxProxyManager/nginx-proxy-manager?tab=readme-ov-file#quick-setup) section in their official repo.
48 |
49 | ```
50 | services:
51 | app:
52 | image: 'docker.io/jc21/nginx-proxy-manager:latest'
53 | restart: unless-stopped
54 | ports:
55 | - '80:80'
56 | - '81:81'
57 | - '443:443'
58 | volumes:
59 | - ./data:/data
60 | - ./letsencrypt:/etc/letsencrypt
61 | ```
62 |
63 | Due note, as seen in my docker compose you'll need to either need to set the network mode to [host](https://stackoverflow.com/questions/42438381/docker-nginx-proxy-to-host#:~:text=Use%20network_mode%3A%20host%2C%20this%20will%20bind%20your%20nginx,every%20exposed%20port%20is%20binded%20to%20host%27s%20interface.) or [expose the specific ports](https://www.reddit.com/r/homelab/comments/1c38ize/nginx_proxy_manager_cant_route_to_different_port/#:~:text=Nginx%20Proxy%20Manager%20is%20in%20a%20docker%20container.) if running on bridge mode for servers that are running on your home network from a different machine. Also, be sure to check out their [Advanced Configuration](https://nginxproxymanager.com/advanced-config/) documents.
64 |
65 | #### If using bridge mode see the example below
66 | ```
67 | proxy:
68 | ...
69 | network_mode: bridge
70 | ports:
71 | - 5080:80
72 | - 5443:443
73 | - 5000:81
74 | - 8096:8096 # add ports you want to expose that are not on your local server
75 | ...
76 | ```
77 |
78 |
79 | ## Setup DDNS for and Cloudflare for Public Access
80 |
81 | ### Cloudflare Setup
82 | 1. Sign up for a Cloudflare account and use it to manage your domain using [this guide](https://developers.cloudflare.com/fundamentals/setup/manage-domains/add-site/).
83 | 2. Within Cloudflare [obtain your API token](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/). _My Profile > API Tokens > Create Token > Edit Zone DNS > Include All Zones > Create Token > Save your Token_. We will be using this token in the cloudflare-ddns container configuration and when we generate SSL certificates.
84 |
85 | ### Port Forwarding
86 | This is different for every router so you may need to do additional research to do this on your specific hardware. I currently use the Omada stack for networking needs. Basically, it's like Ubiquiti but cheaper (you get what you pay for).
87 |
88 | Open the ports on your router for the 80 and 443 ports we set up in NGINX Proxy Manager. In my docker compose file I'm using the host networking mode so I'd open the ports 80 and 443 with the local IP of the machine that NGINX Proxy Manager is installed on. In my setup I needed to set the source port and destination port. See my example below.
89 |
90 |
91 | Source Port vs. Destination Port
92 |
93 | Source Port:
94 | This is the port on the device that is initiating the communication. For example, when your computer sends a request to a server, it uses a source port to identify itself.
95 |
96 | Destination Port:
97 | This is the port on the device that will receive the communication. For example, when you're connecting to a web server. The destination port is fixed for the service you're trying to reach and tells the receiving device what service or application should handle the incoming data.
98 |
99 |
100 | 
101 |
102 | If using bridge mode with custom ports, for example 5080 and 5443 as shown in the example. I'd set the destination port to 5443 and the source port to 443 for https.
103 |
104 | ### Dynamic DNS
105 | 1. Within Cloudflare use an A record to create the root domain and/or sub-domains you wish to point to specific services within your home network. For the IPv4 address we will have our DDNS container handle that. I recommend adding a random IP now (ie. 8.8.8.8) so in the next step we can verify that it will update automatically to our public IP. Be sure to keep the 'Proxy status' option enabled.
106 | 2. If you need to use DDNS, edit your Docker Compose file, add your API, and domain names including subdomains you want to set up for external access. When the container runs ensure there are no errors and the public IP in Cloudflare is updated to your actual IP.
107 |
108 | Below is the compose template for the cloudflare-dynamic-dns container. You can use it as I have it within my compose file or set it up separately.
109 |
110 | ```
111 | services:
112 | ddns:
113 | image: favonia/cloudflare-ddns:latest
114 | container_name: cloudflare-ddns
115 | # network_mode: host # This bypasses network isolation and makes IPv6 easier (optional; see below)
116 | restart: always
117 | user: "1000:1000" # Run the updater with specific user and group IDs (in that order).
118 | read_only: true # Make the container filesystem read-only (optional but recommended)
119 | cap_drop: [all] # Drop all Linux capabilities (optional but recommended)
120 | security_opt: [no-new-privileges:true] # Another protection to restrict superuser privileges (optional but recommended)
121 | environment:
122 | - CLOUDFLARE_API_TOKEN=KEY
123 | - DOMAINS=example.com,jellyfin.example.com
124 | - PROXIED=true
125 | - IP6_PROVIDER=none
126 | ```
127 |
128 | ### Generate SSL Certificates and Add Hosts
129 | 1. Now head over to NGINX Proxy Manager and create your SSL certificates. You navigate to _SSL Certificates > Add SSL Certifcate_. Type in your domain name and then enable 'Use a DNS Challenge'. Select Cloudflare and paste in the API we saved from earlier.
130 | 2. Now in NGINX Proxy Manager navigate to _Hosts > Add Proxy Host_. Add the domain name for the service (ie. nextcloud.example.com) and select http (this may vary on if the service is running on https locally) then add the local IP and port for the service you want forwarded to the domain.
131 | * Depending on the service you may need to enable _Websockets Support_, but I always select _Block Common Exploits_.
132 | * Navigate the the SSL tab and select your SSL Certificate and enable _Force SSL_. **See known issues below.**
133 | * Depending on the service you may need to make changes to the settings in the specific service, such as allowing proxies and add some advanced configuration, for example Jellyfin requires some additional configuration.
134 | * Jellyfin requires you to add the approved proxy ip for the local NGINX Proxy Manager Machine. [source](https://jellyfin.org/docs/general/networking/#:~:text=SERVER_IP_ADDRESS)
135 | * Jellyfin has additional configurations for the advanced tab in proxy host settings. [source](https://jellyfin.org/docs/general/networking/nginx/#nginx-proxy-manager)
136 |
137 | #### Known Issues and Tips
138 | * **Too Many Redirects:** Force SSL may not work with CloudFlare proxying. [issue](https://github.com/NginxProxyManager/nginx-proxy-manager/issues/852)
139 | * **Disable Cloudflare Proxy on Streaming:** Jellyfin, Plex and other streaming services are not allowed to use Proxy on the free plan. Doing this technically [breaks their TOS](https://www.cloudflare.com/service-specific-terms-application-services/#content-delivery-network-terms) and may result in your account getting banned. Just to be safe I used a subdomain for my Jellyfin instance as a separate A-Record and disabled the Cloudflare Proxy.
140 |
141 | 
142 |
143 | ---
144 |
145 | # Local Top-Level Domains and Twingate
146 |
147 | Within this section we will use our NGINX Proxy Manager setup and our domain registrar directly to create a proxy host scheme for local access only. This will also allow us to use letsencrypt to generate SSL certificates for our local network. This will eliminate that horrible _this site is not secure_ message on our services! Also, we will be setting up Twingate (a channel sponsor) to enable a zero trust network for remote access to those services we don't want to expose publically.
148 |
149 | ## Setup a Top-Level Domain for Local Use
150 |
151 | ### Local IP on Registar
152 | Assign a local IP scheme in the domain registration website. The local IP you will use is the same as the machine running NGINX Proxy Manager. (ie. 10.0.0.60). You'll want to assign this to the A-Record for the main domain and create a CNAME Record as a wildcard (*) pointing to the main domain name. Due note, this may take some time, it took about 15 minutes for the record to update for me. If you're using Cloudflare make sure you disable their proxy service.
153 |
154 | 
155 |
156 | While you're on Cloudflare or the registar find your API key. You'll need this for generating SSL certificates in the DNS challenges option. Many providers are supported and you can see a [full list here](https://community.letsencrypt.org/t/dns-providers-who-easily-integrate-with-lets-encrypt-dns-validation/86438).
157 |
158 | ### Adding Proxy Hosts
159 | This will mirror the steps above, with some slight differences. In NGINX Proxy Manager navigate to _Hosts > Add Proxy Host_. Add the domain name for the service (ie. example.com) and select http (this may vary depending on if the service is running on https locally) then add the local IP and port for the service you want forwarded to that domain. If you want to test everything check below.
160 |
161 | #### Testing
162 | There is a simple container we can use to test our domain with the local IP. In the terminal run the docker command below on the same machine that is running your Proxy Manager. This is also available as docker compose in the compose.yaml file in this repository.
163 |
164 | ```
165 | docker run -p 8888:80/tcp "karthequian/helloworld:latest"
166 | ```
167 |
168 | Add a subdomain (hello.example.com) in proxy hosts with the IP running this helloworld container and the port _8888_. Set it to http only with no SSL since we have not set that up yet.
169 | 1. Navigate to example.com:8888 to test if the A-Record and CNAME is working properly.
170 | 2. Navigate to hello.example.com to test if the reverse proxy is working.
171 |
172 | ### Generate Let's Encrypt Certificates
173 | Navigate to _SSL Certificates > Add SSL Certifcate_. Type in your root domain name (example.com) click add then input the wildcare domain (*.example.com) and then enable 'Use a DNS Challenge'. Select your registar and paste in the API we saved from eariler. If you run into error make sure that your API key is correct, whitelist your public IP with you registar if needed, or try increasing the _Propagation Seconds_ to 120 seconds.
174 |
175 | #### Testing
176 | With the helloworld container still running, head over to _Proxy Hosts_ and edit the hello.example.com host. In the SSL tab add _*.example.com_ under the SSL Certificate and enable _Force SSL_. Navigate to hello.example.com to ensure that the connection is automatically redirected to https.
177 |
178 | #### Known Issues and Tips
179 | * **Namecheap API Whitelist:** Namecheap isn't really the best for this if you have a Dynamic IP. Whenever I want to update my certificates I need to whitelist my public IP so it can use their API. I will be switching to using Cloudflare for this going forward.
180 |
181 | ## Setup Twingate for remote connections
182 | **Notice: Twingate is a channel sponsor, thus this is a bias disclosure.** Twingate uses cloud based software for managing networks, resources, and users. Some users prefer to self-host every aspect of this, if that's you look into something like [Netbird](https://github.com/netbirdio/netbird). For myself, Twingate has been awesome; easy to use and [others rate it well](https://www.reddit.com/r/twingate/comments/1awg76l/how_safe_is_twingate/).
183 |
184 | After [creating an account on Twingate](https://bit.ly/feb24-twingate) and setting up [your first network](https://www.twingate.com/docs/quick-start) we need to set up a connector. Within my docker compose file I have the twingate-connector service ready to deploy with the entire stack. Here is what this service looks like.
185 |
186 | ```
187 | services:
188 | twingate_connector:
189 | container_name: twingate_connector
190 | restart: always
191 | image: "twingate/connector:latest"
192 | environment:
193 | - TWINGATE_NETWORK=
194 | - TWINGATE_ACCESS_TOKEN=
195 | - TWINGATE_REFRESH_TOKEN=
196 | ```
197 | When you create your connector in the Twingate dashboard you'll generate some tokens. Enter them in the environmental variables and launch the stack. Verify a connection under networks in Twingate.
198 |
199 | Next, create a new resource with the IP of your proxy manager and add the local root domain as an alias. Once created you should be able to have access to the local domain we created earlier including sub-domains. See the image before for an example.
200 |
201 | 
202 |
203 | # Additional Resources
204 |
205 | | Additional Security Steps | Twingate Guide |
206 | | ------------- | ------------- |
207 | | [](https://www.youtube.com/watch?v=Cs8yOmTJNYQ "DITCH your VPN! - How I Access my Home Server from ANYWHERE @TechHut") | [](https://youtu.be/yaw2A3DG664 "Self-Hosting Security Guide for your HomeLab @TechnoTim") |
208 |
209 |
210 | ## Setup Netbird for remote connections (work in progress)
211 | NetBird is an open source platform responsible for handling peer-to-peer connections, tunneling, authentication, and network management. While Netbird has a wonderful option to [fully self host](https://docs.netbird.io/selfhosted/self-hosted-vs-cloud-netbird), I opt for their free teir so I don't need to worry about having my own instance in my home or in a VPS. NetBird uses WireGuard’s lightweight encryption to establish direct, encrypted tunnels between devices or “peers" automatically. It eliminates manual configuration by handling tasks like IP assignment, NAT traversal, and firewall negotiation through built-in signaling servers. Plus you can setup various single sign on services and multi-factor authentication for added security. If you're interested in learning more about the technology used and how it works checkout [their docs](https://docs.netbird.io/about-netbird/how-netbird-works).
212 |
213 | (image here)
214 |
215 | ### Self Hosting Netbird Managment (skip if using their platform)
216 | wip
217 |
218 | ### Mangment Setup
219 | If you're not using the self-hosted instance
220 | Obtain your [security key](https://docs.netbird.io/how-to/register-machines-using-setup-keys).
221 |
222 | ### Setup
223 |
224 | There are two ways you can go about setting this up. First is a Full Peer-to-Peer (P2P) Mesh Network. For this, NetBird is installed on every device. It enables a full mesh network, allowing direct, secure connections between all peers. Or you can enable Remote Network Access because sometimes, it’s not feasible or necessary to install NetBird on every device. You probably can’t install Netbird on all your printers and IoT devices. This is what I'm going to do for my main network, you can set up a NetBird-enabled connector on something like a Raspberry Pi, Proxmox LXC, or whatever you’d like. This acts as a bridge, allowing other devices in the network to securely access devices on your network that you allow it to.
225 |
226 | #### Installing on Linux
227 | Installing on Linux is simple with a single line command. You can install this directly on any Linux system such as the Proxmox host system, an LXC container, and so on.
228 | ```
229 | curl -fsSL https://pkgs.netbird.io/install.sh | sh
230 | ```
231 | Now connect it using the setup key from the managment dashboard.
232 | ```
233 | netbird up --setup-key
234 | ```
235 | If you're self hosting you will need to specificy the URL that your instance is hosted on, for example, `netbird up --setup-key --management-url http://10.0.0.102:33073`.
236 |
237 | #### Install on Docker
238 | If you want to spin up a docker container or run Netbird in a docker stack checkout the following docker compose.yaml.
239 | ```
240 | #Untested
241 | services:
242 | netbird:
243 | container_name: netbird-client
244 | hostname: PEER_NAM
245 | cap_add:
246 | - NET_ADMIN
247 | - SYS_ADMIN
248 | - SYS_RESOURCE
249 | network_mode: host
250 | privileged: true
251 | environment:
252 | # - NB_SETUP_KEY=SETUP
253 | # - NB_FOREGROUND_MODE=true
254 | # - NB_MANAGEMENT_URL=netbird.mydomain.net # Needed if self-hosting
255 | volumes:
256 | - netbird-client:/etc/netbird
257 | image: netbirdio/netbird:lastest
258 | volumes:
259 | netbird-client:
260 | name: netbird-client
261 | ```
262 |
--------------------------------------------------------------------------------
/apps/README.md:
--------------------------------------------------------------------------------
1 | **This is a work in progress.**
2 |
3 | # Awesome Homelab
4 |
5 | This page in the homelab repository is a way to feature all of the apps that I have running! While the purpose of the directory is to give a home of all the apps that don't need their own guides and resources, it will still feature everything I run on my machines. Formatting of the readme inspired by [awesome-selfhosted](https://github.com/awesome-selfhosted/awesome-selfhosted).
6 |
7 | ## Navigation
8 | * [__Apps__](https://github.com/TechHutTV/homelab/tree/main/apps) - List of all the apps and services.
9 | * [Home Assistant](https://github.com/TechHutTV/homelab/tree/main/homeassistant) - Smart home services and automation.
10 | * [Media Server](https://github.com/TechHutTV/homelab/tree/main/media) - Plex, Jellyfin, *arr stack, and more.
11 | * [Server Monitoring](https://github.com/TechHutTV/homelab/tree/main/monitoring) - Graphs and Visualizations for Unraid, Proxmox, and more.
12 | * [Surveillance System](https://github.com/TechHutTV/homelab/tree/main/surveillance) - Frigate NVR Solution with Coral TPU.
13 | * [Storage](https://github.com/TechHutTV/homelab/tree/main/storage) - Current Storage and Backup Solution.
14 | * [Proxy Management](https://github.com/TechHutTV/homelab/tree/main/proxy) - NGINX Proxy Manager, DDNS with Cloudflare, Local Domains, and more.
15 |
16 |
17 | In my network I also have two Raspberry Pis. One of them is a Pi 5 with a PoE HAT and that is responsible for a Twingate connector and updating my IP address on Cloudflare. The other is hooked up to a 3D printer running Octoprint.
18 |
19 | ## Dashboards
20 |
21 | Dashboards are used to create a simple webpage with links to all the services, websites, or really anything you care about. What makes each dashboard special and unique is the features they come with. Many can act as monitoring tools, have widgets to get more details from services, weather, and more.
22 |
23 | ### Glance
24 |
25 | 
26 |
27 | This dashboard is a new addition for me, it’s not the most feature rich of the options out there, but for me it’s simplistic and default look and feel is what stands out to me. You can use it to monitor and link to all your applications, like most tools in this category, but it also is great for monitoring various feeds, websites, and a customizable RSS feed. I use the tool as a start page for my web browser and it gives a quick and simple _glance_ of everything that I care about. One of the best things about it, in my opinion, is that everything is customized and configured in a simple yaml file.
28 |
29 | **Resources:** [Video](https://youtu.be/QGONe-NTWuI) | [Github](https://github.com/glanceapp/glance)
30 |
31 | ### Homarr
32 |
33 | I’m not using this one at the moment, but it’s currently a VERY CLOSE second for me. This one is more feature rich than Glance as it has much more widgets and is customizable through the graphical interface of the application. Homarr has its main focus in the name and that is a deep integration with the \*arr stack of applications. This dashboard, like Glance, can be used to monitor the up status of your applications, but it also integrates easily with Docker, Proxmox and other platforms.
34 |
35 | **Resources:** [Video](https://youtu.be/A6vcTIzp_Ww) | [Github](https://github.com/homarr-labs/homarr) | [Website](https://homarr.dev/)
36 |
37 | ## Tools and Utilities
38 |
39 | ### File Browser
40 |
41 | 
42 |
43 | This is another new addition, while not great for moving or copying large amounts of data, it has helped me significantly jumping though my rather large media server. Features rather simple and straight forward file management features, as described on their official website; “File Browser is a **create-your-own-cloud-kind** of software where you can install it on a server, direct it to a path and then access your files through a nice web interface. You have many available features!”
44 |
45 | **Resources:** [Github](https://github.com/filebrowser/filebrowser) | [Website](https://filebrowser.org/)
46 |
47 | ### Vaultwarden
48 |
49 | 
50 |
51 | After being suggested this for YEARS I finally bit the bullet and have a self-hosted password vault. It’s fully compatible with Bitwardens extensions and applications, this allows me to keep all my passwords, emails, and payment information in one place.
52 |
53 | **Resources:** [Github](https://github.com/dani-garcia/vaultwarden)
54 |
55 | ### Hoarder
56 |
57 | 
58 |
59 | My video covering Hoarder may have turned into an unfortunate story of drama, that’s not to take away from how awesome this tool actually is. I think of it as a dumping ground for anything I come across that is slightly interesting. This is a self-hostable bookmark-everything app with a touch of AI for the data hoarders out there. Some of the features include the ability to take simple notes and store images and pdfs, automatic fetching for link titles, descriptions and images, sorting tools, and full text search of all the content stored.
60 |
61 | **Resources:** [Video](https://youtu.be/TDWombBvK8c) | [Github](https://github.com/hoarder-app/hoarder) | [Website](https://hoarder.app/)
62 |
63 | ### Portainer
64 |
65 | 
66 |
67 | I’ll admit, I do have plans to slowly remove Portainer from my home server. I’ve gotten comfortable enough with using docker compose and other Docker features in the command line that it almost slows me down. With that said Portainer is a GREAT tool for managing Docker stacks, containers, and other instances on other machines.
68 |
69 | **Resources:** [Video](https://www.youtube.com/watch?v=olUD_F37n0E) | [Github](https://github.com/portainer/portainer) | [Website](https://docs.portainer.io/start/install-ce)
70 |
71 | ### Cockpit
72 |
73 | 
74 |
75 | Cockpit is one of the best tools that you can use to give your server a nice web interface to monitor and manage. Their website says; “See your server in a web browser and perform system tasks with a mouse. It’s easy to start containers, administer storage, configure networks, and inspect logs. Basically, you can think of Cockpit like a graphical “desktop interface”, but for individual servers.”
76 |
77 | I was using this in a centralized LXC for managing shares and using various extensions to give cockpit even more features. After a very recent change in my home server setup I have yet to install it on anything, but I’m leaving it here on this list as it is an amazing tool.
78 |
79 | **Resources:** [Video](https://youtu.be/zLFB6ulC0Fg?si=9eFVzVcAebZUTgFi&t=1072) | [Github](https://github.com/cockpit-project/cockpit) | [Website](https://cockpit-project.org/)
80 |
81 | ### Octoprint
82 |
83 | 
84 |
85 | Octoprint is another great tool that has actually helped me increase the use of my 3D printer. I have this software setup on a Raspberry Pi 4 plugged directly into the printer. Essentially turning my dumb 3D printer smart. This allows control of all aspects of 3D printing including, uploading gcodes, printing, monitoring, and much more. Setting up camera monitoring and video recording is as simple as plugging in a webcam.
86 |
87 | **Resources:** [Github](https://github.com/OctoPrint/OctoPrint) | [Website](https://octoprint.org/)
88 |
89 | ## Media Server
90 |
91 | ### Jellyfin
92 |
93 | 
94 |
95 | Jellyfin is by far the best free and open source media server on the market right now. It has all the features you’d expect without any paywalls. This includes streaming to a wide variety of platforms. I currently run Jellyfin as a backup to Plex as that is currently my preferred platform. See the video above for much more information.
96 |
97 | **Resources:** [Video](https://www.youtube.com/watch?v=eJvQKLVrmU8) | [Github](https://github.com/jellyfin/jellyfin) | [Website](https://jellyfin.org/)
98 |
99 | ### Plex
100 |
101 | 
102 |
103 | Plex is my main media streaming platform. I have quite a few family members using it and Plex has support for more platforms and easier login capabilities. I’ve also recently setup a TV tuner and it has been working great. Another reason why I use Plex is the support for 3rd party tools such as Tautulli that we will get into below.
104 |
105 | **Resources:** [Video](https://youtu.be/lXcfKTNObOo) | [Github](https://github.com/plexinc) | [Website](https://www.plex.tv/)
106 |
107 | ### Tautulli
108 |
109 | 
110 |
111 | While Plex does have some statistics and logs to see what’s going on, it is nothing compared to what we get from Tautulli. From their website; “Tautulli is a 3rd party application that you can run alongside your Plex Media Server to monitor activity and track various statistics. Most importantly, these statistics include what has been watched, who watched it, when and where they watched it, and how it was watched.” This data is very helpful when I clean up and remove some media from the server. One of my favorite features of all this is the newsletter option that you can setup giving the users an overview of new media that has been added to the server.
112 |
113 | **Resources:** [Github](https://github.com/Tautulli/Tautulli) | [Website](https://tautulli.com/)
114 |
115 | ## Media Management
116 |
117 | Many of the applications below act in similar function with a slightly different goal or media type so the descriptions will be brief. With that these tools are by far some of my favorites in my home server.
118 |
119 | ### Overseerr
120 |
121 | 
122 |
123 | Overseerr is an amazing tool for discovering new movies and shows as well as having Plex users request media they want to see. Overseerr integrates really well into Plex and some of the other services in this category. It can see what is already in your media library and if a request is made it can automatically add that entry to Radarr or Sonarr. I particularly like it because of the discover functionality, you can filter movies and shows by what streaming service they’re on, rating, and more.
124 |
125 | **Resources:** [Github](https://github.com/sct/overseerr) | [Website](https://overseerr.dev/)
126 |
127 | ### Radarr
128 |
129 | 
130 |
131 | Radarr is a media organization tool for movies. This allows you to scan your library to see everything you have. Manage file names, see the media quality, and even search indexers for media. From their wiki; “Radarr is a movie collection manager for Usenet and BitTorrent users. It can monitor multiple RSS feeds for new movies and will interface with clients and indexers to grab, sort, and rename them. It can also be configured to automatically upgrade the quality of existing files in the library when a better quality format becomes available.”
132 |
133 | **Resources:** [Wiki](https://wiki.servarr.com/radarr) | [Github](https://github.com/Radarr/Radarr) | [Website](https://radarr.video/)
134 |
135 | ### Sonarr
136 |
137 | 
138 |
139 | This does all the same things as Radarr but with TV shows and series. It uses TVDB to see if you’re missing any episodes and even specials. From their wiki; “Sonarr is a PVR for Usenet and BitTorrent users. It can monitor multiple RSS feeds for new episodes of your favorite shows and will grab, sort and rename them. It can also be configured to automatically upgrade the quality of files already downloaded when a better quality format becomes available.”
140 |
141 | **Resources:** [Wiki](https://wiki.servarr.com/sonarr) | [Github](https://github.com/Sonarr/Sonarr) | [Website](https://sonarr.tv/)
142 |
143 | ### Lidarr
144 |
145 | 
146 |
147 | This acts the same as Radarr and Sonarr, but for music. From their wiki; “Lidarr is a music collection manager for Usenet and BitTorrent users. It can monitor multiple RSS feeds for new tracks from your favorite artists and will grab, sort and rename them. It can also be configured to automatically upgrade the quality of files already downloaded when a better quality format becomes available.”
148 |
149 | **Resources:** [Wiki](https://wiki.servarr.com/lidarr) | [Github](https://github.com/Lidarr/Lidarr) | [Website](https://lidarr.audio/)
150 |
151 | ### Bazarr
152 |
153 | This also acts similar to the other \*arr application, but with a focus on subtitles. From the Bazarr site; “Bazarr is a companion application to Sonarr and Radarr that manages and downloads subtitles based on your requirements. \[With manual search to\] find all the matching subtitles, choose the one you want and download it to your media directory with the proper name to be used by your media player.”
154 |
155 | **Resources:** [Wiki]() | [Github](https://github.com/morpheus65535/bazarr) | [Website](https://www.bazarr.media/)
156 |
157 | ### Prowlarr
158 |
159 | 
160 |
161 | Without using Prowlarr you’d need to manually setup your trackers and indexers in each application. This allows a centralized place to manage that aspect of these tools if you’re using it in this way. From their wiki; “Prowlarr is an indexer manager/proxy built on the popular arr .net/reactjs base stack to integrate with your various PVR apps. Prowlarr supports management of both Torrent Trackers and Usenet Indexers. It integrates seamlessly with [LazyLibrarian](https://lazylibrarian.gitlab.io/), [Lidarr](https://wiki.servarr.com/lidarr), [Mylar3](https://github.com/mylar3/mylar3), [Radarr](https://wiki.servarr.com/radarr), [Readarr](https://wiki.servarr.com/readarr), and [Sonarr](https://wiki.servarr.com/sonarr) offering complete management of your indexers with no per app Indexer setup required (we do it all).”
162 |
163 | **Resources:** [Wiki](https://wiki.servarr.com/prowlarr) | [Github](https://github.com/Prowlarr/Prowlarr) | [Website](https://prowlarr.com/)
164 |
165 | ## Download Clients
166 |
167 | I highly recommend using a VPN for downloading things. Especially when using peer-to-peer downloaders. Using a VPN will keep your public IP address hidden. I have tried a few VPN services and so far my favorite is [AirVPN](https://airvpn.org/?referred_by=673908), they're not a sponsor, but that is a affiliate link.
168 |
169 | [](https://airvpn.org/?referred_by=673908)
170 |
171 | ### qBittorrent
172 |
173 | 
174 |
175 | This is a web version of the popular qBittorrent peer-to-peer file sharing client. Overall its clean, simple, and has a fair bit of features. Works well with AirVPN (my favorite VPN service) and integrates well with various \*arr applications.
176 |
177 | **Resources:** [Github](https://github.com/qbittorrent/qBittorrent) | [Website](https://www.qbittorrent.org/)
178 |
179 | ### NZBGet
180 |
181 | 
182 |
183 | This is a Usenet client written in C++. It works very well and out of any that I’ve used it seems to give the least amount of issues. This can pull files, fix them in some cases if the health is low, rename and move files.
184 |
185 | https://nzbget.net/
186 | **Resources:** [Github](https://github.com/nzbgetcom/nzbget) | [Website](https://radarr.video/)
187 |
188 |
189 | ## Files and Images
190 |
191 | ### Nextcloud
192 |
193 | 
194 |
195 | Nextcloud is the best in the game for replacing cloud services like Google Drive, Onedrive, and so on. Not only can it act as a great on-premise cloud, but there are many other add-ons and features that it offers. This includes a complete groupware suite, collaborative document editing, tasks, and much more.
196 |
197 | **Resources:** [Video](https://www.youtube.com/watch?v=Nh2-LjIymmQ) | [Github](https://github.com/nextcloud) | [Website](https://nextcloud.com/)
198 |
199 | ### Immich
200 |
201 | 
202 |
203 | This is arguably the most important application that I am running. This is what I’ve used to completely replace Google Photos. Myself and a few of my family members use this as their primary Photo backup solution. It has a mobile app that supports easy backups and some other key features include facial recognition and a location map of your photos. From their website; “Easily back up, organize, and manage your photos on your own server. Immich helps you browse, search and organize your photos and videos with ease, without sacrificing your privacy.”
204 |
205 | **Resources:** [Video](https://www.youtube.com/watch?v=s1ufPvO0BVE) | [Github](https://github.com/immich-app/immich) | [Website](https://immich.app/)
206 |
207 | ### Docmost
208 |
209 | 
210 |
211 | This is a new addition and it’s actually how I’m initially drafting this entire article. In my hunt to replace Notion I’ve started using this. While I’m still on a hunt for a more one-to-one replacement this is doing the trick for now. This tool is used to manage your own personal wiki, knowledge base, and notes. The UI is clean, elegant, and simple.
212 |
213 | **Resources:** [Github](https://github.com/docmost/docmost) | [Website](https://docmost.com/)
214 |
215 | ## Smart Home and Automation
216 |
217 | ### Home Assistant
218 |
219 | 
220 |
221 | Home Assistant is a great tool that allows the connection of many devices in your smart home and integrate them together with a variety blueprints, automatons, and more. You can create custom dashboards, use their mobile app, and so much more I can’t even properly describe here how much this tool is capable of.
222 |
223 | https://www.home-assistant.io/
224 | **Resources:** [Video](https://www.youtube.com/watch?v=Y8xY4keybnw) | [Github](https://github.com/plexinc) | [Website](https://www.plex.tv/)
225 |
226 | ### Frigate
227 |
228 | 
229 |
230 | Frigate is the best open source, self-hosted NVR option that I can find. For a while I was using Blue Iris, but I HATE that you have to use Windows. This tool shines with you hook it up with a Coral TPU for AI object detection. The interface is wonderful and it supports most of what you’d expect of an NVR. Granted depending on your cameras it may be difficult to configure and use all the features a camera may support, for example, two way audio.
231 |
232 | **Resources:** [Video](https://youtu.be/NzbghOfRx3k?si=HY7aHdCbqz1X5ONe) | [Github](https://github.com/blakeblackshear/frigate) | [Website](https://frigate.video/)
233 |
234 | ### Zigbee2MQTT
235 |
236 | 
237 |
238 | I was originally using this with Home Assistant as an add-on, but I’ve noticed it to be way more reliable if it is separated out. Zigbee2MQTT supports various Zigbee adapters and a bunch of devices.
239 |
240 | **Resources:** [Github](https://github.com/Koenkk/zigbee2mqtt) | [Website](https://www.zigbee2mqtt.io/)
241 |
242 | ## DNS and Remote Connections
243 |
244 | ### Pi-Hole
245 |
246 | 
247 |
248 | By far the most popular “DNS Sinkhole” a Domain Name Service that blocks certain DNS inquiries. In the case of Pi-Hole it uses black lists full of domains associated with advertisements and tracking. For example, one of the most blocked domain on my server is [s2s.mparticle.com](https://www.mparticle.com/about-us/) a data collection firm. And with Pi-Hole I can investigate and figure out why this data collection company is being reached out to so much. This is in addition to the main use case of simple ad blocking. Pi-Hole has many other features I’ve yet to dive into, but it’s a wonderful tool that is worth trying out of anyone.
249 |
250 | **Resources:** [Video](https://www.youtube.com/watch?v=xtMFcVx3cHU) | [Github](https://github.com/pi-hole/pi-hole) | [Website](https://pi-hole.net/)
251 |
252 | ### NGINX Proxy Manager
253 |
254 | 
255 |
256 | NGINX Proxy Manager is a simple web based proxy manager for setting up and forwarding domain names to your services and generating SSL certifications. I use this for both local top level domains and exposing a few select services to the public internet.
257 |
258 | **Resources:** [Video](https://youtu.be/79e6KBYcVmQ?si=1h1daKy-0fZeiBtI) | [Github](https://github.com/NginxProxyManager/nginx-proxy-manager) | [Website](https://nginxproxymanager.com/)
259 |
260 | ### Twingate
261 |
262 | Full disclosure, Twingate is one of the channel sponsors. This is a VPN alternative for remotely connecting to your home server. It works by spinning up a smaller connector on your local network, then you use a client to establish a secure peer-to-peer connection. All this is managed and verified through the Twingate cloud platform. Something I started using recently is the Twingate service API to connect with a headless client. Connecting to one headless service to another.
263 |
264 | **Resources:** [Video](https://www.youtube.com/watch?v=yaw2A3DG664) | [Website](https://www.twingate.com/onboarding?utm_source=youtube&utm_medium=referral&utm_campaign=techhut-q1-25 )
265 |
266 | ### Cloudflare DDNS
267 |
268 | 
269 |
270 | This is a very simple docker container used to update your public IP address within the Cloudflare A records using their API. I need to use this because my public IP is dynamic, meaning it will randomly and automatically change every few weeks or sometimes every few days. From their Github it’s; “A feature-rich and robust Cloudflare DDNS updater with a small footprint. The program will detect your machine’s public IP addresses and update DNS records using the Cloudflare API.”
271 |
272 | **Resources:** [Video](https://youtu.be/79e6KBYcVmQ?si=1h1daKy-0fZeiBtI) | [Github](https://github.com/favonia/cloudflare-ddns)
273 |
274 | ## Data and Metrics
275 |
276 | ### Grafana
277 |
278 | 
279 |
280 | Grafana is a BEAUTIFUL dashboard tool that can translate various databases into stunning graphs, charts, and presentation. There is a huge amount of integrations and custom dashboard that many people create for their specific use cases. You can easily add a connection and import a dashboard to display the data. The most popular is for the Node Exporter that you can see above.
281 |
282 | **Resources:** [Video](https://www.youtube.com/watch?v=vffhtqK3ZU) | [Github](https://github.com/grafana/grafana) | [Website](https://grafana.com/)
283 |
284 | ### TeslaMate
285 |
286 | 
287 |
288 | TeslaMate is a tool that uses the Tesla API to gather every possible data point about the car. This includes trips, mileage, battery, elevation, and much more. This is a stack that includes Teslamate itself, a database, Grafana, and a few others.
289 |
290 | **Resources:** [Github](https://github.com/teslamate-org/teslamate) | [Website](https://docs.teslamate.org)
291 |
292 | ### InfluxDB2
293 |
294 | 
295 |
296 | InfluxDB is described as; “Purpose-built database for all types of time series data at any scale.” This database tool has its own way to turn data into charts and graphs, but I’m primarily using it for helpful data from my Proxmox server and pulling that data to Grafana dashboards.
297 |
298 | **Resources:** [Video](https://www.youtube.com/watch?v=vffhtqK3ZU) | [Github](https://github.com/influxdata/influxdb) | [Website](https://www.influxdata.com/)
299 |
300 | ### Prometheus (with Node Exporter)
301 |
302 | 
303 |
304 | Like InfluxDB this is a data collection tool for monitoring and data analytics. This one this the most popular of what I’m using so there are a ton of different integrations and dashboards to pick from. The most popular and probably the easiest to setup is the Node Exporter, I have this installed and two Raspberry Pi systems for monitoring.
305 |
306 | **Resources:** [Video](https://www.youtube.com/watch?v=vffhtqK3ZU) | [Github](https://github.com/prometheus/prometheus) | [Website](https://prometheus.io/)
307 |
308 | **Warning!** This 'Alternatives and Extras' section is actively being worked on.
309 |
310 | ### Alternatives and Extras
311 | Dashboards
312 | - (alt to Glance/Homarr)
313 |
314 | Tools and Utilities
315 | - (alt to File Browser)
316 | - (alt to Vaultwarden)
317 | - (alt to Hoarder)
318 | - (alt to Portainer)
319 | - (alt to Cockpit)
320 | - (alt to Octoprint)
321 |
322 | Media Server
323 | - (alt to Jellyfin/Plex)
324 | - (alt to Tautulli)
325 |
326 | Media Management
327 | - (alt to Overseerr)
328 | - (alt to Radarr)
329 | - (alt to Sonarr)
330 | - (alt to Lidarr)
331 | - (alt to Bazarr)
332 | - (alt to Prowlarr)
333 |
334 | Download Clients
335 | - (alt to qBittorrent)
336 | - (alt to NZBGet)
337 |
338 | Files and Images
339 | - [Owncloud](https://owncloud.com/), [Pydio](https://github.com/pydio) (alts to Nextcloud)
340 | - [Nextcloud Memories](https://apps.nextcloud.com/apps/memories), [a bunch more](https://github.com/meichthys/foss_photo_libraries) (alts to Immich)
341 | - (alt to Docmost)
342 |
343 | Smart Home and Automation
344 | - [openHAB](https://www.openhab.org/), [Homey](https://homey.app/en-us/) (alts to Home Assistant)
345 | - [AgentDVR](https://www.ispyconnect.com/), [Shinobi NVR](https://shinobi.video/) (alts to Frigate)
346 |
347 | DNS and Remote Connections
348 | - [AdGuard Home](https://adguard.com/en/adguard-home/overview.html) (alt to Pi-Hole)
349 | - [SWAG](https://docs.linuxserver.io/general/swag/#creating-a-swag-container) (alt to NGINX Proxy Manager)
350 | - [Tailscale](https://tailscale.com/) (alt to Twingate)
351 | - [ddns-updater](https://github.com/qdm12/ddns-updater) (alt to Cloudflare DDNS)
352 |
353 |
354 |
355 |
356 |
357 |
--------------------------------------------------------------------------------