feat: Initial commit

This commit is contained in:
Adrien Poupa 2022-02-19 17:17:15 -05:00 committed by AdrienPoupa
commit 421ed4f6c1
13 changed files with 386 additions and 0 deletions

7
.env.example Normal file
View File

@ -0,0 +1,7 @@
USER_ID=1000
GROUP_ID=1000
TIMEZONE="America/New_York"
PIA_LOCATION=ca
PIA_USER=
PIA_PASS=
PIA_LOCAL_NETWORK="192.168.0.0/16"

16
.gitignore vendored Normal file
View File

@ -0,0 +1,16 @@
.env
.idea
/heimdall
!/heimdall/.gitkeep
/sonarr
!/sonarr/.gitkeep
/radarr
!/radarr/.gitkeep
/prowlarr
!/prowlarr/.gitkeep
/qbittorrent
!/qbittorrent/.gitkeep
/pia
!/pia/.gitkeep
/pia-shared
!/pia-shared/.gitkeep

101
CONFIGURATION.md Normal file
View File

@ -0,0 +1,101 @@
# Configuration
## Environment Variables
`cp .env.example .env`
then fill the `.env` file with your variables:
- `USER_ID`: ID of the user to use in Docker containers, defaults to `1000`
- `GROUP_ID`: ID of the user group to use in Docker containers, defaults to `1000`
- `TIMEZONE`: for the containers, defaults to `America/New_York`
- `PIA_LOCATION`: servers to use for PIA, defaults to `ca`, ie Montreal, Canada with port forwarding support
- `PIA_USER`: PIA username
- `PIA_PASS`: PIA password
## PIA Wireguard VPN
I chose PIA since it supports Wireguard and [port forwarding](https://github.com/thrnz/docker-wireguard-pia/issues/26#issuecomment-868165281),
but you could use other providers:
- OpenVPN: [linuxserver/openvpn-as](https://hub.docker.com/r/linuxserver/openvpn-as)
- Wireguard: [linuxserver/wireguard](https://hub.docker.com/r/linuxserver/wireguard)
- NordVPN + OpenVPN: [bubuntux/nordvpn](https://hub.docker.com/r/bubuntux/nordvpn/dockerfile)
- NordVPN + Wireguard (NordLynx): [bubuntux/nordlynx](https://hub.docker.com/r/bubuntux/nordlynx)
For PIA + Wireguard, copy the example `.env` and fill it with your PIA credentials:
`cp .env.example .env`
The location of the server it will connect to is set by `LOC=ca`, defaulting to Montreal - Canada.
## Sonarr & Radarr
### File Structure
Sonarr and Radarr must be configured to support hardlinks, to allow instant moves and prevent using twice the storage
(Bittorrent downloads and final file). The trick is to use a single volume shared by the Bittorrent client and the *arrs.
Subfolders are used to separate the TV shows from the movies.
The configuration is well explained by [this guide](https://trash-guides.info/Hardlinks/How-to-setup-for/Docker/).
In summary, the final structure of the shared volume will be as follows:
```
data
├── torrents = shared folder qBittorrent downloads
│ ├── movies = movies downloads tagged by Radarr
│ └── tv = movies downloads tagged by Sonarr
└── media = shared folder for Sonarr and Radarr files
├── movies = Radarr
└── tv = Sonarr
```
Go to Settings > Management.
In Sonarr, set the Root folder to `/data/media/tv`.
In Radar, set the Root folder to `/data/media/movies`.
![](https://cdn.poupa.net/uploads/2022/03/root-folder.png)
### Download Client
Then qBittorrent can be configured at Settings > Download Clients. Because all the networking for qBittorrent takes
place in the VPN container, the hostname for qBittorrent is the hostname of the VPN container, ie `vpn`, and the port is `8080`:
![](https://cdn.poupa.net/uploads/2022/03/qbittorrent.png)
## Prowlarr
The indexers are configured through Prowlarr. They synchronize automatically to Radarr and Sonarr.
Radarr and Sonarr may then be added via Settongs > Apps. The Prowlarr server is `http://prowlarr:9696`, the Radarr server
is `http://radarr:7878` and Sonarr `http://sonarr:8989`:
![](https://cdn.poupa.net/uploads/2022/03/sonarr.png)
Their API keys can be found in Settings > Security > API Key.
## qBittorrent
Set the default save path to `/data/torrents` in Settings:
![](https://cdn.poupa.net/uploads/2022/03/path.png)
Restrict the network interface to Wireguard:
![](https://cdn.poupa.net/uploads/2022/03/wireguard.png)
The web UI login page can be disabled on for the local network in Settings > Web UI > Bypass authentication for clients
```
192.168.0.0/16
127.0.0.0/8
172.17.0.0/16
```
## Heimdall
Applications can be added in Items > Add. The URLs should be the static IP, ie: `http://192.168.0.10:8989/` for Sonarr
for example.
![](https://cdn.poupa.net/uploads/2022/03/homepage.png)

88
INSTALL.md Normal file
View File

@ -0,0 +1,88 @@
# Installation
## Requirements
Any Docker-capable recent Linux box.
I am using a fresh Ubuntu Server 20.04 on a repurposed laptop so this guide reflects it,
but it would probably work with other distributions and different versions with a few tweaks.
## Pre-Docker Steps
### OpenSSH
If not done during installation, install OpenSSH server for remote connection: `sudo apt install openssh-server`
### Static IP
Set a static IP:
`sudo nano /etc//netplan/00-installer-config.yaml`
```yaml
# This is the network config written by 'subiquity'
network:
ethernets:
enp2s0:
dhcp4: no
addresses:
- 192.168.0.10/24
gateway4: 192.168.0.1
nameservers:
addresses: [8.8.8.8, 8.8.4.4]
version: 2
```
Here, `192.168.0.10` is going to be the static IP, and we will use Google's DNS servers. Apply the plan:
`sudo netplan apply`
You can check the server uses the right IP with `ip a`.
### Laptop Specific Configuration
If the server is installed on a laptop, you may want to disable the suspension when the lid is closed:
`sudo nano /etc/systemd/logind.conf`
Replace:
- `#HandleLidSwitch=suspend` by `HandleLidSwitch=ignore`
- `#LidSwitchIgnoreInhibited=yes` by `LidSwitchIgnoreInhibited=no`
Then restart: `sudo service systemd-logind restart`
## Docker Setup
Install Docker by following [these instructions](https://docs.docker.com/engine/install/ubuntu/).
Then, [install Compose V2](https://docs.docker.com/compose/cli-command/#install-on-linux).
For a global installation (both your current user and `root` when using `sudo`),
copy `/usr/libexec/docker/cli-plugins` rather than `$HOME/.docker/cli-plugins/docker-compose`.
You may then run the applications with `sudo docker compose up -d`
## NFS Share
It is now time to share the folders to other local devices using NFS, as it is easy to set up and fast.
Install the NFS kernel server:
`sudo apt-get install nfs-kernel-server`
Then edit `/etc/exports` to configure your shares:
`/mnt/data/media 192.168.0.0/255.255.255.0(rw,all_squash,nohide,no_subtree_check,anonuid=1000,anongid=1000)`
This will share the `media` folder to anybody on your local network (192.168.0.x).
I purposely left out the `sync` flag that would slow down file transfer.
On [some devices](https://forum.kodi.tv/showthread.php?tid=343434) you may need to use the `insecure` option for the share to be available.
Restart the NFS server to apply the changes: `sudo /etc/init.d/nfs-kernel-server restart`
On other machines, you can see the shared folder by adding the following to your `/etc/fstab`:
`192.168.0.10:/mnt/data/media /mnt/nas nfs ro,hard,intr,auto,_netdev 0 0`
## References
- [NFS setup](https://askubuntu.com/a/7124)
- [Hardlinks and Instant Moves (Atomic-Moves)](https://trash-guides.info/Hardlinks/Hardlinks-and-Instant-Moves/)

52
README.md Normal file
View File

@ -0,0 +1,52 @@
# Docker Compose NAS
After searching for the perfect NAS solution, I realized what I wanted could be achieved
with some Docker containers on a vanilla Linux box. The result is an opinionated Docker Compose configuration capable of
browsing indexers to retrieve media resources and downloading them through a Wireguard VPN with port forwarding.
## Applications
The following applications are available:
- [Sonarr](https://sonarr.tv/): PVR for newsgroup and bittorrent users
- [Radarr](https://radarr.video/): Movie collection manager for Usenet and BitTorrent users
- [Prowlarr](https://github.com/Prowlarr/Prowlarr): Indexer aggregator for Sonarr and Radarr
- [qBittorrent](https://www.qbittorrent.org/): Bittorrent client with a complete web UI
- [PIA Wireguard VPN](https://github.com/thrnz/docker-wireguard-pia): Encapsulate qBittorrent traffic in
[PIA](https://www.privateinternetaccess.com/) with [Wireguard](https://www.wireguard.com/) with port forwarding.
- [Heimdall](https://heimdall.site/): Application dashboard
## Installation
See [installation instructions](./INSTALL.md).
TLDR: `cp .env.example .env`, edit to your needs then `sudo docker compose up -d`
## Configuration
See [configuration](./CONFIGURATION.md).
## Containers
| **Application** | **Image** | **Port** | **Notes** |
|-------------------|------------------------------------------------------------------------------------|----------|-------------------------------------------------------------------|
| Sonarr | [linuxserver/sonarr](https://hub.docker.com/r/linuxserver/sonarr) | 8989 | |
| Radarr | [linuxserver/radarr](https://hub.docker.com/r/linuxserver/radarr) | 7878 | |
| Prowlarr | [linuxserver/prowlarr:develop](https://hub.docker.com/r/linuxserver/prowlarr) | 9696 | `develop` tag as it is not stable yet |
| PIA Wireguard VPN | [thrnz/docker-wireguard-pia](https://hub.docker.com/r/thrnz/docker-wireguard-pia) | | |
| qBittorrent | [linuxserver/qbittorrent:14.3.9](https://hub.docker.com/r/linuxserver/qbittorrent) | 8080 | Uses VPN network<br>Frozen to v4.3.9 due to Libtorrent 2.x issues |
| Heimdall | [linuxserver/heimdall](https://hub.docker.com/r/linuxserver/heimdall) | 80, 443 | |
## Improvement
There is always room for improvement. I did not need those containers so I did not include them, but maybe you could
benefit from:
- [Bazarr](https://www.bazarr.media/): companion application to Sonarr and Radarr that manages and downloads subtitles
- [Lidarr](https://lidarr.audio/): music collection manager for Usenet and BitTorrent users
- [FlareSolverr](https://github.com/FlareSolverr/FlareSolverr): Proxy server to bypass Cloudflare protection, useful
for some indexers in Prowlarr
- [Jackett](https://github.com/Jackett/Jackett): API Support for your favorite torrent trackers, as a Prowlarr replacement
- [Plex](https://www.plex.tv/): Plex Media Server
- you tell me!

99
docker-compose.yml Normal file
View File

@ -0,0 +1,99 @@
version: "3.9"
services:
sonarr:
image: lscr.io/linuxserver/sonarr
container_name: sonarr
environment:
- PUID=${USER_ID}
- PGID=${GROUP_ID}
- PGID=${GROUP_ID}
volumes:
- ./sonarr:/config
- /mnt/data:/data
ports:
- "8989:8989"
restart: unless-stopped
radarr:
image: lscr.io/linuxserver/radarr
container_name: radarr
environment:
- PUID=${USER_ID}
- PGID=${GROUP_ID}
- PGID=${GROUP_ID}
volumes:
- ./radarr:/config
- /mnt/data:/data
ports:
- "7878:7878"
restart: unless-stopped
prowlarr:
image: lscr.io/linuxserver/prowlarr:develop
container_name: prowlarr
environment:
- PUID=${USER_ID}
- PGID=${GROUP_ID}
- PGID=${GROUP_ID}
volumes:
- ./prowlarr:/config
ports:
- "9696:9696"
restart: unless-stopped
qbittorrent:
image: lscr.io/linuxserver/qbittorrent:14.3.9
container_name: qbittorrent
environment:
- PUID=${USER_ID}
- PGID=${GROUP_ID}
- TZ=${TIMEZONE}
- WEBUI_PORT=8080
volumes:
- ./qbittorrent:/config
- /mnt/data/torrents:/data/torrents
restart: unless-stopped
network_mode: "service:vpn"
depends_on:
- vpn
vpn:
image: thrnz/docker-wireguard-pia
container_name: vpn
volumes:
- ./pia:/pia
- ./pia-shared:/pia-shared
ports:
- "6881:6881"
- "6881:6881/udp"
- "8080:8080"
cap_add:
- NET_ADMIN
- SYS_MODULE
environment:
- LOC=${PIA_LOCATION}
- USER=${PIA_USER}
- PASS=${PIA_PASS}
- LOCAL_NETWORK=${PIA_LOCAL_NETWORK}
- PORT_FORWARDING=1
- PORT_SCRIPT=/pia-shared/portupdate-qbittorrent.sh
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
- net.ipv6.conf.default.disable_ipv6=1
- net.ipv6.conf.all.disable_ipv6=1
- net.ipv6.conf.lo.disable_ipv6=1
healthcheck:
test: ping -c 1 www.google.com || exit 1
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
heimdall:
image: lscr.io/linuxserver/heimdall
container_name: heimdall
environment:
- PUID=${USER_ID}
- PGID=${GROUP_ID}
- PGID=${GROUP_ID}
volumes:
- ./heimdall:/config
ports:
- "80:80"
- "443:443"
restart: unless-stopped

0
heimdall/.gitkeep Normal file
View File

View File

@ -0,0 +1,23 @@
#!/bin/bash
port="$1"
QBT_USER=admin
QBT_PASS=adminadmin
QBT_PORT=8080
echo "Setting qBittorrent port settings ($port)..."
# Very basic retry logic so we don't fail if qBittorrent isn't running yet
while ! curl --silent --retry 10 --retry-delay 15 --max-time 10 \
--data "username=${QBT_USER}&password=${QBT_PASS}" \
--cookie-jar /tmp/qb-cookies.txt \
http://localhost:${QBT_PORT}/api/v2/auth/login
do
sleep 10
done
curl --silent --retry 10 --retry-delay 15 --max-time 10 \
--data 'json={"listen_port": "'"$port"'"}' \
--cookie /tmp/qb-cookies.txt \
http://localhost:${QBT_PORT}/api/v2/app/setPreferences
echo "qBittorrent port updated successfully ($port)..."

0
pia/.gitkeep Normal file
View File

0
prowlarr/.gitkeep Normal file
View File

0
qbittorrent/.gitkeep Normal file
View File

0
radarr/.gitkeep Normal file
View File

0
sonarr/.gitkeep Normal file
View File