docs(README): Refactor and simplify documentation
Some checks failed
/ validate-docker-compose (push) Has been cancelled
Some checks failed
/ validate-docker-compose (push) Has been cancelled
- Restructure README with standard sections (Prerequisites, Quick Start, Config, Access, Optional, Troubleshooting). - Rewrite introduction for clarity on project goals. - Focus Quick Start on core Docker Compose setup. - Detail .env variables with clear groupings. - Clarify Tailscale's role for remote access and HTTPS. - Remove outdated/overly specific setup details for individual services, VPN, Synology, NFS, etc. - Add SELinux troubleshooting specific to Docker socket access.
This commit is contained in:
parent
3ce7262e38
commit
64dcce36f0
731
README.md
731
README.md
@ -1,600 +1,283 @@
|
||||
# Docker Compose NAS
|
||||
<!-- # 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.
|
||||
SSL certificates and remote access through Tailscale are supported.
|
||||
This project provides a comprehensive, self-hosted media and utility server setup using Docker Compose. It aims to replicate and enhance the functionality of a typical NAS using containerized applications on a standard Linux host.
|
||||
|
||||
Requirements: Any Docker-capable recent Linux box with Docker Engine and Docker Compose V2.
|
||||
I am running it in Ubuntu Server 22.04; I also tested this setup on a [Synology DS220+ with DSM 7.1](#synology-quirks).
|
||||
The core idea is to manage media libraries (movies, TV shows, music), automate downloads securely, provide easy access via a dashboard, and enable remote access through Tailscale.
|
||||
|
||||

|
||||
## Features
|
||||
|
||||
## Table of Contents
|
||||
This stack includes:
|
||||
|
||||
<!-- TOC -->
|
||||
* [Docker Compose NAS](#docker-compose-nas)
|
||||
* [Table of Contents](#table-of-contents)
|
||||
* [Applications](#applications)
|
||||
* [Quick Start](#quick-start)
|
||||
* [Environment Variables](#environment-variables)
|
||||
* [PIA WireGuard VPN](#pia-wireguard-vpn)
|
||||
* [Sonarr, Radarr & Lidarr](#sonarr-radarr--lidarr)
|
||||
* [File Structure](#file-structure)
|
||||
* [Download Client](#download-client)
|
||||
* [Prowlarr](#prowlarr)
|
||||
* [qBittorrent](#qbittorrent)
|
||||
* [Jellyfin](#jellyfin)
|
||||
* [Homepage](#homepage)
|
||||
* [Jellyseerr](#jellyseerr)
|
||||
* [Traefik and SSL Certificates](#traefik-and-ssl-certificates)
|
||||
* [Accessing from the outside with Tailscale](#accessing-from-the-outside-with-tailscale)
|
||||
* [Optional Services](#optional-services)
|
||||
* [FlareSolverr](#flaresolverr)
|
||||
* [SABnzbd](#sabnzbd)
|
||||
* [AdGuard Home](#adguard-home)
|
||||
* [Encryption](#encryption)
|
||||
* [DHCP](#dhcp)
|
||||
* [Expose DNS Server with Tailscale](#expose-dns-server-with-tailscale)
|
||||
* [Calibre-Web](#calibre-web)
|
||||
* [Decluttarr](#decluttarr)
|
||||
* [Tandoor](#tandoor)
|
||||
* [Joplin](#joplin)
|
||||
* [Home Assistant](#home-assistant)
|
||||
* [Immich](#immich)
|
||||
* [Customization](#customization)
|
||||
* [Optional: Using the VPN for *arr apps](#optional-using-the-vpn-for-arr-apps)
|
||||
* [Synology Quirks](#synology-quirks)
|
||||
* [Free Ports 80 and 443](#free-ports-80-and-443)
|
||||
* [Install Synology WireGuard](#install-synology-wireguard)
|
||||
* [Free Port 1900](#free-port-1900)
|
||||
* [User Permissions](#user-permissions)
|
||||
* [Synology DHCP Server and Adguard Home Port Conflict](#synology-dhcp-server-and-adguard-home-port-conflict)
|
||||
* [Use Separate Paths for Torrents and Storage](#use-separate-paths-for-torrents-and-storage)
|
||||
* [NFS Share](#nfs-share)
|
||||
* [Static IP](#static-ip)
|
||||
* [Laptop Specific Configuration](#laptop-specific-configuration)
|
||||
<!-- TOC -->
|
||||
* **Reverse Proxy & Service Discovery:** [Traefik](https://traefik.io) automatically routes traffic to services.
|
||||
* **Media Management:**
|
||||
* [Sonarr](https://sonarr.tv): TV show management.
|
||||
* [Radarr](https://radarr.video): Movie management.
|
||||
* [Lidarr](https://lidarr.audio) (Optional): Music management.
|
||||
* [Bazarr](https://www.bazarr.media/): Subtitle management.
|
||||
* **Indexers & Downloads:**
|
||||
* [Prowlarr](https://github.com/Prowlarr/Prowlarr): Indexer management for *arr apps.
|
||||
* [qBittorrent](https://www.qbittorrent.org): Bittorrent client (can be configured to run through a VPN).
|
||||
* [SABnzbd](https://sabnzbd.org/) (Optional): Usenet download client.
|
||||
* **Media Server:** [Jellyfin](https://jellyfin.org) organizes and streams your media.
|
||||
* **Request Management:** [Jellyseerr](https://github.com/FallenBagel/jellyseerr) allows users (including Jellyfin users) to request media.
|
||||
* **Dashboard:** [Homepage](https://gethomepage.dev) provides a central dashboard to access all services.
|
||||
* **Remote Access:** [Tailscale](https://tailscale.com) provides secure access to your services from anywhere without opening firewall ports. It handles HTTPS termination.
|
||||
* **Utilities:**
|
||||
* [Watchtower](https://containrrr.dev/watchtower/): Automatically updates running containers to the latest image.
|
||||
* [Autoheal](https://github.com/willfarrell/docker-autoheal/): Monitors and restarts unhealthy containers.
|
||||
* [Unpackerr](https://unpackerr.zip): Automatically extracts downloaded archives.
|
||||
* **Other Optional Services:** AdGuard Home, Calibre-Web, Decluttarr, Tandoor Recipes, Joplin Server, Home Assistant, Immich Photos (enable via profiles).
|
||||
|
||||
## Applications
|
||||
## Prerequisites
|
||||
|
||||
| **Application** | **Description** | **Image** | **URL** |
|
||||
|--------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------|--------------|
|
||||
| [Sonarr](https://sonarr.tv) | PVR for newsgroup and bittorrent users | [linuxserver/sonarr](https://hub.docker.com/r/linuxserver/sonarr) | /sonarr |
|
||||
| [Radarr](https://radarr.video) | Movie collection manager for Usenet and BitTorrent users | [linuxserver/radarr](https://hub.docker.com/r/linuxserver/radarr) | /radarr |
|
||||
| [Bazarr](https://www.bazarr.media/) | Companion application to Sonarr and Radarr that manages and downloads subtitles | [linuxserver/bazarr](https://hub.docker.com/r/linuxserver/bazarr) | /bazarr |
|
||||
| [Prowlarr](https://github.com/Prowlarr/Prowlarr) | Indexer aggregator for Sonarr and Radarr | [linuxserver/prowlarr:latest](https://hub.docker.com/r/linuxserver/prowlarr) | /prowlarr |
|
||||
| [PIA WireGuard VPN](https://github.com/thrnz/docker-wireguard-pia) | Encapsulate qBittorrent traffic in [PIA](https://www.privateinternetaccess.com/) using [WireGuard](https://www.wireguard.com/) with port forwarding. | [thrnz/docker-wireguard-pia](https://hub.docker.com/r/thrnz/docker-wireguard-pia) | |
|
||||
| [qBittorrent](https://www.qbittorrent.org) | Bittorrent client with a complete web UI<br/>Uses VPN network<br/>Using Libtorrent 1.x | [linuxserver/qbittorrent:libtorrentv1](https://hub.docker.com/r/linuxserver/qbittorrent) | /qbittorrent |
|
||||
| [Unpackerr](https://unpackerr.zip) | Automated Archive Extractions | [golift/unpackerr](https://hub.docker.com/r/golift/unpackerr) | |
|
||||
| [Jellyfin](https://jellyfin.org) | Media server designed to organize, manage, and share digital media files to networked devices | [linuxserver/jellyfin](https://hub.docker.com/r/linuxserver/jellyfin) | /jellyfin |
|
||||
| [Jellyseer](https://jellyfin.org) | Manages requests for your media library | [fallenbagel/jellyseerr](https://hub.docker.com/r/fallenbagel/jellyseerr) | /jellyseer |
|
||||
| [Homepage](https://gethomepage.dev) | Application dashboard | [gethomepage/homepage](https://github.com/gethomepage/homepage/pkgs/container/homepage) | / |
|
||||
| [Traefik](https://traefik.io) | Reverse proxy | [traefik](https://hub.docker.com/_/traefik) | |
|
||||
| [Watchtower](https://containrrr.dev/watchtower/) | Automated Docker images update | [containrrr/watchtower](https://hub.docker.com/r/containrrr/watchtower) | |
|
||||
| [Autoheal](https://github.com/willfarrell/docker-autoheal/) | Monitor and restart unhealthy Docker containers | [willfarrell/autoheal](https://hub.docker.com/r/willfarrell/autoheal) | |
|
||||
| [Lidarr](https://lidarr.audio) | Optional - Music collection manager for Usenet and BitTorrent users<br/>Enable with `COMPOSE_PROFILES=lidarr` | [linuxserver/lidarr](https://hub.docker.com/r/linuxserver/lidarr) | /lidarr |
|
||||
| [SABnzbd](https://sabnzbd.org/) | Optional - Free and easy binary newsreader<br/>Enable with `COMPOSE_PROFILES=sabnzbd` | [linuxserver/sabnzbd](https://hub.docker.com/r/linuxserver/sabnzbd) | /sabnzbd |
|
||||
| [FlareSolverr](https://github.com/FlareSolverr/FlareSolverr) | Optional - Proxy server to bypass Cloudflare protection in Prowlarr<br/>Enable with `COMPOSE_PROFILES=flaresolverr` | [flaresolverr/flaresolverr](https://hub.docker.com/r/flaresolverr/flaresolverr) | |
|
||||
| [AdGuard Home](https://adguard.com/en/adguard-home/overview.html) | Optional - Network-wide software for blocking ads & tracking<br/>Enable with `COMPOSE_PROFILES=adguardhome` | [adguard/adguardhome](https://hub.docker.com/r/adguard/adguardhome) | |
|
||||
| [Tandoor](https://tandoor.dev) | Optional - Smart recipe management<br/>Enable with `COMPOSE_PROFILES=tandoor` | [vabene1111/recipes](https://hub.docker.com/r/vabene1111/recipes) | /recipes |
|
||||
| [Joplin](https://joplinapp.org) | Optional - Note taking application<br/>Enable with `COMPOSE_PROFILES=joplin` | [joplin/server](https://hub.docker.com/r/joplin/server) | /joplin |
|
||||
| [Home Assistant](https://www.home-assistant.io) | Optional - Open source home automation that puts local control and privacy first<br/>Enable with `COMPOSE_PROFILES=homeassistant` | [home-assistant/home-assistant:stable](https://ghcr.io/home-assistant/home-assistant) | |
|
||||
| [Immich](https://immich.app) | Optional - Self-hosted photo and video management solution<br/>Enable with `COMPOSE_PROFILES=immich` | [immich-app/immich-server:release](https://ghcr.io/immich-app/immich-server) | |
|
||||
| [Calibre-Web](https://github.com/janeczku/calibre-web) | Optional - Web app for browsing, reading and downloading eBooks stored in a Calibre database<br/>Enable with `COMPOSE_PROFILES=calibre-web` | [linuxserver/calibre-web](https://hub.docker.com/r/linuxserver/calibre-web) | /calibre |
|
||||
| [Decluttarr](https://github.com/ManiMatter/decluttarr) | Optional - Keeps the download queues free of stalled and redundant downloads. <br/>Enable with `COMPOSE_PROFILES=decluttarr` | [manimatter/decluttarr:latest](https://ghcr.io/manimatter/decluttarr:latest) | |
|
||||
|
||||
Optional containers are not enabled by default, they need to be enabled,
|
||||
see [Optional Services](#optional-services) for more information.
|
||||
* **Linux Host:** Any recent Linux distribution capable of running Docker. Tested on Ubuntu Server 22.04.
|
||||
* **Docker Engine:** Install the latest version of Docker Engine. [Official Installation Guide](https://docs.docker.com/engine/install/).
|
||||
* **Docker Compose V2:** Ensure you have Docker Compose V2 (usually installed as a Docker plugin, invoked via `docker compose`). [Official Installation Guide](https://docs.docker.com/compose/install/).
|
||||
* **User Permissions:** You'll need a user account that can run `docker` commands (usually by adding the user to the `docker` group) or run `docker compose` via `sudo`.
|
||||
* **SELinux (If Enabled):** If your host uses SELinux (e.g., Fedora, CentOS, RHEL), you might need additional host configuration. See the [Troubleshooting](#selinux-socket-permissions) section.
|
||||
|
||||
## Quick Start
|
||||
|
||||
`cp .env.example .env`, edit to your needs then `docker compose up -d`.
|
||||
|
||||
For the first time, run `./update-config.sh` to update the applications base URLs and set the API keys in `.env`.
|
||||
|
||||
If you want to show Jellyfin information in the homepage, create it in Jellyfin settings and fill `JELLYFIN_API_KEY`.
|
||||
|
||||
### Podman / SELinux Note (Rootful Mode)
|
||||
|
||||
If you are running `podman compose` with `sudo` (rootful mode) on an SELinux-enabled system (like Fedora, CentOS, RHEL) and encounter 'permission denied' errors when containers (like Watchtower, Autoheal, Traefik) try to access `/var/run/docker.sock`, you likely need to allow containers to manage the host system's container resources. Run the following command on your host system to enable this persistently:
|
||||
|
||||
1. **Clone the Repository:**
|
||||
```bash
|
||||
sudo setsebool -P container_manage_cgroup on
|
||||
git clone https://github.com/AdrienPoupa/docker-compose-nas.git
|
||||
cd docker-compose-nas
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Before starting, copy `.env.example` to `.env` and ensure all necessary variables are set according to your environment. This includes user/group IDs (`USER_ID`/`GROUP_ID`), paths (`CONFIG_ROOT`, `DATA_ROOT`, `DOWNLOAD_ROOT`), credentials (like `TAILSCALE_AUTHKEY`, `PIA_USER`/`PASS` if using VPN), your desired `HOSTNAME`, and any API keys required for Homepage widgets (`SONARR_API_KEY`, `RADARR_API_KEY`, etc.).
|
||||
|
||||
| Variable | Description | Default |
|
||||
|--------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------|
|
||||
| `COMPOSE_FILE` | Docker compose files to load | |
|
||||
| `COMPOSE_PROFILES` | Docker compose profiles to load (`flaresolverr`, `adguardhome`, `sabnzbd`) | |
|
||||
| `USER_ID` | ID of the user to use in Docker containers | `1000` |
|
||||
| `GROUP_ID` | ID of the user group to use in Docker containers | `1000` |
|
||||
| `TIMEZONE` | TimeZone used by the container. | `America/New_York` |
|
||||
| `CONFIG_ROOT` | Host location for configuration files | `.` |
|
||||
| `DATA_ROOT` | Host location of the data files | `/mnt/data` |
|
||||
| `DOWNLOAD_ROOT` | Host download location for qBittorrent, should be a subfolder of `DATA_ROOT` | `/mnt/data/torrents` |
|
||||
| `PIA_LOCATION` | Servers to use for PIA. [see list here](https://serverlist.piaservers.net/vpninfo/servers/v6) | `ca` (Montreal, Canada) |
|
||||
| `PIA_USER` | PIA username | |
|
||||
| `PIA_PASS` | PIA password | |
|
||||
| `PIA_LOCAL_NETWORK` | PIA local network | `192.168.0.0/16` |
|
||||
| `HOSTNAME` | Hostname of the NAS, could be a local IP or a domain name | `localhost` |
|
||||
| `ADGUARD_HOSTNAME` | Optional - AdGuard Home hostname used, if enabled | |
|
||||
| `ADGUARD_USERNAME` | Optional - AdGuard Home username to show details in the homepage, if enabled | |
|
||||
| `ADGUARD_PASSWORD` | Optional - AdGuard Home password to show details in the homepage, if enabled | |
|
||||
| `QBITTORRENT_USERNAME` | qBittorrent username to access the web UI | `admin` |
|
||||
| `QBITTORRENT_PASSWORD` | qBittorrent password to access the web UI | `adminadmin` |
|
||||
| `DNS_CHALLENGE` | Enable/Disable DNS01 challenge, set to `false` to disable. | `true` |
|
||||
| `DNS_CHALLENGE_PROVIDER` | Provider for DNS01 challenge, [see list here](https://doc.traefik.io/traefik/https/acme/#providers). | `cloudflare` |
|
||||
| `LETS_ENCRYPT_CA_SERVER` | Let's Encrypt CA Server used to generate certificates, set to production by default.<br/>Set to `https://acme-staging-v02.api.letsencrypt.org/directory` to test your changes with the staging server. | `https://acme-v02.api.letsencrypt.org/directory` |
|
||||
| `LETS_ENCRYPT_EMAIL` | E-mail address used to send expiration notifications | |
|
||||
| `CLOUDFLARE_EMAIL` | CloudFlare Account email | |
|
||||
| `CLOUDFLARE_DNS_API_TOKEN` | API token with `DNS:Edit` permission | |
|
||||
| `CLOUDFLARE_ZONE_API_TOKEN` | API token with `Zone:Read` permission | |
|
||||
| `SONARR_API_KEY` | Sonarr API key to show information in the homepage | |
|
||||
| `RADARR_API_KEY` | Radarr API key to show information in the homepage | |
|
||||
| `LIDARR_API_KEY` | Lidarr API key to show information in the homepage | |
|
||||
| `PROWLARR_API_KEY` | Prowlarr API key to show information in the homepage | |
|
||||
| `BAZARR_API_KEY` | Bazarr API key to show information in the homepage | |
|
||||
| `JELLYFIN_API_KEY` | Jellyfin API key to show information in the homepage | |
|
||||
| `JELLYSEERR_API_KEY` | Jellyseer API key to show information in the homepage | |
|
||||
| `SABNZBD_API_KEY` | Sabnzbd API key to show information in the homepage | |
|
||||
| `HOMEPAGE_VAR_TITLE` | Title of the homepage | `Docker-Compose NAS` |
|
||||
| `HOMEPAGE_VAR_SEARCH_PROVIDER` | Homepage search provider, [see list here](https://gethomepage.dev/en/widgets/search/) | `google` |
|
||||
| `HOMEPAGE_VAR_HEADER_STYLE` | Homepage header style, [see list here](https://gethomepage.dev/en/configs/settings/#header-style) | `boxed` |
|
||||
| `HOMEPAGE_VAR_WEATHER_CITY` | Homepage weather city name | |
|
||||
| `HOMEPAGE_VAR_WEATHER_LAT` | Homepage weather city latitude | |
|
||||
| `HOMEPAGE_VAR_WEATHER_LONG` | Homepage weather city longitude | |
|
||||
| `HOMEPAGE_VAR_WEATHER_UNIT` | Homepage weather unit, either `metric` or `imperial` | `metric` |
|
||||
| `CALIBRE_USERNAME` | Optional - Calibre-Web username to show details in the homepage, if enabled | `admin` |
|
||||
| `CALIBRE_PASSWORD` | Optional - Calibre-Web password to show details in the homepage, if enabled | `admin123` |
|
||||
|
||||
## 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, fill `.env` and fill it with your PIA credentials.
|
||||
|
||||
The location of the server it will connect to is set by `LOC=ca`, defaulting to Montreal - Canada.
|
||||
|
||||
You need to fill the credentials in the `PIA_*` environment variable,
|
||||
otherwise the VPN container will exit and qBittorrent will not start.
|
||||
|
||||
## Sonarr, Radarr & Lidarr
|
||||
|
||||
### File Structure
|
||||
|
||||
Sonarr, Radarr, and Lidarr 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
|
||||
└── music = Lidarr
|
||||
2. **Create Configuration File:**
|
||||
Copy the example environment file:
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Go to Settings > Management.
|
||||
In Sonarr, set the Root folder to `/data/media/tv`.
|
||||
In Radarr, set the Root folder to `/data/media/movies`.
|
||||
In Lidarr, set the Root folder to `/data/media/music`.
|
||||
3. **Edit `.env` File:**
|
||||
Open the `.env` file with a text editor and configure it according to your system and preferences. **This is the most crucial step.** See the detailed [Configuration (`.env` File)](#configuration-env-file) section below for explanations of each variable. Minimally, you **must** set `USER_ID`, `GROUP_ID`, `TIMEZONE`, `HOSTNAME`, and `TAILSCALE_AUTHKEY`.
|
||||
|
||||
### 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`:
|
||||
|
||||
## Prowlarr
|
||||
|
||||
The indexers are configured through Prowlarr. They synchronize automatically to Radarr and Sonarr.
|
||||
|
||||
Radarr and Sonarr may then be added via Settings > Apps. The Prowlarr server is `http://prowlarr:9696/prowlarr`, the Radarr server
|
||||
is `http://radarr:7878/radarr` Sonarr `http://sonarr:8989/sonarr`, and Lidarr `http://lidarr:8686/lidarr`.
|
||||
|
||||
Their API keys can be found in Settings > Security > API Key.
|
||||
|
||||
## qBittorrent
|
||||
|
||||
Running `update-config.sh` will set qBittorrent's password to `adminadmin`. If you wish to update the password manually,
|
||||
since qBittorrent v4.6.2, a temporary password is generated on startup. Get it with `docker compose logs qbittorrent`:
|
||||
4. **Start the Stack:**
|
||||
Run Docker Compose (use `sudo` if your user isn't in the `docker` group):
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
The WebUI administrator username is: admin
|
||||
The WebUI administrator password was not set. A temporary password is provided for this session: <some_password>
|
||||
This will pull the necessary images and start all the core services in the background.
|
||||
|
||||
5. **Run Initial Configuration Script:**
|
||||
This script helps configure base URLs and API keys within the running *arr applications based on your `.env` file.
|
||||
```bash
|
||||
./update-config.sh
|
||||
```
|
||||
*(Note: You might need to make it executable first: `chmod +x ./update-config.sh`)*
|
||||
|
||||
Use this password to access the UI, then go to Settings > Web UI and set your own password,
|
||||
then set it in `.env`'s `QBITTORRENT_PASSWORD` variable.
|
||||
6. **Access Services:** Once Tailscale is connected, you should be able to access your services via `https://<TAILSCALE_HOSTNAME>.<your-tailnet-name>.ts.net/<service_path>` or `https://<TAILSCALE_IP>/<service_path>`. If you set up DNS for your `HOSTNAME`, you can use `https://<HOSTNAME>/<service_path>`. The main dashboard is at `/`.
|
||||
|
||||
The login page can be disabled on for the local network in by enabling `Bypass authentication for clients`.
|
||||
## Configuration (`.env` File)
|
||||
|
||||
```
|
||||
192.168.0.0/16
|
||||
127.0.0.0/8
|
||||
172.17.0.0/16
|
||||
```
|
||||
This file controls all the essential settings for your Docker Compose stack. Copy `.env.example` to `.env` and edit the values.
|
||||
|
||||
Set the default save path to `/data/torrents` in Settings, and restrict the network interface to WireGuard (`wg0`).
|
||||
---
|
||||
|
||||
To use the VueTorrent WebUI just go to `qBittorrent`, `Options`, `Web UI`, `Use Alternative WebUI`, and enter `/vuetorrent`. Special thanks to gabe565 for the easy enablement with (https://github.com/gabe565/linuxserver-mod-vuetorrent).
|
||||
### **Core Settings (Required)**
|
||||
|
||||
## Jellyfin
|
||||
These are fundamental for basic operation and permissions.
|
||||
|
||||
To enable [hardware transcoding](https://jellyfin.org/docs/general/administration/hardware-acceleration/),
|
||||
depending on your system, you may need to add the following block:
|
||||
* `USER_ID`: The Linux user ID that the containers will run as. Find yours with `id -u`.
|
||||
* *Default:* `1000`
|
||||
* `GROUP_ID`: The Linux group ID that the containers will run as. Find yours with `id -g`.
|
||||
* *Default:* `1000`
|
||||
* **Note:** Using the correct IDs is crucial for file permissions, especially for accessing media files on the host.
|
||||
* `TIMEZONE`: Your local timezone (e.g., `America/New_York`, `Europe/London`, `Asia/Manila`). Find yours from [this list](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
|
||||
* *Default:* `America/New_York`
|
||||
* `HOSTNAME`: The primary hostname or IP address you intend to use to access your services. Traefik uses this for routing. Can be a local IP or a fully qualified domain name (e.g., `nas.example.com`).
|
||||
* *Default:* `localhost`
|
||||
|
||||
```
|
||||
devices:
|
||||
- /dev/dri/renderD128:/dev/dri/renderD128
|
||||
- /dev/dri/card0:/dev/dri/card0
|
||||
```
|
||||
---
|
||||
|
||||
Generally, running Docker on Linux you will want to use VA-API, but the exact mount paths may differ depending on your
|
||||
hardware.
|
||||
### **Host Paths (Required)**
|
||||
|
||||
## Homepage
|
||||
Define where container data and configuration are stored on your host machine.
|
||||
|
||||
The homepage comes with sensible defaults; some settings can ben controlled via environment variables in `.env`.
|
||||
* `CONFIG_ROOT`: The base directory on your host where configuration files for each service will be stored. Using `.` stores them in subdirectories within the project folder.
|
||||
* *Default:* `.`
|
||||
* `DATA_ROOT`: The main directory on your host containing your media libraries (movies, TV shows, music, books).
|
||||
* *Default:* `/mnt/data`
|
||||
* `DOWNLOAD_ROOT`: The directory on your host where the download client (qBittorrent/SABnzbd) will store downloads in progress and completed files *before* they are imported by *arr apps.
|
||||
* *Default:* `/mnt/data/torrents`
|
||||
* **Hardlink Note:** For efficient storage (avoiding duplicate files), it's highly recommended that `DOWNLOAD_ROOT` is on the **same filesystem** as `DATA_ROOT` (e.g., `/mnt/data/torrents` is inside `/mnt/data`). This allows instant moves via hardlinks instead of slow copies.
|
||||
|
||||
If you to customize further, you can modify the files in `/homepage/*.yaml` according to the [documentation](https://gethomepage.dev).
|
||||
Due to how the Docker socket is configured for the Docker integration, files must be edited as root.
|
||||
---
|
||||
|
||||
The files in `/homepage/tpl/*.yaml` only serve as a base to set up the homepage configuration on first run.
|
||||
### **Tailscale Access (Required)**
|
||||
|
||||
## Jellyseerr
|
||||
Controls secure remote access via Tailscale.
|
||||
|
||||
Jellyseer gives you content recommendations, allows others to make requests to you, and allows logging in with Jellyfin credentials.
|
||||
* `TAILSCALE_AUTHKEY`: **Required.** An authentication key from your Tailscale account. Generate one in the Tailscale Admin Console under Settings > Keys. You can use a reusable key or an ephemeral key (recommended for containers).
|
||||
* *Default:* (None - **Must be set**)
|
||||
* `TAILSCALE_HOSTNAME`: The desired hostname for this NAS within your Tailscale network.
|
||||
* *Default:* `tailscale-nas`
|
||||
* `TAILSCALE_TAGS`: Optional tags to apply to the Tailscale node (e.g., `tag:nas`).
|
||||
* *Default:* `tag:nas`
|
||||
* `ENABLE_FUNNEL_HTTPS`: Controls Tailscale's public accessibility.
|
||||
* `true`: Enables Tailscale Funnel, making services accessible publicly via the Tailscale domain (`<TAILSCALE_HOSTNAME>.<your-tailnet-name>.ts.net`). Use with caution.
|
||||
* `false`: Uses Tailscale Serve, making services accessible *only* to devices logged into your Tailnet. (Recommended)
|
||||
* *Default:* `false`
|
||||
|
||||
To set up, go to https://hostname/jellyseerr/setup, and set the URLs as follows:
|
||||
- Jellyfin: http://jellyfin:8096/jellyfin
|
||||
- Radarr:
|
||||
- Hostname: radarr
|
||||
- Port: 7878
|
||||
- URL Base: /radarr
|
||||
- Sonarr
|
||||
- Hostname: sonarr
|
||||
- Port: 8989
|
||||
- URL Base: /sonarr
|
||||
---
|
||||
|
||||
## Traefik and SSL Certificates
|
||||
### **Homepage Widgets (Optional)**
|
||||
|
||||
While you can use the private IP to access your NAS, how cool would it be for it to be accessible through a subdomain
|
||||
with a valid SSL certificate?
|
||||
API keys needed *only* if you want to display real-time information from these services on the Homepage dashboard. Find the API keys within each application's settings (usually under Settings > General or Settings > Security).
|
||||
|
||||
Traefik makes this trivial by using Let's Encrypt and one of its
|
||||
[supported ACME challenge providers](https://doc.traefik.io/traefik/https/acme).
|
||||
* `SONARR_API_KEY`
|
||||
* `RADARR_API_KEY`
|
||||
* `LIDARR_API_KEY` (If Lidarr profile is enabled)
|
||||
* `BAZARR_API_KEY`
|
||||
* `PROWLARR_API_KEY`
|
||||
* `JELLYFIN_API_KEY`
|
||||
* `JELLYSEERR_API_KEY`
|
||||
* `SABNZBD_API_KEY` (If SABnzbd profile is enabled)
|
||||
* `ADGUARD_USERNAME` / `ADGUARD_PASSWORD` (If AdGuard Home profile is enabled)
|
||||
* `CALIBRE_USERNAME` / `CALIBRE_PASSWORD` (If Calibre-Web profile is enabled)
|
||||
|
||||
Let's assume we are using `nas.domain.com` as custom subdomain.
|
||||
---
|
||||
|
||||
The idea is to create an A record pointing to the private IP of the NAS, `192.168.0.10` for example:
|
||||
```
|
||||
nas.domain.com. 1 IN A 192.168.0.10
|
||||
```
|
||||
### **Homepage Customization (Optional)**
|
||||
|
||||
The record will be publicly exposed but not resolve given this is a private IP.
|
||||
Control the appearance and behavior of the Homepage dashboard.
|
||||
|
||||
Given the NAS is not accessible from the internet, we need to do a dnsChallenge.
|
||||
Here we will be using CloudFlare, but the mechanism will be the same for all DNS providers
|
||||
baring environment variable changes, see the Traefik documentation above and [Lego's documentation](https://go-acme.github.io/lego/dns).
|
||||
* `HOMEPAGE_VAR_TITLE`: Title shown on the dashboard.
|
||||
* *Default:* `Docker-Compose NAS`
|
||||
* `HOMEPAGE_VAR_SEARCH_PROVIDER`: Default search engine. [See options](https://gethomepage.dev/en/widgets/search/).
|
||||
* *Default:* `google`
|
||||
* `HOMEPAGE_VAR_HEADER_STYLE`: Dashboard header style. [See options](https://gethomepage.dev/en/configs/settings/#header-style).
|
||||
* *Default:* `boxed`
|
||||
* `HOMEPAGE_VAR_WEATHER_CITY`, `_LAT`, `_LONG`, `_UNIT`: Configure the weather widget.
|
||||
|
||||
Then, fill the CloudFlare `.env` entries.
|
||||
---
|
||||
|
||||
If you want to test your configuration first, use the Let's Encrypt staging server by updating `LETS_ENCRYPT_CA_SERVER`'s
|
||||
value in `.env`:
|
||||
```
|
||||
LETS_ENCRYPT_CA_SERVER=https://acme-staging-v02.api.letsencrypt.org/directory
|
||||
```
|
||||
### **Download Client Settings**
|
||||
|
||||
If it worked, you will see the staging certificate at https://nas.domain.com.
|
||||
You may remove the `./letsencrypt/acme.json` file and restart the services to issue the real certificate.
|
||||
Credentials for included download clients.
|
||||
|
||||
You are free to use any DNS01 provider. Simply replace `DNS_CHALLENGE_PROVIDER` with your own provider,
|
||||
[see complete list here](https://doc.traefik.io/traefik/https/acme/#providers).
|
||||
You will also need to inject the environments variables specific to your provider.
|
||||
* `QBITTORRENT_USERNAME`: Username for qBittorrent Web UI.
|
||||
* *Default:* `admin`
|
||||
* `QBITTORRENT_PASSWORD`: Password for qBittorrent Web UI.
|
||||
* *Default:* `adminadmin`
|
||||
* **Note:** On first run, qBittorrent might generate a temporary password shown in its logs (`docker compose logs qbittorrent`). Log in with that, change the password in qBittorrent settings, and update this `.env` variable accordingly.
|
||||
|
||||
Certificate generation can be disabled by setting `DNS_CHALLENGE` to `false`.
|
||||
---
|
||||
|
||||
### Accessing from the outside with Tailscale
|
||||
### **VPN Configuration (Example: PIA - Optional)**
|
||||
|
||||
This setup includes a `tailscale` sidecar container to manage external access via your Tailnet, handling HTTPS termination. If we want to make the services reachable from outside the local network without opening router ports or exposing them directly to the internet, [Tailscale](https://tailscale.com) is a great solution.
|
||||
These variables are specific to the example `thrnz/docker-wireguard-pia` VPN container used for qBittorrent in the default setup. If you use a different VPN provider or container, you'll need different variables. **If you don't use the VPN, you can ignore these.**
|
||||
|
||||
**How it works:**
|
||||
1. The `tailscale` container authenticates to your Tailnet using the `TAILSCALE_AUTHKEY` provided in your `.env` file.
|
||||
2. Based on the `ENABLE_FUNNEL_HTTPS` variable in `.env`:
|
||||
* If `true`, Tailscale Funnel is enabled, making your services accessible publicly via your Tailscale domain (`<TAILSCALE_HOSTNAME>.<your-tailnet-name>.ts.net`).
|
||||
* If `false` (default), Tailscale Serve is used, making your services accessible only to devices logged into your Tailnet via the Tailscale domain or the container's Tailscale IP.
|
||||
3. Tailscale handles the incoming HTTPS connection and terminates the TLS encryption.
|
||||
4. It then forwards the decrypted HTTP request internally to Traefik (`http://traefik:80`), which routes it to the correct application based on the hostname/path.
|
||||
* `PIA_USER`: Private Internet Access username.
|
||||
* `PIA_PASS`: Private Internet Access password.
|
||||
* `PIA_LOCATION`: PIA server location code (e.g., `ca_montreal`, `us_east`). [See list](https://serverlist.piaservers.net/vpninfo/servers/v6).
|
||||
* *Default:* `ca`
|
||||
* `PIA_LOCAL_NETWORK`: Your local network CIDR (e.g., `192.168.1.0/24`). Allows local access to the qBittorrent UI when the VPN is active.
|
||||
* *Default:* `192.168.0.0/16`
|
||||
|
||||
**DNS Setup:**
|
||||
For this to work seamlessly with your `HOSTNAME` (e.g., `nas.domain.com`), you need a DNS record pointing to the Tailscale IP of the `tailscale` container.
|
||||
```
|
||||
nas.domain.com. 1 IN A <TAILSCALE_NAS_IP>
|
||||
```
|
||||
You can find the Tailscale IP in the Tailscale admin console or by running `tailscale ip -4` inside the container (or on the host if Tailscale is also installed there).
|
||||
---
|
||||
|
||||
**Local Access:**
|
||||
Using the Tailscale IP means you will always need to be connected to Tailscale to access your NAS via its hostname, even locally. This can be remedied by overriding the DNS entry for the NAS domain in your local DNS resolver (like Pi-hole or AdGuard Home) to point to the NAS's *local* IP address (`192.168.x.x`).
|
||||
### **Traefik DNS Challenge (Optional)**
|
||||
|
||||
This way, when connected to the local network, the NAS is accessible directly via its local IP, and from the outside, you connect via Tailscale, and the Tailscale DNS resolves the hostname correctly.
|
||||
These settings are for enabling automatic HTTPS certificate generation via Let's Encrypt using the DNS-01 challenge method. **This is generally NOT needed** because Tailscale handles HTTPS termination by default in this setup. Only configure this if you have a specific reason to manage your own certificates via Traefik (e.g., accessing services without Tailscale).
|
||||
|
||||
* `DNS_CHALLENGE`: Set to `true` to enable DNS challenge.
|
||||
* *Default:* `true` (Consider setting to `false` if using Tailscale for HTTPS)
|
||||
* `DNS_CHALLENGE_PROVIDER`: Your DNS provider supported by Traefik/Lego (e.g., `cloudflare`, `godaddy`). [See providers](https://doc.traefik.io/traefik/https/acme/#providers).
|
||||
* *Default:* `cloudflare`
|
||||
* `LETS_ENCRYPT_EMAIL`: Your email address for Let's Encrypt notifications.
|
||||
* `LETS_ENCRYPT_CA_SERVER`: Let's Encrypt server URL (use staging for testing).
|
||||
* *Default:* `https://acme-v02.api.letsencrypt.org/directory` (Production)
|
||||
* Provider-Specific Variables (e.g., `CLOUDFLARE_EMAIL`, `CLOUDFLARE_DNS_API_TOKEN`, `CLOUDFLARE_ZONE_API_TOKEN`): Credentials required by your chosen `DNS_CHALLENGE_PROVIDER`. Refer to Traefik documentation.
|
||||
|
||||
---
|
||||
|
||||
### **Compose Profiles & Files (Advanced)**
|
||||
|
||||
* `COMPOSE_PROFILES`: Comma-separated list of optional service profiles to enable (e.g., `lidarr,sabnzbd,adguardhome`). See [Optional Services](#optional-services).
|
||||
* `COMPOSE_FILE`: Colon-separated list of compose files to use. Allows extending the base configuration.
|
||||
* *Default:* `docker-compose.yml`
|
||||
|
||||
## Service Access
|
||||
|
||||
With the default Tailscale setup, services are securely accessible via HTTPS using your Tailscale node's name or IP, followed by the service path:
|
||||
|
||||
* **Homepage:** `https://<TAILSCALE_NODE>/`
|
||||
* **Sonarr:** `https://<TAILSCALE_NODE>/sonarr`
|
||||
* **Radarr:** `https://<TAILSCALE_NODE>/radarr`
|
||||
* **qBittorrent:** `https://<TAILSCALE_NODE>/qbittorrent`
|
||||
* **Jellyfin:** `https://<TAILSCALE_NODE>/jellyfin`
|
||||
* ...and so on.
|
||||
|
||||
Replace `<TAILSCALE_NODE>` with your Tailscale device name (e.g., `tailscale-nas.your-tailnet.ts.net`) or its Tailscale IP address.
|
||||
|
||||
If you configure DNS for your `HOSTNAME` variable to point to the Tailscale IP, you can use `https://<HOSTNAME>/<service_path>`.
|
||||
|
||||
## Optional Services
|
||||
|
||||
Optional services are not launched by default and enabled by appending their profile name to the
|
||||
`COMPOSE_PROFILES` environment variable (see [Docker documentation](https://docs.docker.com/compose/profiles)).
|
||||
Several services are included but disabled by default. Enable them by adding their profile name to the `COMPOSE_PROFILES` variable in your `.env` file (separate multiple profiles with commas).
|
||||
|
||||
Say you want to enable FlareSolverr, you should have `COMPOSE_PROFILES=flaresolverr`.
|
||||
|
||||
Multiple optional services can be enabled separated by commas: `COMPOSE_PROFILES=flaresolverr,adguardhome`.
|
||||
|
||||
### FlareSolverr
|
||||
|
||||
In Prowlarr, add the FlareSolverr indexer with the URL http://flaresolverr:8191/
|
||||
|
||||
### SABnzbd
|
||||
|
||||
Enable SABnzbd by setting `COMPOSE_PROFILES=sabnzbd`. It will be accessible at `/sabnzbd`.
|
||||
|
||||
If that is not the case, the `url_base` parameter in `sabnzbd.ini` should be set to `/sabnzbd`.
|
||||
|
||||
Additionally, `host_whitelist` value should be set to your hostname.
|
||||
|
||||
### AdGuard Home
|
||||
|
||||
Enable AdGuard Home by setting `COMPOSE_PROFILES=adguardhome`.
|
||||
|
||||
Set the `ADGUARD_HOSTNAME`, I chose a different subdomain to use secure DNS without the folder.
|
||||
|
||||
On first run, specify the port 3000 and enable listen on all interfaces to make it work with Tailscale.
|
||||
|
||||
If after running `docker compose up -d`, you're getting `network docker-compose-nas declared as external, but could not be found`,
|
||||
run `docker network create docker-compose-nas` first.
|
||||
|
||||
#### Encryption
|
||||
|
||||
In Settings > Encryption Settings, set the certificates path to `/opt/adguardhome/certs/certs/<YOUR_HOSTNAME>.crt`
|
||||
and the private key to `/opt/adguardhome/certs/private/<YOUR_HOSTNAME>.key`, those files are created by Traefik cert dumper
|
||||
from the ACME certificates Traefik generates in JSON.
|
||||
|
||||
#### DHCP
|
||||
|
||||
If you want to use the AdGuard Home DHCP server, for example because your router does not allow changing its DNS server,
|
||||
you will need to select the `eth0` DHCP interface matching `10.0.0.10`, then specify the
|
||||
Gateway IP to match your router address (`192.168.0.1` for example) and set a range of IP addresses assigned to local
|
||||
devices.
|
||||
|
||||
In `adguardhome/docker-compose.yml`, set the network interface `dhcp-relay` should listen to. By default, it is set to
|
||||
`enp2s0`, but you may need to change it to your host's network interface, verify it with `ip a`.
|
||||
|
||||
In the configuration (`adguardhome/conf/AdGuardHome.yaml`), set the DHCP options 6th key to your NAS internal IP address:
|
||||
```yml
|
||||
dhcp:
|
||||
dhcpv4:
|
||||
options:
|
||||
- 6 ips 192.168.0.10,192.168.0.10
|
||||
Example: Enable Lidarr and SABnzbd
|
||||
```dotenv
|
||||
COMPOSE_PROFILES=lidarr,sabnzbd
|
||||
```
|
||||
|
||||
Enable DHCP Relay by setting `COMPOSE_PROFILES=adguardhome-dhcp`.
|
||||
Available Profiles:
|
||||
* `lidarr`: Music management.
|
||||
* `sabnzbd`: Usenet download client.
|
||||
* `flaresolverr`: Bypasses Cloudflare challenges for Prowlarr.
|
||||
* `adguardhome`: Network-wide ad blocking (see `adguardhome/README.md`).
|
||||
* `calibre-web`: E-book library management.
|
||||
* `decluttarr`: Automated download cleanup.
|
||||
* `tandoor`: Recipe management (see `tandoor/README.md`).
|
||||
* `joplin`: Note-taking server (see `joplin/README.md`).
|
||||
* `homeassistant`: Home automation (see `homeassistant/README.md`).
|
||||
* `immich`: Photo management (see `immich/README.md`).
|
||||
|
||||
#### Expose DNS Server with Tailscale
|
||||
## Troubleshooting
|
||||
|
||||
Based on [Tailscale's documentation](https://tailscale.com/kb/1114/pi-hole), it is easy to use your AdGuard server everywhere.
|
||||
Just make sure that AdGuard Home listens to all interfaces.
|
||||
### SELinux Socket Permissions (Docker)
|
||||
|
||||
### Calibre-Web
|
||||
If you are running Docker on a host with SELinux enabled (like Fedora, CentOS, RHEL) and services like Traefik, Watchtower, or Autoheal fail with "permission denied" errors when trying to access `/var/run/docker.sock`:
|
||||
|
||||
If you do not have a Calibre database, download a sample from: https://github.com/janeczku/calibre-web/raw/master/library/metadata.db
|
||||
and place it in `${DATA_ROOT}/books`.
|
||||
|
||||
On the initial setup screen, enter `/books` as your calibre library location.
|
||||
|
||||
**Default admin login:** Username: `admin` Password: `admin123`.
|
||||
|
||||
Unrar is included by default and needs to be set in the Calibre-Web admin page (Basic Configuration:External Binaries)
|
||||
with a path of `/usr/bin/unrar`.
|
||||
|
||||
### Decluttarr
|
||||
Decluttarr keeps the queue free of stalled and redundant downloads. For configuration options and examples,
|
||||
please see https://github.com/ManiMatter/decluttarr/blob/dev/README.md.
|
||||
|
||||
All environment variables are prefixed with `DECLUTTARR_`.
|
||||
|
||||
### Tandoor
|
||||
|
||||
See [here](./tandoor/README.md).
|
||||
|
||||
### Joplin
|
||||
|
||||
See [here](./joplin/README.md).
|
||||
|
||||
### Home Assistant
|
||||
|
||||
See [here](./homeassistant/README.md).
|
||||
|
||||
### Immich
|
||||
|
||||
See [here](./immich/README.md).
|
||||
|
||||
## Customization
|
||||
|
||||
You can override the configuration of a service or add new services by creating a new `docker-compose.override.yml` file,
|
||||
then appending it to the `COMPOSE_FILE` environment variable: `COMPOSE_FILE=docker-compose.yml:docker-compose.override.yml`
|
||||
|
||||
[See official documentation](https://docs.docker.com/compose/extends).
|
||||
|
||||
For example, use a [different VPN provider](https://github.com/bubuntux/nordvpn):
|
||||
|
||||
```yml
|
||||
services:
|
||||
vpn:
|
||||
image: ghcr.io/bubuntux/nordvpn
|
||||
cap_add:
|
||||
- NET_ADMIN # Required
|
||||
- NET_RAW # Required
|
||||
environment: # Review https://github.com/bubuntux/nordvpn#environment-variables
|
||||
- USER=user@email.com # Required
|
||||
- "PASS=pas$word" # Required
|
||||
- CONNECT=United_States
|
||||
- TECHNOLOGY=NordLynx
|
||||
- NETWORK=192.168.1.0/24 # So it can be accessed within the local network
|
||||
1. **Check Audit Logs:** Immediately after seeing the error, check the SELinux audit log on the host:
|
||||
```bash
|
||||
sudo ausearch -m avc -ts recent
|
||||
```
|
||||
Look for lines containing `denied`, `docker.sock`, and the name of the failing service (e.g., `traefik`, `watchtower`).
|
||||
|
||||
### Optional: Using the VPN for *arr apps
|
||||
2. **Generate Custom Policy:** If denials are found, you may need to create a custom SELinux policy module using `audit2allow`. Pipe the denial messages into it:
|
||||
```bash
|
||||
# Generate policy files (my-dockersock.te and my-dockersock.pp)
|
||||
sudo ausearch -m avc -ts recent | audit2allow -M my-dockersock
|
||||
|
||||
If you want to use the VPN for Prowlarr and other *arr applications, add the following block to all the desired containers:
|
||||
```yml
|
||||
network_mode: "service:vpn"
|
||||
depends_on:
|
||||
vpn:
|
||||
condition: service_healthy
|
||||
# Install the policy module
|
||||
sudo semodule -i my-dockersock.pp
|
||||
```
|
||||
This allows the specific actions that were being denied. You might need to repeat this if different denials appear after applying the first policy.
|
||||
|
||||
Change the healthcheck to mark the containers as unhealthy when internet connection is not working by appending a URL
|
||||
to the healthcheck, eg: `test: [ "CMD", "curl", "--fail", "http://127.0.0.1:7878/radarr/ping", "https://google.com" ]`
|
||||
### Tailscale Issues
|
||||
|
||||
Then in Prowlarr, use `localhost` rather than `vpn` as the hostname, since they are on the same network.
|
||||
* **Authentication:** Ensure your `TAILSCALE_AUTHKEY` in `.env` is valid and hasn't expired (especially if using ephemeral keys). Check the `tailscale` container logs (`docker compose logs tailscale`) for authentication errors.
|
||||
* **Connectivity:** Verify the `tailscale` container is running and connected to your Tailnet (`docker compose exec tailscale tailscale status`).
|
||||
* **Funnel/Serve Command:** If you modified the Tailscale command, ensure the syntax for `tailscale funnel` or `tailscale serve` is correct.
|
||||
|
||||
## Synology Quirks
|
||||
### File Permissions
|
||||
|
||||
Docker compose NAS can run on DSM 7.1, with a few extra steps.
|
||||
If services report permission errors when accessing `/config` or `/data` directories, double-check that:
|
||||
* The `USER_ID` and `GROUP_ID` in your `.env` file match the owner/group of the corresponding `CONFIG_ROOT` and `DATA_ROOT` directories on your host.
|
||||
* The host directories have appropriate read/write permissions for that user/group.
|
||||
* If using SELinux, the `:Z` flag on the volume mounts in `docker-compose.yml` is correctly applied to allow the container to write to the host paths.
|
||||
|
||||
### Free Ports 80 and 443
|
||||
## Advanced Topics
|
||||
|
||||
By default, ports 80 and 443 are used by Nginx but not actually used for anything useful. Free them by creating a new task
|
||||
in the Task Scheduler > Create > Triggered Task > User-defined script. Leave the Event as `Boot-up` and the `root` user,
|
||||
go to Task Settings and paste the following in User-defined script:
|
||||
```
|
||||
sed -i -e 's/80/81/' -e 's/443/444/' /usr/syno/share/nginx/server.mustache /usr/syno/share/nginx/DSM.mustache /usr/syno/share/nginx/WWWService.mustache
|
||||
*(Relevant sections like Synology Quirks, NFS Share, Static IP, etc., can be kept here, but review them to ensure they align with a standard Docker setup rather than Podman specifics where applicable.)*
|
||||
|
||||
synosystemctl restart nginx
|
||||
```
|
||||
*(Example: Synology section should focus on Docker package setup, port conflicts, user IDs, etc., relevant to DSM.)*
|
||||
|
||||
### Install Synology WireGuard
|
||||
*(Example: Remove Podman-specific commands or troubleshooting steps from these sections.)*
|
||||
|
||||
Since WireGuard is not part of DSM's kernel, an external package must be installed for the `vpn` container to run.
|
||||
---
|
||||
|
||||
For DSM 7.1, download and install the package corresponding to your NAS CPU architecture
|
||||
[from here](https://github.com/vegardit/synology-wireguard/releases).
|
||||
|
||||
As specified in the [project's README](https://github.com/vegardit/synology-wireguard#installation),
|
||||
the package must be run as `root` from the command line: `sudo /var/packages/WireGuard/scripts/start`
|
||||
|
||||
### Free Port 1900
|
||||
|
||||
Jellyfin will fail to run by default since the port 1900
|
||||
[is not free](https://lookanotherblog.com/resolve-port-1900-conflict-between-plex-and-synology/).
|
||||
You may free it by going to Control Panel > File Services > Advanced > SSTP > Untick `Enable Windows network discovery`.
|
||||
|
||||
### User Permissions
|
||||
|
||||
By default, the user and groups are set to `1000` as it is the default on Ubuntu and many other Linux distributions.
|
||||
However, that is not the case in Synology; the first user should have an ID of `1026` and a group of `100`.
|
||||
You may check yours with `id`.
|
||||
Update the `USER_ID` and `GROUP_ID` in `.env` with your IDs.
|
||||
Not updating them may result in [permission issues](https://github.com/AdrienPoupa/docker-compose-nas/issues/10).
|
||||
|
||||
```
|
||||
USER_ID=1026
|
||||
GROUP_ID=100
|
||||
```
|
||||
|
||||
### Synology DHCP Server and Adguard Home Port Conflict
|
||||
|
||||
If you are using the Synology DHCP Server package, it will use port 53 even if it does not need it. This is because
|
||||
it uses Dnsmasq to handle DHCP requests, but does not serve DNS queries. The port can be released by editing (as root)
|
||||
`/usr/local/lib/systemd/system/pkg-dhcpserver.service` and [adding -p 0](https://www.reddit.com/r/synology/comments/njwdao/comment/j2d23qr/?utm_source=reddit&utm_medium=web2x&context=3):
|
||||
`ExecStart=/var/packages/DhcpServer/target/dnsmasq-2.x/usr/bin/dnsmasq --user=DhcpServer --group=DhcpServer --cache-size=200 --conf-file=/etc/dhcpd/dhcpd.conf --dhcp-lease-max=2147483648 -p 0`
|
||||
Reboot the NAS and the port 53 will be free for Adguard.
|
||||
|
||||
## Use Separate Paths for Torrents and Storage
|
||||
|
||||
If you want to use separate paths for torrents download and long term storage, to use different disks for example,
|
||||
set your `docker-compose.override.yml` to:
|
||||
|
||||
```yml
|
||||
services:
|
||||
sonarr:
|
||||
volumes:
|
||||
- ./sonarr:/config
|
||||
- ${DATA_ROOT}/media/tv:/data/media/tv
|
||||
- ${DOWNLOAD_ROOT}/tv:/data/torrents/tv
|
||||
radarr:
|
||||
volumes:
|
||||
- ./radarr:/config
|
||||
- ${DATA_ROOT}/media/movies:/data/media/movies
|
||||
- ${DOWNLOAD_ROOT}/movies:/data/torrents/movies
|
||||
```
|
||||
|
||||
Note you will lose the hard link ability, ie your files will be duplicated.
|
||||
|
||||
In Sonarr and Radarr, go to `Settings` > `Importing` > Untick `Use Hardlinks instead of Copy`
|
||||
|
||||
## NFS Share
|
||||
|
||||
This can be useful to share the media folder to a local player like Kodi or computers in the local network,
|
||||
but may not be necessary if Jellyfin is going to be used to access the media.
|
||||
|
||||
Install the NFS kernel server: `sudo apt 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`
|
||||
|
||||
## Static IP
|
||||
|
||||
Set a static IP, assuming `192.168.0.10` and using Google DNS servers: `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
|
||||
```
|
||||
|
||||
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`
|
||||
*Self-hosted media stack powered by Docker, Traefik, Tailscale, and the \*arr suite.* -->
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user