Add WireGuard VPN, kobodl, and calibre-web
WireGuard for private service access (kobodl behind VPN). kobodl downloads and de-DRMs Kobo store purchases. calibre-web serves the library at books.monotrope.au. sync.sh script handles ongoing download + import workflow. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
14
Makefile
14
Makefile
@@ -1,4 +1,4 @@
|
|||||||
.PHONY: build serve deploy ssh setup miniflux gitea goatcounter hermes hermes-sync hermes-chat enrich
|
.PHONY: build serve deploy ssh setup miniflux gitea goatcounter hermes hermes-sync hermes-chat enrich wireguard calibre calibre-sync
|
||||||
|
|
||||||
# Load .env if it exists
|
# Load .env if it exists
|
||||||
-include .env
|
-include .env
|
||||||
@@ -66,5 +66,17 @@ hermes-chat:
|
|||||||
ssh -t root@$(MONOTROPE_HOST) docker exec -it hermes hermes chat
|
ssh -t root@$(MONOTROPE_HOST) docker exec -it hermes hermes chat
|
||||||
|
|
||||||
|
|
||||||
|
wireguard:
|
||||||
|
@test -n "$(MONOTROPE_HOST)" || (echo "Error: MONOTROPE_HOST is not set"; exit 1)
|
||||||
|
ansible-playbook -i "$(MONOTROPE_HOST)," -u root infra/ansible/playbook.yml --tags wireguard
|
||||||
|
|
||||||
|
calibre:
|
||||||
|
@test -n "$(MONOTROPE_HOST)" || (echo "Error: MONOTROPE_HOST is not set"; exit 1)
|
||||||
|
ansible-playbook -i "$(MONOTROPE_HOST)," -u root infra/ansible/playbook.yml --tags calibre
|
||||||
|
|
||||||
|
calibre-sync:
|
||||||
|
@test -n "$(MONOTROPE_HOST)" || (echo "Error: MONOTROPE_HOST is not set"; exit 1)
|
||||||
|
ssh root@$(MONOTROPE_HOST) /opt/calibre/sync.sh
|
||||||
|
|
||||||
enrich:
|
enrich:
|
||||||
uv run enrich.py
|
uv run enrich.py
|
||||||
|
|||||||
@@ -60,6 +60,20 @@ git.monotrope.au {
|
|||||||
encode zstd gzip
|
encode zstd gzip
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Calibre-web
|
||||||
|
books.monotrope.au {
|
||||||
|
reverse_proxy localhost:8083
|
||||||
|
|
||||||
|
header {
|
||||||
|
X-Content-Type-Options "nosniff"
|
||||||
|
X-Frame-Options "DENY"
|
||||||
|
Referrer-Policy "strict-origin-when-cross-origin"
|
||||||
|
Permissions-Policy "camera=(), microphone=(), geolocation=()"
|
||||||
|
}
|
||||||
|
|
||||||
|
encode zstd gzip
|
||||||
|
}
|
||||||
|
|
||||||
# GoatCounter analytics
|
# GoatCounter analytics
|
||||||
stats.monotrope.au {
|
stats.monotrope.au {
|
||||||
reverse_proxy localhost:8081
|
reverse_proxy localhost:8081
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
hermes_telegram_bot_token: "{{ lookup('env', 'HERMES_TELEGRAM_BOT_TOKEN') }}"
|
hermes_telegram_bot_token: "{{ lookup('env', 'HERMES_TELEGRAM_BOT_TOKEN') }}"
|
||||||
hermes_telegram_allowed_users: "{{ lookup('env', 'HERMES_TELEGRAM_ALLOWED_USERS') }}"
|
hermes_telegram_allowed_users: "{{ lookup('env', 'HERMES_TELEGRAM_ALLOWED_USERS') }}"
|
||||||
hermes_miniflux_api_key: "{{ lookup('env', 'HERMES_MINIFLUX_API_KEY') }}"
|
hermes_miniflux_api_key: "{{ lookup('env', 'HERMES_MINIFLUX_API_KEY') }}"
|
||||||
|
wg_client_pubkey: "{{ lookup('env', 'WG_CLIENT_PUBKEY') }}"
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
|
|
||||||
@@ -100,6 +101,7 @@
|
|||||||
- miniflux
|
- miniflux
|
||||||
- gitea
|
- gitea
|
||||||
- goatcounter
|
- goatcounter
|
||||||
|
- calibre
|
||||||
|
|
||||||
- name: Enable and start Caddy
|
- name: Enable and start Caddy
|
||||||
systemd:
|
systemd:
|
||||||
@@ -198,6 +200,75 @@
|
|||||||
ufw:
|
ufw:
|
||||||
state: enabled
|
state: enabled
|
||||||
|
|
||||||
|
# ── WireGuard ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
- name: Install WireGuard
|
||||||
|
apt:
|
||||||
|
name: wireguard
|
||||||
|
state: present
|
||||||
|
tags: wireguard
|
||||||
|
|
||||||
|
- name: Generate WireGuard server private key
|
||||||
|
shell: wg genkey > /etc/wireguard/server_privatekey && chmod 600 /etc/wireguard/server_privatekey
|
||||||
|
args:
|
||||||
|
creates: /etc/wireguard/server_privatekey
|
||||||
|
tags: wireguard
|
||||||
|
|
||||||
|
- name: Generate WireGuard server public key
|
||||||
|
shell: cat /etc/wireguard/server_privatekey | wg pubkey > /etc/wireguard/server_publickey
|
||||||
|
args:
|
||||||
|
creates: /etc/wireguard/server_publickey
|
||||||
|
tags: wireguard
|
||||||
|
|
||||||
|
- name: Read server private key
|
||||||
|
slurp:
|
||||||
|
src: /etc/wireguard/server_privatekey
|
||||||
|
register: wg_server_privkey
|
||||||
|
tags: wireguard
|
||||||
|
|
||||||
|
- name: Read server public key
|
||||||
|
slurp:
|
||||||
|
src: /etc/wireguard/server_publickey
|
||||||
|
register: wg_server_pubkey
|
||||||
|
tags: wireguard
|
||||||
|
|
||||||
|
- name: Write WireGuard config
|
||||||
|
copy:
|
||||||
|
dest: /etc/wireguard/wg0.conf
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0600'
|
||||||
|
content: |
|
||||||
|
[Interface]
|
||||||
|
PrivateKey = {{ wg_server_privkey.content | b64decode | trim }}
|
||||||
|
Address = 10.100.0.1/24
|
||||||
|
ListenPort = 51820
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
PublicKey = {{ wg_client_pubkey }}
|
||||||
|
AllowedIPs = 10.100.0.2/32
|
||||||
|
notify: Restart WireGuard
|
||||||
|
tags: wireguard
|
||||||
|
|
||||||
|
- name: Allow WireGuard UDP port
|
||||||
|
ufw:
|
||||||
|
rule: allow
|
||||||
|
port: '51820'
|
||||||
|
proto: udp
|
||||||
|
tags: wireguard
|
||||||
|
|
||||||
|
- name: Enable and start WireGuard
|
||||||
|
systemd:
|
||||||
|
name: wg-quick@wg0
|
||||||
|
enabled: true
|
||||||
|
state: started
|
||||||
|
tags: wireguard
|
||||||
|
|
||||||
|
- name: Display server public key
|
||||||
|
debug:
|
||||||
|
msg: "WireGuard server public key: {{ wg_server_pubkey.content | b64decode | trim }}"
|
||||||
|
tags: wireguard
|
||||||
|
|
||||||
# ── Docker ──────────────────────────────────────────────────────────────
|
# ── Docker ──────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
- name: Create Docker keyring directory
|
- name: Create Docker keyring directory
|
||||||
@@ -404,6 +475,83 @@
|
|||||||
tags: hermes
|
tags: hermes
|
||||||
|
|
||||||
|
|
||||||
|
# ── Calibre (kobodl + calibre-web) ────────────────────────────────────
|
||||||
|
|
||||||
|
- name: Create Calibre directory
|
||||||
|
file:
|
||||||
|
path: /opt/calibre
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0750'
|
||||||
|
tags: calibre
|
||||||
|
|
||||||
|
- name: Copy Calibre docker-compose.yml
|
||||||
|
copy:
|
||||||
|
src: ../calibre/docker-compose.yml
|
||||||
|
dest: /opt/calibre/docker-compose.yml
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0640'
|
||||||
|
tags: calibre
|
||||||
|
|
||||||
|
- name: Pull and start Calibre services
|
||||||
|
command: docker compose up -d --pull always
|
||||||
|
args:
|
||||||
|
chdir: /opt/calibre
|
||||||
|
tags: calibre
|
||||||
|
|
||||||
|
- name: Fix downloads volume ownership
|
||||||
|
command: >
|
||||||
|
docker compose exec -T kobodl
|
||||||
|
chown 1000:1000 /downloads
|
||||||
|
args:
|
||||||
|
chdir: /opt/calibre
|
||||||
|
tags: calibre
|
||||||
|
|
||||||
|
- name: Check if Calibre library exists
|
||||||
|
command: >
|
||||||
|
docker compose exec -T calibre-web
|
||||||
|
test -f /library/metadata.db
|
||||||
|
args:
|
||||||
|
chdir: /opt/calibre
|
||||||
|
register: calibre_db_check
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
tags: calibre
|
||||||
|
|
||||||
|
- name: Initialise Calibre library
|
||||||
|
command: >
|
||||||
|
docker compose exec -T --user abc calibre-web
|
||||||
|
calibredb add --empty --with-library /library/
|
||||||
|
args:
|
||||||
|
chdir: /opt/calibre
|
||||||
|
when: calibre_db_check.rc != 0
|
||||||
|
tags: calibre
|
||||||
|
|
||||||
|
- name: Install calibre-sync script
|
||||||
|
copy:
|
||||||
|
dest: /opt/calibre/sync.sh
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0755'
|
||||||
|
content: |
|
||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
cd /opt/calibre
|
||||||
|
|
||||||
|
# Download all books from Kobo
|
||||||
|
docker compose exec -T kobodl kobodl --config /home/config/kobodl.json book get --get-all --output-dir /downloads
|
||||||
|
|
||||||
|
# Import any new EPUBs into Calibre library
|
||||||
|
docker compose exec -T calibre-web sh -c '
|
||||||
|
for f in /downloads/*.epub; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
calibredb add "$f" --with-library /library/ && rm "$f"
|
||||||
|
done
|
||||||
|
'
|
||||||
|
tags: calibre
|
||||||
|
|
||||||
# ── GoatCounter ─────────────────────────────────────────────────────────
|
# ── GoatCounter ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
- name: Create goatcounter system user
|
- name: Create goatcounter system user
|
||||||
@@ -559,3 +707,8 @@
|
|||||||
command: docker compose restart
|
command: docker compose restart
|
||||||
args:
|
args:
|
||||||
chdir: /opt/hermes
|
chdir: /opt/hermes
|
||||||
|
|
||||||
|
- name: Restart WireGuard
|
||||||
|
systemd:
|
||||||
|
name: wg-quick@wg0
|
||||||
|
state: restarted
|
||||||
|
|||||||
50
infra/calibre/docker-compose.yml
Normal file
50
infra/calibre/docker-compose.yml
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
services:
|
||||||
|
kobodl:
|
||||||
|
image: ghcr.io/subdavis/kobodl
|
||||||
|
restart: unless-stopped
|
||||||
|
user: "1000:1000"
|
||||||
|
command: --config /home/config/kobodl.json serve --host 0.0.0.0 --output-dir /downloads
|
||||||
|
logging:
|
||||||
|
driver: json-file
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
|
ports:
|
||||||
|
- "10.100.0.1:5100:5000"
|
||||||
|
volumes:
|
||||||
|
- kobodl_config:/home/config
|
||||||
|
- downloads:/downloads
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
- monotrope
|
||||||
|
|
||||||
|
calibre-web:
|
||||||
|
image: lscr.io/linuxserver/calibre-web:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
logging:
|
||||||
|
driver: json-file
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:8083:8083"
|
||||||
|
volumes:
|
||||||
|
- calibre_config:/config
|
||||||
|
- library:/library
|
||||||
|
- downloads:/downloads
|
||||||
|
environment:
|
||||||
|
PUID: "1000"
|
||||||
|
PGID: "1000"
|
||||||
|
TZ: "Australia/Sydney"
|
||||||
|
DOCKER_MODS: "linuxserver/mods:universal-calibre"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
monotrope:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
kobodl_config:
|
||||||
|
calibre_config:
|
||||||
|
library:
|
||||||
|
downloads:
|
||||||
Reference in New Issue
Block a user