diff --git a/README.md b/README.md new file mode 100644 index 0000000..125094e --- /dev/null +++ b/README.md @@ -0,0 +1,80 @@ +# Audiobookshelf Deployment + +This repository contains the deployment configuration for **Audiobookshelf**, a self-hosted audiobook and podcast server. It leverages a CI/CD pipeline via Woodpecker CI and integrates with a cloud-backed storage solution for long-term archiving. + +## 🏗️ Architecture Overview + +The deployment is designed with a "separation of concerns" approach: +* **Containerization**: Managed via Docker Compose. +* **Networking**: Integrated into a `web_traffic` external network, designed to sit behind a reverse proxy (e.g., Caddy) for SSL termination. +* **Storage**: A hybrid approach using local SSDs for active metadata/config and an **Rclone-mounted Google Drive** for the main library. +* **CI/CD**: Automated deployment via Woodpecker CI on every push to the `main` branch. + +## 📂 Repository Structure + +* `docker-compose.yaml`: Defines the application service, volumes, and network bridge. +* `.woodpecker.yaml`: Automation script for deployment to the host server. + +## 📚 Cloud Storage Setup + +This server uses **Rclone** and **FUSE** to bridge Google Drive with Audiobookshelf, allowing for a massive library with a minimal local storage footprint. + +### ☁️ Cloud Integration (Rclone) +The system mounts a Google Drive subdirectory as a local filesystem. It utilizes a **VFS (Virtual File System) Cache** to make remote files behave like local ones, which is critical for smooth metadata scanning. + +#### Mount Details +* **Source**: `gdrive:audiobooks` +* **Local Destination**: `/home/george/google-drive` +* **Cache Mode**: `full` (Allows the app to interact with files before they are fully downloaded) +* **Optimization**: Includes `--dir-cache-time 1000h` to ensure the folder structure remains snappy and reduces API calls to Google. + +#### Fail-Safe Mechanism +To prevent Audiobookshelf from wiping its database if the connection drops, the service includes **Forceful Cleanup** logic. Before starting, it attempts to unmount any "zombie" connections to ensure the mount point is clean and ready. + +--- + +### 🛠️ Management & Maintenance + +The mount is managed by a systemd service (`rclone-gdrive.service`) to ensure high availability and automatic recovery. + +| Task | Command | +| :--- | :--- | +| **Check Health** | `sudo systemctl status rclone-gdrive` | +| **Restart Mount** | `sudo systemctl restart rclone-gdrive` | +| **Apply Config Changes** | `sudo systemctl daemon-reload && sudo systemctl restart rclone-gdrive` | +| **Emergency Unmount** | `sudo fusermount -uz ~/google-drive` | +| **Refresh API Token** | `rclone config reconnect gdrive:` | +| **Test Cloud Link** | `rclone lsd gdrive:` | + +--- + +### ⚠️ Troubleshooting: The "Missing Library" Issue +If Audiobookshelf shows 0 books, the Google Drive API token has likely expired (a common occurrence with Google's Oauth security). + +1. **Check Logs**: Run `journalctl -u rclone-gdrive.service -n 50`. Look for `invalid_grant` or `token expired`. +2. **Re-authenticate**: Run `rclone config reconnect gdrive:` and follow the headless authentication prompts. +3. **Verify Mount**: Ensure files are visible on the host via `ls ~/google-drive`. +4. **Sync ABS**: Trigger a **Library Scan** in the Audiobookshelf Web UI to re-link the database. + +> **Note on Moving Books**: To move a book from the local SSD to the Cloud Archive, use: +> `mv ~/audiobookshelf/audiobooks/AuthorName ~/google-drive/` +> *The `--vfs-cache-mode full` flag will handle the upload to Google Drive in the background.* + +## 🚀 Deployment + +### Manual Setup +1. Ensure the `web_traffic` network exists: + ```bash + docker network create web_traffic + ``` +2. Deploy the stack: + ```bash + docker compose up -d + ``` + +### CI/CD Workflow + +The Woodpecker pipeline automates the following on every push: + +1. Copies the repository files to the deployment directory on the host. +2. Triggers a docker compose up -d --pull always --force-recreate to ensure the latest image and configuration are live.