feat(calibre-server): Calibre Content Server as a boot-persistent Quadlet
lscr.io/linuxserver/calibre:9.15.0 (desktop build) running calibre-server as the s6 main service on internal 8090 -> host 8084, auth-gated with a plaintext userdb (mode 600) bootstrapped once by the deploy handler. The desktop GUI is kept on 8080/8182, basic-authed with the same credential pair via the machine-local env file.
This commit is contained in:
@@ -92,7 +92,7 @@ service_is_allowed() {
|
||||
dankclaw:caddy|dankclaw:homepage|dankclaw:seerr|dankclaw:marreta|\
|
||||
dankclaw:frank-large|dankclaw:frank-small|\
|
||||
dankserver:romm-mariadb|dankserver:romm-redis|dankserver:romm|\
|
||||
dankserver:copyparty|dankserver:jellyfin|dankserver:calibre-web|dankserver:plex|dankserver:tautulli|\
|
||||
dankserver:copyparty|dankserver:jellyfin|dankserver:calibre-web|dankserver:calibre-server|dankserver:plex|dankserver:tautulli|\
|
||||
dankserver:prowlarr|dankserver:qbittorrent|dankserver:radarr|\
|
||||
dankserver:sonarr|dankserver:lidarr|dankserver:readarr|\
|
||||
dankserver:frank-medium|dankserver:node-exporter|\
|
||||
@@ -850,6 +850,50 @@ deploy_calibre_web() {
|
||||
systemctl --user restart calibre-web.service
|
||||
}
|
||||
|
||||
# The content server's single admin account and the desktop's basic-auth
|
||||
# credential (same pair) are bootstrapped exactly once: the env file is the
|
||||
# plaintext store (mode 600), the userdb's pw column is plaintext too, so
|
||||
# its file is mode 600 as well. The password is piped on stdin with printf -
|
||||
# a trailing newline from echo lands in the stored password and breaks every
|
||||
# login (verified 2026-09-21).
|
||||
deploy_calibre_server() {
|
||||
local data_root=/home/dank/Containers/calibre-server
|
||||
mkdir -p "$data_root"
|
||||
if [[ ! -f $data_root/env ]]; then
|
||||
local pw
|
||||
pw=$(openssl rand -base64 18 | tr -d '/+=' | head -c 20)
|
||||
printf 'CUSTOM_USER=calibre\nCUSTOM_PASSWORD=%s\n' "$pw" > "$data_root/env"
|
||||
chmod 600 "$data_root/env"
|
||||
echo "calibre-server: generated credential (shown once): calibre / $pw"
|
||||
fi
|
||||
[[ -f $data_root/env ]] || {
|
||||
echo "FAIL: $data_root/env does not exist; seed it before the first calibre-server deploy" >&2
|
||||
return 1
|
||||
}
|
||||
if [[ ! -f $data_root/userdb.sqlite ]]; then
|
||||
local pw
|
||||
pw=$(grep '^CUSTOM_PASSWORD=' "$data_root/env" | cut -d= -f2)
|
||||
touch "$data_root/userdb.sqlite"
|
||||
printf '%s' "$pw" | podman run --rm -i --entrypoint /usr/bin/calibre-server \
|
||||
-v "$data_root/userdb.sqlite:/userdb.sqlite" \
|
||||
lscr.io/linuxserver/calibre:9.15.0 \
|
||||
--userdb /userdb.sqlite --manage-users -- add calibre
|
||||
chown 1000:1000 "$data_root/userdb.sqlite"
|
||||
chmod 600 "$data_root/userdb.sqlite"
|
||||
fi
|
||||
[[ -f $data_root/userdb.sqlite && -s $data_root/userdb.sqlite ]] || {
|
||||
echo "FAIL: $data_root/userdb.sqlite missing or empty; the --manage-users bootstrap failed" >&2
|
||||
return 1
|
||||
}
|
||||
cp "dankserver/calibre-server/quadlet/calibre-server.container" "$quadlet_unit_dir/"
|
||||
systemctl --user daemon-reload
|
||||
if ! systemctl --user is-active -q calibre-server.service; then
|
||||
podman stop calibre-server 2>/dev/null || true
|
||||
podman rm calibre-server 2>/dev/null || true
|
||||
fi
|
||||
systemctl --user restart calibre-server.service
|
||||
}
|
||||
|
||||
deploy_copyparty() {
|
||||
# The admin account is created from ${COPAY_ACCOUNT}:${COPAY_PASSWORD} expanded
|
||||
# at ExecStart time; a missing env file must fail the unit, not boot copyparty
|
||||
@@ -1476,6 +1520,7 @@ deploy_service() {
|
||||
romm|romm-mariadb|romm-redis|mariadb|redis) deploy_romm_stack "$service" ;;
|
||||
jellyfin) deploy_jellyfin ;;
|
||||
calibre-web) deploy_calibre_web ;;
|
||||
calibre-server) deploy_calibre_server ;;
|
||||
copyparty) deploy_copyparty ;;
|
||||
plex) deploy_plex ;;
|
||||
tautulli) deploy_tautulli ;;
|
||||
|
||||
Reference in New Issue
Block a user