- Add detailed setup instructions - Clarify configuration variables - Update sections on architecture, features, prerequisites, and troubleshooting to reflect recent changes.
545 lines
38 KiB
Markdown
545 lines
38 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.
|
||
|
||
## Table of Contents
|
||
|
||
- [Docker Compose NAS](#docker-compose-nas)
|
||
- [Table of Contents](#table-of-contents)
|
||
- [Architecture Overview](#architecture-overview)
|
||
- [Features](#features)
|
||
- [Prerequisites](#prerequisites)
|
||
- [Required Setup Steps](#required-setup-steps)
|
||
- [Quick Start Guide](#quick-start-guide)
|
||
- [Configuration (`.env` Variables)](#configuration-env-variables)
|
||
- [Core System \& Paths](#core-system--paths)
|
||
- [Networking \& Access (Tailscale)](#networking--access-tailscale)
|
||
- [Authentication (Authelia)](#authentication-authelia)
|
||
- [Service Credentials](#service-credentials)
|
||
- [Homepage Customization \& Widgets](#homepage-customization--widgets)
|
||
- [Optional Features \& Services](#optional-features--services)
|
||
- [Detailed Setup \& Usage](#detailed-setup--usage)
|
||
- [Authelia User Management](#authelia-user-management)
|
||
- [(Optional) VPN Configuration](#optional-vpn-configuration)
|
||
- [(Optional) Traefik DNS Challenge](#optional-traefik-dns-challenge)
|
||
- [Service Access](#service-access)
|
||
- [Setup Script Commands (`update-setup.sh`)](#setup-script-commands-update-setupsh)
|
||
- [Managing Service Authentication](#managing-service-authentication-authelia-policies)
|
||
- [Optional Services](#optional-services)
|
||
- [Troubleshooting](#troubleshooting)
|
||
- [Middleware Not Found Errors](#middleware-not-found-errors)
|
||
- [SELinux Socket Permissions (Docker)](#selinux-socket-permissions-docker)
|
||
- [Authelia v4.38+ Configuration](#authelia-v438-configuration)
|
||
- [Tailscale Issues](#tailscale-issues)
|
||
- [File Permissions](#file-permissions)
|
||
- [Advanced Topics](#advanced-topics)
|
||
|
||
## Architecture Overview
|
||
|
||
This stack uses a combination of key services for routing, access, and security:
|
||
|
||
- **[Tailscale](https://tailscale.com):** Provides a secure overlay network (WireGuard-based VPN) connecting your devices. It allows access to the NAS services from anywhere without opening firewall ports and handles HTTPS termination via its built-in `tailscale serve` or `tailscale funnel` features. All other services run within Tailscale's network namespace.
|
||
- **[Traefik](https://traefik.io):** Acts as a reverse proxy *within* the Tailscale network. It discovers services via Docker labels and routes incoming requests (from Tailscale) to the appropriate container based on paths (e.g., `/sonarr`, `/radarr`).
|
||
- **[Authelia](https://www.authelia.com):** Serves as the authentication gateway. Traefik forwards requests to Authelia for verification. If a user isn't logged in, they are redirected to the Authelia portal (`/`). Once authenticated, Authelia sets a session cookie (stored in Redis), and Traefik allows access to the requested service. You can configure which services require authentication via environment variables.
|
||
|
||
## Features
|
||
|
||
This stack includes the following services, categorized for clarity:
|
||
|
||
**Core Infrastructure:**
|
||
|
||
- **Reverse Proxy:** [Traefik](https://traefik.io) - Manages internal routing and service discovery.
|
||
- **Secure Remote Access:** [Tailscale](https://tailscale.com) - Provides VPN access and HTTPS.
|
||
- **Authentication:** [Authelia](https://www.authelia.com) & [Redis](https://redis.io) - Single sign-on portal and session management.
|
||
- **Dashboard:** [Homepage](https://gethomepage.dev) - Centralized access point (at `/home`).
|
||
|
||
**Media Management (\*Arr Suite):**
|
||
|
||
- [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.
|
||
- [Prowlarr](https://github.com/Prowlarr/Prowlarr): Indexer management for *arr apps.
|
||
|
||
**Download Clients:**
|
||
|
||
- [qBittorrent](https://www.qbittorrent.org): Bittorrent client.
|
||
- [SABnzbd](https://sabnzbd.org/) (Optional): Usenet download client.
|
||
|
||
**Media Serving & Requests:**
|
||
|
||
- [Jellyfin](https://jellyfin.org): Media server for streaming.
|
||
- [Jellyseerr](https://github.com/FallenBagel/jellyseerr): Media request management.
|
||
|
||
**Utilities:**
|
||
|
||
- [Watchtower](https://containrrr.dev/watchtower/): Automatic container updates.
|
||
- [Autoheal](https://github.com/willfarrell/docker-autoheal/): Automatic container restarts on failure.
|
||
- [Unpackerr](https://unpackerr.zip): Automated archive extraction.
|
||
|
||
**Optional Services (Enabled via Profiles):**
|
||
|
||
- [AdGuard Home](https://adguard.com/en/adguard-home/overview.html): Network-wide ad blocking.
|
||
- [Calibre-Web](https://github.com/janeczku/calibre-web): E-book library management.
|
||
- [Decluttarr](https://github.com/manimatter/decluttarr): Automated download cleanup.
|
||
- [Tandoor Recipes](https://docs.tandoor.dev/): Recipe management.
|
||
- [Joplin Server](https://joplinapp.org/): Note-taking synchronization server.
|
||
- [Home Assistant](https://www.home-assistant.io/): Home automation platform.
|
||
- [Immich](https://immich.app/): Self-hosted photo and video backup.
|
||
- [FlareSolverr](https://github.com/FlareSolverr/FlareSolverr): Bypasses Cloudflare challenges (e.g., for Prowlarr).
|
||
|
||
## Prerequisites
|
||
|
||
- **Linux Host:** A system capable of running Docker (e.g., Ubuntu, Debian, Fedora).
|
||
- **Docker & Docker Compose:** Latest versions installed. See [Docker Engine Install](https://docs.docker.com/engine/install/) and [Docker Compose Install](https://docs.docker.com/compose/install/).
|
||
- **User Permissions:** Ability to run `docker` commands (user in `docker` group or use `sudo`).
|
||
- **Basic Linux Knowledge:** Familiarity with command line, text editors, and file permissions.
|
||
- **Tailscale Account:** Required for remote access. [Sign up here](https://tailscale.com/login).
|
||
- **(Optional) SELinux:** If enabled, see [Troubleshooting](#selinux-socket-permissions-docker).
|
||
|
||
## Required Setup Steps
|
||
|
||
These steps are **mandatory** for a working installation. Without properly completing these, the stack will not function correctly.
|
||
|
||
1. **⚠️ Required: System User Information**
|
||
- Set `USER_ID` and `GROUP_ID` in `.env` (run `id -u` and `id -g` to get yours)
|
||
- Incorrect values will cause permission errors with mounted volumes
|
||
|
||
2. **⚠️ Required: Directory Paths**
|
||
- Set `CONFIG_ROOT` (where service configurations will be stored)
|
||
- Set `DATA_ROOT` (where your media libraries will be stored)
|
||
- Set `DOWNLOAD_ROOT` (must be on same filesystem as DATA_ROOT for hardlinks)
|
||
|
||
3. **⚠️ Required: Tailscale Configuration**
|
||
- Create a Tailscale account at [tailscale.com](https://tailscale.com)
|
||
- Generate an Auth Key in the [Tailscale Admin Console](https://login.tailscale.com/admin/settings/keys)
|
||
- Set `TAILSCALE_AUTHKEY` in `.env`
|
||
- Set `TAILSCALE_TAILNET_DOMAIN` to your Tailnet domain (e.g., `your-name.ts.net`)
|
||
|
||
4. **⚠️ Required: Security Credentials**
|
||
- Generate four strong random secrets using `openssl rand -hex 32`:
|
||
|
||
```bash
|
||
echo "AUTHELIA_JWT_SECRET=$(openssl rand -hex 32)"
|
||
echo "AUTHELIA_SESSION_SECRET=$(openssl rand -hex 32)"
|
||
echo "AUTHELIA_STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)"
|
||
echo "AUTHELIA_REDIS_PASSWORD=$(openssl rand -hex 32)"
|
||
```
|
||
|
||
- Add these to your `.env` file as shown
|
||
|
||
5. **⚠️ Required: Create Authelia Account**
|
||
- Create an Authelia account (only for yourself and those you trust!)
|
||
|
||
```bash
|
||
docker run --rm authelia/authelia:latest authelia hash-password 'your_secure_password'
|
||
```
|
||
|
||
6. **ℹ️ Optional: Set up**
|
||
- Generate a password hash for Authelia:
|
||
|
||
```bash
|
||
docker run --rm authelia/authelia:latest authelia hash-password 'your_secure_password'
|
||
```
|
||
|
||
- Replace the example hash in `authelia/users_database.yml` with your generated hash
|
||
|
||
## Quick Start Guide
|
||
|
||
After completing all [Required Setup Steps](#required-setup-steps) above, follow these steps to get up and running:
|
||
|
||
1. **Clone Repository:**
|
||
|
||
```bash
|
||
git clone https://github.com/AdrienPoupa/docker-compose-nas.git
|
||
cd docker-compose-nas
|
||
```
|
||
|
||
2. **Configure Environment:**
|
||
|
||
```bash
|
||
# Create an .env file from the example
|
||
cp .env.example .env
|
||
|
||
# Edit the .env file and fill in ALL required values
|
||
nano .env
|
||
```
|
||
|
||
3. **Configure Authelia Admin:**
|
||
|
||
```bash
|
||
# Generate a password hash
|
||
docker run --rm authelia/authelia:latest authelia hash-password 'your_secure_password'
|
||
|
||
# Edit the users_database.yml with the generated hash
|
||
nano authelia/users_database.yml
|
||
```
|
||
|
||
4. **Run the Setup Script:**
|
||
|
||
```bash
|
||
# Make the script executable
|
||
chmod +x ./update-setup.sh
|
||
|
||
# Run the setup tool (use 'all' for initial setup)
|
||
./update-setup.sh all
|
||
```
|
||
|
||
This script will:
|
||
- Update your `.env` file while preserving existing values (`update-env`).
|
||
- Configure Authelia with your Tailscale domain settings (`update-authelia`).
|
||
- Set up service configurations and retrieve API keys (`update-services`).
|
||
|
||
You can also run individual commands like `./update-setup.sh update-authelia`. Run `./update-setup.sh help` for all options.
|
||
|
||
5. **Start the Stack:**
|
||
|
||
```bash
|
||
# Start containers
|
||
docker compose up -d
|
||
```
|
||
|
||
*(Wait for containers to download and start)*
|
||
|
||
6. **Access Your NAS:**
|
||
- Open `https://<TAILSCALE_HOSTNAME>.<TAILSCALE_TAILNET_DOMAIN>/`
|
||
- Log in with username `admin` and the password you set
|
||
- After login, you'll land on the Homepage dashboard at `/home`
|
||
|
||
> ⚠️ **IMPORTANT:** If the stack fails to start, check the [Troubleshooting](#troubleshooting) section and verify you've properly completed all [Required Setup Steps](#required-setup-steps).
|
||
|
||
## Configuration (`.env` Variables)
|
||
|
||
This file controls essential settings. Copy `.env.example` to `.env` and modify the values. **Bold variables** are critical for initial setup.
|
||
|
||
#### Core System & Paths
|
||
|
||
| Variable | Description | Default |
|
||
| :----------------------- | :---------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------- |
|
||
| **`USER_ID`** | Linux user ID for container permissions. Find with `id -u`. | `1000` |
|
||
| **`GROUP_ID`** | Linux group ID for container permissions. Find with `id -g`. | `1000` |
|
||
| **`TIMEZONE`** | Your local timezone (e.g., `America/New_York`, `Asia/Manila`). [List](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). | `America/New_York` |
|
||
| `CONFIG_ROOT` | Host base directory for service configurations. `.` = project subdirs. | `.` |
|
||
| `DATA_ROOT` | Host directory for media libraries (movies, TV, music, etc.). | `/mnt/data` |
|
||
| `DOWNLOAD_ROOT` | Host directory for downloads (in progress/completed). **Must be on same filesystem as `DATA_ROOT` for hardlinks.** | `/mnt/data/torrents` |
|
||
| `IMMICH_UPLOAD_LOCATION` | Host path for Immich uploads (if `immich` profile enabled). | `/mnt/data/photos` |
|
||
|
||
#### Networking & Access (Tailscale)
|
||
|
||
| Variable | Description | Default |
|
||
| :-------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------- |
|
||
| **`TAILSCALE_AUTHKEY`** | **Required.** Auth key from [Tailscale Admin Console](https://login.tailscale.com/admin/settings/keys). Use reusable or ephemeral. | *(None)* |
|
||
| **`TAILSCALE_TAILNET_DOMAIN`**| **Required.** Your unique Tailnet domain (e.g., `your-name.ts.net`). | `your-tailnet.ts.net` |
|
||
| `TAILSCALE_HOSTNAME` | Desired hostname for this NAS within Tailscale. | `tailscale-nas` |
|
||
| `TAILSCALE_TAGS` | Optional tags for the Tailscale node (e.g., `tag:nas`). | `tag:nas` |
|
||
| `ENABLE_FUNNEL_HTTPS` | Use Tailscale Funnel (`true` = public access via Tailscale domain) or Serve (`false` = Tailnet-only access, recommended). | `false` |
|
||
| `APP_HOSTNAME` | Primary hostname used by Traefik/Authelia. Defaults to Tailscale FQDN. Renamed from `HOSTNAME` to avoid host system conflicts. Can be overridden if using custom DNS. | `${TAILSCALE_HOSTNAME}.${TAILSCALE_TAILNET_DOMAIN}` |
|
||
|
||
#### Authentication (Authelia)
|
||
|
||
| Variable | Description | Default |
|
||
| :---------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------- |
|
||
| **`AUTHELIA_JWT_SECRET`** | **Required.** Random secret for Authelia (used for password reset JWT). **Generate your own!** | *(None - Example in file)* |
|
||
| **`AUTHELIA_SESSION_SECRET`** | **Required.** Random secret for session cookies. **Generate your own!** | *(None - Example in file)* |
|
||
| **`AUTHELIA_STORAGE_ENCRYPTION_KEY`** | **Required.** Random secret for encrypting data at rest (e.g., SQLite DB). **Generate your own!** | *(None - Example in file)* |
|
||
| **`AUTHELIA_REDIS_PASSWORD`** | **Required.** Password for the Redis database (used for session storage). **Generate your own!** | *(None - Example in file)* |
|
||
|
||
#### Service Credentials
|
||
|
||
| Variable | Description | Default |
|
||
| :----------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------- |
|
||
| `QBITTORRENT_USERNAME` | Username for qBittorrent Web UI. | `admin` |
|
||
| `QBITTORRENT_PASSWORD` | Password for qBittorrent Web UI. **Change default!** (May need to use temp password from logs on first run, then change in UI & `.env`). | `adminadmin` |
|
||
| `CALIBRE_USERNAME` | Username for Calibre-Web (if `calibre-web` profile enabled). | `admin` |
|
||
| `CALIBRE_PASSWORD` | Password for Calibre-Web (if `calibre-web` profile enabled). | `admin123` |
|
||
| `IMMICH_DB_PASSWORD` | Password for Immich's internal database (if `immich` profile enabled). | `postgres` |
|
||
| `ADGUARD_USERNAME` | Username for AdGuard Home (if `adguardhome` profile enabled). | *(None)* |
|
||
| `ADGUARD_PASSWORD` | Password for AdGuard Home (if `adguardhome` profile enabled). | *(None)* |
|
||
|
||
#### Homepage Customization & Widgets
|
||
|
||
| Variable | Description | Default |
|
||
| :------------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------- |
|
||
| `HOMEPAGE_VAR_TITLE` | Title shown on the dashboard. | `Docker-Compose NAS` |
|
||
| `HOMEPAGE_VAR_SEARCH_PROVIDER` | Default search engine. [Options](https://gethomepage.dev/en/widgets/search/). | `google` |
|
||
| `HOMEPAGE_VAR_HEADER_STYLE` | Dashboard header style. [Options](https://gethomepage.dev/en/configs/settings/#header-style). | `boxed` |
|
||
| `HOMEPAGE_VAR_WEATHER_CITY` | City for weather widget. | *(None)* |
|
||
| `HOMEPAGE_VAR_WEATHER_LAT` | Latitude for weather widget. | *(None)* |
|
||
| `HOMEPAGE_VAR_WEATHER_LONG` | Longitude for weather widget. | *(None)* |
|
||
| `HOMEPAGE_VAR_WEATHER_UNIT` | Weather units (`metric` or `imperial`). | `metric` |
|
||
| `SONARR_API_KEY` | API Keys for various services, primarily used for Homepage widgets. Find keys in each app's settings. | *(None)* |
|
||
| `RADARR_API_KEY` | " | *(None)* |
|
||
| `LIDARR_API_KEY` | " (if `lidarr` profile enabled) | *(None)* |
|
||
| `BAZARR_API_KEY` | " | *(None)* |
|
||
| `PROWLARR_API_KEY` | " | *(None)* |
|
||
| `JELLYFIN_API_KEY` | " | *(None)* |
|
||
| `JELLYSEERR_API_KEY` | " | *(None)* |
|
||
| `SABNZBD_API_KEY` | " (if `sabnzbd` profile enabled) | *(None)* |
|
||
| `IMMICH_API_KEY` | " (if `immich` profile enabled) | *(None)* |
|
||
| `HOMEASSISTANT_ACCESS_TOKEN` | " (if `homeassistant` profile enabled) | *(None)* |
|
||
|
||
#### Optional Features & Services
|
||
|
||
| Variable | Description | Default |
|
||
| :---------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------- |
|
||
| `COMPOSE_PROFILES` | Comma-separated list of optional service profiles to enable (e.g., `lidarr,sabnzbd`). See [Optional Services](#optional-services). | *(None)* |
|
||
| `COMPOSE_PATH_SEPARATOR` | Path separator for `COMPOSE_FILE` (use `;` for Windows). | `:` |
|
||
| `COMPOSE_FILE` | Colon-separated list of compose files to use. Allows extending base config. | `docker-compose.yml:...` (See `.env.example`) |
|
||
| `DECLUTTARR_TEST_RUN` | Run Decluttarr in test mode (`True`/`False`)? (if `decluttarr` profile enabled). | `True` |
|
||
| `DECLUTTARR_...` | Other Decluttarr settings (see `.env.example`). | *(Varies)* |
|
||
| `PIA_USER` / `PIA_PASS` | Credentials for PIA VPN (if using default VPN setup for qBittorrent). | *(None)* |
|
||
| `PIA_LOCATION` | PIA server location (if using default VPN). [List](https://serverlist.piaservers.net/vpninfo/servers/v6). | `ca` |
|
||
| `PIA_LOCAL_NETWORK` | Your local network CIDR (e.g., `192.168.1.0/24`) to allow local access to VPN'd containers. | `192.168.0.0/16` |
|
||
| `DNS_CHALLENGE` | Enable Traefik DNS challenge for Let's Encrypt (`true`/`false`). **Not needed if using Tailscale for HTTPS.** | `true` |
|
||
| `DNS_CHALLENGE_PROVIDER` | Your DNS provider (e.g., `cloudflare`). [Providers](https://doc.traefik.io/traefik/https/acme/#providers). | `cloudflare` |
|
||
| `LETS_ENCRYPT_EMAIL` | Email for Let's Encrypt (if using DNS challenge). | *(None)* |
|
||
| `LETS_ENCRYPT_CA_SERVER` | Let's Encrypt server URL (if using DNS challenge). | `https://acme-v02.api.letsencrypt.org/directory` |
|
||
| `CLOUDFLARE_...` / `PROVIDER_...` | DNS provider API credentials (if using DNS challenge). | *(None)* |
|
||
| `HOMEASSISTANT_HOSTNAME` | Specific hostname for Home Assistant (if `homeassistant` profile enabled). | *(None)* |
|
||
| `IMMICH_HOSTNAME` | Specific hostname for Immich (if `immich` profile enabled). | *(None)* |
|
||
| `ADGUARD_HOSTNAME` | Specific hostname for AdGuard Home (if `adguardhome` profile enabled). | *(None)* |
|
||
|
||
## Detailed Setup & Usage
|
||
|
||
### Authelia User Management
|
||
|
||
Authelia uses the `authelia/users_database.yml` file to manage users.
|
||
|
||
- **Setting the Initial Admin Password:**
|
||
1. As mentioned in the Quick Start, you **must** set a strong password for the default `admin` user.
|
||
2. Generate a hash using Docker (replace `'your_secure_password'`):
|
||
|
||
```bash
|
||
docker run --rm authelia/authelia:latest authelia hash-password 'your_secure_password'
|
||
```
|
||
|
||
3. Copy the **entire output hash** (starting with `$argon2id...`).
|
||
4. Open `authelia/users_database.yml` and replace the example `password:` value under `admin:` with your generated hash.
|
||
5. Ensure the `admin` user belongs to the `admins` and `users` groups as shown in the example.
|
||
|
||
- **Adding More Users:**
|
||
1. Generate a password hash for the new user as shown above.
|
||
2. Edit `authelia/users_database.yml`.
|
||
3. Add a new entry under `users:`, following the format of the `admin` user:
|
||
|
||
```yaml
|
||
users:
|
||
admin:
|
||
# ... (admin details) ...
|
||
newuser:
|
||
displayname: "New User Name"
|
||
password: "paste_generated_hash_here"
|
||
email: newuser@example.com
|
||
groups:
|
||
- users # Add to 'admins' group if needed
|
||
```
|
||
|
||
4. Save the file and restart Authelia: `docker compose restart authelia`.
|
||
|
||
- **Adding/Updating Users (Recommended Method):**
|
||
Use the setup script's interactive tool:
|
||
|
||
```bash
|
||
./update-setup.sh manage-accounts
|
||
```
|
||
|
||
This script handles password hashing and file formatting, reducing the chance of errors. It will prompt you for the username, display name, email, and groups, then generate a secure password hash.
|
||
|
||
- **Enabling User Registration (Optional):**
|
||
1. Edit `authelia/configuration.yml`.
|
||
2. Find the commented-out `registration:` section near the bottom.
|
||
3. Uncomment it and set `enable: true`.
|
||
4. Save the file and restart Authelia (`docker compose restart authelia`).
|
||
5. A "Register" link will now appear on the Authelia login page.
|
||
|
||
- **Approving Registered Users:**
|
||
1. When a user registers (if enabled), their details are added to `authelia/users_database.yml` but marked as `disabled: true`.
|
||
2. To approve them, edit `authelia/users_database.yml`.
|
||
3. Find the new user's entry.
|
||
4. Change `disabled: true` to `disabled: false` (or simply remove the `disabled: true` line).
|
||
5. Save the file. The user should now be able to log in.
|
||
|
||
### (Optional) VPN Configuration
|
||
|
||
*(Details about configuring the PIA VPN or other VPN setups could go here if needed.)*
|
||
|
||
### (Optional) Traefik DNS Challenge
|
||
|
||
*(Details about setting up DNS provider credentials for Let's Encrypt could go here if needed.)*
|
||
|
||
## Service Access
|
||
|
||
With the default Tailscale setup and Authelia enabled, services are securely accessible via HTTPS using your Tailscale node's name or IP. Authentication is controlled by the included `update-setup.sh` script.
|
||
|
||
- **Login Portal:** `https://<TAILSCALE_NODE>/` (Redirects unauthenticated users here for secured services)
|
||
- **Homepage Dashboard:** `https://<TAILSCALE_NODE>/home` (Requires login by default)
|
||
- **Sonarr:** `https://<TAILSCALE_NODE>/sonarr` (Requires login by default)
|
||
- **Radarr:** `https://<TAILSCALE_NODE>/radarr` (Requires login by default)
|
||
- **qBittorrent:** `https://<TAILSCALE_NODE>/qbittorrent` (Requires login by default)
|
||
- **Jellyfin:** `https://<TAILSCALE_NODE>/jellyfin` (Requires login by default)
|
||
- ...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 `APP_HOSTNAME` variable to point to the Tailscale IP, you can use `https://<APP_HOSTNAME>/<service_path>`.
|
||
|
||
### Setup Script Commands (`update-setup.sh`)
|
||
|
||
The `update-setup.sh` script provides various commands to manage your configuration. Run `./update-setup.sh help` to see all options.
|
||
|
||
**Core Setup & Updates:**
|
||
|
||
- `./update-setup.sh update-env`: Updates `.env` from `.env.example`, preserving existing values and highlighting new/deprecated keys.
|
||
- `./update-setup.sh update-authelia`: Updates `authelia/configuration.yml` from the example, applying domain settings from `.env` and attempting to preserve secrets (uses `yq` if available).
|
||
- `./update-setup.sh update-services`: Updates configurations for running *arr/qBittorrent/Bazarr containers (sets URL base, extracts API keys to `.env`). Restarts affected containers.
|
||
- `./update-setup.sh all`: Runs `update-env`, `update-authelia`, and `update-services` sequentially. Recommended for initial setup and major updates.
|
||
|
||
**Authelia Policy Management:**
|
||
|
||
- `./update-setup.sh manage-policies`: Starts an interactive menu to list or set Authelia access policies (`one_factor`, `two_factor`, `bypass`, `deny`) for specific services defined in `authelia/configuration.yml`.
|
||
- `./update-setup.sh list-policies`: Lists services defined in `authelia/configuration.yml` and their current access policy.
|
||
- `./update-setup.sh set-policy <service> <policy>`: Directly sets the Authelia access policy for the specified `<service>` to the given `<policy>` (e.g., `one_factor`, `two_factor`, `bypass`, `deny`).
|
||
|
||
> **Important:** After changing Authelia policies using `manage-policies` or `set-policy`, you **must** restart Authelia for the changes to take effect:
|
||
>
|
||
> ```bash
|
||
> docker compose restart authelia
|
||
> ```
|
||
|
||
**User & File Management:**
|
||
|
||
- `./update-setup.sh manage-accounts`: Starts an interactive tool to add or update users in `authelia/users_database.yml`. It generates password hashes and prompts for user details.
|
||
- `./update-setup.sh cleanup`: Interactively finds and deletes old backup files (`.bak`) created by the script. Allows keeping the most recent backup of each type.
|
||
|
||
**Help:**
|
||
|
||
- `./update-setup.sh help`: Displays the full list of commands and usage instructions.
|
||
|
||
### Managing Service Authentication (Authelia Policies)
|
||
|
||
Use the `update-setup.sh` script to easily control which services require Authelia login and what level of authentication is needed. This is done by managing *access control rules* within Authelia's configuration (`authelia/configuration.yml`).
|
||
|
||
See the `Authelia Policy Management` commands in the [Setup Script Commands](#setup-script-commands-update-setupsh) section above for details on how to list and set policies like `one_factor`, `two_factor`, `bypass`, or `deny` for each service.
|
||
|
||
## 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
|
||
|
||
### Middleware Not Found Errors
|
||
|
||
If you see error messages like `middleware "authelia-auth@docker" does not exist` in the Traefik logs, please check Authelia logs for any fatal errors. It is likely due to a misconfigured `configuration.yml` in `authelia/configuration.yml`
|
||
|
||
Make sure Traefik can access the Docker socket. See the [SELinux Socket Permissions](#selinux-socket-permissions-docker) section below for more details.
|
||
|
||
### 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.
|
||
|
||
### Authelia v4.38+ Configuration
|
||
|
||
Authelia v4.38+ introduces significant changes to its configuration structure, particularly for session domains and authentication flows. The setup in this repository has been carefully configured to work with these changes:
|
||
|
||
1. **Domain Configuration**:
|
||
- You must use your specific Tailnet domain (e.g., `example.ts.net`) for cookies, not just `ts.net`
|
||
- The domain `ts.net` is part of the [Public Suffix List](https://publicsuffix.org/), which means browsers restrict cookies on it for security reasons
|
||
- Authelia will refuse to start if you try to use a domain from this list
|
||
|
||
2. **Required Secret Variables**: You must set these four variables in your `.env` file:
|
||
- `AUTHELIA_JWT_SECRET`: Used for password reset tokens
|
||
- `AUTHELIA_SESSION_SECRET`: Used for session cookie encryption
|
||
- `AUTHELIA_STORAGE_ENCRYPTION_KEY`: Used for database encryption
|
||
- `AUTHELIA_REDIS_PASSWORD`: Used for Redis authentication
|
||
|
||
Generate strong random values for these with: `openssl rand -hex 32`
|
||
|
||
3. **Automatic Domain Setup**: The `update-setup.sh` script automatically:
|
||
- Uses your specific Tailnet domain (e.g., `example.ts.net`) from your `.env` file
|
||
- Configures cookie domains properly to avoid Public Suffix List issues
|
||
- Sets up proper access control rules for both your domain and its subdomains
|
||
|
||
If you encounter any of these common errors:
|
||
|
||
```log
|
||
error: option 'domain' is not a valid cookie domain: the domain is part of the special public suffix list
|
||
error: option 'authelia_url' does not share a cookie scope with domain
|
||
error: can't be specified at the same time: option 'domain' and option 'cookies'
|
||
configuration key 'jwt_secret' is deprecated in 4.38.0
|
||
```
|
||
|
||
Running the setup script should resolve them. After making changes to the configuration, restart Authelia with:
|
||
|
||
```bash
|
||
docker compose restart authelia
|
||
```
|
||
|
||
See the [Authelia documentation](https://www.authelia.com/configuration/session/introduction/) for more details on the v4.38+ configuration structure.
|
||
|
||
### 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.*
|