3 Commits

Author SHA1 Message Date
aki
cf78372b71 feat: Refactor Tailscale & Traefik Integration
Some checks failed
/ validate-docker-compose (push) Has been cancelled
- Integrate Traefik directly with Tailscale network using `network_mode: service:tailscale`.
- Remove direct port mappings for Traefik (80, 443).
- Configure Tailscale container to use `tailscale serve` (Tailnet only) or `tailscale funnel` (public HTTPS) based on `ENABLE_FUNNEL_HTTPS` env var.
- Update Traefik routing rules (`Host()`) to use `${TAILSCALE_HOSTNAME}.${TAILSCALE_TAILNET_DOMAIN}` for all services.
- Update Homepage path to `/home` and adjust its Traefik rule.
- Remove Homepage basic authentication variables (`HOMEPAGE_AUTH_USER`, `HOMEPAGE_AUTH_HASH`) from `.env.example` and `README.md`.
- Update `README.md` to reflect new access methods, hostname configuration, and removal of basic auth.
- Add `extra_hosts` to Tailscale service for `host.docker.internal`.
2025-04-25 14:15:44 +08:00
aki
8c5cdb111d fix(env): Update Tailscale settings and add homepage configuration options
Some checks failed
/ validate-docker-compose (push) Has been cancelled
2025-04-25 13:08:06 +08:00
aki
42ee02d8e7 fix(homepage): Update allowed hosts and add basic auth middleware configuration 2025-04-25 13:07:53 +08:00
3 changed files with 105 additions and 37 deletions

View File

