{"id":13587300,"url":"https://github.com/AdrienPoupa/docker-compose-nas","last_synced_at":"2025-04-07T21:33:34.161Z","repository":{"id":42022456,"uuid":"461326497","full_name":"AdrienPoupa/docker-compose-nas","owner":"AdrienPoupa","description":"Simple Docker Compose NAS featuring Sonarr, Radarr, Prowlarr, Jellyfin, qBittorrent, PIA VPN and Traefik with SSL support","archived":false,"fork":false,"pushed_at":"2024-03-15T15:04:49.000Z","size":136,"stargazers_count":741,"open_issues_count":2,"forks_count":91,"subscribers_count":15,"default_branch":"master","last_synced_at":"2024-03-15T21:33:26.935Z","etag":null,"topics":["adguardhome","docker","docker-compose","homepage","jellyfin","letsencrypt","nas","pia","privateinternetaccess","prowlarr","qbittorrent","radarr","self-hosted","sonarr","ssl","torrent","traefik","traefik-v2","vpn","wireguard"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AdrienPoupa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2022-02-19T22:17:15.000Z","updated_at":"2024-04-15T06:04:37.119Z","dependencies_parsed_at":"2024-01-04T05:32:17.908Z","dependency_job_id":"eddc6be4-f6b5-4831-8039-53d2e61ec824","html_url":"https://github.com/AdrienPoupa/docker-compose-nas","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AdrienPoupa%2Fdocker-compose-nas","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AdrienPoupa%2Fdocker-compose-nas/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AdrienPoupa%2Fdocker-compose-nas/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AdrienPoupa%2Fdocker-compose-nas/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AdrienPoupa","download_url":"https://codeload.github.com/AdrienPoupa/docker-compose-nas/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247732860,"owners_count":20986942,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["adguardhome","docker","docker-compose","homepage","jellyfin","letsencrypt","nas","pia","privateinternetaccess","prowlarr","qbittorrent","radarr","self-hosted","sonarr","ssl","torrent","traefik","traefik-v2","vpn","wireguard"],"created_at":"2024-08-01T15:06:08.750Z","updated_at":"2025-04-07T21:33:34.147Z","avatar_url":"https://github.com/AdrienPoupa.png","language":"Shell","funding_links":[],"categories":["Shell"],"sub_categories":[],"readme":"# Docker Compose NAS\n\nAfter searching for the perfect NAS solution, I realized what I wanted could be achieved \nwith some Docker containers on a vanilla Linux box. The result is an opinionated Docker Compose configuration capable of \nbrowsing indexers to retrieve media resources and downloading them through a WireGuard VPN with port forwarding.\nSSL certificates and remote access through Tailscale are supported.\n\nRequirements: Any Docker-capable recent Linux box with Docker Engine and Docker Compose V2.\nI am running it in Ubuntu Server 22.04; I also tested this setup on a [Synology DS220+ with DSM 7.1](#synology-quirks).\n\n![Docker-Compose NAS Homepage](https://github.com/AdrienPoupa/docker-compose-nas/assets/15086425/3492a9f6-3779-49a5-b052-4193844f16f0)\n\n## Table of Contents\n\n\u003c!-- TOC --\u003e\n* [Docker Compose NAS](#docker-compose-nas)\n  * [Table of Contents](#table-of-contents)\n  * [Applications](#applications)\n  * [Quick Start](#quick-start)\n  * [Environment Variables](#environment-variables)\n  * [PIA WireGuard VPN](#pia-wireguard-vpn)\n  * [Sonarr, Radarr \u0026 Lidarr](#sonarr-radarr--lidarr)\n    * [File Structure](#file-structure)\n    * [Download Client](#download-client)\n  * [Prowlarr](#prowlarr)\n  * [qBittorrent](#qbittorrent)\n  * [Jellyfin](#jellyfin)\n  * [Homepage](#homepage)\n  * [Jellyseerr](#jellyseerr)\n  * [Traefik and SSL Certificates](#traefik-and-ssl-certificates)\n    * [Accessing from the outside with Tailscale](#accessing-from-the-outside-with-tailscale)\n  * [Optional Services](#optional-services)\n    * [FlareSolverr](#flaresolverr)\n    * [SABnzbd](#sabnzbd)\n    * [AdGuard Home](#adguard-home)\n      * [Encryption](#encryption)\n      * [DHCP](#dhcp)\n      * [Expose DNS Server with Tailscale](#expose-dns-server-with-tailscale)\n    * [Calibre-Web](#calibre-web)\n    * [Decluttarr](#decluttarr)\n    * [Tandoor](#tandoor)\n    * [Joplin](#joplin)\n    * [Home Assistant](#home-assistant)\n    * [Immich](#immich)\n  * [Customization](#customization)\n    * [Optional: Using the VPN for *arr apps](#optional-using-the-vpn-for-arr-apps)\n  * [Synology Quirks](#synology-quirks)\n    * [Free Ports 80 and 443](#free-ports-80-and-443)\n    * [Install Synology WireGuard](#install-synology-wireguard)\n    * [Free Port 1900](#free-port-1900)\n    * [User Permissions](#user-permissions)\n    * [Synology DHCP Server and Adguard Home Port Conflict](#synology-dhcp-server-and-adguard-home-port-conflict)\n  * [Use Separate Paths for Torrents and Storage](#use-separate-paths-for-torrents-and-storage)\n  * [NFS Share](#nfs-share)\n  * [Static IP](#static-ip)\n  * [Laptop Specific Configuration](#laptop-specific-configuration)\n\u003c!-- TOC --\u003e\n\n## Applications\n\n| **Application**                                                    | **Description**                                                                                                                                      | **Image**                                                                                | **URL**      |\n|--------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------|--------------|\n| [Sonarr](https://sonarr.tv)                                        | PVR for newsgroup and bittorrent users                                                                                                               | [linuxserver/sonarr](https://hub.docker.com/r/linuxserver/sonarr)                        | /sonarr      |\n| [Radarr](https://radarr.video)                                     | Movie collection manager for Usenet and BitTorrent users                                                                                             | [linuxserver/radarr](https://hub.docker.com/r/linuxserver/radarr)                        | /radarr      |\n| [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      |\n| [Prowlarr](https://github.com/Prowlarr/Prowlarr)                   | Indexer aggregator for Sonarr and Radarr                                                                                                             | [linuxserver/prowlarr:latest](https://hub.docker.com/r/linuxserver/prowlarr)             | /prowlarr    |\n| [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)        |              |\n| [qBittorrent](https://www.qbittorrent.org)                         | Bittorrent client with a complete web UI\u003cbr/\u003eUses VPN network\u003cbr/\u003eUsing Libtorrent 1.x                                                               | [linuxserver/qbittorrent:libtorrentv1](https://hub.docker.com/r/linuxserver/qbittorrent) | /qbittorrent |\n| [Unpackerr](https://unpackerr.zip)                                 | Automated Archive Extractions                                                                                                                        | [golift/unpackerr](https://hub.docker.com/r/golift/unpackerr)                            |              |\n| [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    |\n| [Jellyseer](https://jellyfin.org)                                  | Manages requests for your media library                                                                                                              | [fallenbagel/jellyseerr](https://hub.docker.com/r/fallenbagel/jellyseerr)                | /jellyseer   |\n| [Homepage](https://gethomepage.dev)                                | Application dashboard                                                                                                                                | [gethomepage/homepage](https://github.com/gethomepage/homepage/pkgs/container/homepage)  | /            |\n| [Traefik](https://traefik.io)                                      | Reverse proxy                                                                                                                                        | [traefik](https://hub.docker.com/_/traefik)                                              |              |\n| [Watchtower](https://containrrr.dev/watchtower/)                   | Automated Docker images update                                                                                                                       | [containrrr/watchtower](https://hub.docker.com/r/containrrr/watchtower)                  |              |\n| [Autoheal](https://github.com/willfarrell/docker-autoheal/)        | Monitor and restart unhealthy Docker containers                                                                                                      | [willfarrell/autoheal](https://hub.docker.com/r/willfarrell/autoheal)                    |              |\n| [Lidarr](https://lidarr.audio)                                     | Optional - Music collection manager for Usenet and BitTorrent users\u003cbr/\u003eEnable with `COMPOSE_PROFILES=lidarr`                                        | [linuxserver/lidarr](https://hub.docker.com/r/linuxserver/lidarr)                        | /lidarr      |\n| [SABnzbd](https://sabnzbd.org/)                                    | Optional - Free and easy binary newsreader\u003cbr/\u003eEnable with `COMPOSE_PROFILES=sabnzbd`                                                                | [linuxserver/sabnzbd](https://hub.docker.com/r/linuxserver/sabnzbd)                      | /sabnzbd     |\n| [FlareSolverr](https://github.com/FlareSolverr/FlareSolverr)       | Optional - Proxy server to bypass Cloudflare protection in Prowlarr\u003cbr/\u003eEnable with `COMPOSE_PROFILES=flaresolverr`                                  | [flaresolverr/flaresolverr](https://hub.docker.com/r/flaresolverr/flaresolverr)          |              |\n| [AdGuard Home](https://adguard.com/en/adguard-home/overview.html)  | Optional - Network-wide software for blocking ads \u0026 tracking\u003cbr/\u003eEnable with `COMPOSE_PROFILES=adguardhome`                                          | [adguard/adguardhome](https://hub.docker.com/r/adguard/adguardhome)                      |              |\n| [Tandoor](https://tandoor.dev)                                     | Optional - Smart recipe management\u003cbr/\u003eEnable with `COMPOSE_PROFILES=tandoor`                                                                        | [vabene1111/recipes](https://hub.docker.com/r/vabene1111/recipes)                        | /recipes     |\n| [Joplin](https://joplinapp.org)                                    | Optional - Note taking application\u003cbr/\u003eEnable with `COMPOSE_PROFILES=joplin`                                                                         | [joplin/server](https://hub.docker.com/r/joplin/server)                                  | /joplin      |\n| [Home Assistant](https://www.home-assistant.io)                    | Optional - Open source home automation that puts local control and privacy first\u003cbr/\u003eEnable with `COMPOSE_PROFILES=homeassistant`                    | [home-assistant/home-assistant:stable](https://ghcr.io/home-assistant/home-assistant)    |              |\n| [Immich](https://immich.app)                                       | Optional - Self-hosted photo and video management solution\u003cbr/\u003eEnable with `COMPOSE_PROFILES=immich`                                                 | [immich-app/immich-server:release](https://ghcr.io/immich-app/immich-server)             |              |\n| [Calibre-Web](https://github.com/janeczku/calibre-web)             | Optional - Web app for browsing, reading and downloading eBooks stored in a Calibre database\u003cbr/\u003eEnable with `COMPOSE_PROFILES=calibre-web`          | [linuxserver/calibre-web](https://hub.docker.com/r/linuxserver/calibre-web)              | /calibre     |\n| [Decluttarr](https://github.com/ManiMatter/decluttarr)             | Optional - Keeps the download queues free of stalled and redundant downloads. \u003cbr/\u003eEnable with `COMPOSE_PROFILES=decluttarr`                         | [manimatter/decluttarr:latest](https://ghcr.io/manimatter/decluttarr:latest)             |              |\n\nOptional containers are not enabled by default, they need to be enabled, \nsee [Optional Services](#optional-services) for more information.\n\n## Quick Start\n\n`cp .env.example .env`, edit to your needs then `docker compose up -d`.\n\nFor the first time, run `./update-config.sh` to update the applications base URLs and set the API keys in `.env`.\n\nIf you want to show Jellyfin information in the homepage, create it in Jellyfin settings and fill `JELLYFIN_API_KEY`.\n\n## Environment Variables\n\n| Variable                       | Description                                                                                                                                                                                            | Default                                          |\n|--------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------|\n| `COMPOSE_FILE`                 | Docker compose files to load                                                                                                                                                                           |                                                  |\n| `COMPOSE_PROFILES`             | Docker compose profiles to load (`flaresolverr`, `adguardhome`, `sabnzbd`)                                                                                                                             |                                                  |\n| `USER_ID`                      | ID of the user to use in Docker containers                                                                                                                                                             | `1000`                                           |\n| `GROUP_ID`                     | ID of the user group to use in Docker containers                                                                                                                                                       | `1000`                                           |\n| `TIMEZONE`                     | TimeZone used by the container.                                                                                                                                                                        | `America/New_York`                               |\n| `CONFIG_ROOT`                  | Host location for configuration files                                                                                                                                                                  | `.`                                              |\n| `DATA_ROOT`                    | Host location of the data files                                                                                                                                                                        | `/mnt/data`                                      |\n| `DOWNLOAD_ROOT`                | Host download location for qBittorrent, should be a subfolder of `DATA_ROOT`                                                                                                                           | `/mnt/data/torrents`                             |\n| `PIA_LOCATION`                 | Servers to use for PIA. [see list here](https://serverlist.piaservers.net/vpninfo/servers/v6)                                                                                                          | `ca` (Montreal, Canada)                          |\n| `PIA_USER`                     | PIA username                                                                                                                                                                                           |                                                  |\n| `PIA_PASS`                     | PIA password                                                                                                                                                                                           |                                                  |\n| `PIA_LOCAL_NETWORK`            | PIA local network                                                                                                                                                                                      | `192.168.0.0/16`                                 |\n| `HOSTNAME`                     | Hostname of the NAS, could be a local IP or a domain name                                                                                                                                              | `localhost`                                      |\n| `ADGUARD_HOSTNAME`             | Optional - AdGuard Home hostname used, if enabled                                                                                                                                                      |                                                  |\n| `ADGUARD_USERNAME`             | Optional - AdGuard Home username to show details in the homepage, if enabled                                                                                                                           |                                                  |\n| `ADGUARD_PASSWORD`             | Optional - AdGuard Home password to show details in the homepage, if enabled                                                                                                                           |                                                  |\n| `QBITTORRENT_USERNAME`         | qBittorrent username to access the web UI                                                                                                                                                              | `admin`                                          |\n| `QBITTORRENT_PASSWORD`         | qBittorrent password to access the web UI                                                                                                                                                              | `adminadmin`                                     |\n| `DNS_CHALLENGE`                | Enable/Disable DNS01 challenge, set to `false` to disable.                                                                                                                                             | `true`                                           |\n| `DNS_CHALLENGE_PROVIDER`       | Provider for DNS01 challenge, [see list here](https://doc.traefik.io/traefik/https/acme/#providers).                                                                                                   | `cloudflare`                                     |\n| `LETS_ENCRYPT_CA_SERVER`       | Let's Encrypt CA Server used to generate certificates, set to production by default.\u003cbr/\u003eSet to `https://acme-staging-v02.api.letsencrypt.org/directory` to test your changes with the staging server. | `https://acme-v02.api.letsencrypt.org/directory` |\n| `LETS_ENCRYPT_EMAIL`           | E-mail address used to send expiration notifications                                                                                                                                                   |                                                  |\n| `CLOUDFLARE_EMAIL`             | CloudFlare Account email                                                                                                                                                                               |                                                  |\n| `CLOUDFLARE_DNS_API_TOKEN`     | API token with `DNS:Edit` permission                                                                                                                                                                   |                                                  |\n| `CLOUDFLARE_ZONE_API_TOKEN`    | API token with `Zone:Read` permission                                                                                                                                                                  |                                                  |\n| `SONARR_API_KEY`               | Sonarr API key to show information in the homepage                                                                                                                                                     |                                                  |\n| `RADARR_API_KEY`               | Radarr API key to show information in the homepage                                                                                                                                                     |                                                  |\n| `LIDARR_API_KEY`               | Lidarr API key to show information in the homepage                                                                                                                                                     |                                                  |\n| `PROWLARR_API_KEY`             | Prowlarr API key to show information in the homepage                                                                                                                                                   |                                                  |\n| `BAZARR_API_KEY`               | Bazarr API key to show information in the homepage                                                                                                                                                     |                                                  |\n| `JELLYFIN_API_KEY`             | Jellyfin API key to show information in the homepage                                                                                                                                                   |                                                  |\n| `JELLYSEERR_API_KEY`           | Jellyseer API key to show information in the homepage                                                                                                                                                  |                                                  |\n| `SABNZBD_API_KEY`              | Sabnzbd API key to show information in the homepage                                                                                                                                                    |                                                  |\n| `HOMEPAGE_VAR_TITLE`           | Title of the homepage                                                                                                                                                                                  | `Docker-Compose NAS`                             |\n| `HOMEPAGE_VAR_SEARCH_PROVIDER` | Homepage search provider, [see list here](https://gethomepage.dev/en/widgets/search/)                                                                                                                  | `google`                                         |\n| `HOMEPAGE_VAR_HEADER_STYLE`    | Homepage header style, [see list here](https://gethomepage.dev/en/configs/settings/#header-style)                                                                                                      | `boxed`                                          |\n| `HOMEPAGE_VAR_WEATHER_CITY`    | Homepage weather city name                                                                                                                                                                             |                                                  |\n| `HOMEPAGE_VAR_WEATHER_LAT`     | Homepage weather city latitude                                                                                                                                                                         |                                                  |\n| `HOMEPAGE_VAR_WEATHER_LONG`    | Homepage weather city longitude                                                                                                                                                                        |                                                  |\n| `HOMEPAGE_VAR_WEATHER_UNIT`    | Homepage weather unit, either `metric` or `imperial`                                                                                                                                                   | `metric`                                         |\n| `CALIBRE_USERNAME`             | Optional - Calibre-Web username to show details in the homepage, if enabled                                                                                                                            | `admin`                                          |\n| `CALIBRE_PASSWORD`             | Optional - Calibre-Web password to show details in the homepage, if enabled                                                                                                                            | `admin123`                                       |\n\n## PIA WireGuard VPN\n\nI chose PIA since it supports WireGuard and [port forwarding](https://github.com/thrnz/docker-wireguard-pia/issues/26#issuecomment-868165281),\nbut you could use other providers:\n\n- OpenVPN: [linuxserver/openvpn-as](https://hub.docker.com/r/linuxserver/openvpn-as)\n- WireGuard: [linuxserver/wireguard](https://hub.docker.com/r/linuxserver/wireguard)\n- NordVPN + OpenVPN: [bubuntux/nordvpn](https://hub.docker.com/r/bubuntux/nordvpn/dockerfile)\n- NordVPN + WireGuard (NordLynx): [bubuntux/nordlynx](https://hub.docker.com/r/bubuntux/nordlynx)\n\nFor PIA + WireGuard, fill `.env` and fill it with your PIA credentials.\n\nThe location of the server it will connect to is set by `LOC=ca`, defaulting to Montreal - Canada.\n\nYou need to fill the credentials in the `PIA_*` environment variable, \notherwise the VPN container will exit and qBittorrent will not start.\n\n## Sonarr, Radarr \u0026 Lidarr\n\n### File Structure\n\nSonarr, Radarr, and Lidarr must be configured to support hardlinks, to allow instant moves and prevent using twice the storage\n(Bittorrent downloads and final file). The trick is to use a single volume shared by the Bittorrent client and the *arrs.\nSubfolders are used to separate the TV shows from the movies.\n\nThe configuration is well explained by [this guide](https://trash-guides.info/Hardlinks/How-to-setup-for/Docker/).\n\nIn summary, the final structure of the shared volume will be as follows:\n\n```\ndata\n├── torrents = shared folder qBittorrent downloads\n│  ├── movies = movies downloads tagged by Radarr\n│  └── tv = movies downloads tagged by Sonarr\n└── media = shared folder for Sonarr and Radarr files\n   ├── movies = Radarr\n   └── tv = Sonarr\n   └── music = Lidarr\n```\n\nGo to Settings \u003e Management.\nIn Sonarr, set the Root folder to `/data/media/tv`.\nIn Radarr, set the Root folder to `/data/media/movies`.\nIn Lidarr, set the Root folder to `/data/media/music`.\n\n### Download Client\n\nThen qBittorrent can be configured at Settings \u003e Download Clients. Because all the networking for qBittorrent takes\nplace in the VPN container, the hostname for qBittorrent is the hostname of the VPN container, ie `vpn`, and the port is `8080`:\n\n## Prowlarr\n\nThe indexers are configured through Prowlarr. They synchronize automatically to Radarr and Sonarr.\n\nRadarr and Sonarr may then be added via Settings \u003e Apps. The Prowlarr server is `http://prowlarr:9696/prowlarr`, the Radarr server\nis `http://radarr:7878/radarr` Sonarr `http://sonarr:8989/sonarr`, and Lidarr `http://lidarr:8686/lidarr`.\n\nTheir API keys can be found in Settings \u003e Security \u003e API Key.\n\n## qBittorrent\n\nRunning `update-config.sh` will set qBittorrent's password to `adminadmin`. If you wish to update the password manually,\nsince qBittorrent v4.6.2, a temporary password is generated on startup. Get it with `docker compose logs qbittorrent`:\n```\nThe WebUI administrator username is: admin\nThe WebUI administrator password was not set. A temporary password is provided for this session: \u003csome_password\u003e\n```\n\nUse this password to access the UI, then go to Settings \u003e Web UI and set your own password, \nthen set it in `.env`'s `QBITTORRENT_PASSWORD` variable.\n\nThe login page can be disabled on for the local network in by enabling `Bypass authentication for clients`.\n\n```\n192.168.0.0/16\n127.0.0.0/8\n172.17.0.0/16\n```\n\nSet the default save path to `/data/torrents` in Settings, and restrict the network interface to WireGuard (`wg0`).\n\nTo 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).\n\n## Jellyfin\n\nTo enable [hardware transcoding](https://jellyfin.org/docs/general/administration/hardware-acceleration/),\ndepending on your system, you may need to add the following block:\n\n```    \ndevices:\n  - /dev/dri/renderD128:/dev/dri/renderD128\n  - /dev/dri/card0:/dev/dri/card0\n```\n\nGenerally, running Docker on Linux you will want to use VA-API, but the exact mount paths may differ depending on your\nhardware.\n\n## Homepage\n\nThe homepage comes with sensible defaults; some settings can ben controlled via environment variables in `.env`.\n\nIf you to customize further, you can modify the files in `/homepage/*.yaml` according to the [documentation](https://gethomepage.dev). \nDue to how the Docker socket is configured for the Docker integration, files must be edited as root.\n\nThe files in `/homepage/tpl/*.yaml` only serve as a base to set up the homepage configuration on first run.\n\n## Jellyseerr\n\nJellyseer gives you content recommendations, allows others to make requests to you, and allows logging in with Jellyfin credentials.\n\nTo set up, go to https://hostname/jellyseerr/setup, and set the URLs as follows:\n- Jellyfin: http://jellyfin:8096/jellyfin\n- Radarr:\n  - Hostname: radarr\n  - Port: 7878\n  - URL Base: /radarr\n- Sonarr\n  - Hostname: sonarr\n  - Port: 8989\n  - URL Base: /sonarr\n\n## Traefik and SSL Certificates\n\nWhile you can use the private IP to access your NAS, how cool would it be for it to be accessible through a subdomain\nwith a valid SSL certificate?\n\nTraefik makes this trivial by using Let's Encrypt and one of its\n[supported ACME challenge providers](https://doc.traefik.io/traefik/https/acme).\n\nLet's assume we are using `nas.domain.com` as custom subdomain.\n\nThe idea is to create an A record pointing to the private IP of the NAS, `192.168.0.10` for example:\n```\nnas.domain.com.\t1\tIN\tA\t192.168.0.10\n```\n\nThe record will be publicly exposed but not resolve given this is a private IP.\n\nGiven the NAS is not accessible from the internet, we need to do a dnsChallenge.\nHere we will be using CloudFlare, but the mechanism will be the same for all DNS providers\nbaring environment variable changes, see the Traefik documentation above and [Lego's documentation](https://go-acme.github.io/lego/dns).\n\nThen, fill the CloudFlare `.env` entries.\n\nIf you want to test your configuration first, use the Let's Encrypt staging server by updating `LETS_ENCRYPT_CA_SERVER`'s\nvalue in `.env`:\n```\nLETS_ENCRYPT_CA_SERVER=https://acme-staging-v02.api.letsencrypt.org/directory\n```\n\nIf it worked, you will see the staging certificate at https://nas.domain.com.\nYou may remove the `./letsencrypt/acme.json` file and restart the services to issue the real certificate.\n\nYou are free to use any DNS01 provider. Simply replace `DNS_CHALLENGE_PROVIDER` with your own provider, \n[see complete list here](https://doc.traefik.io/traefik/https/acme/#providers). \nYou will also need to inject the environments variables specific to your provider.\n\nCertificate generation can be disabled by setting `DNS_CHALLENGE` to `false`.\n\n### Accessing from the outside with Tailscale\n\nIf we want to make it reachable from outside the network without opening ports or exposing it to the internet, I found\n[Tailscale](https://tailscale.com) to be a great solution: create a network, run the client on both the NAS and the device\nyou are connecting from, and they will see each other.\n\nIn this case, the A record should point to the IP Tailscale assigned to the NAS, eg `100.xxx.xxx.xxx`:\n```\nnas.domain.com.\t1\tIN\tA\t100.xxx.xxx.xxx\n```\n\nSee [here](https://tailscale.com/kb/installation) for installation instructions.\n\nHowever, this means you will always need to be connected to Tailscale to access your NAS, even locally.\nThis can be remedied by overriding the DNS entry for the NAS domain like `192.168.0.10 nas.domain.com`\nin your local DNS resolver such as Pi-Hole.\n\nThis way, when connected to the local network, the NAS is accessible directly from the private IP,\nand from the outside you need to connect to Tailscale first, then the NAS domain will be accessible.\n\n## Optional Services\n\nOptional services are not launched by default and enabled by appending their profile name to the \n`COMPOSE_PROFILES` environment variable (see [Docker documentation](https://docs.docker.com/compose/profiles)).\n\nSay you want to enable FlareSolverr, you should have `COMPOSE_PROFILES=flaresolverr`.\n\nMultiple optional services can be enabled separated by commas: `COMPOSE_PROFILES=flaresolverr,adguardhome`.\n\n### FlareSolverr\n\nIn Prowlarr, add the FlareSolverr indexer with the URL http://flaresolverr:8191/\n\n### SABnzbd\n\nEnable SABnzbd by setting `COMPOSE_PROFILES=sabnzbd`. It will be accessible at `/sabnzbd`.\n\nIf that is not the case, the `url_base` parameter in `sabnzbd.ini` should be set to `/sabnzbd`.\n\nAdditionally, `host_whitelist` value should be set to your hostname.\n\n### AdGuard Home\n\nEnable AdGuard Home by setting `COMPOSE_PROFILES=adguardhome`.\n\nSet the `ADGUARD_HOSTNAME`, I chose a different subdomain to use secure DNS without the folder.\n\nOn first run, specify the port 3000 and enable listen on all interfaces to make it work with Tailscale.\n\nIf after running `docker compose up -d`, you're getting `network docker-compose-nas declared as external, but could not be found`,\nrun `docker network create docker-compose-nas` first.\n\n#### Encryption\n\nIn Settings \u003e Encryption Settings, set the certificates path to `/opt/adguardhome/certs/certs/\u003cYOUR_HOSTNAME\u003e.crt`\nand the private key to `/opt/adguardhome/certs/private/\u003cYOUR_HOSTNAME\u003e.key`, those files are created by Traefik cert dumper\nfrom the ACME certificates Traefik generates in JSON.\n\n#### DHCP\n\nIf you want to use the AdGuard Home DHCP server, for example because your router does not allow changing its DNS server,\nyou will need to select the `eth0` DHCP interface matching `10.0.0.10`, then specify the \nGateway IP to match your router address (`192.168.0.1` for example) and set a range of IP addresses assigned to local\ndevices.\n\nIn `adguardhome/docker-compose.yml`, set the network interface `dhcp-relay` should listen to. By default, it is set to\n`enp2s0`, but you may need to change it to your host's network interface, verify it with `ip a`.\n\nIn the configuration (`adguardhome/conf/AdGuardHome.yaml`), set the DHCP options 6th key to your NAS internal IP address:\n```yml\ndhcp:\n  dhcpv4:\n    options:\n      - 6 ips 192.168.0.10,192.168.0.10\n```\n\nEnable DHCP Relay by setting `COMPOSE_PROFILES=adguardhome-dhcp`.\n\n#### Expose DNS Server with Tailscale\n\nBased on [Tailscale's documentation](https://tailscale.com/kb/1114/pi-hole), it is easy to use your AdGuard server everywhere.\nJust make sure that AdGuard Home listens to all interfaces.\n\n### Calibre-Web\n\nIf you do not have a Calibre database, download a sample from: https://github.com/janeczku/calibre-web/raw/master/library/metadata.db\nand place it in `${DATA_ROOT}/books`.\n\nOn the initial setup screen, enter `/books` as your calibre library location.\n\n**Default admin login:** Username: `admin` Password: `admin123`.\n\nUnrar is included by default and needs to be set in the Calibre-Web admin page (Basic Configuration:External Binaries)\nwith a path of `/usr/bin/unrar`.\n\n### Decluttarr\nDecluttarr keeps the queue free of stalled and redundant downloads. For configuration options and examples, \nplease see https://github.com/ManiMatter/decluttarr/blob/dev/README.md.\n\nAll environment variables are prefixed with `DECLUTTARR_`. \n\n### Tandoor\n\nSee [here](./tandoor/README.md).\n\n### Joplin\n\nSee [here](./joplin/README.md).\n\n### Home Assistant\n\nSee [here](./homeassistant/README.md).\n\n### Immich\n\nSee [here](./immich/README.md).\n\n## Customization\n\nYou can override the configuration of a service or add new services by creating a new `docker-compose.override.yml` file,\nthen appending it to the `COMPOSE_FILE` environment variable: `COMPOSE_FILE=docker-compose.yml:docker-compose.override.yml`\n\n[See official documentation](https://docs.docker.com/compose/extends).\n\nFor example, use a [different VPN provider](https://github.com/bubuntux/nordvpn):\n\n```yml\nservices:\n  vpn:\n    image: ghcr.io/bubuntux/nordvpn\n    cap_add:\n      - NET_ADMIN               # Required\n      - NET_RAW                 # Required\n    environment:                # Review https://github.com/bubuntux/nordvpn#environment-variables\n      - USER=user@email.com     # Required\n      - \"PASS=pas$word\"         # Required\n      - CONNECT=United_States\n      - TECHNOLOGY=NordLynx\n      - NETWORK=192.168.1.0/24  # So it can be accessed within the local network\n```\n\n### Optional: Using the VPN for *arr apps\n\nIf you want to use the VPN for Prowlarr and other *arr applications, add the following block to all the desired containers:\n```yml\n    network_mode: \"service:vpn\"\n    depends_on:\n      vpn:\n        condition: service_healthy\n```\n\nChange the healthcheck to mark the containers as unhealthy when internet connection is not working by appending a URL\nto the healthcheck, eg: `test: [ \"CMD\", \"curl\", \"--fail\", \"http://127.0.0.1:7878/radarr/ping\", \"https://google.com\" ]`\n\nThen in Prowlarr, use `localhost` rather than `vpn` as the hostname, since they are on the same network.\n\n## Synology Quirks\n\nDocker compose NAS can run on DSM 7.1, with a few extra steps.\n\n### Free Ports 80 and 443\n\nBy default, ports 80 and 443 are used by Nginx but not actually used for anything useful. Free them by creating a new task\nin the Task Scheduler \u003e Create \u003e Triggered Task \u003e User-defined script. Leave the Event as `Boot-up` and the `root` user,\ngo to Task Settings and paste the following in User-defined script:\n```\nsed -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\n\nsynosystemctl restart nginx\n```\n\n### Install Synology WireGuard\n\nSince WireGuard is not part of DSM's kernel, an external package must be installed for the `vpn` container to run.\n\nFor DSM 7.1, download and install the package corresponding to your NAS CPU architecture \n[from here](https://github.com/vegardit/synology-wireguard/releases).\n\nAs specified in the [project's README](https://github.com/vegardit/synology-wireguard#installation), \nthe package must be run as `root` from the command line: `sudo /var/packages/WireGuard/scripts/start`\n\n### Free Port 1900\n\nJellyfin will fail to run by default since the port 1900 \n[is not free](https://lookanotherblog.com/resolve-port-1900-conflict-between-plex-and-synology/). \nYou may free it by going to  Control Panel \u003e File Services \u003e Advanced \u003e SSTP \u003e Untick `Enable Windows network discovery`.\n\n### User Permissions\n\nBy default, the user and groups are set to `1000` as it is the default on Ubuntu and many other Linux distributions.\nHowever, that is not the case in Synology; the first user should have an ID of `1026` and a group of `100`. \nYou may check yours with `id`. \nUpdate the `USER_ID` and `GROUP_ID` in `.env` with your IDs.\nNot updating them may result in [permission issues](https://github.com/AdrienPoupa/docker-compose-nas/issues/10).\n\n```\nUSER_ID=1026\nGROUP_ID=100\n```\n\n### Synology DHCP Server and Adguard Home Port Conflict\n\nIf you are using the Synology DHCP Server package, it will use port 53 even if it does not need it. This is because\nit uses Dnsmasq to handle DHCP requests, but does not serve DNS queries. The port can be released by editing (as root) \n`/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\u0026utm_medium=web2x\u0026context=3):\n`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`\nReboot the NAS and the port 53 will be free for Adguard.\n\n## Use Separate Paths for Torrents and Storage\n\nIf you want to use separate paths for torrents download and long term storage, to use different disks for example,\nset your `docker-compose.override.yml` to:\n\n```yml\nservices:\n  sonarr:\n    volumes:\n      - ./sonarr:/config\n      - ${DATA_ROOT}/media/tv:/data/media/tv\n      - ${DOWNLOAD_ROOT}/tv:/data/torrents/tv\n  radarr:\n    volumes:\n      - ./radarr:/config\n      - ${DATA_ROOT}/media/movies:/data/media/movies\n      - ${DOWNLOAD_ROOT}/movies:/data/torrents/movies\n```\n\nNote you will lose the hard link ability, ie your files will be duplicated.\n\nIn Sonarr and Radarr, go to `Settings` \u003e `Importing` \u003e Untick `Use Hardlinks instead of Copy`\n\n## NFS Share\n\nThis can be useful to share the media folder to a local player like Kodi or computers in the local network,\nbut may not be necessary if Jellyfin is going to be used to access the media.\n\nInstall the NFS kernel server: `sudo apt install nfs-kernel-server`\n\nThen edit `/etc/exports` to configure your shares:\n\n`/mnt/data/media 192.168.0.0/255.255.255.0(rw,all_squash,nohide,no_subtree_check,anonuid=1000,anongid=1000)`\n\nThis will share the `media` folder to anybody on your local network (192.168.0.x).\nI purposely left out the `sync` flag that would slow down file transfer.\nOn [some devices](https://forum.kodi.tv/showthread.php?tid=343434) you may need to use the `insecure`\noption for the share to be available.\n\nRestart the NFS server to apply the changes: `sudo /etc/init.d/nfs-kernel-server restart`\n\nOn other machines, you can see the shared folder by adding the following to your `/etc/fstab`:\n\n`192.168.0.10:/mnt/data/media /mnt/nas nfs ro,hard,intr,auto,_netdev 0 0`\n\n## Static IP\n\nSet a static IP, assuming `192.168.0.10` and using Google DNS servers: `sudo nano /etc/netplan/00-installer-config.yaml`\n\n```yaml\n# This is the network config written by 'subiquity'\nnetwork:\n  ethernets:\n    enp2s0:\n      dhcp4: no\n      addresses:\n        - 192.168.0.10/24\n      gateway4: 192.168.0.1\n      nameservers:\n          addresses: [8.8.8.8, 8.8.4.4]\n  version: 2\n```\n\nApply the plan: `sudo netplan apply`. You can check the server uses the right IP with `ip a`.\n\n## Laptop Specific Configuration\n\nIf the server is installed on a laptop, you may want to disable the suspension when the lid is closed:\n`sudo nano /etc/systemd/logind.conf`\n\nReplace:\n- `#HandleLidSwitch=suspend` by `HandleLidSwitch=ignore`\n- `#LidSwitchIgnoreInhibited=yes` by `LidSwitchIgnoreInhibited=no`\n\nThen restart: `sudo service systemd-logind restart`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAdrienPoupa%2Fdocker-compose-nas","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAdrienPoupa%2Fdocker-compose-nas","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAdrienPoupa%2Fdocker-compose-nas/lists"}