refactor: split 'compose.yml' into three distinct '.yml' files

This commit is contained in:
2026-09-16 23:07:52 -07:00
parent b9ca020f99
commit fba0546eff
18 changed files with 1515 additions and 1386 deletions
+40 -57
View File
@@ -9,20 +9,16 @@ TIMEZONE=America/Los_Angeles
# ----- Host -----
LOCAL_IPV4=192.168.50.0 # of your device
EXTERNAL_IPV4=123.156.178.190
SERVER_NAME=your-server # most likely, set this to be the same as your local ipv4, unless you use tailscale or any sort of mDNS on your machine. homepage relies on this for hyperlinks, but not api calls.
WEB_NAME=your-server.com
TAILNET_NAME=tasty-food.ts.net
EXTERNAL_IPV4=255.255.255.0
SERVER_NAME=localhost # most likely, set this to be the same as your local ipv4, unless you use tailscale or any sort of mDNS on your machine. homepage relies on this for hyperlinks, but not api calls.
WEB_NAME=127.0.0.1
TAILNET_NAME=favorite-food.ts.net
WEB_PROTOCOL=http
# ----- Storage -----
DISK1=/mnt/media
DISK2=/mnt/11tb_ext
DISK3=/mnt/shaimpy
# ----- Gluetun (VPN) -----
GLUETUN_KEY=
VPN_PRIVATE_KEY=
DISK1=/mnt/disk1
DISK2=/mnt/disk2
DISK3=/mnt/disk3
# ----- Service Ports -----
PLEX_PORT=32400
@@ -39,7 +35,7 @@ LIDARR_PORT=8686
QBITTORRENT_PORT=2161
TDARR_PORT=8265
TDARR_NODE_PORT=8266
ODYSSEUS_PORT=7001
OPENWEBUI_PORT=7001
PORTAINER_PORT=9443
SCRUTINY_PORT=4545
SCRUTINY_ADMIN_PORT=4646
@@ -47,51 +43,38 @@ PIHOLE_PORT=6060
KARAKEEP_PORT=4621
KARAKEEP_CHROME_PORT=9222
MEILI_PORT=7700
LLAMA_PORT=8079
BAZARR_PORT=8787
VLLM_PORT=5081
SPOTIZERR_PORT=7171
SPOTIZERR_REDIS_PORT=6379
TDARR_NODE_ID=ShaanNode
# ----- API Keys (for homepage widgets & service integrations) -----
PLEX_KEY=
PROWLARR_KEY=
RADARR_KEY=
SONARR_KEY=
LIDARR_KEY=
TAUTULLI_KEY=
SEERR_KEY=
QBITTORRENT_KEY=
TAILSCALE_KEY=
TAILSCALE_DEVICE_KEY=
CLOUDFLARED_KEY=
# ----- Docker Images -----
# get with command:
# docker compose ps -q | xargs docker inspect --format '{{.Image}}' | sort -u | xargs docker inspect --format '{{if .RepoDigests}}{{index .RepoDigests 0}}{{else}}{{.Id}} (local build){{end}}'
# ----- Cloudflare (for homepage widget) -----
CLOUDFLARED_ACCOUNT_ID=
CLOUDFLARED_TUNNEL_ID=
CLOUDFLARED_API_KEY=
# ----- Portainer (for homepage widget) -----
PORTAINER_API_KEY=
# ----- Pi-hole -----
PIHOLE_WEBPASSWORD=
# ----- Glances -----
GLANCES_USERNAME=
GLANCES_PASSWORD=
# ----- Karakeep -----
# KARAKEEP
DATA_DIR=/karakeep-data
MEILI_ADDR=http://127.0.0.1:${MEILI_PORT}
MEILI_MASTER_KEY=
NEXTAUTH_URL=http://localhost:3001
NEXTAUTH_SECRET=
OPENAI_API_KEY=ollama
OPENAI_BASE_URL=http://${LOCAL_IPV4}:${LLAMA_PORT}/v1
INFERENCE_TEXT_MODEL=Qwen3.6
INFERENCE_IMAGE_MODEL=Qwen3.6
EMBEDDING_TEXT_MODEL=Qwen3-Embedding
EMBEDDING_DIMENSIONS=2048
EMBEDDING_CONTEXT_LENGTH=4096
EMBEDDING_ENABLE_AUTO_INDEXING=true
TAUTULLI_IMAGE=ghcr.io/tautulli/tautulli:latest
GLUETUN_IMAGE=qmcgaw/gluetun@sha256:e3272b29a4bc177b389fbdcb54cf9716ccbfc30f04d8b7a35b0a5be9cdb58461
QBITTORRENT_IMAGE=lscr.io/linuxserver/qbittorrent@sha256:b6ab43fe86039e5bdd3cc0b59b946414fcff0c8183e93636e6cb438fdac45028
PROWLARR_IMAGE=lscr.io/linuxserver/prowlarr@sha256:1295cff29d10b486c0d8324d1559a552140a5932bf8b3d87e398654414f63f92
SONARR_IMAGE=lscr.io/linuxserver/sonarr@sha256:373159ba768e23a3a1c497d9f2b936addf8fd5b1fdce7dd6a14080ac928bfda0
RADARR_IMAGE=lscr.io/linuxserver/radarr@sha256:a45b5ab0f850f39edb4cc9c95bbd967b52ddc3d4574a4dfb45561177db6c88f4
LIDARR_IMAGE=lscr.io/linuxserver/lidarr@sha256:bfec0ec2dc351fa5928379d785b08be395886f109393b9040ed7973bd1008060
BAZARR_IMAGE=lscr.io/linuxserver/bazarr@sha256:819327cb5da94a4187bd0512a8f6f8632541404e52cf5977a96e8865d983b07b
TDARR_IMAGE=haveagitgat/tdarr@sha256:45742f00e51a58553844c8b13d97e7ae9b2ee9a056bd8e5993d9a8282a45a23f
TDARR_NODE_IMAGE=haveagitgat/tdarr_node@sha256:7542459ac5ed5cd299600530e9625b9d590629d5dc391c0016773f5d6aa3fe75
SEERR_IMAGE=ghcr.io/seerr-team/seerr:latest
SEARXNG_IMAGE=searxng/searxng:latest
OPENWEBUI_IMAGE=ghcr.io/open-webui/open-webui@sha256:f67aea542a85e82cfab8c1de0719487b1566bffbb53c2b5448223611a16889dc
KARAKEEP_IMAGE=ghcr.io/karakeep-app/karakeep@sha256:5467873df817ab3aa837f2b06bd7f2b0974132ba1ae5bce0b7e2fd134abc269b
CLOUDFLARED_IMAGE=cloudflare/cloudflared:latest
PORTUPDATER_IMAGE=curlimages/curl:8.21.0
CADDY_IMAGE=caddy:latest
AUTOHEAL_IMAGE=willfarrell/autoheal:latest
MYSPEED_IMAGE=germannewsmaker/myspeed:latest
HOMEPAGE_IMAGE=ghcr.io/gethomepage/homepage:latest
SCRUTINY_IMAGE=ghcr.io/analogj/scrutiny@sha256:9d0e6d146529d9d1407e1d0a9f685d0b6b840cac070e87e0ab62034d9b80c2b7
PIHOLE_IMAGE=pihole/pihole@sha256:f7d1be836e3bc608b56d82fc9904f5a831cdfbc0dc9c6d58f94e4c985c70038b
PORTAINER_IMAGE=portainer/portainer-ce:lts
SPOTIZERR_IMAGE=spotizerrphoenix/spotizerr:latest
REDIS_IMAGE=redis:alpine
+6 -109
View File
@@ -29,7 +29,12 @@ karakeep-data
SECURITY.md
init-database.*
etc*
!odysseus/.*
openwebui/
searxng/
vllm/
bazarr/
docker-data/
spotizerr/
# Only track homepage structural yaml files, ignore app cache
homepage/*
@@ -38,111 +43,3 @@ homepage/*
!homepage/*.css
!homepage/*.js
!homepage/images/
# from odysseus .gitignore
# Python
__pycache__/
*.pyc
*.pyo
*.egg-info/
dist/
build/
!static/js/editor/build/
venv/
.venv/
*.egg
# Environment
.env
.env.bak.*
!.env.example
# Local uv lockfile (optional, per-platform — see "Faster installs with uv" in README)
requirements.lock
# SOPS workflow — encrypted `secrets.env` is intentionally committable,
# but every variant (plaintext, manual decrypt copy, editor backup)
# must stay out of git. Mirrored in .dockerignore so the same artifacts
# also cannot enter image build layers.
secrets.env.*
!secrets.env.example
# Data — all user data stays local
data/
!services/hwfit/data/
!services/hwfit/data/hf_models.json
logs/
*.log
*.db
*.sqlite
*.sqlite3
# Node
node_modules/
services/node_modules/
services/data/
# IDE / Editor
.aider*
.claude/
.vscode/
.idea/
*.swp
*.swo
*~
# Test capture artifacts (browser session dumps may contain personal content)
.playwright-mcp/
# OS
.DS_Store
Thumbs.db
# Build artifacts
*.cache
cache/
output.txt.txt
# Media (uploaded/generated)
*.jpg
*.jpeg
*.png
*.gif
*.bmp
*.webp
*.tiff
*.pdf
# …except shipped static assets
!static/icons/*.png
# …except shipped demo assets in docs/ that the README links to.
!docs/*.jpg
!docs/*.jpeg
!docs/*.png
!docs/*.gif
!docs/*.webp
# …and curated docs/ subfolder assets (e.g. accessibility before/after shots).
!docs/**/*.png
!docs/**/*.jpg
!docs/**/*.gif
!docs/**/*.webp
# Reports and temp files
reports/
tasks/
scripts/compound/*.json
research_data/
**/search_analytics.json
# Internal dev/review notes — not for public repo
dev-docs/
# Windows-port working docs (local only, not for public repo)
docs/windows-port/
# Local config
compound.config.json
*.error.log
_scratch/
/odysseus/
Regular → Executable
View File
Regular → Executable
+9 -725
View File
@@ -1,10 +1,8 @@
# =============================================================================
# Torrent Stack - Docker Compose
# =============================================================================
name: torrent-stack
networks:
caddy_net:
external: true
#caddy_net:
# external: true
tdarr-net:
driver: bridge
default:
@@ -14,8 +12,8 @@ volumes:
#caddy_config:
#caddy_data:
# external: true
myspeed:
external: true
#myspeed:
# external: true
portainer_data:
name: portainer_data
@@ -27,721 +25,7 @@ volumes:
# → devices → restart
# =============================================================================
services:
# ---------------------------------------------------------------------------
# VPN & Download
# ---------------------------------------------------------------------------
gluetun:
image: qmcgaw/gluetun:latest
container_name: gluetun
env_file:
- .env
- ./env/.gluetun.env
cap_add:
- NET_ADMIN
ports:
- 8888:8000/tcp
- ${QBITTORRENT_PORT}:${QBITTORRENT_PORT}
- ${PROWLARR_PORT}:${PROWLARR_PORT}
- ${SONARR_PORT}:${SONARR_PORT}
- ${RADARR_PORT}:${RADARR_PORT}
- ${LIDARR_PORT}:${LIDARR_PORT}
volumes:
- ./gluetun-data:/tmp/gluetun:rw
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- VPN_SERVICE_PROVIDER=protonvpn
- VPN_TYPE=wireguard
- HTTP_CONTROL_SERVER=ON
- WIREGUARD_MTU=1280
- VPN_PORT_FORWARDING=on
- VPN_PORT_FORWARDING_PROVIDER=protonvpn
- SERVER_COUNTRIES=Netherlands
- NETWORK_LOCAL_ADDRESSES=192.168.50.0/24,172.16.0.0/12
- FIREWALL_OUTBOUND_SUBNETS=192.168.50.0/24
- TZ=${TIMEZONE}
- DNS_UPSTREAM_RESOLVER_TYPE=doh
healthcheck:
test: ["CMD-SHELL", "wget --spider -q http://1.1.1.1 || exit 1"]
interval: 30s
timeout: 15s
retries: 3
start_period: 1m
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
extra_hosts:
- "host.docker.internal:host-gateway"
devices:
- /dev/net/tun:/dev/net/tun
restart: always
qbittorrent:
image: lscr.io/linuxserver/qbittorrent:latest
container_name: qbittorrent
network_mode: "container:gluetun"
depends_on:
gluetun:
condition: service_healthy
volumes:
- ./qbittorrent:/config
- ${DISK1}:${DISK1}
- ${DISK2}:${DISK2}
- ./gluetun-data:/tmp/gluetun
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
- WEBUI_PORT=${QBITTORRENT_PORT}
labels:
- "autoheal=true"
healthcheck:
test:
[
"CMD-SHELL",
"curl -sf http://localhost:${QBITTORRENT_PORT}/api/v2/app/version || exit 1",
]
interval: 1m
timeout: 10s
retries: 3
start_period: 30s
security_opt:
- no-new-privileges:true
mem_limit: 512m
cpus: 2.0
restart: unless-stopped
port-updater:
image: curlimages/curl:latest
container_name: port-updater
network_mode: "container:gluetun"
depends_on:
gluetun:
condition: service_healthy
volumes:
- ./gluetun-data:/tmp/gluetun:ro
entrypoint: ["/bin/sh", "-c"]
command:
- |
trap 'exit 0' SIGTERM;
while true; do
while [ ! -s /tmp/gluetun/forwarded_port ]; do
echo "Waiting for Gluetun to provide a port..."
sleep 5
done
read -r PORT_VAL < /tmp/gluetun/forwarded_port;
CLEAN_PORT=$$(echo "$$PORT_VAL" | tr -d '\r\n ');
if [ -n "$$CLEAN_PORT" ]; then
echo "Updating qBit to port: $$CLEAN_PORT";
sleep 10;
curl -s -X POST -d "json={\"listen_port\":$$CLEAN_PORT}" http://localhost:${QBITTORRENT_PORT}/api/v2/app/setPreferences;
sleep 3600 & wait $$!;
else
sleep 10
fi
done
labels:
- "autoheal=true"
healthcheck:
test: ["CMD-SHELL", "curl -sf https://1.1.1.1 || exit 1"]
interval: 1m
timeout: 10s
retries: 3
start_period: 30s
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp
mem_limit: 64m
cpus: 0.25
restart: unless-stopped
# ---------------------------------------------------------------------------
# *arr Stack
# ---------------------------------------------------------------------------
prowlarr:
image: lscr.io/linuxserver/prowlarr:latest
container_name: prowlarr
network_mode: "container:gluetun"
depends_on:
gluetun:
condition: service_healthy
volumes:
- ./prowlarr:/config
- ./notify.sh:/notify.sh:ro
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
labels:
- "autoheal=true"
healthcheck:
test:
[
"CMD-SHELL",
"curl -sf http://localhost:${PROWLARR_PORT}/ping || exit 1",
]
interval: 1m
timeout: 10s
retries: 3
start_period: 30s
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
restart: unless-stopped
sonarr:
image: lscr.io/linuxserver/sonarr:latest
container_name: sonarr
network_mode: "container:gluetun"
depends_on:
gluetun:
condition: service_healthy
volumes:
- /var/lib/sonarr:/config
- ${DISK1}:${DISK1}
- ${DISK2}:${DISK2}
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
labels:
- "autoheal=true"
healthcheck:
test:
["CMD-SHELL", "curl -sf http://localhost:${SONARR_PORT}/ping || exit 1"]
interval: 1m
timeout: 10s
retries: 3
start_period: 60s
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
restart: unless-stopped
radarr:
image: lscr.io/linuxserver/radarr:latest
container_name: radarr
network_mode: "container:gluetun"
depends_on:
gluetun:
condition: service_healthy
volumes:
- /var/lib/radarr:/config
- ${DISK1}:${DISK1}
- ${DISK2}:${DISK2}
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
labels:
- "autoheal=true"
healthcheck:
test:
["CMD-SHELL", "curl -sf http://localhost:${RADARR_PORT}/ping || exit 1"]
interval: 1m
timeout: 10s
retries: 3
start_period: 30s
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
restart: unless-stopped
lidarr:
image: lscr.io/linuxserver/lidarr:latest
container_name: lidarr
network_mode: "container:gluetun"
depends_on:
gluetun:
condition: service_healthy
volumes:
- ./lidarr:/music
- /var/lib/lidarr:/config
- ${DISK1}:${DISK1}
- ${DISK2}:${DISK2}
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
labels:
- "autoheal=true"
healthcheck:
test:
["CMD-SHELL", "curl -sf http://localhost:${LIDARR_PORT}/ping || exit 1"]
interval: 1m
timeout: 10s
retries: 3
start_period: 30s
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
restart: unless-stopped
# ---------------------------------------------------------------------------
# Media
# ---------------------------------------------------------------------------
tautulli:
image: ghcr.io/tautulli/tautulli
container_name: tautulli
networks:
- caddy_net
ports:
- ${TAUTULLI_PORT}:${TAUTULLI_PORT}
volumes:
- ./tautulli:/config
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
restart: unless-stopped
tdarr:
image: haveagitgat/tdarr:latest
container_name: tdarr
networks:
- tdarr-net
ports:
- ${TDARR_PORT}:${TDARR_PORT}
- ${TDARR_NODE_PORT}:${TDARR_NODE_PORT}
volumes:
- ./tdarr/server:/app/server
- ./tdarr/configs:/app/configs
- ./tdarr/temp:/temp
- ${DISK1}:${DISK1}
- ${DISK2}:${DISK2}
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- TZ=${TIMEZONE}
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- UMASK_SET=002
- serverIP=0.0.0.0
security_opt:
- no-new-privileges:true
mem_limit: 512m
cpus: 2.0
restart: unless-stopped
tdarr-node:
image: haveagitgat/tdarr_node:latest
container_name: tdarr-node
networks:
- tdarr-net
volumes:
- ./tdarr/configs:/app/configs
- ./tdarr/logs:/app/logs
- ./tdarr/temp:/temp
- ${DISK1}:${DISK1}
- ${DISK2}:${DISK2}
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- TZ=${TIMEZONE}
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- nodeID=${TDARR_NODE_ID}
- nodeIP=0.0.0.0
- serverIP=tdarr
- serverPort=${TDARR_NODE_PORT}
security_opt:
- no-new-privileges:true
mem_limit: 2g
cpus: 4.0
devices:
- /dev/dri:/dev/dri
restart: unless-stopped
seerr:
image: ghcr.io/seerr-team/seerr:latest
container_name: seerr
networks:
- caddy_net
ports:
- ${SEERR_PORT}:${SEERR_PORT}
volumes:
- ./seerr:/app/config
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- LOG_LEVEL=info
- TZ=${TIMEZONE}
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
labels:
- "autoheal=true"
init: true
working_dir: "/app"
healthcheck:
test:
[
"CMD-SHELL",
"wget -qO- http://127.0.0.1:${SEERR_PORT}/api/v1/status || exit 1",
]
interval: 1m
timeout: 10s
retries: 3
start_period: 60s
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
restart: unless-stopped
# Anubis anti-bot proxy for Seerr (uncomment to enable):
#seerr-anubis:
# image: ghcr.io/techarohq/anubis:latest
# container_name: seerr-anubis
# networks:
# - caddy_net
# environment:
# - BIND=:55055
# - TARGET=http://seerr:${SEERR_PORT}
# security_opt:
# - no-new-privileges:true
# mem_limit: 128m
# cpus: 0.5
# restart: unless-stopped
# ---------------------------------------------------------------------------
# Monitoring
# ---------------------------------------------------------------------------
homepage:
image: ghcr.io/gethomepage/homepage:latest
container_name: homepage
env_file:
- .env
- ./env/.homepage.env
networks:
- caddy_net
ports:
- ${HOMEPAGE_PORT}:${HOMEPAGE_PORT}
volumes:
- ./homepage:/app/config
- ./homepage/images:/app/public/images
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./gluetun-data:/tmp/gluetun:ro
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- "HOMEPAGE_ALLOWED_HOSTS=gethomepage.dev,${LOCAL_IPV4}:${HOMEPAGE_PORT},${SERVER_NAME}:${HOMEPAGE_PORT},${SERVER_NAME}.${TAILNET_NAME}:${HOMEPAGE_PORT}"
- "HOMEPAGE_VAR_DISK1=${DISK1}"
- "HOMEPAGE_VAR_DISK2=${DISK2}"
- "HOMEPAGE_VAR_DISK3=${DISK3}"
- "HOMEPAGE_VAR_WEB_PROTOCOL=${WEB_PROTOCOL}"
- "HOMEPAGE_VAR_LOCAL_IPV4=${LOCAL_IPV4}"
- "HOMEPAGE_VAR_SERVER_NAME=${SERVER_NAME}"
- "HOMEPAGE_VAR_PLEX_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${PLEX_PORT}"
- "HOMEPAGE_VAR_QBITTORRENT_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${QBITTORRENT_PORT}"
- "HOMEPAGE_VAR_PROWLARR_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${PROWLARR_PORT}"
- "HOMEPAGE_VAR_SONARR_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${SONARR_PORT}"
- "HOMEPAGE_VAR_RADARR_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${RADARR_PORT}"
- "HOMEPAGE_VAR_LIDARR_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${LIDARR_PORT}"
- "HOMEPAGE_VAR_TAUTULLI_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${TAUTULLI_PORT}"
- "HOMEPAGE_VAR_TDARR_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${TDARR_PORT}"
- "HOMEPAGE_VAR_HOMEPAGE_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${HOMEPAGE_PORT}"
- "HOMEPAGE_VAR_GLANCES_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${GLANCES_PORT}"
- "HOMEPAGE_VAR_SEERR_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${SEERR_PORT}"
- "HOMEPAGE_VAR_MYSPEED_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${MYSPEED_PORT}"
- "HOMEPAGE_VAR_ODYSSEUS_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${ODYSSEUS_PORT}"
- "HOMEPAGE_VAR_PIHOLE_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${PIHOLE_PORT}"
- "HOMEPAGE_VAR_PORTAINER_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${PORTAINER_PORT}"
- "HOMEPAGE_VAR_SCRUTINY_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${SCRUTINY_PORT}"
- "HOMEPAGE_VAR_KARAKEEP_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${KARAKEEP_PORT}"
- "HOMEPAGE_VAR_PLEX_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${PLEX_PORT}"
- "HOMEPAGE_VAR_QBITTORRENT_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${QBITTORRENT_PORT}"
- "HOMEPAGE_VAR_PROWLARR_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${PROWLARR_PORT}"
- "HOMEPAGE_VAR_SONARR_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${SONARR_PORT}"
- "HOMEPAGE_VAR_RADARR_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${RADARR_PORT}"
- "HOMEPAGE_VAR_LIDARR_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${LIDARR_PORT}"
- "HOMEPAGE_VAR_TAUTULLI_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${TAUTULLI_PORT}"
- "HOMEPAGE_VAR_TDARR_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${TDARR_PORT}"
- "HOMEPAGE_VAR_HOMEPAGE_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${HOMEPAGE_PORT}"
- "HOMEPAGE_VAR_GLANCES_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${GLANCES_PORT}"
- "HOMEPAGE_VAR_SEERR_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${SEERR_PORT}"
- "HOMEPAGE_VAR_MYSPEED_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${MYSPEED_PORT}"
- "HOMEPAGE_VAR_ODYSSEUS_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${ODYSSEUS_PORT}"
- "HOMEPAGE_VAR_PIHOLE_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${PIHOLE_PORT}"
- "HOMEPAGE_VAR_PORTAINER_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${PORTAINER_PORT}"
- "HOMEPAGE_VAR_SCRUTINY_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${SCRUTINY_PORT}"
- "HOMEPAGE_VAR_KARAKEEP_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${KARAKEEP_PORT}"
- TZ=${TIMEZONE}
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
extra_hosts:
- "host.docker.internal:host-gateway"
restart: unless-stopped
# glances:
# image: nicolargo/glances:latest-full
# container_name: glances
# network_mode: host
# volumes:
# - /etc/os-release:/etc/os-release:ro
# - /:/host:ro
# #- /etc/localtime:/etc/localtime:ro
# #- /etc/timezone:/etc/timezone:ro
# environment:
# - "GLANCES_OPT=-w --password ${GLANCES_PASSWORD}"
# - PUID=${HOST_PUID:-1000}
# - PGID=${HOST_PGID:-1000}
# - TZ=${TIMEZONE}
# healthcheck:
# test:
# ["CMD", "curl", "-f", "http://localhost:${GLANCES_PORT}/api/4/status"]
# interval: 1m
# timeout: 10s
# retries: 3
# start_period: 60s
# security_opt:
# - no-new-privileges:true
# mem_limit: 256m
# cpus: 1.0
# devices:
# - /dev/dri:/dev/dri
# restart: unless-stopped
# # Uncomment to protect Glances WebUI by a login/password (add --password to GLANCES_OPT)
# secrets:
# - source: glances_password
# target: /root/.config/glances/<login>.pwd
# secrets:
# glances_password:
# file: ./secrets/glances_password
autoheal:
image: willfarrell/autoheal:latest
container_name: autoheal
volumes:
- /var/run/docker.sock:/var/run/docker.sock
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- AUTOHEAL_CONTAINER_LABEL=all
- AUTOHEAL_INTERVAL=30
- AUTOHEAL_START_PERIOD=60
- TZ=${TIMEZONE}
security_opt:
- no-new-privileges:true
read_only: true
mem_limit: 64m
cpus: 0.25
restart: unless-stopped
myspeed:
image: germannewsmaker/myspeed
container_name: myspeed
ports:
- ${MYSPEED_PORT}:${MYSPEED_PORT}/tcp
volumes:
- myspeed:/myspeed/data
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- TZ=${TIMEZONE}
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
restart: unless-stopped
scrutiny:
image: ghcr.io/analogj/scrutiny:nightly-omnibus
container_name: scrutiny
cap_add:
- SYS_RAWIO
ports:
- ${SCRUTINY_PORT}:8080
- ${SCRUTINY_ADMIN_PORT}:8086
volumes:
- /run/udev:/run/udev:ro
- ./scrutiny/config:/opt/scrutiny/config
- ./scrutiny/influxdb:/opt/scrutiny/influxdb
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- TZ=${TIMEZONE}
security_opt:
- no-new-privileges:true
mem_limit: 512m
cpus: 1.0
devices:
- /dev/nvme0n1
- /dev/sda
restart: unless-stopped
# ---------------------------------------------------------------------------
# Infrastructure
# ---------------------------------------------------------------------------
pihole:
image: pihole/pihole:latest
container_name: pihole
cap_add:
- NET_ADMIN # Allows managing network interfaces & sockets
- NET_BIND_SERVICE # Allows non-root users to bind to ports < 1024 (port 53 & 123)
- SYS_TIME # Resolves the NTP system time warning
network_mode: host
ports:
- 53:53/tcp
- 53:53/udp
- 67:67/udp
- ${PIHOLE_PORT}:${PIHOLE_PORT}/tcp
volumes:
- ./etc-pihole:/etc/pihole
- ./etc-dnsmasq.d:/etc/dnsmasq.d
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- TZ=${TIMEZONE}
- FTLCONF_misc_etc_dnsmasq_d=true
# security_opt:
# - no-new-privileges:true
mem_limit: 256m
cpus: 1.0
restart: unless-stopped
cloudflared:
image: cloudflare/cloudflared:latest
container_name: cloudflared
env_file:
- ./env/.cloudflared.env
command: tunnel --no-autoupdate run # --token ${CLOUDFLARED_KEY}
security_opt:
- no-new-privileges:true
read_only: true
mem_limit: 128m
cpus: 0.5
restart: always
portainer:
image: portainer/portainer-ce:lts
container_name: portainer
ports:
- ${PORTAINER_PORT}:${PORTAINER_PORT}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- TZ=${TIMEZONE}
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
restart: unless-stopped
caddy:
image: caddy:latest
container_name: caddy
networks:
- caddy_net
ports:
- 80:80
- 443:443
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile
- ./caddy/site:/srv
- ./caddy/caddy_data:/data
- ./caddy/caddy_config:/config
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- TZ=${TIMEZONE}
security_opt:
- no-new-privileges:true
mem_limit: 128m
cpus: 0.5
restart: unless-stopped
# ---------------------------------------------------------------------------
# Karakeep
# ---------------------------------------------------------------------------
karakeep:
image: ghcr.io/karakeep-app/karakeep:${KARAKEEP_VERSION:-release}
container_name: karakeep
env_file:
- ./env/.karakeep.env
ports:
- ${KARAKEEP_PORT}:3000 # must be 3000 as per the dev
volumes:
- ./karakeep-data:/data
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- MEILI_ADDR=http://meilisearch:${MEILI_PORT}
- BROWSER_WEB_URL=http://chrome:${KARAKEEP_CHROME_PORT}
- DATA_DIR=/data
security_opt:
- no-new-privileges:true
mem_limit: 512m
cpus: 2.0
restart: unless-stopped
chrome:
image: gcr.io/zenika-hub/alpine-chrome:124
container_name: karakeep-chromebrowser
command:
- --no-sandbox
- --disable-gpu
- --disable-dev-shm-usage
- --remote-debugging-address=0.0.0.0
- --remote-debugging-port=${KARAKEEP_CHROME_PORT}
- --hide-scrollbars
- --disable-blink-features=AutomationControlled
- --window-size=1440,900
security_opt:
- no-new-privileges:true
mem_limit: 512m
cpus: 1.0
restart: unless-stopped
meilisearch:
image: getmeili/meilisearch:v1.41.0
container_name: karakeep-meilisearch
env_file:
- .env
volumes:
- ./meilisearch:/meili_data
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- MEILI_NO_ANALYTICS=true
security_opt:
- no-new-privileges:true
mem_limit: 512m
cpus: 1.0
restart: unless-stopped
include:
- media.yml
- infra.yml
- web.yml
Regular → Executable
+78 -73
View File
@@ -3,80 +3,85 @@
# https://gethomepage.dev/configs/bookmarks
- "User":
- "Plex":
- icon: si-plex-#EBAF00
href: "{{HOMEPAGE_VAR_PLEX_HOST}}"
- "Seerr":
- icon: sh-seerr
href: "{{HOMEPAGE_VAR_SEERR_HOST}}"
- "Odysseus":
- icon: http://shaan-server:7001/static/icons/icon-192.png
href: https://shaan-server.cc
- "Karakeep":
- icon: sh-karakeep-light
href: "{{HOMEPAGE_VAR_KARAKEEP_HOST}}"
- "Plex":
- icon: si-plex-#EBAF00
href: "{{HOMEPAGE_VAR_PLEX_HOST}}"
- "Seerr":
- icon: sh-seerr
href: "{{HOMEPAGE_VAR_SEERR_HOST}}"
- "Open WebUI":
- icon: sh-open-webui
href: https://shaan-server.cc
- "Hermes Agent":
- icon: http://shaan-server:9119/favicon.ico # "{{HOMEPAGE_VAR_HERMES_HOST}}"/favicon.ico
href: http://shaan-server:9119 # "{{HOMEPAGE_VAR_HERMES_HOST}}"
- "Karakeep":
- icon: sh-karakeep-light
href: "{{HOMEPAGE_VAR_KARAKEEP_HOST}}"
- "SearXNG":
- icon: sh-searxng
href: http://shaan-server:5080 # "{{HOMEPAGE_VAR_SEARXNG_HOST}}"
- "Admin":
- "Sonarr":
- icon: sh-sonarr
href: "{{HOMEPAGE_VAR_SONARR_HOST}}"
- "Radarr":
- icon: sh-radarr
href: "{{HOMEPAGE_VAR_RADARR_HOST}}"
- "Lidarr":
- icon: sh-lidarr
href: "{{HOMEPAGE_VAR_LIDARR_HOST}}"
- "Prowlarr":
- icon: sh-prowlarr
href: "{{HOMEPAGE_VAR_PROWLARR_HOST}}"
- "Tautulli":
- icon: sh-tautulli
href: "{{HOMEPAGE_VAR_TAUTULLI_HOST}}"
- "Tdarr":
- icon: sh-tdarr
href: "{{HOMEPAGE_VAR_TDARR_HOST}}"
- "qBittorrent":
- icon: sh-qbittorrent
href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}"
- "Speedtest":
- icon: sh-speedtest-light
href: "{{HOMEPAGE_VAR_MYSPEED_HOST}}"
- "Scrutiny":
- icon: sh-scrutiny-light
href: "{{HOMEPAGE_VAR_SCRUTINY_HOST}}"
- "Router Gateway":
- icon: "http://192.168.50.1/images/favicon.png"
href: http://192.168.50.1
- "Tailscale":
- icon: sh-tailscale-light
href: https://login.tailscale.com
- "Portainer":
- icon: sh-portainer-light
href: "{{HOMEPAGE_VAR_PORTAINER_HOST}}"
- "Pi-Hole":
- icon: sh-pi-hole
href: "{{HOMEPAGE_VAR_PIHOLE_HOST}}/admin"
- "Cloudflare":
- icon: sh-cloudflare
href: https://dash.cloudflare.com
- Monitorix:
- icon: "{{HOMEPAGE_VAR_WEB_PROTOCOL}}://{{HOMEPAGE_VAR_LOCAL_IPV4}}:4000/monitorix/monitorixico.png"
href: http://{{HOMEPAGE_VAR_SERVER_NAME}}:4000/monitorix
- "Sonarr":
- icon: sh-sonarr
href: "{{HOMEPAGE_VAR_SONARR_HOST}}"
- "Radarr":
- icon: sh-radarr
href: "{{HOMEPAGE_VAR_RADARR_HOST}}"
- "Lidarr":
- icon: sh-lidarr
href: "{{HOMEPAGE_VAR_LIDARR_HOST}}"
- "Prowlarr":
- icon: sh-prowlarr
href: "{{HOMEPAGE_VAR_PROWLARR_HOST}}"
- "Tautulli":
- icon: sh-tautulli
href: "{{HOMEPAGE_VAR_TAUTULLI_HOST}}"
- "Tdarr":
- icon: sh-tdarr
href: "{{HOMEPAGE_VAR_TDARR_HOST}}"
- "qBittorrent":
- icon: sh-qbittorrent
href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}"
- "Scrutiny":
- icon: sh-scrutiny-light
href: "{{HOMEPAGE_VAR_SCRUTINY_HOST}}"
- "Router Gateway":
- icon: "http://192.168.50.1/images/favicon.png"
href: http://192.168.50.1
- "Tailscale":
- icon: sh-tailscale-light
href: https://login.tailscale.com
- "Portainer":
- icon: sh-portainer-light
href: "{{HOMEPAGE_VAR_PORTAINER_HOST}}"
- "Pi-Hole":
- icon: sh-pi-hole
href: "{{HOMEPAGE_VAR_PIHOLE_HOST}}/admin"
- "Cloudflare":
- icon: sh-cloudflare
href: https://dash.cloudflare.com
- Bookmarks:
- "Youtube":
- icon: sh-youtube
href: https://www.youtube.com
- "Gmail":
- icon: sh-gmail
href: https://mail.google.com
# - github/dhaan7/torrent-stack:
# - icon: sh-github-light
# href: https://github.com/dhaan7/torrent-stack
# description: link to this GitHub repository
# - Termix:
# - icon: "{{HOMEPAGE_VAR_TERMIX_ADDRESS}}/favicon.ico"
# href: "{{HOMEPAGE_VAR_TERMIX_HOST}}"
# description: Terminal emulator in your web browser
#
#
- "Youtube":
- icon: sh-youtube
href: https://www.youtube.com
- "Gmail":
- icon: sh-gmail
href: https://mail.google.com
- "dhaan7/torrent-stack":
- icon: sh-github-light
href: https://github.com/dhaan7/torrent-stack
- "Twitter":
- icon: sh-twitter
href: https://x.com/
- "Roblox":
- icon: sh-roblox
href: https://roblox.com
- "Reddit":
- icon: sh-reddit
href: https://reddit.com
- "Discord":
- icon: sh-discord
href: https://discord.com/channels/@me
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
+415 -409
View File
@@ -1,423 +1,429 @@
---
# For configuration options and examples, please see:
# https://gethomepage.dev/configs/services/
- "Top":
- "Cloudflared Tunnel":
icon: sh-cloudflare
href: "https://dash.cloudflare.com/"
server: my-docker
container: cloudflared
description:
widget:
type: cloudflared
accountid: "{{HOMEPAGE_VAR_CLOUDFLARED_ACCOUNT_ID}}"
tunnelid: "{{HOMEPAGE_VAR_CLOUDFLARED_TUNNEL_ID}}"
key: "{{HOMEPAGE_VAR_CLOUDFLARED_API_KEY}}"
- "VPN Address >":
icon: sh-gluetun
href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}"
server: my-docker
container: gluetun
widget:
type: customapi
url: "{{HOMEPAGE_VAR_QBITTORRENT_ADDRESS}}/api/v2/sync/maindata"
mappings:
- "Cloudflared Tunnel":
icon: sh-cloudflare
href: "https://dash.cloudflare.com/"
server: my-docker
container: cloudflared
description:
widget:
type: cloudflared
accountid: "{{HOMEPAGE_VAR_CLOUDFLARED_ACCOUNT_ID}}"
tunnelid: "{{HOMEPAGE_VAR_CLOUDFLARED_TUNNEL_ID}}"
key: "{{HOMEPAGE_VAR_CLOUDFLARED_API_KEY}}"
- "VPN Address >":
icon: sh-gluetun
href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}"
server: my-docker
container: gluetun
widget:
type: customapi
url: "{{HOMEPAGE_VAR_QBITTORRENT_ADDRESS}}/api/v2/sync/maindata"
mappings:
- field: server_state.last_external_address_v4
label: "Address"
format: string
- "Tailscale >":
icon: sh-tailscale-light
href: https://login.tailscale.com
siteMonitor: https://tailscale.com
widget:
type: tailscale
deviceid: "{{HOMEPAGE_VAR_TAILSCALE_DEVICE_KEY}}"
key: "{{HOMEPAGE_VAR_TAILSCALE_KEY}}"
fields: [address]
- "Speedtest Results >":
icon: sh-speedtest-light
href: "{{HOMEPAGE_VAR_MYSPEED_HOST}}"
server: my-docker
container: myspeed
widget:
type: myspeed
url: "{{HOMEPAGE_VAR_MYSPEED_ADDRESS}}"
fields: [download, upload]
- "Tailscale >":
icon: sh-tailscale-light
href: https://login.tailscale.com
siteMonitor: https://tailscale.com
widget:
type: tailscale
deviceid: "{{HOMEPAGE_VAR_TAILSCALE_DEVICE_KEY}}"
key: "{{HOMEPAGE_VAR_TAILSCALE_KEY}}"
fields: [address]
- "Media":
- "Media_1":
- "Odysseus":
icon: "{{HOMEPAGE_VAR_ODYSSEUS_HOST}}/static/icons/icon-192.png"
href: "{{HOMEPAGE_VAR_ODYSSEUS_HOST}}"
siteMonitor: "{{HOMEPAGE_VAR_ODYSSEUS_HOST}}"
description: Local AI Models
- "Port Updater":
icon: sh-docker
description: Shell
server: my-docker
container: port-updater
- "Monitorix":
icon: "{{HOMEPAGE_VAR_WEB_PROTOCOL}}://{{HOMEPAGE_VAR_LOCAL_IPV4}}:4000/monitorix/monitorixico.png"
href: http://{{HOMEPAGE_VAR_SERVER_NAME}}:4000/monitorix
description: System
- "Media_2":
- "Plex >":
icon: sh-plex
#icon: sh-plex-dark
href: "{{HOMEPAGE_VAR_PLEX_HOST}}"
description: Watch
siteMonitor: "{{HOMEPAGE_VAR_PLEX_ADDRESS}}"
widget:
type: plex
url: "{{HOMEPAGE_VAR_PLEX_ADDRESS}}"
key: "{{HOMEPAGE_VAR_PLEX_KEY}}"
fields: [albums, movies, tv]
- "Tautulli >":
icon: sh-tautulli
href: "{{HOMEPAGE_VAR_TAUTULLI_HOST}}"
description: Monitor
server: my-docker
container: tautulli
widget:
type: tautulli
url: "{{HOMEPAGE_VAR_TAUTULLI_ADDRESS}}"
key: "{{HOMEPAGE_VAR_TAUTULLI_KEY}}"
enableUser: false
expandOneStreamToTwoRows: false
- "Sonarr >":
icon: sh-sonarr
href: "{{HOMEPAGE_VAR_SONARR_HOST}}"
description: Shows
server: my-docker
container: sonarr
widget:
type: sonarr
url: "{{HOMEPAGE_VAR_SONARR_ADDRESS}}"
key: "{{HOMEPAGE_VAR_SONARR_KEY}}"
enableQueue: false # shows a long list of queued items. looks ugly unless you reorder the page yourself
fields: [wanted, queued]
highlight:
queued:
numeric:
- level: warn
when: gt
value: 0
- Upcoming TV Episodes:
icon: sh-sonarr
server: my-docker
container: sonarr
widget:
type: calendar
firstDayInWeek: sunday # optional - defaults to monday
view: agenda # optional - possible values monthly, agenda
maxEvents: 2 # optional - defaults to 10
showTime: true # optional - show time for event happening today - defaults to false
timezone: America/Los_Angeles
integrations: # optional
- type: sonarr
service_name: "Sonarr >"
baseUrl: "{{HOMEPAGE_VAR_SONARR_HOST}}"
unmonitored: true
- "Radarr >":
icon: sh-radarr
href: "{{HOMEPAGE_VAR_RADARR_HOST}}"
description: Movies
server: my-docker
container: radarr
widget:
type: radarr
url: "{{HOMEPAGE_VAR_RADARR_ADDRESS}}"
key: "{{HOMEPAGE_VAR_RADARR_KEY}}"
fields: [wanted, queued]
highlight:
queued:
numeric:
- level: warn
when: gt
value: 0
- Upcoming Movies:
icon: sh-radarr
server: my-docker
container: radarr
widget:
type: calendar
firstDayInWeek: sunday # optional - defaults to monday
view: agenda # optional - possible values monthly, agenda
maxEvents: 2 # optional - defaults to 10
showTime: true # optional - show time for event happening today - defaults to false
timezone: America/Los_Angeles
integrations: # optional
- type: radarr
service_name: "Radarr >"
baseUrl: "{{HOMEPAGE_VAR_RADARR_HOST}}"
unmonitored: true
- "Lidarr >":
icon: sh-lidarr
href: "{{HOMEPAGE_VAR_LIDARR_HOST}}"
description: Music
server: my-docker
container: lidarr
widget:
type: lidarr
url: "{{HOMEPAGE_VAR_LIDARR_ADDRESS}}"
key: "{{HOMEPAGE_VAR_LIDARR_KEY}}"
fields: [wanted, queued]
highlight:
queued:
numeric:
- level: warn
when: gt
value: 0
- "Seerr >":
icon: sh-overseerr
href: "{{HOMEPAGE_VAR_SEERR_HOST}}"
description: Request
server: my-docker
container: seerr
widget:
type: seerr
url: "{{HOMEPAGE_VAR_SEERR_ADDRESS}}"
key: "{{HOMEPAGE_VAR_SEERR_KEY}}"
fields: [completed, pending]
highlight:
pending:
numeric:
- level: warn
when: gt
value: 0
- "Tdarr Node (Intel Arc Pro B70)":
icon: sh-tdarr
server: my-docker
container: tdarr-node
- "Tdarr Node (Intel Graphics UHD 710)":
icon: sh-tdarr
server: my-docker
container: tdarr-node
- "Media_Bottom":
- "Tdarr >":
icon: sh-tdarr
href: "{{HOMEPAGE_VAR_TDARR_HOST}}"
description: Transcode
server: my-docker
container: tdarr
widget:
type: tdarr
url: "{{HOMEPAGE_VAR_TDARR_ADDRESS}}"
key: "{{HOMEPAGE_VAR_TDARR_KEY}}"
highlight:
queue:
numeric:
- level: warn
when: gt
value: 0
errored:
numeric:
- level: danger
when: gt
value: 0
- "Media_1":
- "Open WebUI":
icon: sh-open-webui
href: "{{HOMEPAGE_VAR_OPENWEBUI_HOST}}"
siteMonitor: "{{HOMEPAGE_VAR_OPENWEBUI_ADDRESS}}"
description: Chatbot
- "Port Updater":
icon: sh-docker
description: Shell
server: my-docker
container: port-updater
- "VLLM Status":
icon: sh-vllm
server: my-docker
href: "{{HOMEPAGE_VAR_WEB_PROTOCOL}}://{{HOMEPAGE_VAR_SERVER_NAME}}:9119"
container: vllm
description: LLM Serving
- "Media_2":
- "Plex >":
icon: sh-plex
#icon: sh-plex-dark
href: "{{HOMEPAGE_VAR_PLEX_HOST}}"
description: Watch
siteMonitor: "{{HOMEPAGE_VAR_PLEX_ADDRESS}}"
widget:
type: plex
url: "{{HOMEPAGE_VAR_PLEX_ADDRESS}}"
key: "{{HOMEPAGE_VAR_PLEX_KEY}}"
fields: [albums, movies, tv]
- "Tautulli >":
icon: sh-tautulli
href: "{{HOMEPAGE_VAR_TAUTULLI_HOST}}"
description: Monitor
server: my-docker
container: tautulli
widget:
type: tautulli
url: "{{HOMEPAGE_VAR_TAUTULLI_ADDRESS}}"
key: "{{HOMEPAGE_VAR_TAUTULLI_KEY}}"
enableUser: false
expandOneStreamToTwoRows: false
- "Sonarr >":
icon: sh-sonarr
href: "{{HOMEPAGE_VAR_SONARR_HOST}}"
description: Shows
server: my-docker
container: sonarr
widget:
type: sonarr
url: "{{HOMEPAGE_VAR_SONARR_ADDRESS}}"
key: "{{HOMEPAGE_VAR_SONARR_KEY}}"
enableQueue: false # shows a long list of queued items. looks ugly unless you reorder the page yourself
fields: [wanted, queued]
highlight:
queued:
numeric:
- level: warn
when: gt
value: 0
- Upcoming TV Episodes:
icon: sh-sonarr
server: my-docker
container: sonarr
widget:
type: calendar
firstDayInWeek: sunday # optional - defaults to monday
view: agenda # optional - possible values monthly, agenda
maxEvents: 2 # optional - defaults to 10
showTime: true # optional - show time for event happening today - defaults to false
timezone: America/Los_Angeles
integrations: # optional
- type: sonarr
service_name: "Sonarr >"
baseUrl: "{{HOMEPAGE_VAR_SONARR_HOST}}"
unmonitored: true
- "Radarr >":
icon: sh-radarr
href: "{{HOMEPAGE_VAR_RADARR_HOST}}"
description: Movies
server: my-docker
container: radarr
widget:
type: radarr
url: "{{HOMEPAGE_VAR_RADARR_ADDRESS}}"
key: "{{HOMEPAGE_VAR_RADARR_KEY}}"
fields: [wanted, queued]
highlight:
queued:
numeric:
- level: warn
when: gt
value: 0
- Upcoming Movies:
icon: sh-radarr
server: my-docker
container: radarr
widget:
type: calendar
firstDayInWeek: sunday # optional - defaults to monday
view: agenda # optional - possible values monthly, agenda
maxEvents: 2 # optional - defaults to 10
showTime: true # optional - show time for event happening today - defaults to false
timezone: America/Los_Angeles
integrations: # optional
- type: radarr
service_name: "Radarr >"
baseUrl: "{{HOMEPAGE_VAR_RADARR_HOST}}"
unmonitored: true
- "Lidarr >":
icon: sh-lidarr
href: "{{HOMEPAGE_VAR_LIDARR_HOST}}"
description: Music
server: my-docker
container: lidarr
widget:
type: lidarr
url: "{{HOMEPAGE_VAR_LIDARR_ADDRESS}}"
key: "{{HOMEPAGE_VAR_LIDARR_KEY}}"
fields: [wanted, queued]
highlight:
queued:
numeric:
- level: warn
when: gt
value: 0
- "Seerr >":
icon: sh-overseerr
href: "{{HOMEPAGE_VAR_SEERR_HOST}}"
description: Request
server: my-docker
container: seerr
widget:
type: seerr
url: "{{HOMEPAGE_VAR_SEERR_ADDRESS}}"
key: "{{HOMEPAGE_VAR_SEERR_KEY}}"
fields: [completed, pending]
highlight:
pending:
numeric:
- level: warn
when: gt
value: 0
- "Bazarr >":
icon: sh-bazarr
href: "{{HOMEPAGE_VAR_BAZARR_HOST}}"
description: Subtitles
server: my-docker
container: bazarr
widget:
type: bazarr
url: "{{HOMEPAGE_VAR_BAZARR_ADDRESS}}"
key: "{{HOMEPAGE_VAR_BAZARR_KEY}}"
# fields: [wanted, queued]
highlight:
queued:
numeric:
- level: warn
when: gt
value: 0
- "Spotizerr":
icon: sh-spotify
href: http://shaan-server:7171
server: my-docker
container: spotizerr
- "Media_Bottom":
- "Tdarr >":
icon: sh-tdarr
href: "{{HOMEPAGE_VAR_TDARR_HOST}}"
description: Transcode
server: my-docker
container: tdarr-node
widget:
type: tdarr
url: "{{HOMEPAGE_VAR_TDARR_ADDRESS}}"
key: "{{HOMEPAGE_VAR_TDARR_KEY}}"
highlight:
queue:
numeric:
- level: warn
when: gt
value: 0
errored:
numeric:
- level: danger
when: gt
value: 0
- "Network":
- "Network_1":
- "Portainer":
icon: sh-portainer-light
href: https://shaan-server:9443
description: Containers
server: my-docker
container: portainer
widget:
type: portainer
url: https://shaan-server:9443
env: 3
key: "{{HOMEPAGE_VAR_PORTAINER_KEY}}"
- "Pi-Hole Adblocker":
icon: sh-pi-hole
href: "http://192.168.50.2:6060/admin/login"
description: DNS
server: my-docker
container: pihole
widget:
type: pihole
url: http://shaan-server:6060
version: 6 # required if running v6 or higher, defaults to 5
key: "{{HOMEPAGE_VAR_PIHOLE_PASSWORD}}"
- "Network_2":
- "Scrutiny":
icon: sh-scrutiny
href: http://192.168.50.2:4545 #"{{HOMEPAGE_VAR_SCRUTINY_ADDRESS}}""
description: S.M.A.R.T.
server: my-docker
container: scrutiny
widget:
type: scrutiny
url: http://192.168.50.2:4545 #"{{HOMEPAGE_VAR_SCRUTINY_ADDRESS}}"
- "Karakeep":
icon: sh-karakeep-light
href: http://192.168.50.2:4545 #"{{HOMEPAGE_VAR_SCRUTINY_ADDRESS}}""
description: Bookmarks
server: my-docker
container: karakeep
widget:
type: karakeep
url: http://shaan-server:4621
key: ak2_bfee1806ec533a9557bd_940feeb8fbe798d465ab6f90a3562c43
- "Network_qbit":
- "Prowlarr >":
icon: sh-prowlarr
href: "{{HOMEPAGE_VAR_PROWLARR_HOST}}"
description: Indexers
server: my-docker
container: prowlarr
widget:
type: prowlarr
url: "{{HOMEPAGE_VAR_PROWLARR_ADDRESS}}"
key: "{{HOMEPAGE_VAR_PROWLARR_KEY}}"
#fields: ["numberOfGrabs"]
highlight:
"numberOfGrabs":
numeric:
- level: warn
when: lte
value: 0
"numberOfQueries":
numeric:
- level: warn
when: lte
value: 0
"numberOfFailGrabs":
numeric:
- level: warn
when: gt
value: 0
"numberOfFailQueries":
numeric:
- level: warn
when: gt
value: 0
- "Network_1":
- "Portainer":
icon: sh-portainer-light
href: https://shaan-server:9443
description: Containers
server: my-docker
container: portainer
widget:
type: portainer
url: https://portainer:9443
env: 3
key: "{{HOMEPAGE_VAR_PORTAINER_KEY}}"
- "Pi-Hole Adblocker":
icon: sh-pi-hole
href: "{{HOMEPAGE_VAR_PIHOLE_ADDRESS}}/admin/login"
description: DNS
server: my-docker
container: pihole
widget:
type: pihole
url: "{{HOMEPAGE_VAR_PIHOLE_ADDRESS}}"
version: 6 # required if running v6 or higher, defaults to 5
key: "{{HOMEPAGE_VAR_PIHOLE_PASSWORD}}"
- "Network_2":
- "Scrutiny":
icon: sh-scrutiny
href: "{{HOMEPAGE_VAR_SCRUTINY_HOST}}"
description: S.M.A.R.T.
server: my-docker
container: scrutiny
widget:
type: scrutiny
url: "{{HOMEPAGE_VAR_SCRUTINY_ADDRESS}}"
- "Karakeep":
icon: sh-karakeep-light
href: "{{HOMEPAGE_VAR_KARAKEEP_HOST}}"
description: Bookmarks
server: my-docker
container: karakeep
widget:
type: karakeep
url: "{{HOMEPAGE_VAR_KARAKEEP_ADDRESS}}"
key: ak2_bfee1806ec533a9557bd_940feeb8fbe798d465ab6f90a3562c43
- "Network_qbit":
- "Prowlarr >":
icon: sh-prowlarr
href: "{{HOMEPAGE_VAR_PROWLARR_HOST}}"
description: Indexers
server: my-docker
container: prowlarr
widget:
type: prowlarr
url: "{{HOMEPAGE_VAR_PROWLARR_ADDRESS}}"
key: "{{HOMEPAGE_VAR_PROWLARR_KEY}}"
#fields: ["numberOfGrabs"]
highlight:
"numberOfGrabs":
numeric:
- level: warn
when: lte
value: 0
"numberOfQueries":
numeric:
- level: warn
when: lte
value: 0
"numberOfFailGrabs":
numeric:
- level: warn
when: gt
value: 0
"numberOfFailQueries":
numeric:
- level: warn
when: gt
value: 0
- "qBittorrent Active >":
icon: sh-qbittorrent
href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}"
server: my-docker
container: qbittorrent
#description:
widget:
type: customapi
url: "{{HOMEPAGE_VAR_QBITTORRENT_ADDRESS}}/api/v2/torrents/info?filter=seeding"
mappings:
#- field:
- field: _count
label: "Active"
format: integer
scale: 1
highlight:
"Active":
numeric:
- level: danger
when: lte
value: 20
- "qBittorrent Active >":
icon: sh-qbittorrent
href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}"
server: my-docker
container: qbittorrent
#description:
widget:
type: customapi
url: "{{HOMEPAGE_VAR_QBITTORRENT_ADDRESS}}/api/v2/torrents/info?filter=seeding"
mappings:
#- field:
- field: _count
label: "Active"
format: integer
scale: 1
highlight:
"Active":
numeric:
- level: danger
when: lte
value: 20
- "qBittorrent Status >":
icon: sh-qbittorrent
href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}"
server: my-docker
container: qbittorrent
widget:
type: customapi
url: "{{HOMEPAGE_VAR_QBITTORRENT_ADDRESS}}/api/v2/sync/maindata"
mappings:
- field: server_state.connection_status
label: "status"
format: string
- field: server_state.dht_nodes
label: "DHT"
format: integer
scale: 1
- field: server_state.last_external_address_v4
label: "Address"
format: string
highlight:
"status":
string:
- level: danger
when: equals
value: connected
negate: true
"DHT":
#valueOnly: true
numeric:
- level: danger
when: lte
value: 0
- level: warn
when: lte
value: 200
- "qBittorrent Status >":
icon: sh-qbittorrent
href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}"
server: my-docker
container: qbittorrent
widget:
type: customapi
url: "{{HOMEPAGE_VAR_QBITTORRENT_ADDRESS}}/api/v2/sync/maindata"
mappings:
- field: server_state.connection_status
label: "status"
format: string
- field: server_state.dht_nodes
label: "DHT"
format: integer
scale: 1
- field: server_state.last_external_address_v4
label: "Address"
format: string
highlight:
"status":
string:
- level: danger
when: equals
value: connected
negate: true
"DHT":
#valueOnly: true
numeric:
- level: danger
when: lte
value: 0
- level: warn
when: lte
value: 200
- "qBittorrent Stats >":
icon: sh-qbittorrent
href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}"
server: my-docker
container: qbittorrent
widget:
type: customapi
url: "{{HOMEPAGE_VAR_QBITTORRENT_ADDRESS}}/api/v2/sync/maindata"
mappings:
- field: server_state.alltime_dl
label: "T. Down"
format: bytes
scale: 0.862
- field: server_state.alltime_ul
label: "T. Up"
format: bytes
scale: 0.862
- field: server_state.global_ratio
label: "Ratio"
format: percent
scale: 100
#suffix: "%"
highlight:
"Ratio":
numeric:
- level: warn
when: lt
value: 100
- level: danger
when: lte
value: 60
- "qBittorrent Stats >":
icon: sh-qbittorrent
href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}"
server: my-docker
container: qbittorrent
widget:
type: customapi
url: "{{HOMEPAGE_VAR_QBITTORRENT_ADDRESS}}/api/v2/sync/maindata"
mappings:
- field: server_state.alltime_dl
label: "T. Down"
format: bytes
scale: 0.862
- field: server_state.alltime_ul
label: "T. Up"
format: bytes
scale: 0.862
- field: server_state.global_ratio
label: "Ratio"
format: percent
scale: 100
#suffix: "%"
highlight:
"Ratio":
numeric:
- level: warn
when: lt
value: 100
- level: danger
when: lte
value: 60
- "qBittorrent Session >":
icon: sh-qbittorrent
href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}"
server: my-docker
container: qbittorrent
widget:
type: customapi
url: "{{HOMEPAGE_VAR_QBITTORRENT_ADDRESS}}/api/v2/sync/maindata"
key: "{{HOMEPAGE_VAR_QBITTORRENT_KEY}}"
mappings:
- field: server_state.dl_info_speed
label: Down
format: bitrate
scale: 0.862
- field: server_state.dl_info_data
label: T. Down
format: bytes
scale: 0.862
- field: server_state.up_info_speed
label: Up
format: bitrate
scale: 0.862
- field: server_state.up_info_data
label: T. Up
format: bytes
scale: 0.862
highlight:
"Down":
numeric:
- level: good
when: gt
value: 0
"Up":
numeric:
- level: good
when: gt
value: 0
- "qBittorrent Session >":
icon: sh-qbittorrent
href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}"
server: my-docker
container: qbittorrent
widget:
type: customapi
url: "{{HOMEPAGE_VAR_QBITTORRENT_ADDRESS}}/api/v2/sync/maindata"
key: "{{HOMEPAGE_VAR_QBITTORRENT_KEY}}"
mappings:
- field: server_state.dl_info_speed
label: Down
format: bitrate
scale: 0.862
- field: server_state.dl_info_data
label: T. Down
format: bytes
scale: 0.862
- field: server_state.up_info_speed
label: Up
format: bitrate
scale: 0.862
- field: server_state.up_info_data
label: T. Up
format: bytes
scale: 0.862
highlight:
"Down":
numeric:
- level: good
when: gt
value: 0
"Up":
numeric:
- level: good
when: gt
value: 0
Regular → Executable
+4 -4
View File
@@ -6,7 +6,7 @@ instanceName: torrent-stack
# Aesthetics
background:
image: /images/wallhaven-pk997m.jpg
image: ./images/wallhaven-pk997m.jpg
#blur: sm # Options: sm, md, lg, xl
#saturate: 10
#brightness: 10
@@ -44,20 +44,20 @@ layout:
tab: Apps
iconsOnly: false
header: true
disableCollapse: true
initiallyCollapsed: false
style: row
columns: 3
"Admin":
tab: Apps
iconsOnly: false
header: true
disableCollapse: true
initiallyCollapsed: false
style: row
columns: 3
"Bookmarks":
tab: Apps
header: true
initiallyCollapsed: true
initiallyCollapsed: false
style: row
columns: 3
"Top":
Regular → Executable
View File
+157
View File
@@ -0,0 +1,157 @@
# =============================================================================
# Torrent Stack (infra) - DNS, management & monitoring
#
# Split from compose.yml on 2026-09-11 - verbatim service blocks.
# Shared top-level networks:/volumes: are repeated in each subfile so it also
# works standalone (docker compose -f infra.yml up -d). Identical copies merge
# cleanly under compose.yml's `include:` with no change to the live config.
# Keep ./ paths, container names and /mnt data as-is.
# =============================================================================
networks:
#caddy_net:
# external: true
tdarr-net:
driver: bridge
default:
name: portainer_network
volumes:
#caddy_config:
#caddy_data:
# external: true
#myspeed:
# external: true
portainer_data:
name: portainer_data
services:
# ---------------------------------------------------------------------------
# Monitoring
# ---------------------------------------------------------------------------
# glances:
# image: ${GLANCES_IMAGE}
# container_name: glances
# network_mode: host
# volumes:
# - /etc/os-release:/etc/os-release:ro
# - /:/host:ro
# #- /etc/localtime:/etc/localtime:ro
# #- /etc/timezone:/etc/timezone:ro
# environment:
# - "GLANCES_OPT=-w --password ${GLANCES_PASSWORD}"
# - PUID=${HOST_PUID:-1000}
# - PGID=${HOST_PGID:-1000}
# - TZ=${TIMEZONE}
# healthcheck:
# test:
# ["CMD", "curl", "-f", "http://localhost:${GLANCES_PORT}/api/4/status"]
# interval: 1m
# timeout: 10s
# retries: 3
# start_period: 60s
# security_opt:
# - no-new-privileges:true
# mem_limit: 256m
# cpus: 1.0
# devices:
# - /dev/dri:/dev/dri
# restart: unless-stopped
# # Uncomment to protect Glances WebUI by a login/password (add --password to GLANCES_OPT)
# secrets:
# - source: glances_password
# target: /root/.config/glances/<login>.pwd
# secrets:
# glances_password:
# file: ./secrets/glances_password
autoheal:
image: ${AUTOHEAL_IMAGE}
container_name: autoheal
volumes:
- /var/run/docker.sock:/var/run/docker.sock
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- AUTOHEAL_CONTAINER_LABEL=all
- AUTOHEAL_INTERVAL=30
- AUTOHEAL_START_PERIOD=60
- TZ=${TIMEZONE}
security_opt:
- no-new-privileges:true
read_only: true
mem_limit: 64m
cpus: 0.25
restart: unless-stopped
scrutiny:
image: ${SCRUTINY_IMAGE}
container_name: scrutiny
cap_add:
- SYS_RAWIO
ports:
- ${SCRUTINY_PORT}:8080
- ${SCRUTINY_ADMIN_PORT}:8086
volumes:
- /run/udev:/run/udev:ro
- ./scrutiny/config:/opt/scrutiny/config
- ./scrutiny/influxdb:/opt/scrutiny/influxdb
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- TZ=${TIMEZONE}
security_opt:
- no-new-privileges:true
mem_limit: 128m
cpus: 0.25
devices:
- /dev/nvme0n1
- /dev/sda
restart: unless-stopped
# ---------------------------------------------------------------------------
# Infrastructure
# ---------------------------------------------------------------------------
pihole:
image: ${PIHOLE_IMAGE}
container_name: pihole
cap_add:
- NET_ADMIN # Allows managing network interfaces & sockets
- NET_BIND_SERVICE # Allows non-root users to bind to ports < 1024 (port 53 & 123)
- SYS_TIME # Resolves the NTP system time warning
network_mode: host
volumes:
- ./etc-pihole:/etc/pihole
- ./etc-dnsmasq.d:/etc/dnsmasq.d
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- TZ=${TIMEZONE}
- FTLCONF_misc_etc_dnsmasq_d=true
- FTLCONF_webserver_port=${PIHOLE_PORT:-80}
# security_opt:
# - no-new-privileges:true
mem_limit: 256m
cpus: 1.0
restart: unless-stopped
portainer:
image: ${PORTAINER_IMAGE}
container_name: portainer
ports:
- ${PORTAINER_PORT}:${PORTAINER_PORT}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- TZ=${TIMEZONE}
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
restart: unless-stopped
+517
View File
@@ -0,0 +1,517 @@
# =============================================================================
# Torrent Stack (media) - VPN, *arr stack & media tooling
#
# Split from compose.yml on 2026-09-11 - verbatim service blocks.
# Shared top-level networks:/volumes: are repeated in each subfile so it also
# works standalone (docker compose -f media.yml up -d). Identical copies merge
# cleanly under compose.yml's `include:` with no change to the live config.
# Keep ./ paths, container names and /mnt data as-is.
# =============================================================================
networks:
#caddy_net:
# external: true
tdarr-net:
driver: bridge
default:
name: portainer_network
volumes:
#caddy_config:
#caddy_data:
# external: true
#myspeed:
# external: true
portainer_data:
name: portainer_data
redis-data:
driver: local
services:
# ---------------------------------------------------------------------------
# VPN & Download
# ---------------------------------------------------------------------------
gluetun:
image: ${GLUETUN_IMAGE}
container_name: gluetun
env_file:
- .env
- ./env/.gluetun.env
cap_add:
- NET_ADMIN
ports:
- 8877:8000/tcp
- ${QBITTORRENT_PORT}:${QBITTORRENT_PORT}
- ${PROWLARR_PORT}:${PROWLARR_PORT}
- ${SONARR_PORT}:${SONARR_PORT}
- ${RADARR_PORT}:${RADARR_PORT}
- ${LIDARR_PORT}:${LIDARR_PORT}
- ${BAZARR_PORT}:${BAZARR_PORT}
volumes:
- ./gluetun-data:/tmp/gluetun:rw
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- VPN_SERVICE_PROVIDER=protonvpn
- VPN_TYPE=wireguard
- HTTP_CONTROL_SERVER=ON
- WIREGUARD_MTU=1280
- VPN_PORT_FORWARDING=on
- VPN_PORT_FORWARDING_PROVIDER=protonvpn
- SERVER_COUNTRIES=Netherlands
- NETWORK_LOCAL_ADDRESSES=192.168.50.0/24,172.16.0.0/12
- FIREWALL_OUTBOUND_SUBNETS=192.168.50.0/24
- HEALTH_SERVER_ADDRESS=0.0.0.0:8877
- HEALTH_TARGET_ADDRESSES=${EXTERNAL_IPV4}:${PLEX_PFWD_PORT}
- TZ=${TIMEZONE}
- DNS_UPSTREAM_RESOLVER_TYPE=doh
healthcheck:
test:
[
"CMD-SHELL",
"wget -qO- '${WEB_PROTOCOL}://${EXTERNAL_IPV4}:${PLEX_PFWD_PORT}/identity' | grep -q 'MediaContainer' || exit 1",
]
interval: 1m30s
timeout: 15s
retries: 3
start_period: 45s
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
devices:
- /dev/net/tun:/dev/net/tun
restart: no
qbittorrent:
image: ${QBITTORRENT_IMAGE}
container_name: qbittorrent
network_mode: "container:gluetun"
depends_on:
gluetun:
condition: service_healthy
volumes:
- ./qbittorrent:/config
- ${DISK1}:${DISK1}
- ${DISK2}:${DISK2}
- ./gluetun-data:/tmp/gluetun
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
- WEBUI_PORT=${QBITTORRENT_PORT}
labels:
- "autoheal=true"
healthcheck:
test:
[
"CMD-SHELL",
"curl -sf '${WEB_PROTOCOL}://${EXTERNAL_IPV4}:${PLEX_PFWD_PORT}/identity' | grep -q 'MediaContainer' || exit 1",
]
interval: 1m
timeout: 10s
retries: 3
start_period: 30s
security_opt:
- no-new-privileges:true
mem_limit: 512m
cpus: 1.0
restart: unless-stopped
port-updater:
image: curlimages/curl:8.21.0
container_name: port-updater
network_mode: "container:gluetun"
depends_on:
gluetun:
condition: service_healthy
volumes:
- ./gluetun-data:/tmp/gluetun:ro
entrypoint: ["/bin/sh", "-c"]
command:
- |
trap 'exit 0' SIGTERM;
while true; do
while [ ! -s /tmp/gluetun/forwarded_port ]; do
echo "Waiting for Gluetun to provide a port..."
sleep 5
done
read -r PORT_VAL < /tmp/gluetun/forwarded_port;
CLEAN_PORT=$$(echo "$$PORT_VAL" | tr -d '\r\n ');
if [ -n "$$CLEAN_PORT" ]; then
echo "Updating qBit to port: $$CLEAN_PORT";
sleep 10;
curl -s -X POST -d "json={\"listen_port\":$$CLEAN_PORT}" http://localhost:${QBITTORRENT_PORT}/api/v2/app/setPreferences;
sleep 3600 & wait $$!;
else
sleep 10
fi
done
labels:
- "autoheal=true"
healthcheck:
test:
[
"CMD-SHELL",
"curl -sf '${WEB_PROTOCOL}://${EXTERNAL_IPV4}:${PLEX_PFWD_PORT}/identity' | grep -q 'MediaContainer' || exit 1",
]
interval: 1m
timeout: 10s
retries: 3
start_period: 30s
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp
mem_limit: 64m
cpus: 0.25
restart: unless-stopped
# ---------------------------------------------------------------------------
# *arr Stack
# ---------------------------------------------------------------------------
prowlarr:
image: ${PROWLARR_IMAGE}
container_name: prowlarr
network_mode: "container:gluetun"
depends_on:
gluetun:
condition: service_healthy
volumes:
- ./prowlarr:/config
- ./notify.sh:/notify.sh:ro
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
labels:
- "autoheal=true"
healthcheck:
test:
[
"CMD-SHELL",
"curl -sf '${WEB_PROTOCOL}://${EXTERNAL_IPV4}:${PLEX_PFWD_PORT}/identity' | grep -q 'MediaContainer' || exit 1",
]
interval: 1m
timeout: 10s
retries: 3
start_period: 30s
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
restart: unless-stopped
sonarr:
image: ${SONARR_IMAGE}
container_name: sonarr
network_mode: "container:gluetun"
depends_on:
gluetun:
condition: service_healthy
volumes:
- ./sonarr:/config
- ${DISK1}:${DISK1}
- ${DISK2}:${DISK2}
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
labels:
- "autoheal=true"
healthcheck:
test:
[
"CMD-SHELL",
"curl -sf '${WEB_PROTOCOL}://${EXTERNAL_IPV4}:${PLEX_PFWD_PORT}/identity' | grep -q 'MediaContainer' || exit 1",
]
interval: 1m
timeout: 10s
retries: 3
start_period: 60s
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
restart: unless-stopped
radarr:
image: ${RADARR_IMAGE}
container_name: radarr
network_mode: "container:gluetun"
depends_on:
gluetun:
condition: service_healthy
volumes:
- ./radarr:/config
- ${DISK1}:${DISK1}
- ${DISK2}:${DISK2}
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
labels:
- "autoheal=true"
healthcheck:
test:
[
"CMD-SHELL",
"curl -sf '${WEB_PROTOCOL}://${EXTERNAL_IPV4}:${PLEX_PFWD_PORT}/identity' | grep -q 'MediaContainer' || exit 1",
]
interval: 1m
timeout: 10s
retries: 3
start_period: 30s
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
restart: unless-stopped
lidarr:
image: ${LIDARR_IMAGE}
container_name: lidarr
network_mode: "container:gluetun"
depends_on:
gluetun:
condition: service_healthy
volumes:
- ./lidarr:/music
- ./lidarr:/config
- ${DISK1}:${DISK1}
- ${DISK2}:${DISK2}
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
labels:
- "autoheal=true"
healthcheck:
test:
[
"CMD-SHELL",
"curl -sf '${WEB_PROTOCOL}://${EXTERNAL_IPV4}:${PLEX_PFWD_PORT}/identity' | grep -q 'MediaContainer' || exit 1",
]
interval: 1m
timeout: 10s
retries: 3
start_period: 30s
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
restart: unless-stopped
bazarr:
image: ${BAZARR_IMAGE}
container_name: bazarr
network_mode: "container:gluetun"
depends_on:
gluetun:
condition: service_healthy
volumes:
- ./bazarr:/config
- ${DISK1}:${DISK1}
- ${DISK2}:${DISK2}
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
labels:
- "autoheal=true"
healthcheck:
test:
[
"CMD-SHELL",
"curl -sf '${WEB_PROTOCOL}://${EXTERNAL_IPV4}:${PLEX_PFWD_PORT}/identity' | grep -q 'MediaContainer' || exit 1",
]
interval: 1m
timeout: 10s
retries: 3
start_period: 30s
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
restart: unless-stopped
# ---------------------------------------------------------------------------
# Media
# ---------------------------------------------------------------------------
tautulli:
image: ${TAUTULLI_IMAGE}
container_name: tautulli
#networks:
# - caddy_net
ports:
- ${TAUTULLI_PORT}:${TAUTULLI_PORT}
volumes:
- ./tautulli:/config
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
restart: unless-stopped
tdarr:
image: ${TDARR_IMAGE}
container_name: tdarr
networks:
- tdarr-net
ports:
- ${TDARR_PORT}:${TDARR_PORT}
- ${TDARR_NODE_PORT}:${TDARR_NODE_PORT}
volumes:
- ./tdarr/server:/app/server
- ./tdarr/configs:/app/configs
- ./tdarr/temp:/temp
- ${DISK1}:${DISK1}
- ${DISK2}:${DISK2}
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- TZ=${TIMEZONE}
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- UMASK_SET=002
- serverIP=0.0.0.0
security_opt:
- no-new-privileges:true
mem_limit: 512m
cpus: 2.0
restart: unless-stopped
tdarr-node:
image: ${TDARR_NODE_IMAGE}
container_name: tdarr-node
networks:
- tdarr-net
volumes:
- ./tdarr/configs:/app/configs
- ./tdarr/logs:/app/logs
- ./tdarr/temp:/temp
- ${DISK1}:${DISK1}
- ${DISK2}:${DISK2}
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- TZ=${TIMEZONE}
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- nodeID=${TDARR_NODE_ID}
- nodeIP=0.0.0.0
- serverIP=tdarr
- serverPort=${TDARR_NODE_PORT}
security_opt:
- no-new-privileges:true
mem_limit: 4g
cpus: 4.0
devices:
- /dev/dri:/dev/dri
restart: unless-stopped
seerr:
image: ${SEERR_IMAGE}
container_name: seerr
# networks:
# - caddy_net
ports:
- ${SEERR_PORT}:${SEERR_PORT}
volumes:
- ./seerr:/app/config
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- LOG_LEVEL=info
- TZ=${TIMEZONE}
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
labels:
- "autoheal=true"
init: true
working_dir: "/app"
healthcheck:
test:
[
"CMD-SHELL",
"wget -qO- '${WEB_PROTOCOL}://${EXTERNAL_IPV4}:${PLEX_PFWD_PORT}/identity' | grep -q 'MediaContainer' || exit 1",
]
interval: 1m
timeout: 10s
retries: 3
start_period: 60s
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
restart: unless-stopped
spotizerr:
image: spotizerrphoenix/spotizerr
user: "1000:1000" # Spotizerr user:group ids
volumes:
# Ensure these directories and the .cache file exist and are writable by the container user
- ./spotizerr:/app/data # data directory, contains config, creds, watch, history
- ${DISK1}/media/Music/spotizerr:/app/downloads # downloads directory, contains downloaded files
- ./spotizerr/logs:/app/logs # logs directory, contains logs
- ./spotizerr/.cache:/app/.cache # cache file
ports:
# Port to expose the app on
- 7171:7171
container_name: spotizerr
restart: unless-stopped
env_file:
# Ensure you have a .env file in the root of the project, with the correct values
- ./.env
depends_on:
- redis
redis:
image: redis:alpine
container_name: spotizerr-redis
restart: unless-stopped
env_file:
- .env
volumes:
- redis-data:/data
command: sh -c 'redis-server --requirepass "$REDIS_PASSWORD" --appendonly yes'
# Anubis anti-bot proxy for Seerr (uncomment to enable):
#seerr-anubis:
# image: ghcr.io/techarohq/anubis:latest
# container_name: seerr-anubis
# networks:
# - caddy_net
# environment:
# - BIND=:55055
# - TARGET=http://seerr:${SEERR_PORT}
# security_opt:
# - no-new-privileges:true
# mem_limit: 128m
# cpus: 0.5
# restart: unless-stopped
+2 -9
View File
@@ -2,12 +2,5 @@
sleep 15
cd /home/shaan/torrent-stack || exit
docker compose up -d gluetun & sleep 90
docker compose up -d
sleep 5
cd /home/shaan/torrent-stack/odysseus || exit
git pull . dev
docker compose pull
docker compose up -d
docker compose config ||> /tmp/startup.log && exit 1
docker compose up -d 2>&1 | tee /tmp/startup.log
+287
View File
@@ -0,0 +1,287 @@
# =============================================================================
# Torrent Stack (web) - dashboard, edge & AI services
#
# Split from compose.yml on 2026-09-11 - verbatim service blocks.
# Shared top-level networks:/volumes: are repeated in each subfile so it also
# works standalone (docker compose -f web.yml up -d). Identical copies merge
# cleanly under compose.yml's `include:` with no change to the live config.
# Keep ./ paths, container names and /mnt data as-is.
# =============================================================================
networks:
#caddy_net:
# external: true
tdarr-net:
driver: bridge
default:
name: portainer_network
volumes:
#caddy_config:
#caddy_data:
# external: true
#myspeed:
# external: true
portainer_data:
name: portainer_data
services:
# ---------------------------------------------------------------------------
# Dashboard
# ---------------------------------------------------------------------------
homepage:
image: ${HOMEPAGE_IMAGE}
container_name: homepage
env_file:
- .env
- ./env/.homepage.env
#networks:
# - caddy_net
ports:
- ${HOMEPAGE_PORT}:${HOMEPAGE_PORT}
volumes:
- ./homepage:/app/config
- ./homepage/images:/app/public/images
- /var/run/docker.sock:/var/run/docker.sock:ro
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- "HOMEPAGE_ALLOWED_HOSTS=gethomepage.dev,${LOCAL_IPV4}:${HOMEPAGE_PORT},${SERVER_NAME}:${HOMEPAGE_PORT},${SERVER_NAME}.${TAILNET_NAME}:${HOMEPAGE_PORT},host.docker.internal:{HOMEPAGE_PORT}"
- "HOMEPAGE_VAR_DISK1=${DISK1}"
- "HOMEPAGE_VAR_DISK2=${DISK2}"
- "HOMEPAGE_VAR_DISK3=${DISK3}"
- "HOMEPAGE_VAR_WEB_PROTOCOL=${WEB_PROTOCOL}"
- "HOMEPAGE_VAR_LOCAL_IPV4=${LOCAL_IPV4}"
- "HOMEPAGE_VAR_SERVER_NAME=${SERVER_NAME}"
- "HOMEPAGE_VAR_PLEX_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${PLEX_PORT}"
- "HOMEPAGE_VAR_QBITTORRENT_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${QBITTORRENT_PORT}"
- "HOMEPAGE_VAR_PROWLARR_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${PROWLARR_PORT}"
- "HOMEPAGE_VAR_SONARR_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${SONARR_PORT}"
- "HOMEPAGE_VAR_RADARR_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${RADARR_PORT}"
- "HOMEPAGE_VAR_LIDARR_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${LIDARR_PORT}"
- "HOMEPAGE_VAR_BAZARR_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${BAZARR_PORT}"
- "HOMEPAGE_VAR_TAUTULLI_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${TAUTULLI_PORT}"
- "HOMEPAGE_VAR_TDARR_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${TDARR_PORT}"
- "HOMEPAGE_VAR_HOMEPAGE_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${HOMEPAGE_PORT}"
- "HOMEPAGE_VAR_GLANCES_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${GLANCES_PORT}"
- "HOMEPAGE_VAR_SEERR_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${SEERR_PORT}"
- "HOMEPAGE_VAR_OPENWEBUI_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${OPENWEBUI_PORT}"
- "HOMEPAGE_VAR_PIHOLE_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${PIHOLE_PORT}"
- "HOMEPAGE_VAR_PORTAINER_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${PORTAINER_PORT}"
- "HOMEPAGE_VAR_SCRUTINY_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${SCRUTINY_PORT}"
- "HOMEPAGE_VAR_KARAKEEP_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${KARAKEEP_PORT}"
- "HOMEPAGE_VAR_VLLM_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${VLLM_PORT}"
- "HOMEPAGE_VAR_PLEX_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${PLEX_PORT}"
- "HOMEPAGE_VAR_QBITTORRENT_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${QBITTORRENT_PORT}"
- "HOMEPAGE_VAR_PROWLARR_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${PROWLARR_PORT}"
- "HOMEPAGE_VAR_SONARR_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${SONARR_PORT}"
- "HOMEPAGE_VAR_RADARR_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${RADARR_PORT}"
- "HOMEPAGE_VAR_LIDARR_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${LIDARR_PORT}"
- "HOMEPAGE_VAR_BAZARR_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${BAZARR_PORT}"
- "HOMEPAGE_VAR_TAUTULLI_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${TAUTULLI_PORT}"
- "HOMEPAGE_VAR_TDARR_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${TDARR_PORT}"
- "HOMEPAGE_VAR_HOMEPAGE_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${HOMEPAGE_PORT}"
- "HOMEPAGE_VAR_GLANCES_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${GLANCES_PORT}"
- "HOMEPAGE_VAR_SEERR_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${SEERR_PORT}"
- "HOMEPAGE_VAR_OPENWEBUI_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${OPENWEBUI_PORT}"
- "HOMEPAGE_VAR_PIHOLE_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${PIHOLE_PORT}"
- "HOMEPAGE_VAR_PORTAINER_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${PORTAINER_PORT}"
- "HOMEPAGE_VAR_SCRUTINY_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${SCRUTINY_PORT}"
- "HOMEPAGE_VAR_KARAKEEP_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${KARAKEEP_PORT}"
- "HOMEPAGE_VAR_VLLM_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${VLLM_PORT}"
- TZ=${TIMEZONE}
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1
# extra_hosts:
# - "host.docker.internal:${LOCAL_IPV4}"
restart: unless-stopped
# ---------------------------------------------------------------------------
# Edge
# ---------------------------------------------------------------------------
cloudflared:
image: cloudflare/cloudflared:latest
container_name: cloudflared
env_file:
- ./env/.cloudflared.env
command: tunnel --no-autoupdate run # --token ${CLOUDFLARED_KEY}
security_opt:
- no-new-privileges:true
read_only: true
mem_limit: 128m
cpus: 0.5
restart: always
caddy:
image: ${CADDY_IMAGE}
container_name: caddy
#networks:
# - caddy_net
ports:
- 82:80
- 444:443
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile
- ./caddy/site:/srv
- ./caddy/caddy_data:/data
- ./caddy/caddy_config:/config
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- TZ=${TIMEZONE}
security_opt:
- no-new-privileges:true
mem_limit: 128m
cpus: 0.5
restart: unless-stopped
# ---------------------------------------------------------------------------
# Web & AI
# ---------------------------------------------------------------------------
openwebui:
image: ghcr.io/open-webui/open-webui:main-slim
container_name: openwebui
ports:
- "7001:8080"
volumes:
- ./openwebui:/app/backend/data
mem_limit: 1g
cpus: 1.0
searxng:
image: ${SEARXNG_IMAGE}
container_name: searxng
ports:
- "5080:8080"
volumes:
- ./searxng:/etc/searxng
environment:
- SEARXNG_SECRET=abcd
restart: unless-stopped
vllm:
image: vllm/vllm-openai-xpu@sha256:f01e24f6c7ff01f1e0662234255a1372297d1dbd89d003cf13c8fad3eab1ba4f
container_name: vllm
network_mode: host
ipc: host
privileged: true
devices:
- "/dev/dri:/dev/dri"
volumes:
- ~/llm/huggingface:/root/.cache/huggingface
- ~/llm/:/llm/
- ./vllm/xpu-patches:/patches/:ro
environment:
- "HUGGING_FACE_HUB_TOKEN=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"
- "SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=1"
- "ZES_ENABLE_SYSMAN=1"
- "ONEAPI_DEVICE_SELECTOR=level_zero:0"
- "UR_L0_ENABLE_RELAXED_ALLOCATION_LIMITS=1"
- "VLLM_XPU_ENABLE_XPU_GRAPH=1"
- "VLLM_ALLOW_LONG_MAX_MODEL_LEN=1"
- "VLLM_WORKER-MULTIPROC_METHOD=spawn"
- "VLLM_TARGET_DEVICE=xpu"
- "ZE_FLAT_DEVICE_HIERARCHY=COMPOSITE"
- "ZE_AFFINITY_MASK=0"
- "B70_MTP_BF16_DRAFT=1"
- "B70_DRAFT_LMHEAD_INT4=1"
- "B70_DRAFT_MTP_INT4=1"
- "PYTORCH_ALLOC_CONF=expandable_segments:True"
entrypoint: ["/bin/bash", "-lc"]
command:
- |
set -e
python /patches/patch_mtp_nightly.py
python /patches/patch_mtp_boundary.py
python /patches/patch_gdn_mixed_split_v5.py
python /patches/patch_draft_lmhead_int4.py
python /patches/patch_draft_mtp_int4.py
exec vllm serve /llm/Qwen3.8-27B-GPTQINT4-G128-MTP-BF16 \
--quantization gptq \
--dtype float16 \
--max-model-len 131072 \
--gpu-memory-utilization 0.88 \
--kv-cache-dtype fp8 \
--port 5081 \
--max-num-seqs 64 \
--block-size 64 \
--max-num-batched-tokens 8192 \
--served-model-name 'Qwen3.8' \
--language-model-only \
--speculative-config '{"method":"mtp","num_speculative_tokens":4}' \
--reasoning-parser qwen3 \
--tool-call-parser qwen3_coder \
--default-chat-template-kwargs '{"enable_thinking": false, "reasoning_effort": "medium", "reasoning_preserve": "true"}' \
--enable-auto-tool-choice \
--disable-sliding-window \
--enable-prefix-caching \
--enable-chunked-prefill
restart: on-failure:5
# ---------------------------------------------------------------------------
# Karakeep
# ---------------------------------------------------------------------------
karakeep:
image: ghcr.io/karakeep-app/karakeep:${KARAKEEP_VERSION:-release}
container_name: karakeep
env_file:
- ./env/.karakeep.env
ports:
- ${KARAKEEP_PORT}:3000 # must be 3000 as per the dev
volumes:
- ./karakeep-data:/data
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- MEILI_ADDR=http://meilisearch:${MEILI_PORT}
- BROWSER_WEB_URL=http://chrome:${KARAKEEP_CHROME_PORT}
- DATA_DIR=/data
security_opt:
- no-new-privileges:true
mem_limit: 512m
cpus: 1.0
restart: unless-stopped
chrome:
image: zenika/alpine-chrome:124
container_name: karakeep-chromebrowser
command:
- --no-sandbox
- --disable-gpu
- --disable-dev-shm-usage
- --remote-debugging-address=0.0.0.0
- --remote-debugging-port=${KARAKEEP_CHROME_PORT}
- --hide-scrollbars
- --disable-blink-features=AutomationControlled
- --window-size=1440,900
security_opt:
- no-new-privileges:true
mem_limit: 1g
cpus: 1.0
restart: unless-stopped
meilisearch:
image: getmeili/meilisearch:v1.41.0
container_name: karakeep-meilisearch
env_file:
- .env
volumes:
- ./meilisearch:/meili_data
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
environment:
- MEILI_NO_ANALYTICS=true
security_opt:
- no-new-privileges:true
mem_limit: 512m
cpus: 1.0
restart: no