feat: add Tube Archivist service
- 3-container stack: tubearchivist (Django web UI), ES 7.17, Redis - Traefik secureweb router + service in traefik-internal.yaml - Tunnel router via Docker labels for Cloudflare/authentik access - Master compose include (service #44) - No VPN routing (reaches YouTube directly) - Env vars required: TA_USERNAME, TA_PASSWORD NOTE: traefik-internal-noauth.yaml needs manual update on production-1
This commit is contained in:
@@ -588,6 +588,18 @@ http:
|
|||||||
- security-headers@file
|
- security-headers@file
|
||||||
- traefik-bouncer@file
|
- traefik-bouncer@file
|
||||||
|
|
||||||
|
tubearchivist:
|
||||||
|
rule: "Host(`tubearchivist.gharbeia.net`)"
|
||||||
|
service: tubearchivist-internal
|
||||||
|
entryPoints:
|
||||||
|
- secureweb
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
middlewares:
|
||||||
|
- authentik-forwardauth@file
|
||||||
|
- security-headers@file
|
||||||
|
- traefik-bouncer@file
|
||||||
|
|
||||||
guacamole:
|
guacamole:
|
||||||
rule: "Host(`guacamole.gharbeia.net`)"
|
rule: "Host(`guacamole.gharbeia.net`)"
|
||||||
service: guacamole-internal
|
service: guacamole-internal
|
||||||
@@ -713,6 +725,10 @@ http:
|
|||||||
loadBalancer:
|
loadBalancer:
|
||||||
servers:
|
servers:
|
||||||
- url: http://audiobookshelf:13378
|
- url: http://audiobookshelf:13378
|
||||||
|
tubearchivist-internal:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: http://tubearchivist:8000
|
||||||
guacamole-internal:
|
guacamole-internal:
|
||||||
loadBalancer:
|
loadBalancer:
|
||||||
servers:
|
servers:
|
||||||
@@ -860,11 +876,12 @@ include:
|
|||||||
- services/stash.yaml
|
- services/stash.yaml
|
||||||
- services/tdarr.yaml
|
- services/tdarr.yaml
|
||||||
- services/tdarr-node.yaml
|
- services/tdarr-node.yaml
|
||||||
|
- services/tubearchivist.yaml
|
||||||
- services/audiobookshelf.yaml
|
- services/audiobookshelf.yaml
|
||||||
- services/whisparr.yaml
|
- services/whisparr.yaml
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
All 43 services are organized alphabetically by category in the include list.
|
All 44 services are organized alphabetically by category in the include list.
|
||||||
The order matters for startup dependencies: infrastructure services (gluetun,
|
The order matters for startup dependencies: infrastructure services (gluetun,
|
||||||
postgresql, valkey, authentik, traefik) come first.
|
postgresql, valkey, authentik, traefik) come first.
|
||||||
|
|
||||||
@@ -1183,6 +1200,88 @@ services:
|
|||||||
- /docker/appdata/unbound/unbound.conf:/opt/unbound/etc/unbound/unbound.conf:ro
|
- /docker/appdata/unbound/unbound.conf:/opt/unbound/etc/unbound/unbound.conf:ro
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
|
** Tube Archivist — YouTube Archiving
|
||||||
|
|
||||||
|
Tube Archivist downloads and indexes YouTube channels, playlists, and
|
||||||
|
videos. It provides full-text search, metadata browsing, and automatic
|
||||||
|
subscription updates via a web UI. The stack has three containers:
|
||||||
|
|
||||||
|
- =tubearchivist= (main app) — Django-based web UI on port 8000
|
||||||
|
- =tubearchivist-es= — Elasticsearch 7.17 for metadata storage + search
|
||||||
|
- =tubearchivist-redis= — Redis for Celery task queue
|
||||||
|
|
||||||
|
Tube Archivist does NOT need VPN routing (it reaches YouTube directly).
|
||||||
|
|
||||||
|
#+BEGIN_SRC yaml :tangle /docker/compose/services/tubearchivist.yaml
|
||||||
|
services:
|
||||||
|
tubearchivist:
|
||||||
|
image: bbilly1/tubearchivist:latest
|
||||||
|
container_name: tubearchivist
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- networking
|
||||||
|
ports:
|
||||||
|
- ${WEBUI_PORT_TUBEARCHIVIST:-8000}:8000
|
||||||
|
environment:
|
||||||
|
- TZ=${TIMEZONE:?err}
|
||||||
|
- TA_USERNAME=${TA_USERNAME:?err}
|
||||||
|
- TA_PASSWORD=${TA_PASSWORD:?err}
|
||||||
|
- ES_URL=http://tubearchivist-es:9200
|
||||||
|
- REDIS_HOST=tubearchivist-redis
|
||||||
|
- REDIS_PORT=6379
|
||||||
|
- HOST_UID=${PUID:?err}
|
||||||
|
- HOST_GID=${PGID:?err}
|
||||||
|
volumes:
|
||||||
|
- ${FOLDER_FOR_DATA:?err}/tubearchivist/media:/youtube
|
||||||
|
- ${FOLDER_FOR_DATA:?err}/tubearchivist/cache:/cache
|
||||||
|
depends_on:
|
||||||
|
tubearchivist-es:
|
||||||
|
condition: service_healthy
|
||||||
|
tubearchivist-redis:
|
||||||
|
condition: service_healthy
|
||||||
|
labels:
|
||||||
|
- traefik.enable=true
|
||||||
|
- traefik.http.routers.tubearchivist.service=tubearchivist
|
||||||
|
- traefik.http.routers.tubearchivist.rule=Host(`tubearchivist.${CLOUDFLARE_DNS_ZONE:?err}`)
|
||||||
|
- traefik.http.routers.tubearchivist.entrypoints=tunnel
|
||||||
|
- traefik.http.routers.tubearchivist.middlewares=authentik-forwardauth@file,security-headers@file,traefik-bouncer@file
|
||||||
|
- traefik.http.services.tubearchivist.loadbalancer.server.scheme=http
|
||||||
|
- traefik.http.services.tubearchivist.loadbalancer.server.port=8000
|
||||||
|
|
||||||
|
tubearchivist-es:
|
||||||
|
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.22
|
||||||
|
container_name: tubearchivist-es
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- networking
|
||||||
|
environment:
|
||||||
|
- discovery.type=single-node
|
||||||
|
- ES_JAVA_OPTS=-Xms512m -Xmx512m
|
||||||
|
- xpack.security.enabled=false
|
||||||
|
volumes:
|
||||||
|
- ${FOLDER_FOR_DATA:?err}/tubearchivist/es:/usr/share/elasticsearch/data
|
||||||
|
healthcheck:
|
||||||
|
test: curl -s http://localhost:9200/_cluster/health | grep -vq '"status":"red"'
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
|
||||||
|
tubearchivist-redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
container_name: tubearchivist-redis
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- networking
|
||||||
|
command: --save 60 1 --loglevel warning
|
||||||
|
volumes:
|
||||||
|
- ${FOLDER_FOR_DATA:?err}/tubearchivist/redis:/data
|
||||||
|
healthcheck:
|
||||||
|
test: redis-cli ping | grep PONG
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
** Remaining Services
|
** Remaining Services
|
||||||
|
|
||||||
The following services follow the same pattern as those documented above.
|
The following services follow the same pattern as those documented above.
|
||||||
@@ -1209,6 +1308,7 @@ definition, environment, volumes, and Traefik labels.
|
|||||||
- =qbittorrent.yaml, sabnzbd.yaml= — Torrent and usenet clients
|
- =qbittorrent.yaml, sabnzbd.yaml= — Torrent and usenet clients
|
||||||
- =stash.yaml= — Adult content library manager
|
- =stash.yaml= — Adult content library manager
|
||||||
- =tdarr.yaml, tdarr-node.yaml= — Media transcoding automation
|
- =tdarr.yaml, tdarr-node.yaml= — Media transcoding automation
|
||||||
|
- =tubearchivist.yaml= — YouTube archiving (Tube Archivist)
|
||||||
- =audiobookshelf.yaml= — Audiobook and podcast server
|
- =audiobookshelf.yaml= — Audiobook and podcast server
|
||||||
|
|
||||||
* .env Configuration
|
* .env Configuration
|
||||||
@@ -1221,9 +1321,18 @@ Key variables:
|
|||||||
- =CLOUDFLARE_DNS_ZONE= (=gharbeia.net=) is used in all Traefik routes
|
- =CLOUDFLARE_DNS_ZONE= (=gharbeia.net=) is used in all Traefik routes
|
||||||
- =PUID= and =PGID= control file ownership (1000:1000)
|
- =PUID= and =PGID= control file ownership (1000:1000)
|
||||||
- =TUNNEL_TOKEN= is the Cloudflare tunnel auth token (managed externally)
|
- =TUNNEL_TOKEN= is the Cloudflare tunnel auth token (managed externally)
|
||||||
|
- =TA_USERNAME= and =TA_PASSWORD= — Tube Archivist admin credentials
|
||||||
|
|
||||||
* LOGBOOK
|
* LOGBOOK
|
||||||
|
|
||||||
|
** [2026-05-16 Sat 21:40] Tube Archivist added to infrastructure
|
||||||
|
- Added tubearchivist.yaml service fragment (3 containers: tubearchivist + ES 7.17 + Redis)
|
||||||
|
- Added Traefik secureweb router + service entry in traefik-internal.yaml
|
||||||
|
- Added tunnel router via Docker labels for external access through Cloudflare
|
||||||
|
- Added to master compose include list (service #44)
|
||||||
|
- Added TA_USERNAME and TA_PASSWORD to .env reference
|
||||||
|
- NOTE: traefik-internal-noauth.yaml must be updated manually on production-1
|
||||||
|
|
||||||
** [2026-05-15 Thu 09:30] Jellyfin SSO fixed — KnownProxies and Two-Step Flow
|
** [2026-05-15 Thu 09:30] Jellyfin SSO fixed — KnownProxies and Two-Step Flow
|
||||||
- Root cause: Jellyfin's empty KnownProxies caused SSO plugin to use HTTP
|
- Root cause: Jellyfin's empty KnownProxies caused SSO plugin to use HTTP
|
||||||
base URL, breaking the JavaScript two-step auth flow (iframe/POST/redirect)
|
base URL, breaking the JavaScript two-step auth flow (iframe/POST/redirect)
|
||||||
|
|||||||
Reference in New Issue
Block a user