docker-compose-nas

AdrienPoupa活跃维护

用一份 Docker Compose 配置快速搭起家用 NAS 媒体栈,集成 Sonarr、Radarr、Jellyfin、qBittorrent,并通过 PIA VPN 和 Traefik 自动 HTTPS 保障下载与访问安全。

Simple Docker Compose NAS featuring Sonarr, Radarr, Prowlarr, Jellyfin, qBittorrent, PIA VPN and Traefik with SSL support

暂无版本2,159star261fork同步于 2026-11-10 17:47 UTC

怎么上手

由 README 提炼,执行前请确认
cp .env.example .env
docker compose up -d
./update-config.sh
硬件要求按 README 说明

README 未说明具体硬件要求,仅要求任意支持 Docker 的较新 Linux 机器并安装 Docker Engine 与 Docker Compose V2;作者在 Ubuntu Server 22.04 上运行,也在 Synology DS220+(DSM 7.1)上测试过。

有 Docker 镜像
下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

一套开箱即用的 Docker Compose 家庭 NAS 配置,集成媒体下载、管理与播放全流程

用一份 Docker Compose 配置快速搭起家用 NAS 媒体栈,集成 Sonarr、Radarr、Jellyfin、qBittorrent,并通过 PIA VPN 和 Traefik 自动 HTTPS 保障下载与访问安全。

核心能力

  • 用 PIA WireGuard 封装 qBittorrent 流量并支持端口转发
  • 集成 Sonarr、Radarr、Prowlarr 实现索引与媒体自动获取
  • 用 Traefik 反向代理并支持 SSL 证书
  • 通过 Tailscale 实现远程访问
  • 提供 FlareSolverr、AdGuard Home、Immich 等可选服务 profile

容易踩的坑

首次使用需运行 ./update-config.sh 更新各应用 base URL 并在 .env 中设置 API key;qBittorrent 需 PIA 账号密码(PIA_USER/PIA_PASS)才能走 VPN;可选服务需通过 COMPOSE_PROFILES 显式启用;Synology 上需先释放 80/443/1900 端口并单独安装 WireGuard。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

0 个版本