@@ -1,20 +1,82 @@
# --- Docker Compose Settings ---
# Comma-separated list of optional service profiles to enable (e.g., lidarr,sabnzbd,adguardhome)
COMPOSE_PROFILES= COMPOSE_PROFILES=
# Path separator for COMPOSE_FILE (use ';' for Windows)
COMPOSE_PATH_SEPARATOR=: COMPOSE_PATH_SEPARATOR=:
# Colon-separated list of compose files to use. Allows extending the base configuration.
COMPOSE_FILE=docker-compose.yml:adguardhome/docker-compose.yml:tandoor/docker-compose.yml:joplin/docker-compose.yml:homeassistant/docker-compose.yml:immich/docker-compose.yml COMPOSE_FILE=docker-compose.yml:adguardhome/docker-compose.yml:tandoor/docker-compose.yml:joplin/docker-compose.yml:homeassistant/docker-compose.yml:immich/docker-compose.yml
# --- Core System Settings ---
# Linux User ID. Find yours with `id -u`. Crucial for file permissions.
USER_ID=1000 USER_ID=1000
# Linux Group ID. Find yours with `id -g`. Crucial for file permissions.
GROUP_ID=1000 GROUP_ID=1000
# Your local timezone (e.g., America/New_York, Europe/London, Asia/Manila). See: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
TIMEZONE="America/New_York" TIMEZONE="America/New_York"
# --- Host Paths ---
# Base directory on host for storing service configuration files. '.' stores them in subdirectories within the project folder.
CONFIG_ROOT="." CONFIG_ROOT="."
# Main directory on host containing media libraries (movies, TV, music, books).
DATA_ROOT="/mnt/data" DATA_ROOT="/mnt/data"
# Directory on host for download clients (qBittorrent/SABnzbd). Should be on the same filesystem as DATA_ROOT for hardlinks.
DOWNLOAD_ROOT="/mnt/data/torrents" DOWNLOAD_ROOT="/mnt/data/torrents"
# Upload location for Immich (if profile enabled)
IMMICH_UPLOAD_LOCATION="/mnt/data/photos" IMMICH_UPLOAD_LOCATION="/mnt/data/photos"
HOMEASSISTANT_HOSTNAME=
IMMICH_HOSTNAME= # --- Tailscale Settings ---
ADGUARD_HOSTNAME= # Required. Auth key from Tailscale Admin Console (Settings > Keys). Use a reusable or ephemeral key.
ADGUARD_USERNAME= TAILSCALE_AUTHKEY=
ADGUARD_PASSWORD= # Desired hostname for this NAS within your Tailscale network.
TAILSCALE_HOSTNAME=tailscale-nas
# Required. Your Tailnet domain (e.g., your-tailnet-name.ts.net).
TAILSCALE_TAILNET_DOMAIN=your-tailnet.ts.net
# Optional tags to apply to the Tailscale node (e.g., tag:nas).
TAILSCALE_TAGS=tag:nas
# Enable Tailscale Funnel (public access) for HTTPS? Set to 'true' or 'false'. 'false' uses Serve (Tailnet only, recommended).
ENABLE_FUNNEL_HTTPS=false
# --- Primary Hostname ---
# Primary hostname used by Traefik for routing. Derived from Tailscale settings by default.
HOSTNAME=${TAILSCALE_HOSTNAME}.${TAILSCALE_TAILNET_DOMAIN}
# --- Application Credentials ---
# qBittorrent Web UI Credentials (change default!)
QBITTORRENT_USERNAME=admin QBITTORRENT_USERNAME=admin
QBITTORRENT_PASSWORD=adminadmin QBITTORRENT_PASSWORD=adminadmin
# Calibre-Web Credentials (if profile enabled)
CALIBRE_USERNAME=admin
CALIBRE_PASSWORD=admin123
# Immich Database Password (if profile enabled)
IMMICH_DB_PASSWORD=postgres
# --- Homepage Settings ---
HOMEPAGE_VAR_TITLE="Docker-Compose NAS"
HOMEPAGE_VAR_SEARCH_PROVIDER=google
HOMEPAGE_VAR_HEADER_STYLE=boxed
# Weather Widget (Optional)
HOMEPAGE_VAR_WEATHER_CITY=
HOMEPAGE_VAR_WEATHER_LAT=
HOMEPAGE_VAR_WEATHER_LONG=
HOMEPAGE_VAR_WEATHER_UNIT=metric
# --- Authelia Settings ---
# Generate strong random secrets for these using tools like `openssl rand -hex 32`
AUTHELIA_JWT_SECRET= # Example: your_strong_jwt_secret
AUTHELIA_SESSION_SECRET= # Example: your_strong_session_secret
AUTHELIA_STORAGE_ENCRYPTION_KEY= # Example: your_strong_storage_encryption_key
AUTHELIA_REDIS_PASSWORD= # Example: your_strong_redis_password
# Google OIDC Provider Settings (Get from Google Cloud Console - https://console.cloud.google.com/apis/credentials)
AUTHELIA_GOOGLE_OIDC_CLIENT_ID= # Example: your-google-client-id.apps.googleusercontent.com
AUTHELIA_GOOGLE_OIDC_CLIENT_SECRET= # Example: GOCSPX-your-google-client-secret
# Authelia Session Configuration
AUTHELIA_SESSION_DOMAIN=${TAILSCALE_HOSTNAME}.${TAILSCALE_TAILNET_DOMAIN}
AUTHELIA_DEFAULT_REDIRECT_URL=https://${TAILSCALE_HOSTNAME}.${TAILSCALE_TAILNET_DOMAIN}/home
# --- API Keys & Integration Tokens (Optional - Mainly for Homepage Widgets) ---
# Find API keys within each application's settings (usually Settings > General or Security)
SONARR_API_KEY= SONARR_API_KEY=
RADARR_API_KEY= RADARR_API_KEY=
LIDARR_API_KEY= LIDARR_API_KEY=
@@ -25,16 +87,12 @@ JELLYSEERR_API_KEY=
SABNZBD_API_KEY= SABNZBD_API_KEY=
IMMICH_API_KEY= IMMICH_API_KEY=
HOMEASSISTANT_ACCESS_TOKEN= HOMEASSISTANT_ACCESS_TOKEN=
HOMEPAGE_VAR_TITLE="Docker-Compose NAS" # AdGuard Home Credentials (if profile enabled)
HOMEPAGE_VAR_SEARCH_PROVIDER=google ADGUARD_USERNAME=
HOMEPAGE_VAR_HEADER_STYLE=boxed ADGUARD_PASSWORD=
HOMEPAGE_VAR_WEATHER_CITY=
HOMEPAGE_VAR_WEATHER_LAT= # --- Optional Service Settings ---
HOMEPAGE_VAR_WEATHER_LONG= # Decluttarr Settings (if profile enabled)
HOMEPAGE_VAR_WEATHER_UNIT=metric
IMMICH_DB_PASSWORD=postgres
CALIBRE_USERNAME=admin
CALIBRE_PASSWORD=admin123
DECLUTTARR_TEST_RUN=True DECLUTTARR_TEST_RUN=True
DECLUTTARR_REMOVE_TIMER=60 DECLUTTARR_REMOVE_TIMER=60
DECLUTTARR_REMOVE_FAILED=True DECLUTTARR_REMOVE_FAILED=True
@@ -43,12 +101,8 @@ DECLUTTARR_REMOVE_METADATA_MISSING=True
DECLUTTARR_REMOVE_MISSING_FILES=True DECLUTTARR_REMOVE_MISSING_FILES=True
DECLUTTARR_REMOVE_ORPHANS=True DECLUTTARR_REMOVE_ORPHANS=True
# --- Tailscale Settings --- # --- Other Hostnames (Optional Services) ---
TAILSCALE_AUTHKEY= # Set these if you need specific hostnames for these services (e.g., for Home Assistant integrations)
TAILSCALE_HOSTNAME=tailscale-nas HOMEASSISTANT_HOSTNAME=
TAILSCALE_TAILNET_DOMAIN=your-tailnet.ts.net IMMICH_HOSTNAME=
TAILSCALE_TAGS=tag:nas ADGUARD_HOSTNAME=
# Enable Tailscale Funnel (public access) for HTTPS? Set to 'true' or 'false'.
ENABLE_FUNNEL_HTTPS=false
HOSTNAME=${TAILSCALE_HOSTNAME}.${TAILSCALE_TAILNET_DOMAIN}

