docker-compose-nas/README.md
aki 64dcce36f0
Some checks failed
/ validate-docker-compose (push) Has been cancelled
docs(README): Refactor and simplify documentation
- 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.
2025-04-25 10:51:59 +08:00

284 lines
16 KiB
Markdown

<!-- # Docker Compose NAS
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.
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
This stack includes:
* **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).
## Prerequisites
* **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
1. **Clone the Repository:**
```bash
git clone https://github.com/AdrienPoupa/docker-compose-nas.git
cd docker-compose-nas
```
2. **Create Configuration File:**
Copy the example environment file:
```bash
cp .env.example .env
```
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`.
4. **Start the Stack:**
Run Docker Compose (use `sudo` if your user isn't in the `docker` group):
```bash
docker compose up -d
```
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`)*
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 `/`.
## Configuration (`.env` File)
This file controls all the essential settings for your Docker Compose stack. Copy `.env.example` to `.env` and edit the values.
---
### **Core Settings (Required)**
These are fundamental for basic operation and permissions.
* `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`
---
### **Host Paths (Required)**
Define where container data and configuration are stored on your host machine.
* `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.
---
### **Tailscale Access (Required)**
Controls secure remote access via Tailscale.
* `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`
---
### **Homepage Widgets (Optional)**
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).
* `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)
---
### **Homepage Customization (Optional)**
Control the appearance and behavior of the Homepage dashboard.
* `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.
---
### **Download Client Settings**
Credentials for included download clients.
* `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.
---
### **VPN Configuration (Example: PIA - Optional)**
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.**
* `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`
---
### **Traefik DNS Challenge (Optional)**
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
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).
Example: Enable Lidarr and SABnzbd
```dotenv
COMPOSE_PROFILES=lidarr,sabnzbd
```
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`).
## Troubleshooting
### SELinux Socket Permissions (Docker)
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`:
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`).
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
# 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.
### Tailscale Issues
* **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.
### File Permissions
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.
## Advanced Topics
*(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.)*
*(Example: Synology section should focus on Docker package setup, port conflicts, user IDs, etc., relevant to DSM.)*
*(Example: Remove Podman-specific commands or troubleshooting steps from these sections.)*
---
*Self-hosted media stack powered by Docker, Traefik, Tailscale, and the \*arr suite.* -->