暂无 release 数据(可能没有发版,或尚未同步)。

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    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.

    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.

    Docker-Compose NAS Homepage

    Table of Contents

    Applications

    ApplicationDescriptionImageURL
    SonarrPVR for newsgroup and bittorrent userslinuxserver/sonarr/sonarr
    RadarrMovie collection manager for Usenet and BitTorrent userslinuxserver/radarr/radarr
    BazarrCompanion application to Sonarr and Radarr that manages and downloads subtitleslinuxserver/bazarr/bazarr
    ProwlarrIndexer aggregator for Sonarr and Radarrlinuxserver/prowlarr:latest/prowlarr
    PIA WireGuard VPNEncapsulate qBittorrent traffic in PIA using WireGuard with port forwarding.thrnz/docker-wireguard-pia
    qBittorrentBittorrent client with a complete web UIUses VPN networkUsing Libtorrent 1.xlinuxserver/qbittorrent:libtorrentv1/qbittorrent
    UnpackerrAutomated Archive Extractionsgolift/unpackerr
    JellyfinMedia server designed to organize, manage, and share digital media files to networked deviceslinuxserver/jellyfin/jellyfin
    JellyseerManages requests for your media librarydocker pull ghcr.io/seerr-team/seerr:sha-04b9d87$SEERR_HOSTNAME
    HomepageApplication dashboardgethomepage/homepage/
    TraefikReverse proxytraefik
    WatchtowerAutomated Docker images updatenicholas-fedor/watchtower
    AutohealMonitor and restart unhealthy Docker containerswillfarrell/autoheal
    LidarrOptional - Music collection manager for Usenet and BitTorrent usersEnable with COMPOSE_PROFILES=lidarrlinuxserver/lidarr/lidarr
    SABnzbdOptional - Free and easy binary newsreaderEnable with COMPOSE_PROFILES=sabnzbdlinuxserver/sabnzbd/sabnzbd
    FlareSolverrOptional - Proxy server to bypass Cloudflare protection in ProwlarrEnable with COMPOSE_PROFILES=flaresolverrflaresolverr/flaresolverr
    AdGuard HomeOptional - Network-wide software for blocking ads & trackingEnable with COMPOSE_PROFILES=adguardhomeadguard/adguardhome
    TandoorOptional - Smart recipe managementEnable with COMPOSE_PROFILES=tandoorvabene1111/recipes/recipes
    JoplinOptional - Note taking applicationEnable with COMPOSE_PROFILES=joplinjoplin/server/joplin
    Home AssistantOptional - Open source home automation that puts local control and privacy firstEnable with COMPOSE_PROFILES=homeassistanthome-assistant/home-assistant:stable
    ImmichOptional - Self-hosted photo and video management solutionEnable with COMPOSE_PROFILES=immichimmich-app/immich-server:release
    Calibre-WebOptional - Web app for browsing, reading and downloading eBooks stored in a Calibre databaseEnable with COMPOSE_PROFILES=calibre-weblinuxserver/calibre-web/calibre
    VaultwardenOptional - Password managerEnable with COMPOSE_PROFILES=vaultwardendani-garcia/vaultwarden/vaultwarden
    CleanuparrOptional - Cleanuparr is a tool for automating the cleanup of unwanted or blocked files in Sonarr and RadarrEnable with COMPOSE_PROFILES=cleanuparrcleanuparr/cleanuparr/cleanuparr
    Cross-SeedOptional - Cross-Seed is a tool for automating the cross-seeding of torrentsEnable with COMPOSE_PROFILES=cross-seedcross-seed/cross-seed
    AutobrrOptional - Autobrr is a tool for automating the downloading of torrentsEnable with COMPOSE_PROFILES=autobrrautobrr/autobrr/autobrr
    SuggestarrOptional - SuggestArr is a project designed to automate media content recommendations and download requestsEnable with COMPOSE_PROFILES=suggestarrciuse99/suggestarr/suggestarr
    Paperless NgxOptional - Document management system for organizing and searching your documentsEnable with COMPOSE_PROFILES=paperlesspaperless-ngx/paperless-ngx/paperless

    Optional containers are not enabled by default, they need to be enabled, see Optional Services for more information.

    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.

    Environment Variables

    VariableDescriptionDefault
    COMPOSE_FILEDocker compose files to load
    COMPOSE_PROFILESDocker compose profiles to load (flaresolverr, adguardhome, sabnzbd)
    USER_IDID of the user to use in Docker containers1000
    GROUP_IDID of the user group to use in Docker containers1000
    TIMEZONETimeZone used by the container.America/New_York
    CONFIG_ROOTHost location for configuration files.
    DATA_ROOTHost location of the data files/mnt/data
    DOWNLOAD_ROOTHost download location for qBittorrent, should be a subfolder of DATA_ROOT/mnt/data/torrents
    PIA_LOCATIONServers to use for PIA. see list hereca (Montreal, Canada)
    PIA_USERPIA username
    PIA_PASSPIA password
    PIA_LOCAL_NETWORKPIA local network192.168.0.0/16
    HOSTNAMEHostname of the NAS, could be a local IP or a domain namelocalhost
    BASE_HOSTNAMEBase hostname of the NAS, useful if hostname is a subdomainlocalhost
    ADGUARD_HOSTNAMEOptional - AdGuard Home hostname used, if enabled
    ADGUARD_USERNAMEOptional - AdGuard Home username to show details in the homepage, if enabled
    ADGUARD_PASSWORDOptional - AdGuard Home password to show details in the homepage, if enabled
    QBITTORRENT_USERNAMEqBittorrent username to access the web UIadmin
    QBITTORRENT_PASSWORDqBittorrent password to access the web UIadminadmin
    DNS_CHALLENGEEnable/Disable DNS01 challenge, set to false to disable.true
    DNS_CHALLENGE_PROVIDERProvider for DNS01 challenge, see list here.cloudflare
    LETS_ENCRYPT_CA_SERVERLet's Encrypt CA Server used to generate certificates, set to production by default.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_EMAILE-mail address used to send expiration notifications
    CLOUDFLARE_EMAILCloudFlare Account email
    CLOUDFLARE_DNS_API_TOKENAPI token with DNS:Edit permission
    CLOUDFLARE_ZONE_API_TOKENAPI token with Zone:Read permission
    SONARR_API_KEYSonarr API key to show information in the homepage
    RADARR_API_KEYRadarr API key to show information in the homepage
    LIDARR_API_KEYLidarr API key to show information in the homepage
    PROWLARR_API_KEYProwlarr API key to show information in the homepage
    BAZARR_API_KEYBazarr API key to show information in the homepage
    JELLYFIN_API_KEYJellyfin API key to show information in the homepage
    SEERR_API_KEYSeer API key to show information in the homepage
    SABNZBD_API_KEYSabnzbd API key to show information in the homepage
    AUTOBRR_API_KEYAutobrr API key to show information in the homepage
    HOMEPAGE_VAR_TITLETitle of the homepageDocker-Compose NAS
    HOMEPAGE_VAR_SEARCH_PROVIDERHomepage search provider, see list heregoogle
    HOMEPAGE_VAR_HEADER_STYLEHomepage header style, see list hereboxed
    HOMEPAGE_VAR_WEATHER_CITYHomepage weather city name
    HOMEPAGE_VAR_WEATHER_LATHomepage weather city latitude
    HOMEPAGE_VAR_WEATHER_LONGHomepage weather city longitude
    HOMEPAGE_VAR_WEATHER_UNITHomepage weather unit, either metric or imperialmetric
    CALIBRE_USERNAMEOptional - Calibre-Web username to show details in the homepage, if enabledadmin
    CALIBRE_PASSWORDOptional - Calibre-Web password to show details in the homepage, if enabledadmin123
    SEERR_HOSTNAMESeerr hostname used

    PIA WireGuard VPN

    I chose PIA since it supports WireGuard and port forwarding, but you could use other providers:

    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.

    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
    

    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.

    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:

    The WebUI administrator username is: admin
    The WebUI administrator password was not set. A temporary password is provided for this session: <some_password>
    

    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.

    The login page can be disabled on for the local network in by enabling Bypass authentication for clients.

    192.168.0.0/16
    127.0.0.0/8
    172.17.0.0/16
    

    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).

    Jellyfin

    To enable hardware transcoding, depending on your system, you may need to add the following block:

    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.

    Homepage

    The homepage comes with sensible defaults; some settings can ben controlled via environment variables in .env.

    If you to customize further, you can modify the files in /homepage/*.yaml according to the documentation. 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.

    Seerr

    Jellyseer gives you content recommendations, allows others to make requests to you, and allows logging in with Jellyfin credentials.

    Set the SEERR_HOSTNAME, since it does not support running in a subfolder. Add the necessary DNS records in your domain.

    To set up, go to the Seerr hostname, 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

    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?

    Traefik makes this trivial by using Let's Encrypt and one of its supported ACME challenge providers.

    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
    

    The record will be publicly exposed but not resolve given this is a private IP.

    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.

    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
    

    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.

    You are free to use any DNS01 provider. Simply replace DNS_CHALLENGE_PROVIDER with your own provider, see complete list here. You will also need to inject the environments variables specific to your provider.

    Certificate generation can be disabled by setting DNS_CHALLENGE to false.

    Accessing from the outside with Tailscale

    If we want to make it reachable from outside the network without opening ports or exposing it to the internet, I found Tailscale to be a great solution: create a network, run the client on both the NAS and the device you are connecting from, and they will see each other.

    In this case, the A record should point to the IP Tailscale assigned to the NAS, eg 100.xxx.xxx.xxx:

    nas.domain.com.	1	IN	A	100.xxx.xxx.xxx
    

    See here for installation instructions.

    However, this means you will always need to be connected to Tailscale to access your NAS, even locally. This can be remedied by overriding the DNS entry for the NAS domain like 192.168.0.10 nas.domain.com in your local DNS resolver such as Pi-Hole.

    This way, when connected to the local network, the NAS is accessible directly from the private IP, and from the outside you need to connect to Tailscale first, then the NAS domain will be accessible.

    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).

    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/

    Cross-Seed

    Enable Cross-Seed by setting COMPOSE_PROFILES=cross-seed.

    Generate the configuration file with docker compose run -v ./cross-seed:/config cross-seed gen-config.

    Modify the configuration file as follows:

    module.exports = {
      ...
      torznab: [
        "http://prowlarr:9696/prowlarr/1/api?apikey=<api_key>",
        ...
      ],
      sonarr: ["http://sonarr:8989/sonarr?apikey=<api_key>"],
      radarr: ["http://radarr:7878/radarr?apikey=<api_key>"],
      torrentClients: ["qbittorrent:http://admin:adminadmin@vpn:8080"],
      linkDirs: ["/data/torrents"],
      ...
    }
    

    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:

    dhcp:
      dhcpv4:
        options:
          - 6 ips 192.168.0.10,192.168.0.10
    

    Enable DHCP Relay by setting COMPOSE_PROFILES=adguardhome-dhcp.

    Expose DNS Server with Tailscale

    Based on Tailscale's documentation, it is easy to use your AdGuard server everywhere. Just make sure that AdGuard Home listens to all interfaces.

    Calibre-Web

    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.

    Joplin

    See here.

    Home Assistant

    See here.

    Immich

    See here.

    Vaultwarden

    See here.

    Paperless Ngx

    See here.

    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.

    For example, use a different VPN provider:

    services:
      vpn:
        image: ghcr.io/bubuntux/nordvpn
        cap_add:
          - NET_ADMIN # Required
          - NET_RAW # Required
        environment: # Review https://github.com/bubuntux/nordvpn#environment-variables
          - [email protected] # 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
    

    Optional: Using the VPN for *arr apps

    If you want to use the VPN for Prowlarr and other *arr applications, add the following block to all the desired containers:

    network_mode: "service:vpn"
    depends_on:
      vpn:
        condition: service_healthy
    

    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" ]

    Then in Prowlarr, use localhost rather than vpn as the hostname, since they are on the same network.

    Synology Quirks

    Docker compose NAS can run on DSM 7.1, with a few extra steps.

    Free Ports 80 and 443

    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
    
    synosystemctl restart nginx
    

    Install Synology WireGuard

    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.

    As specified in the project's README, 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. 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.

    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: 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:

    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.
    To setup permissions for the DATA_ROOT folder:

    source .env
    sudo chown -R $USER:$USER $DATA_ROOT
    sudo chmod -R a=,a+rX,u+w,g+w $DATA_ROOT
    

    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 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

    # 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