From 2390ccee5395c70fafcde6c96dd9fc64c3eccfc3 Mon Sep 17 00:00:00 2001 From: Jack Spiering <46534141+jackspiering@users.noreply.github.com> Date: Tue, 13 Oct 2026 23:02:18 +0200 Subject: [PATCH 1/3] Storyteller: new service --- README.md | 1 + services/storyteller/.env | 29 ++++++++++++ services/storyteller/README.md | 34 ++++++++++++++ services/storyteller/compose.yaml | 73 +++++++++++++++++++++++++++++++ 4 files changed, 137 insertions(+) create mode 100644 services/storyteller/.env create mode 100644 services/storyteller/README.md create mode 100644 services/storyteller/compose.yaml diff --git a/README.md b/README.md index c648808d..8f3fe84c 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,7 @@ Every stack starts from the same [standard setup](documentation/standard-setup.m | **Seerr** | Request manager for Plex, Jellyfin, and Emby that sends approved requests to Radarr and Sonarr. | [Details](services/seerr) | | **Slink** | Image hosting platform that shares uploads through links. | [Details](services/slink) | | **Sonarr** | Series manager that searches Usenet and BitTorrent for new episodes. | [Details](services/sonarr) | +| **Storyteller** | Platform for reading ebooks and audiobooks with synced narration, built from books you already own. | [Details](services/storyteller) | | **Swing Music** | Music player and streaming server for your local audio files. | [Details](services/swingmx) | | **Tautulli** | Monitoring tool for Plex Media Server, with viewing history, statistics, and notifications. | [Details](services/tautulli) | diff --git a/services/storyteller/.env b/services/storyteller/.env new file mode 100644 index 00000000..a9742501 --- /dev/null +++ b/services/storyteller/.env @@ -0,0 +1,29 @@ +#URL=https://github.com/tailscale-dev/ScaleTail +# To run a second copy, copy the folder under another name and change SERVICE. + +# Service Configuration +# Service name (e.g., adguard). Used as hostname in Tailscale and for container naming. +SERVICE=storyteller +# Docker image URL from container registry (e.g., adguard/adguardhome:latest). +IMAGE_URL=registry.gitlab.com/storyteller-platform/storyteller:web-v2.14.23 + +# Network Configuration +# Port to expose to local network. Uncomment the "ports:" section in compose.yaml to enable. +SERVICEPORT=8001 +# Preferred DNS server for Tailscale. Uncomment the "dns:" section in compose.yaml to enable. +DNS_SERVER=9.9.9.9 + +# Tailscale Configuration +# Auth key from https://console.tailscale.com/admin/settings/keys. See: https://tailscale.com/kb/1085/auth-keys#generate-an-auth-key for instructions. +TS_AUTHKEY= + +# User and group that the server runs as. They own the files in the data folder. +PUID=1000 +PGID=1000 + +# Time Zone setting for containers. See: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones +TZ=Europe/Amsterdam + +# Any Container environment variables are declared below. See https://docs.docker.com/compose/how-tos/environment-variables/ +# Required: signs the login tokens. Generate it with: openssl rand -base64 32 +STORYTELLER_SECRET_KEY= diff --git a/services/storyteller/README.md b/services/storyteller/README.md new file mode 100644 index 00000000..976fe3bd --- /dev/null +++ b/services/storyteller/README.md @@ -0,0 +1,34 @@ +# Storyteller + +[Storyteller](https://storyteller-platform.dev/) is a self-hosted platform for creating and reading ebooks with synced narration. It aligns audiobooks and ebooks that you already own, so that you can read, listen, or do both. + +This stack runs Storyteller with a Tailscale sidecar, as described in [the standard setup](../../documentation/standard-setup.md). + +## At a glance + +| Item | Value | +| ------------- | ------------------------------------------------------ | +| Web interface | `https://storyteller..ts.net` | +| Service port | `8001` | +| Image | `registry.gitlab.com/storyteller-platform/storyteller` | +| Data | `./storyteller-data/data` (database, books, uploads) | + +## Before you start + +Set this value in `.env`. Compose stops with an error if it is empty. + +- **`STORYTELLER_SECRET_KEY`.** The key that signs the login tokens. Generate one with `openssl rand -base64 32`. Keep it: a new key logs everyone out. + +## Deviations from the standard setup + +None. + +## First run + +Open the web interface. Storyteller sends you to its setup page. Enter an email address, your name, a username, and a password to create the first account, which is the administrator account. Then add your ebooks and audiobooks from the web interface. + +## Links + +- [Storyteller documentation](https://storyteller-platform.dev/docs/welcome) +- [Storyteller self-hosting guide](https://storyteller-platform.dev/docs/installation/self-hosting/) +- [Storyteller source code](https://gitlab.com/storyteller-platform/storyteller) diff --git a/services/storyteller/compose.yaml b/services/storyteller/compose.yaml new file mode 100644 index 00000000..0bfbc703 --- /dev/null +++ b/services/storyteller/compose.yaml @@ -0,0 +1,73 @@ +configs: + ts-serve: + content: | + {"TCP":{"443":{"HTTPS":true}}, + "Web":{"$${TS_CERT_DOMAIN}:443": + {"Handlers":{"/": + {"Proxy":"http://127.0.0.1:8001"}}}}, + "AllowFunnel":{"$${TS_CERT_DOMAIN}:443":false}} + +services: +# Make sure you have updated/checked the .env file with the correct variables. +# Every variable used in this file must be defined there, unless it has a default such as ${VAR:-value}. + # 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 : for the healthz endpoint + #- TS_ACCEPT_DNS=true # Uncomment only if the service must resolve MagicDNS names - this replaces Docker DNS, so Compose service names no longer resolve + - 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 the 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 + + # Application + application: + image: ${IMAGE_URL} # Image to be used + network_mode: service:tailscale # Sidecar configuration to route the service through Tailscale + container_name: app-${SERVICE} # Name for local container management + environment: # Variables are declared in .env file. + - PUID=${PUID} # The image runs the server as this user and group, and sets the owner of /data to them + - PGID=${PGID} + - TZ=${TZ} + - STORYTELLER_SECRET_KEY=${STORYTELLER_SECRET_KEY:?Set STORYTELLER_SECRET_KEY in .env} + # Do not set "user:" on this service: the image refuses to start and wants PUID and PGID instead. + volumes: + - ./${SERVICE}-data/data:/data + depends_on: + tailscale: + condition: service_healthy + # Healthcheck: the image defines no HEALTHCHECK, so call the web interface with wget, which the image ships. + healthcheck: + test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:8001/"] # Check if the service is responding + 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: 60s # Time to wait before starting health checks - the first start runs a database migration + restart: always From f36ae816704e16c85bc89973f31f52caaa243a7a Mon Sep 17 00:00:00 2001 From: Jack Spiering <46534141+jackspiering@users.noreply.github.com> Date: Tue, 13 Oct 2026 23:06:25 +0200 Subject: [PATCH 2/3] Storyteller: use the latest tag --- services/storyteller/.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/storyteller/.env b/services/storyteller/.env index a9742501..fe9004fb 100644 --- a/services/storyteller/.env +++ b/services/storyteller/.env @@ -5,7 +5,7 @@ # Service name (e.g., adguard). Used as hostname in Tailscale and for container naming. SERVICE=storyteller # Docker image URL from container registry (e.g., adguard/adguardhome:latest). -IMAGE_URL=registry.gitlab.com/storyteller-platform/storyteller:web-v2.14.23 +IMAGE_URL=registry.gitlab.com/storyteller-platform/storyteller:latest # Network Configuration # Port to expose to local network. Uncomment the "ports:" section in compose.yaml to enable. From d7c778de514f5c1d1b161b0ba7be26e7f005462a Mon Sep 17 00:00:00 2001 From: Jack Spiering <46534141+jackspiering@users.noreply.github.com> Date: Thu, 15 Oct 2026 14:48:28 +0200 Subject: [PATCH 3/3] Storyteller: shorten the README row --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8f3fe84c..c37b8cd5 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,7 @@ Every stack starts from the same [standard setup](documentation/standard-setup.m | **Seerr** | Request manager for Plex, Jellyfin, and Emby that sends approved requests to Radarr and Sonarr. | [Details](services/seerr) | | **Slink** | Image hosting platform that shares uploads through links. | [Details](services/slink) | | **Sonarr** | Series manager that searches Usenet and BitTorrent for new episodes. | [Details](services/sonarr) | -| **Storyteller** | Platform for reading ebooks and audiobooks with synced narration, built from books you already own. | [Details](services/storyteller) | +| **Storyteller** | Platform for reading ebooks with synced audiobook narration. | [Details](services/storyteller) | | **Swing Music** | Music player and streaming server for your local audio files. | [Details](services/swingmx) | | **Tautulli** | Monitoring tool for Plex Media Server, with viewing history, statistics, and notifications. | [Details](services/tautulli) |