View File

@@ -86,7 +86,7 @@ These are fundamental for basic operation and permissions.
* **Note:** Using the correct IDs is crucial for file permissions, especially for accessing media files on the host. * **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). * `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` * *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., `tailscale-nas.your-tailnet.ts.net`). * `HOSTNAME`: **(Deprecated - Now derived)** The primary hostname used by Traefik for routing. This is now automatically constructed from `TAILSCALE_HOSTNAME` and `TAILSCALE_TAILNET_DOMAIN`. You generally don't need to set this directly unless overriding the default behavior.
* *Default:* `${TAILSCALE_HOSTNAME}.${TAILSCALE_TAILNET_DOMAIN}` * *Default:* `${TAILSCALE_HOSTNAME}.${TAILSCALE_TAILNET_DOMAIN}`
--- ---
@@ -203,18 +203,29 @@ These settings are for enabling automatic HTTPS certificate generation via Let's
## Service Access ## 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: With the default Tailscale setup, services are securely accessible via HTTPS using your Tailscale node's name or IP, followed by the service path. Replace `<TAILSCALE_NODE>` with your Tailscale device name (e.g., `tailscale-nas.your-tailnet.ts.net`) or its Tailscale IP address.
* **Homepage:** `https://<TAILSCALE_NODE>/` * **Homepage:** `https://<TAILSCALE_NODE>/home`
* **Sonarr:** `https://<TAILSCALE_NODE>/sonarr` * **Sonarr:** `https://<TAILSCALE_NODE>/sonarr`
* **Radarr:** `https://<TAILSCALE_NODE>/radarr` * **Radarr:** `https://<TAILSCALE_NODE>/radarr`
* **Lidarr:** `https://<TAILSCALE_NODE>/lidarr` (If profile enabled)
* **Bazarr:** `https://<TAILSCALE_NODE>/bazarr`
* **Jellyseerr:** `https://<TAILSCALE_NODE>/jellyseerr`
* **Prowlarr:** `https://<TAILSCALE_NODE>/prowlarr`
* **qBittorrent:** `https://<TAILSCALE_NODE>/qbittorrent` * **qBittorrent:** `https://<TAILSCALE_NODE>/qbittorrent`
* **SABnzbd:** `https://<TAILSCALE_NODE>/sabnzbd` (If profile enabled)
* **Jellyfin:** `https://<TAILSCALE_NODE>/jellyfin` * **Jellyfin:** `https://<TAILSCALE_NODE>/jellyfin`
* ...and so on. * **Calibre-Web:** `https://<TAILSCALE_NODE>/calibre` (If profile enabled)
* **AdGuard Home:** `http://<TAILSCALE_NODE_IP>:3000` (If profile enabled, access via IP/port initially)
* **Tandoor Recipes:** `https://<TAILSCALE_NODE>/recipes` (If profile enabled)
* **Joplin Server:** `https://<TAILSCALE_NODE>/joplin` (If profile enabled)
* **Home Assistant:** `http://<TAILSCALE_NODE_IP>:8123` (If profile enabled, access via IP/port initially)
* **Immich:** `http://<TAILSCALE_NODE_IP>:2283` (If profile enabled, access via IP/port initially)
Replace `<TAILSCALE_NODE>` with your Tailscale device name (e.g., `tailscale-nas.your-tailnet.ts.net`) or its Tailscale IP address. **Note:**
* `<TAILSCALE_NODE>` refers to the full Tailscale name (e.g., `tailscale-nas.your-tailnet.ts.net`).
If you configure DNS for your `HOSTNAME` variable to point to the Tailscale IP, you can use `https://<HOSTNAME>/<service_path>`. * `<TAILSCALE_NODE_IP>` refers to the Tailscale IP address of the NAS.
* Some services (AdGuard, HA, Immich) might require initial setup via their direct IP and port before Tailscale/Traefik routing is fully effective or configured within the application. Authentication for most services will be handled by Authelia (configured later).
## Optional Services ## Optional Services

