Skip to content
Open
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 @@ -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 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) |

Expand Down
29 changes: 29 additions & 0 deletions services/storyteller/.env
Original file line number Diff line number Diff line change
@@ -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:latest

# 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=
34 changes: 34 additions & 0 deletions services/storyteller/README.md
Original file line number Diff line number Diff line change
@@ -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.<tailnet>.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)
73 changes: 73 additions & 0 deletions services/storyteller/compose.yaml
Original file line number Diff line number Diff line change
@@ -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 <addr>:<port> 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
Loading