Compare commits

...

2 commits

Author SHA1 Message Date
644b608831
chore: retire readarr service, replaced by bookshelf (#123)
Some checks are pending
Deploy (on merge) / Discover hosts (push) Waiting to run
Deploy (on merge) / deploy (push) Blocked by required conditions
Bookshelf (PR #122) is a Readarr revival and now owns port 8787 on
london-b, so the old custom Readarr systemd unit is removed:

- drop readarr from the media_stack role's unit-deploy and enable loops,
  and add an idempotent decommission task (stop, disable, remove unit)
  so the host tears it down via Ansible rather than ad-hoc SSH
- delete services/readarr/readarr.service
- update docs (services, london-b host, service inventory) to describe
  bookshelf as a Docker service instead of a custom systemd unit

The public readarr.pez.sh hostname is kept and now reverse-proxies to
bookshelf on :8787 — DNS, Caddy and Authelia (pez_readarr_users group)
are unchanged.
2026-06-06 15:50:37 +01:00
98ac065056
feat: add bookshelf service on london-b (#122)
Bookshelf (a Readarr revival) for managing the ebook/audiobook library.
Runs on london-b with config at /root/bookshelf and the library at
/hdd/books mounted into the container at the same path.
2026-06-06 15:34:57 +01:00
11 changed files with 59 additions and 27 deletions

View file

@ -11,6 +11,7 @@ docker_services:
- miniflux - miniflux
- smartctl-exporter - smartctl-exporter
- plex-exporter - plex-exporter
- bookshelf
# Snap-managed services (deployed by media_stack role) # Snap-managed services (deployed by media_stack role)
snap_services: snap_services:

View file

@ -14,7 +14,6 @@
- radarr - radarr
- prowlarr - prowlarr
- lidarr - lidarr
- readarr
- whisparr - whisparr
- ollama - ollama
notify: Reload systemd daemon notify: Reload systemd daemon
@ -28,7 +27,6 @@
- radarr - radarr
- prowlarr - prowlarr
- lidarr - lidarr
- readarr
- ollama - ollama
# Whisparr is installed but disabled (kept as-is) # Whisparr is installed but disabled (kept as-is)
@ -37,6 +35,22 @@
name: whisparr name: whisparr
enabled: false enabled: false
# Readarr was retired in favour of the bookshelf Docker service (a Readarr
# revival). Decommission the old custom unit so the host stops it and frees
# port 8787, which bookshelf now binds.
- name: Stop and disable retired readarr unit
ansible.builtin.systemd:
name: readarr
state: stopped
enabled: false
failed_when: false
- name: Remove retired readarr unit file
ansible.builtin.file:
path: /etc/systemd/system/readarr.service
state: absent
notify: Reload systemd daemon
# ── Package-managed services (ensure enabled) ── # ── Package-managed services (ensure enabled) ──
- name: Ensure package-managed services are enabled - name: Ensure package-managed services are enabled

View file

@ -27,13 +27,14 @@ There is **no** per-host subdirectory — services are named by what they are, a
| poste-io | Docker | nuremberg-a | Mail | | poste-io | Docker | nuremberg-a | Mail |
| jellyseerr | Docker | london-b | Plex request manager | | jellyseerr | Docker | london-b | Plex request manager |
| navidrome | Docker | london-b | Music streaming | | navidrome | Docker | london-b | Music streaming |
| bookshelf | Docker | london-b | Ebook/audiobook manager (Readarr revival) |
| slskd | Docker | london-b | Soulseek client | | slskd | Docker | london-b | Soulseek client |
| miniflux | Docker | london-b | RSS reader (with postgres) | | miniflux | Docker | london-b | RSS reader (with postgres) |
| smartctl-exporter | Docker | london-b, copenhagen-a | SMART metrics | | smartctl-exporter | Docker | london-b, copenhagen-a | SMART metrics |
| plex-exporter | Docker | london-b | Plex metrics | | plex-exporter | Docker | london-b | Plex metrics |
| octopus-exporter | Docker | london-c | Octopus Energy metrics | | octopus-exporter | Docker | london-c | Octopus Energy metrics |
| minecraft | Docker | copenhagen-a | PaperMC server | | minecraft | Docker | copenhagen-a | PaperMC server |
| radarr / sonarr / lidarr / readarr / prowlarr / whisparr | systemd | london-b | *Arr stack (systemd unit files here) | | radarr / sonarr / lidarr / prowlarr / whisparr | systemd | london-b | *Arr stack (systemd unit files here) |
| transmission | systemd | london-b | Config files (the daemon itself is apt) | | transmission | systemd | london-b | Config files (the daemon itself is apt) |
| samba / vsftpd | systemd | london-b | File-sharing config | | samba / vsftpd | systemd | london-b | File-sharing config |
| ollama | systemd | london-b | Custom unit + binary install | | ollama | systemd | london-b | Custom unit + binary install |

View file

@ -0,0 +1,15 @@
# Bookshelf
Ebook/audiobook collection manager — a revival of Readarr. Monitors RSS
feeds, downloads, sorts and renames books via Usenet/BitTorrent.
- **Host:** london-b
- **Port:** 8787
- **Image:** `ghcr.io/pennydreadful/bookshelf:hardcover` (Hardcover metadata; use the `softcover` tag for a Goodreads/Readarr-compatible database)
- **Config:** `/root/bookshelf/` (`:/config`)
- **Book library:** `/hdd/books` (mounted at the same path in the container, on the ZFS pool)
Exposed at **https://readarr.pez.sh** (and `.solutions`) behind Authelia —
the hostname is retained from the retired Readarr service it replaces, with
Caddy reverse-proxying to `london-b:8787`. Authelia gates access via the
`pez_readarr_users` group.

View file

@ -0,0 +1,18 @@
---
# Bookshelf - Ebook/audiobook collection manager (Readarr revival)
# Host: london-b (100.84.65.101)
# Data: /root/bookshelf (config), /hdd/books (library)
# Image: ghcr.io/pennydreadful/bookshelf (hardcover = Hardcover metadata)
services:
bookshelf:
image: ghcr.io/pennydreadful/bookshelf:hardcover
container_name: bookshelf
restart: unless-stopped
ports:
- "8787:8787"
environment:
TZ: Europe/London
volumes:
- /root/bookshelf:/config
- /hdd/books:/hdd/books

View file

@ -80,7 +80,7 @@ lidarr.pez.solutions, lidarr.pez.sh {
reverse_proxy 100.84.65.101:8686 reverse_proxy 100.84.65.101:8686
} }
# Readarr # Readarr hostname, now serving the bookshelf service (Readarr revival)
readarr.pez.solutions, readarr.pez.sh { readarr.pez.solutions, readarr.pez.sh {
tracing { tracing {
span readarr span readarr

View file

@ -77,7 +77,7 @@ forward_auth localhost:9091 {
| Service | Auth | Reason | | Service | Auth | Reason |
|---------|------|--------| |---------|------|--------|
| Radarr, Sonarr, Lidarr, Readarr | Authelia | Media management | | Radarr, Sonarr, Lidarr, Bookshelf | Authelia | Media management |
| Prowlarr, Transmission (download) | Authelia | Download tools | | Prowlarr, Transmission (download) | Authelia | Download tools |
| slskd (Soulseek) | Authelia | P2P client | | slskd (Soulseek) | Authelia | P2P client |
| Miniflux (RSS) | Authelia | RSS reader | | Miniflux (RSS) | Authelia | RSS reader |

View file

@ -1,16 +0,0 @@
[Unit]
Description=Readarr Daemon
After=syslog.target network.target
[Service]
User=root
Group=root
UMask=0002
Type=simple
ExecStart=/opt/Readarr/Readarr -nobrowser -data=/var/lib/readarr/
TimeoutStopSec=20
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target

View file

@ -13,6 +13,6 @@ TV series management and automated downloading.
## Notes ## Notes
Unlike radarr/lidarr/readarr/prowlarr (which use manually installed binaries with custom unit files), sonarr is installed via APT and its systemd unit is owned by the package. Use `dpkg-reconfigure -plow sonarr` to change User/Group/UMask settings rather than editing the unit file directly. Unlike radarr/lidarr/prowlarr (which use manually installed binaries with custom unit files), sonarr is installed via APT and its systemd unit is owned by the package. Use `dpkg-reconfigure -plow sonarr` to change User/Group/UMask settings rather than editing the unit file directly.
The `media_stack` role also sets up a midnight cron restart (`systemctl restart sonarr`). The `media_stack` role also sets up a midnight cron restart (`systemctl restart sonarr`).

View file

@ -56,7 +56,7 @@ RAIDZ1 tolerates one drive failure per vdev. With this many drives and this much
| Radarr | 7878 | radarr.pez.sh | | Radarr | 7878 | radarr.pez.sh |
| Sonarr | 8989 | sonarr.pez.sh | | Sonarr | 8989 | sonarr.pez.sh |
| Lidarr | 8686 | lidarr.pez.sh | | Lidarr | 8686 | lidarr.pez.sh |
| Readarr | 8787 | readarr.pez.sh | | Bookshelf (Readarr revival, Docker) | 8787 | readarr.pez.sh |
| Prowlarr | 9696 | prowlarr.pez.sh | | Prowlarr | 9696 | prowlarr.pez.sh |
| Transmission | 9091 | download.pez.sh | | Transmission | 9091 | download.pez.sh |
| Jellyseerr | 5055 | request.pez.sh | | Jellyseerr | 5055 | request.pez.sh |
@ -84,7 +84,6 @@ The media automation suite and several supporting services run as native systemd
| Radarr | radarr | /opt/Radarr, custom unit | | Radarr | radarr | /opt/Radarr, custom unit |
| Prowlarr | prowlarr | /opt/Prowlarr, custom unit | | Prowlarr | prowlarr | /opt/Prowlarr, custom unit |
| Lidarr | lidarr | /opt/Lidarr, custom unit | | Lidarr | lidarr | /opt/Lidarr, custom unit |
| Readarr | readarr | /opt/Readarr, custom unit |
| Whisparr | whisparr | /opt/Whisparr, custom unit (disabled) | | Whisparr | whisparr | /opt/Whisparr, custom unit (disabled) |
| Plex | plexmediaserver | Package-managed | | Plex | plexmediaserver | Package-managed |
| Jellyfin | jellyfin | Package-managed | | Jellyfin | jellyfin | Package-managed |

View file

@ -39,14 +39,14 @@ I run both Plex and Jellyfin — some clients work better with one than the othe
| Radarr | 7878 | Custom systemd unit (`/opt/Radarr`) | Authelia | radarr.pez.sh | | Radarr | 7878 | Custom systemd unit (`/opt/Radarr`) | Authelia | radarr.pez.sh |
| Sonarr | 8989 | Native (apt/systemd, mono) | Authelia | sonarr.pez.sh | | Sonarr | 8989 | Native (apt/systemd, mono) | Authelia | sonarr.pez.sh |
| Lidarr | 8686 | Custom systemd unit (`/opt/Lidarr`) | Authelia | lidarr.pez.sh | | Lidarr | 8686 | Custom systemd unit (`/opt/Lidarr`) | Authelia | lidarr.pez.sh |
| Readarr | 8787 | Custom systemd unit (`/opt/Readarr`) | Authelia | readarr.pez.sh | | Bookshelf | 8787 | Docker (`ghcr.io/pennydreadful/bookshelf`, Readarr revival) | Authelia | readarr.pez.sh |
| Prowlarr | 9696 | Custom systemd unit (`/opt/Prowlarr`) | Authelia | prowlarr.pez.sh | | Prowlarr | 9696 | Custom systemd unit (`/opt/Prowlarr`) | Authelia | prowlarr.pez.sh |
| Whisparr | — | Custom systemd unit (disabled) | — | — | | Whisparr | — | Custom systemd unit (disabled) | — | — |
| Transmission | 9091 | Native (apt/systemd) | Authelia | download.pez.sh | | Transmission | 9091 | Native (apt/systemd) | Authelia | download.pez.sh |
| Jellyseerr | 5055 | Docker | Own auth | request.pez.sh | | Jellyseerr | 5055 | Docker | Own auth | request.pez.sh |
| Overseerr | 5056 | Snap (`overseerr` from `latest/beta`) | Own auth | jellyfin-requests.pez.sh | | Overseerr | 5056 | Snap (`overseerr` from `latest/beta`) | Own auth | jellyfin-requests.pez.sh |
The arr stack pipeline: Jellyseerr/Overseerr accept requests → Radarr/Sonarr/Lidarr/Readarr search via Prowlarr → send to Transmission → downloaded content is moved to the library → Plex and Jellyfin pick it up automatically. Two requesters because Overseerr is hooked into Jellyfin and Jellyseerr into Plex. The arr stack pipeline: Jellyseerr/Overseerr accept requests → Radarr/Sonarr/Lidarr/Bookshelf search via Prowlarr → send to Transmission → downloaded content is moved to the library → Plex and Jellyfin pick it up automatically. Two requesters because Overseerr is hooked into Jellyfin and Jellyseerr into Plex.
### Other ### Other
@ -129,7 +129,7 @@ Plus host-specific exporters (smartctl, plex, octopus) called out above. See [mo
Services fall into two categories: Services fall into two categories:
**Behind Authelia** (SSO via Caddy `forward_auth`): **Behind Authelia** (SSO via Caddy `forward_auth`):
- Radarr, Sonarr, Lidarr, Readarr, Prowlarr, Transmission, Soulseek, Miniflux, apps.pez.sh - Radarr, Sonarr, Lidarr, Bookshelf, Prowlarr, Transmission, Soulseek, Miniflux, apps.pez.sh
**Own auth** (handle login themselves): **Own auth** (handle login themselves):
- Bitwarden, Forgejo, Plex, Jellyfin, Navidrome, Jellyseerr, Overseerr, Proxmox, poste.io - Bitwarden, Forgejo, Plex, Jellyfin, Navidrome, Jellyseerr, Overseerr, Proxmox, poste.io