View File

@@ -131,7 +131,7 @@ services:
retries: 10 retries: 10
labels: labels:
- traefik.enable=true - traefik.enable=true
- traefik.http.routers.bazarr.rule=PathPrefix(`/bazarr`) - traefik.http.routers.bazarr.rule=Host(`${TAILSCALE_HOSTNAME}.${TAILSCALE_TAILNET_DOMAIN}`) && PathPrefix(`/bazarr`)
- traefik.http.routers.bazarr.entrypoints=web - traefik.http.routers.bazarr.entrypoints=web
- traefik.http.services.bazarr.loadbalancer.server.port=6767 - traefik.http.services.bazarr.loadbalancer.server.port=6767
- homepage.group=Download - homepage.group=Download
@@ -289,7 +289,7 @@ services:
retries: 10 retries: 10
labels: labels:
- traefik.enable=true - traefik.enable=true
- traefik.http.routers.qbittorrent.rule=PathPrefix(`/qbittorrent`) - traefik.http.routers.qbittorrent.rule=Host(`${TAILSCALE_HOSTNAME}.${TAILSCALE_TAILNET_DOMAIN}`) && PathPrefix(`/qbittorrent`)
- traefik.http.routers.qbittorrent.entrypoints=web - traefik.http.routers.qbittorrent.entrypoints=web
- traefik.http.services.qbittorrent.loadbalancer.server.port=8080 - traefik.http.services.qbittorrent.loadbalancer.server.port=8080
- traefik.http.routers.qbittorrent.middlewares=qbittorrent-strip-slash,qbittorrent-stripprefix - traefik.http.routers.qbittorrent.middlewares=qbittorrent-strip-slash,qbittorrent-stripprefix
@@ -359,7 +359,7 @@ services:
- PUID=${USER_ID} - PUID=${USER_ID}
- PGID=${GROUP_ID} - PGID=${GROUP_ID}
- TZ=${TIMEZONE} - TZ=${TIMEZONE}
- JELLYFIN_PublishedServerUrl=${HOSTNAME}/jellyfin - JELLYFIN_PublishedServerUrl=${TAILSCALE_HOSTNAME}.${TAILSCALE_TAILNET_DOMAIN}/jellyfin
volumes: volumes:
- ${CONFIG_ROOT:-.}/jellyfin:/config:Z - ${CONFIG_ROOT:-.}/jellyfin:/config:Z
- ${DATA_ROOT}:/data:Z - ${DATA_ROOT}:/data:Z
@@ -404,7 +404,7 @@ services:
- traefik.http.middlewares.calibre-headers.headers.customRequestHeaders.X-Script-Name=/calibre - traefik.http.middlewares.calibre-headers.headers.customRequestHeaders.X-Script-Name=/calibre
- traefik.http.middlewares.calibre-stripprefixregex.stripPrefixRegex.regex=/calibre - traefik.http.middlewares.calibre-stripprefixregex.stripPrefixRegex.regex=/calibre
- traefik.http.routers.calibre.middlewares=calibre-headers,calibre-stripprefixregex - traefik.http.routers.calibre.middlewares=calibre-headers,calibre-stripprefixregex
- traefik.http.routers.calibre.rule=PathPrefix(`/calibre`) - traefik.http.routers.calibre.rule=Host(`${TAILSCALE_HOSTNAME}.${TAILSCALE_TAILNET_DOMAIN}`) && PathPrefix(`/calibre`)
- traefik.http.routers.calibre.entrypoints=web - traefik.http.routers.calibre.entrypoints=web
- traefik.http.services.calibre.loadbalancer.server.port=8083 - traefik.http.services.calibre.loadbalancer.server.port=8083
- homepage.group=Media - homepage.group=Media
@@ -467,7 +467,8 @@ services:
- HOMEPAGE_VAR_WEATHER_LONG=${HOMEPAGE_VAR_WEATHER_LONG} - HOMEPAGE_VAR_WEATHER_LONG=${HOMEPAGE_VAR_WEATHER_LONG}
- HOMEPAGE_VAR_WEATHER_TIME=${TIMEZONE} - HOMEPAGE_VAR_WEATHER_TIME=${TIMEZONE}
- HOMEPAGE_VAR_WEATHER_UNIT=${HOMEPAGE_VAR_WEATHER_UNIT} - HOMEPAGE_VAR_WEATHER_UNIT=${HOMEPAGE_VAR_WEATHER_UNIT}
- HOMEPAGE_ALLOWED_HOSTS=${HOSTNAME} # Explicitly allow the hostname constructed from Tailscale variables
- HOMEPAGE_ALLOWED_HOSTS=${TAILSCALE_HOSTNAME}.${TAILSCALE_TAILNET_DOMAIN}
volumes: volumes:
- ${CONFIG_ROOT:-.}/homepage:/app/config:Z - ${CONFIG_ROOT:-.}/homepage:/app/config:Z
- /var/run/docker.sock:/var/run/docker.sock:ro - /var/run/docker.sock:/var/run/docker.sock:ro
@@ -477,8 +478,10 @@ services:
[sh, -c, "cp -n /app/config/tpl/*.yaml /app/config && node server.js"] [sh, -c, "cp -n /app/config/tpl/*.yaml /app/config && node server.js"]
labels: labels:
- traefik.enable=true - traefik.enable=true
- traefik.http.routers.homepage.rule=PathPrefix(`/`) # Change path to /home and use specific Tailscale host
- traefik.http.routers.homepage.rule=Host(`${TAILSCALE_HOSTNAME}.${TAILSCALE_TAILNET_DOMAIN}`) && PathPrefix(`/home`)
- traefik.http.routers.homepage.entrypoints=web - traefik.http.routers.homepage.entrypoints=web
# Authelia middleware will be added in a later commit
- traefik.http.services.homepage.loadbalancer.server.port=3000 - traefik.http.services.homepage.loadbalancer.server.port=3000
watchtower: watchtower:
image: ghcr.io/containrrr/watchtower:latest image: ghcr.io/containrrr/watchtower:latest