Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ ScaleTail provides ready-to-run [Docker Compose](https://docs.docker.com/compose

| 🎥 Service | 📝 Description | 🔗 Link |
| -------------------- | ------------------------------------------------------------------------------------------------------- | ---------------------------------- |
| 🎵 **ArtistTrackarr** | A self-hosted dashboard for tracking upcoming and newly released albums and EPs. | [Details](services/artisttrackarr) |
| 🎧 **Audiobookshelf** | A self-hosted audiobook and podcast server with multi-user support and playback syncing. | [Details](services/audiobookshelf) |
| 🎥 **Bazarr** | A companion tool to Radarr and Sonarr for managing subtitles. | [Details](services/bazarr) |
| 📚 **BookLore** | A self-hosted application for managing and reading books. | [Details](services/booklore) |
Expand Down
33 changes: 33 additions & 0 deletions services/artisttrackarr/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#version=1.1
#URL=https://github.com/tailscale-dev/ScaleTail
#COMPOSE_PROJECT_NAME= # Optional: only use when running multiple deployments on the same infrastructure.

# Service Configuration
SERVICE=artist-trackarr # Service name (e.g., adguard). Used as hostname in Tailscale and for container naming (app-${SERVICE}).
IMAGE_URL=ghcr.io/crypt0rr/artist-trackarr:latest # Docker image URL from container registry (e.g., adguard/adguard-home).

# Network Configuration
SERVICEPORT=8080 # Port to expose to local network. Uncomment the "ports:" section in compose.yaml to enable.
DNS_SERVER=9.9.9.9 # Preferred DNS server for Tailscale. Uncomment the "dns:" section in compose.yaml to enable.

# Tailscale Configuration
TS_AUTHKEY= # Auth key from https://tailscale.com/admin/authkeys. See: https://tailscale.com/kb/1085/auth-keys#generate-an-auth-key for instructions.

# Optional Service variables
# PUID=1000

#Time Zone setting for containers
TZ=Europe/Amsterdam # See: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

# Any Container environment variables are declared below. See https://docs.docker.com/compose/how-tos/environment-variables/

PUBLIC_URL=http://localhost:8080
SETUP_TOKEN=replace-with-at-least-32-random-characters
APP_ENCRYPTION_KEY=replace-with-at-least-32-random-characters
SESSION_SECRET=replace-with-at-least-32-random-characters
MUSICBRAINZ_CONTACT=you@example.com
POLL_INTERVAL=6h
TRUST_PROXY=false
# SPOTIFY_CLIENT_ID=
# SPOTIFY_CLIENT_SECRET=
# SPOTIFY_MARKET=US
60 changes: 60 additions & 0 deletions services/artisttrackarr/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# ArtistTrackarr with Tailscale Sidecar Configuration

This Docker Compose configuration sets up [ArtistTrackarr](https://github.com/crypt0rr/ArtistTrackarr) with Tailscale as a sidecar container, keeping the application securely reachable over your Tailnet without exposing it directly to the public internet.

## ArtistTrackarr

[ArtistTrackarr](https://github.com/crypt0rr/ArtistTrackarr) is a self-hosted household dashboard that monitors MusicBrainz and, optionally, Spotify for newly announced and released albums and EPs. It can send announcement and release-day notifications through Email, Discord, Telegram, ntfy, Gotify, generic webhooks, and other services supported by Shoutrrr.

Pairing ArtistTrackarr with Tailscale provides private access to its web interface from authorized Tailnet devices without requiring public port forwarding or a publicly accessible reverse proxy.

## Configuration Overview

In this setup, the `tailscale-artist-trackarr` service runs Tailscale and manages secure networking for ArtistTrackarr. The `artist-trackarr` service uses the Tailscale container's network stack through Docker's `network_mode: service:tailscale-artist-trackarr` configuration.

ArtistTrackarr listens on port `8080`. Because both containers share the same network namespace, Tailscale Serve can forward traffic directly to `http://127.0.0.1:8080`.

This keeps ArtistTrackarr Tailnet-only unless you intentionally publish its port on the Docker host.

## Good to Know

- **Container permissions:** The ArtistTrackarr image runs as UID and GID `10001`. When using a bind-mounted host directory for `/data`, create it before starting the stack and make it writable by UID and GID `10001`:

```console
mkdir -p ./artist-trackarr-data
sudo chown -R 10001:10001 ./artist-trackarr-data
```

Incorrect ownership can prevent ArtistTrackarr from creating or opening its SQLite database.

- **Volumes:** ArtistTrackarr stores its SQLite database, cached Cover Art Archive artwork, and other persistent application data in `/data`. The upstream deployment uses the legacy-named `artist-tracker-data` Docker volume for compatibility with existing installations.

- **Required application configuration:** Before starting ArtistTrackarr, define the following values:

- `SETUP_TOKEN`
- `APP_ENCRYPTION_KEY`
- `SESSION_SECRET`
- `MUSICBRAINZ_CONTACT`
- `PUBLIC_URL`

`SETUP_TOKEN`, `APP_ENCRYPTION_KEY`, and `SESSION_SECRET` should each contain a random value of at least 32 characters. `MUSICBRAINZ_CONTACT` must contain a real email address or project URL because it is included in the MusicBrainz API User-Agent.

- **Public URL:** Set `PUBLIC_URL` to the HTTPS address through which users will access ArtistTrackarr over Tailscale, for example:

```env
PUBLIC_URL=https://artist-trackarr.example-tailnet.ts.net
```

- **Polling interval:** The default `POLL_INTERVAL` is `6h`. Values below one hour are rejected by the application.

- **Spotify integration:** Spotify integration is optional. Configure `SPOTIFY_CLIENT_ID`, `SPOTIFY_CLIENT_SECRET`, and an appropriate two-letter `SPOTIFY_MARKET`, such as `NL`, to enable Spotify-first artist discovery and an additional release-observation feed.

- **Reverse-proxy handling:** Tailscale Serve acts as the HTTPS reverse proxy in this deployment. Set `TRUST_PROXY=true` only when ArtistTrackarr should trust forwarded client-address headers from the proxy.

- **Backups:** Stop ArtistTrackarr before backing up its persistent `/data` directory or Docker volume to ensure a consistent SQLite backup. Database migrations run automatically when the application is upgraded.

- **Official links:**
- [ArtistTrackarr repository](https://github.com/crypt0rr/ArtistTrackarr)
- [Shoutrrr documentation](https://containrrr.dev/shoutrrr/)
- [MusicBrainz](https://musicbrainz.org/)
- [Spotify Developer Dashboard](https://developer.spotify.com/dashboard)
98 changes: 98 additions & 0 deletions services/artisttrackarr/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
configs:
ts-serve:
content: |
{"TCP":{"443":{"HTTPS":true}},
"Web":{"$${TS_CERT_DOMAIN}:443":
{"Handlers":{"/":
{"Proxy":"http://127.0.0.1:8080"}}}},
"AllowFunnel":{"$${TS_CERT_DOMAIN}:443":false}}

services:
# Make sure you have updated/checked the .env file with the correct variables.
# All the ${ xx } need to be defined there.
# Tailscale Sidecar Configuration
tailscale:
image: tailscale/tailscale:latest # Image to be used
container_name: tailscale-${SERVICE} # Name for local container management
hostname: ${SERVICE} # Name used within your Tailscale environment
environment:
- TS_AUTHKEY=${TS_AUTHKEY}
- TS_STATE_DIR=/var/lib/tailscale
- TS_SERVE_CONFIG=/config/serve.json # Tailscale Serve configuration to expose the web interface on your local Tailnet - remove this line if not required
- TS_USERSPACE=false
- TS_ENABLE_HEALTH_CHECK=true # Enable healthcheck endpoint: "/healthz"
- TS_LOCAL_ADDR_PORT=127.0.0.1:41234 # The <addr>:<port> for the healthz endpoint
#- TS_ACCEPT_DNS=true # Uncomment when using MagicDNS
- TS_AUTH_ONCE=true
configs:
- source: ts-serve
target: /config/serve.json
volumes:
- ./config:/config # Config folder used to store Tailscale files - you may need to change the path
- ./ts/state:/var/lib/tailscale # Tailscale requirement - you may need to change the path
devices:
- /dev/net/tun:/dev/net/tun # Network configuration for Tailscale to work
cap_add:
- net_admin # Tailscale requirement
#ports:
# - 0.0.0.0:${SERVICEPORT}:${SERVICEPORT} # Binding port ${SERVICE}PORT to the local network - may be removed if only exposure to your Tailnet is required
# If any DNS issues arise, use your preferred DNS provider by uncommenting the config below
#dns:
# - ${DNS_SERVER}
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:41234/healthz"] # Check Tailscale has a Tailnet IP and is operational
interval: 1m # How often to perform the check
timeout: 10s # Time to wait for the check to succeed
retries: 3 # Number of retries before marking as unhealthy
start_period: 10s # Time to wait before starting health checks
restart: always

# ${SERVICE}
application:
image: ${IMAGE_URL} # Image to be used
network_mode: service:tailscale # Sidecar configuration to route ${SERVICE} through Tailscale
container_name: app-${SERVICE} # Name for local container management
environment: # Varibles are delared in .env file.
PUID: 1000
PGI: 1000
TZ: ${TZ}
LISTEN_ADDR: ":8080"
PUBLIC_URL: "${PUBLIC_URL:-http://localhost:8080}"
DATABASE_PATH: "/data/artist-tracker.db"
MUSICBRAINZ_CONTACT: "${MUSICBRAINZ_CONTACT:?Set MUSICBRAINZ_CONTACT in .env}"
POLL_INTERVAL: "${POLL_INTERVAL:-6h}"
TRUST_PROXY: "${TRUST_PROXY:-false}"
SETUP_TOKEN_FILE: /run/secrets/setup_token
APP_ENCRYPTION_KEY_FILE: /run/secrets/encryption_key
SESSION_SECRET_FILE: /run/secrets/session_secret
SPOTIFY_CLIENT_ID: "${SPOTIFY_CLIENT_ID:-}"
SPOTIFY_CLIENT_SECRET: "${SPOTIFY_CLIENT_SECRET:-}"
SPOTIFY_MARKET: "${SPOTIFY_MARKET:-US}"
secrets:
- setup_token
- encryption_key
- session_secret
volumes:
- ./${SERVICE}-data:/data
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
depends_on:
tailscale:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:8080/readyz"] # Check if ${SERVICE} process is running
interval: 1m # How often to perform the check
timeout: 10s # Time to wait for the check to succeed
retries: 3 # Number of retries before marking as unhealthy
start_period: 30s # Time to wait before starting health checks
restart: always

secrets:
setup_token:
environment: SETUP_TOKEN
encryption_key:
environment: APP_ENCRYPTION_KEY
session_secret:
environment: SESSION_SECRET