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 ----- # ----- Host -----
LOCAL_IPV4=192.168.50.0 # of your device LOCAL_IPV4=192.168.50.0 # of your device
EXTERNAL_IPV4=123.156.178.190 EXTERNAL_IPV4=255.255.255.0
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. 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=your-server.com WEB_NAME=127.0.0.1
TAILNET_NAME=tasty-food.ts.net TAILNET_NAME=favorite-food.ts.net
WEB_PROTOCOL=http WEB_PROTOCOL=http
# ----- Storage ----- # ----- Storage -----
DISK1=/mnt/media DISK1=/mnt/disk1
DISK2=/mnt/11tb_ext DISK2=/mnt/disk2
DISK3=/mnt/shaimpy DISK3=/mnt/disk3
# ----- Gluetun (VPN) -----
GLUETUN_KEY=
VPN_PRIVATE_KEY=
# ----- Service Ports ----- # ----- Service Ports -----
PLEX_PORT=32400 PLEX_PORT=32400
@@ -39,7 +35,7 @@ LIDARR_PORT=8686
QBITTORRENT_PORT=2161 QBITTORRENT_PORT=2161
TDARR_PORT=8265 TDARR_PORT=8265
TDARR_NODE_PORT=8266 TDARR_NODE_PORT=8266
ODYSSEUS_PORT=7001 OPENWEBUI_PORT=7001
PORTAINER_PORT=9443 PORTAINER_PORT=9443
SCRUTINY_PORT=4545 SCRUTINY_PORT=4545
SCRUTINY_ADMIN_PORT=4646 SCRUTINY_ADMIN_PORT=4646
@@ -47,51 +43,38 @@ PIHOLE_PORT=6060
KARAKEEP_PORT=4621 KARAKEEP_PORT=4621
KARAKEEP_CHROME_PORT=9222 KARAKEEP_CHROME_PORT=9222
MEILI_PORT=7700 MEILI_PORT=7700
LLAMA_PORT=8079 BAZARR_PORT=8787
VLLM_PORT=5081
SPOTIZERR_PORT=7171
SPOTIZERR_REDIS_PORT=6379
TDARR_NODE_ID=ShaanNode TDARR_NODE_ID=ShaanNode
# ----- API Keys (for homepage widgets & service integrations) ----- # ----- Docker Images -----
PLEX_KEY= # get with command:
PROWLARR_KEY= # 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}}'
RADARR_KEY=
SONARR_KEY=
LIDARR_KEY=
TAUTULLI_KEY=
SEERR_KEY=
QBITTORRENT_KEY=
TAILSCALE_KEY=
TAILSCALE_DEVICE_KEY=
CLOUDFLARED_KEY=
# ----- Cloudflare (for homepage widget) ----- TAUTULLI_IMAGE=ghcr.io/tautulli/tautulli:latest
CLOUDFLARED_ACCOUNT_ID= GLUETUN_IMAGE=qmcgaw/gluetun@sha256:e3272b29a4bc177b389fbdcb54cf9716ccbfc30f04d8b7a35b0a5be9cdb58461
CLOUDFLARED_TUNNEL_ID= QBITTORRENT_IMAGE=lscr.io/linuxserver/qbittorrent@sha256:b6ab43fe86039e5bdd3cc0b59b946414fcff0c8183e93636e6cb438fdac45028
CLOUDFLARED_API_KEY= PROWLARR_IMAGE=lscr.io/linuxserver/prowlarr@sha256:1295cff29d10b486c0d8324d1559a552140a5932bf8b3d87e398654414f63f92
SONARR_IMAGE=lscr.io/linuxserver/sonarr@sha256:373159ba768e23a3a1c497d9f2b936addf8fd5b1fdce7dd6a14080ac928bfda0
# ----- Portainer (for homepage widget) ----- RADARR_IMAGE=lscr.io/linuxserver/radarr@sha256:a45b5ab0f850f39edb4cc9c95bbd967b52ddc3d4574a4dfb45561177db6c88f4
PORTAINER_API_KEY= LIDARR_IMAGE=lscr.io/linuxserver/lidarr@sha256:bfec0ec2dc351fa5928379d785b08be395886f109393b9040ed7973bd1008060
BAZARR_IMAGE=lscr.io/linuxserver/bazarr@sha256:819327cb5da94a4187bd0512a8f6f8632541404e52cf5977a96e8865d983b07b
# ----- Pi-hole ----- TDARR_IMAGE=haveagitgat/tdarr@sha256:45742f00e51a58553844c8b13d97e7ae9b2ee9a056bd8e5993d9a8282a45a23f
PIHOLE_WEBPASSWORD= TDARR_NODE_IMAGE=haveagitgat/tdarr_node@sha256:7542459ac5ed5cd299600530e9625b9d590629d5dc391c0016773f5d6aa3fe75
SEERR_IMAGE=ghcr.io/seerr-team/seerr:latest
# ----- Glances ----- SEARXNG_IMAGE=searxng/searxng:latest
GLANCES_USERNAME= OPENWEBUI_IMAGE=ghcr.io/open-webui/open-webui@sha256:f67aea542a85e82cfab8c1de0719487b1566bffbb53c2b5448223611a16889dc
GLANCES_PASSWORD= KARAKEEP_IMAGE=ghcr.io/karakeep-app/karakeep@sha256:5467873df817ab3aa837f2b06bd7f2b0974132ba1ae5bce0b7e2fd134abc269b
CLOUDFLARED_IMAGE=cloudflare/cloudflared:latest
# ----- Karakeep ----- PORTUPDATER_IMAGE=curlimages/curl:8.21.0
# KARAKEEP CADDY_IMAGE=caddy:latest
AUTOHEAL_IMAGE=willfarrell/autoheal:latest
DATA_DIR=/karakeep-data MYSPEED_IMAGE=germannewsmaker/myspeed:latest
MEILI_ADDR=http://127.0.0.1:${MEILI_PORT} HOMEPAGE_IMAGE=ghcr.io/gethomepage/homepage:latest
MEILI_MASTER_KEY= SCRUTINY_IMAGE=ghcr.io/analogj/scrutiny@sha256:9d0e6d146529d9d1407e1d0a9f685d0b6b840cac070e87e0ab62034d9b80c2b7
NEXTAUTH_URL=http://localhost:3001 PIHOLE_IMAGE=pihole/pihole@sha256:f7d1be836e3bc608b56d82fc9904f5a831cdfbc0dc9c6d58f94e4c985c70038b
NEXTAUTH_SECRET= PORTAINER_IMAGE=portainer/portainer-ce:lts
SPOTIZERR_IMAGE=spotizerrphoenix/spotizerr:latest
OPENAI_API_KEY=ollama REDIS_IMAGE=redis:alpine
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
+6 -109
View File
@@ -29,7 +29,12 @@ karakeep-data
SECURITY.md SECURITY.md
init-database.* init-database.*
etc* etc*
!odysseus/.* openwebui/
searxng/
vllm/
bazarr/
docker-data/
spotizerr/
# Only track homepage structural yaml files, ignore app cache # Only track homepage structural yaml files, ignore app cache
homepage/* homepage/*
@@ -38,111 +43,3 @@ homepage/*
!homepage/*.css !homepage/*.css
!homepage/*.js !homepage/*.js
!homepage/images/ !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 @@
# ============================================================================= name: torrent-stack
# Torrent Stack - Docker Compose
# =============================================================================
networks: networks:
caddy_net: #caddy_net:
external: true # external: true
tdarr-net: tdarr-net:
driver: bridge driver: bridge
default: default:
@@ -14,8 +12,8 @@ volumes:
#caddy_config: #caddy_config:
#caddy_data: #caddy_data:
# external: true # external: true
myspeed: #myspeed:
external: true # external: true
portainer_data: portainer_data:
name: portainer_data name: portainer_data
@@ -27,721 +25,7 @@ volumes:
# → devices → restart # → devices → restart
# ============================================================================= # =============================================================================
services: include:
# --------------------------------------------------------------------------- - media.yml
# VPN & Download - infra.yml
# --------------------------------------------------------------------------- - web.yml
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
Regular → Executable
+78 -73
View File
@@ -3,80 +3,85 @@
# https://gethomepage.dev/configs/bookmarks # https://gethomepage.dev/configs/bookmarks
- "User": - "User":
- "Plex": - "Plex":
- icon: si-plex-#EBAF00 - icon: si-plex-#EBAF00
href: "{{HOMEPAGE_VAR_PLEX_HOST}}" href: "{{HOMEPAGE_VAR_PLEX_HOST}}"
- "Seerr": - "Seerr":
- icon: sh-seerr - icon: sh-seerr
href: "{{HOMEPAGE_VAR_SEERR_HOST}}" href: "{{HOMEPAGE_VAR_SEERR_HOST}}"
- "Odysseus": - "Open WebUI":
- icon: http://shaan-server:7001/static/icons/icon-192.png - icon: sh-open-webui
href: https://shaan-server.cc href: https://shaan-server.cc
- "Karakeep": - "Hermes Agent":
- icon: sh-karakeep-light - icon: http://shaan-server:9119/favicon.ico # "{{HOMEPAGE_VAR_HERMES_HOST}}"/favicon.ico
href: "{{HOMEPAGE_VAR_KARAKEEP_HOST}}" 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": - "Admin":
- "Sonarr": - "Sonarr":
- icon: sh-sonarr - icon: sh-sonarr
href: "{{HOMEPAGE_VAR_SONARR_HOST}}" href: "{{HOMEPAGE_VAR_SONARR_HOST}}"
- "Radarr": - "Radarr":
- icon: sh-radarr - icon: sh-radarr
href: "{{HOMEPAGE_VAR_RADARR_HOST}}" href: "{{HOMEPAGE_VAR_RADARR_HOST}}"
- "Lidarr": - "Lidarr":
- icon: sh-lidarr - icon: sh-lidarr
href: "{{HOMEPAGE_VAR_LIDARR_HOST}}" href: "{{HOMEPAGE_VAR_LIDARR_HOST}}"
- "Prowlarr": - "Prowlarr":
- icon: sh-prowlarr - icon: sh-prowlarr
href: "{{HOMEPAGE_VAR_PROWLARR_HOST}}" href: "{{HOMEPAGE_VAR_PROWLARR_HOST}}"
- "Tautulli": - "Tautulli":
- icon: sh-tautulli - icon: sh-tautulli
href: "{{HOMEPAGE_VAR_TAUTULLI_HOST}}" href: "{{HOMEPAGE_VAR_TAUTULLI_HOST}}"
- "Tdarr": - "Tdarr":
- icon: sh-tdarr - icon: sh-tdarr
href: "{{HOMEPAGE_VAR_TDARR_HOST}}" href: "{{HOMEPAGE_VAR_TDARR_HOST}}"
- "qBittorrent": - "qBittorrent":
- icon: sh-qbittorrent - icon: sh-qbittorrent
href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}" href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}"
- "Speedtest": - "Scrutiny":
- icon: sh-speedtest-light - icon: sh-scrutiny-light
href: "{{HOMEPAGE_VAR_MYSPEED_HOST}}" href: "{{HOMEPAGE_VAR_SCRUTINY_HOST}}"
- "Scrutiny": - "Router Gateway":
- icon: sh-scrutiny-light - icon: "http://192.168.50.1/images/favicon.png"
href: "{{HOMEPAGE_VAR_SCRUTINY_HOST}}" href: http://192.168.50.1
- "Router Gateway": - "Tailscale":
- icon: "http://192.168.50.1/images/favicon.png" - icon: sh-tailscale-light
href: http://192.168.50.1 href: https://login.tailscale.com
- "Tailscale": - "Portainer":
- icon: sh-tailscale-light - icon: sh-portainer-light
href: https://login.tailscale.com href: "{{HOMEPAGE_VAR_PORTAINER_HOST}}"
- "Portainer": - "Pi-Hole":
- icon: sh-portainer-light - icon: sh-pi-hole
href: "{{HOMEPAGE_VAR_PORTAINER_HOST}}" href: "{{HOMEPAGE_VAR_PIHOLE_HOST}}/admin"
- "Pi-Hole": - "Cloudflare":
- icon: sh-pi-hole - icon: sh-cloudflare
href: "{{HOMEPAGE_VAR_PIHOLE_HOST}}/admin" href: https://dash.cloudflare.com
- "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
- Bookmarks: - Bookmarks:
- "Youtube": - "Youtube":
- icon: sh-youtube - icon: sh-youtube
href: https://www.youtube.com href: https://www.youtube.com
- "Gmail": - "Gmail":
- icon: sh-gmail - icon: sh-gmail
href: https://mail.google.com href: https://mail.google.com
# - github/dhaan7/torrent-stack: - "dhaan7/torrent-stack":
# - icon: sh-github-light - icon: sh-github-light
# href: https://github.com/dhaan7/torrent-stack href: https://github.com/dhaan7/torrent-stack
# description: link to this GitHub repository - "Twitter":
# - Termix: - icon: sh-twitter
# - icon: "{{HOMEPAGE_VAR_TERMIX_ADDRESS}}/favicon.ico" href: https://x.com/
# href: "{{HOMEPAGE_VAR_TERMIX_HOST}}" - "Roblox":
# description: Terminal emulator in your web browser - 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: # For configuration options and examples, please see:
# https://gethomepage.dev/configs/services/ # https://gethomepage.dev/configs/services/
- "Top": - "Top":
- "Cloudflared Tunnel": - "Cloudflared Tunnel":
icon: sh-cloudflare icon: sh-cloudflare
href: "https://dash.cloudflare.com/" href: "https://dash.cloudflare.com/"
server: my-docker server: my-docker
container: cloudflared container: cloudflared
description: description:
widget: widget:
type: cloudflared type: cloudflared
accountid: "{{HOMEPAGE_VAR_CLOUDFLARED_ACCOUNT_ID}}" accountid: "{{HOMEPAGE_VAR_CLOUDFLARED_ACCOUNT_ID}}"
tunnelid: "{{HOMEPAGE_VAR_CLOUDFLARED_TUNNEL_ID}}" tunnelid: "{{HOMEPAGE_VAR_CLOUDFLARED_TUNNEL_ID}}"
key: "{{HOMEPAGE_VAR_CLOUDFLARED_API_KEY}}" key: "{{HOMEPAGE_VAR_CLOUDFLARED_API_KEY}}"
- "VPN Address >": - "VPN Address >":
icon: sh-gluetun icon: sh-gluetun
href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}" href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}"
server: my-docker server: my-docker
container: gluetun container: gluetun
widget: widget:
type: customapi type: customapi
url: "{{HOMEPAGE_VAR_QBITTORRENT_ADDRESS}}/api/v2/sync/maindata" url: "{{HOMEPAGE_VAR_QBITTORRENT_ADDRESS}}/api/v2/sync/maindata"
mappings: mappings:
- field: server_state.last_external_address_v4 - field: server_state.last_external_address_v4
label: "Address" label: "Address"
format: string format: string
- "Tailscale >": - "Tailscale >":
icon: sh-tailscale-light icon: sh-tailscale-light
href: https://login.tailscale.com href: https://login.tailscale.com
siteMonitor: https://tailscale.com siteMonitor: https://tailscale.com
widget: widget:
type: tailscale type: tailscale
deviceid: "{{HOMEPAGE_VAR_TAILSCALE_DEVICE_KEY}}" deviceid: "{{HOMEPAGE_VAR_TAILSCALE_DEVICE_KEY}}"
key: "{{HOMEPAGE_VAR_TAILSCALE_KEY}}" key: "{{HOMEPAGE_VAR_TAILSCALE_KEY}}"
fields: [address] 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]
- "Media": - "Media":
- "Media_1": - "Media_1":
- "Odysseus": - "Open WebUI":
icon: "{{HOMEPAGE_VAR_ODYSSEUS_HOST}}/static/icons/icon-192.png" icon: sh-open-webui
href: "{{HOMEPAGE_VAR_ODYSSEUS_HOST}}" href: "{{HOMEPAGE_VAR_OPENWEBUI_HOST}}"
siteMonitor: "{{HOMEPAGE_VAR_ODYSSEUS_HOST}}" siteMonitor: "{{HOMEPAGE_VAR_OPENWEBUI_ADDRESS}}"
description: Local AI Models description: Chatbot
- "Port Updater": - "Port Updater":
icon: sh-docker icon: sh-docker
description: Shell description: Shell
server: my-docker server: my-docker
container: port-updater container: port-updater
- "Monitorix": - "VLLM Status":
icon: "{{HOMEPAGE_VAR_WEB_PROTOCOL}}://{{HOMEPAGE_VAR_LOCAL_IPV4}}:4000/monitorix/monitorixico.png" icon: sh-vllm
href: http://{{HOMEPAGE_VAR_SERVER_NAME}}:4000/monitorix server: my-docker
description: System href: "{{HOMEPAGE_VAR_WEB_PROTOCOL}}://{{HOMEPAGE_VAR_SERVER_NAME}}:9119"
- "Media_2": container: vllm
- "Plex >": description: LLM Serving
icon: sh-plex - "Media_2":
#icon: sh-plex-dark - "Plex >":
href: "{{HOMEPAGE_VAR_PLEX_HOST}}" icon: sh-plex
description: Watch #icon: sh-plex-dark
siteMonitor: "{{HOMEPAGE_VAR_PLEX_ADDRESS}}" href: "{{HOMEPAGE_VAR_PLEX_HOST}}"
widget: description: Watch
type: plex siteMonitor: "{{HOMEPAGE_VAR_PLEX_ADDRESS}}"
url: "{{HOMEPAGE_VAR_PLEX_ADDRESS}}" widget:
key: "{{HOMEPAGE_VAR_PLEX_KEY}}" type: plex
fields: [albums, movies, tv] url: "{{HOMEPAGE_VAR_PLEX_ADDRESS}}"
- "Tautulli >": key: "{{HOMEPAGE_VAR_PLEX_KEY}}"
icon: sh-tautulli fields: [albums, movies, tv]
href: "{{HOMEPAGE_VAR_TAUTULLI_HOST}}" - "Tautulli >":
description: Monitor icon: sh-tautulli
server: my-docker href: "{{HOMEPAGE_VAR_TAUTULLI_HOST}}"
container: tautulli description: Monitor
widget: server: my-docker
type: tautulli container: tautulli
url: "{{HOMEPAGE_VAR_TAUTULLI_ADDRESS}}" widget:
key: "{{HOMEPAGE_VAR_TAUTULLI_KEY}}" type: tautulli
enableUser: false url: "{{HOMEPAGE_VAR_TAUTULLI_ADDRESS}}"
expandOneStreamToTwoRows: false key: "{{HOMEPAGE_VAR_TAUTULLI_KEY}}"
- "Sonarr >": enableUser: false
icon: sh-sonarr expandOneStreamToTwoRows: false
href: "{{HOMEPAGE_VAR_SONARR_HOST}}" - "Sonarr >":
description: Shows icon: sh-sonarr
server: my-docker href: "{{HOMEPAGE_VAR_SONARR_HOST}}"
container: sonarr description: Shows
widget: server: my-docker
type: sonarr container: sonarr
url: "{{HOMEPAGE_VAR_SONARR_ADDRESS}}" widget:
key: "{{HOMEPAGE_VAR_SONARR_KEY}}" type: sonarr
enableQueue: false # shows a long list of queued items. looks ugly unless you reorder the page yourself url: "{{HOMEPAGE_VAR_SONARR_ADDRESS}}"
fields: [wanted, queued] key: "{{HOMEPAGE_VAR_SONARR_KEY}}"
highlight: enableQueue: false # shows a long list of queued items. looks ugly unless you reorder the page yourself
queued: fields: [wanted, queued]
numeric: highlight:
- level: warn queued:
when: gt numeric:
value: 0 - level: warn
- Upcoming TV Episodes: when: gt
icon: sh-sonarr value: 0
server: my-docker - Upcoming TV Episodes:
container: sonarr icon: sh-sonarr
widget: server: my-docker
type: calendar container: sonarr
firstDayInWeek: sunday # optional - defaults to monday widget:
view: agenda # optional - possible values monthly, agenda type: calendar
maxEvents: 2 # optional - defaults to 10 firstDayInWeek: sunday # optional - defaults to monday
showTime: true # optional - show time for event happening today - defaults to false view: agenda # optional - possible values monthly, agenda
timezone: America/Los_Angeles maxEvents: 2 # optional - defaults to 10
integrations: # optional showTime: true # optional - show time for event happening today - defaults to false
- type: sonarr timezone: America/Los_Angeles
service_name: "Sonarr >" integrations: # optional
baseUrl: "{{HOMEPAGE_VAR_SONARR_HOST}}" - type: sonarr
unmonitored: true service_name: "Sonarr >"
- "Radarr >": baseUrl: "{{HOMEPAGE_VAR_SONARR_HOST}}"
icon: sh-radarr unmonitored: true
href: "{{HOMEPAGE_VAR_RADARR_HOST}}" - "Radarr >":
description: Movies icon: sh-radarr
server: my-docker href: "{{HOMEPAGE_VAR_RADARR_HOST}}"
container: radarr description: Movies
widget: server: my-docker
type: radarr container: radarr
url: "{{HOMEPAGE_VAR_RADARR_ADDRESS}}" widget:
key: "{{HOMEPAGE_VAR_RADARR_KEY}}" type: radarr
fields: [wanted, queued] url: "{{HOMEPAGE_VAR_RADARR_ADDRESS}}"
highlight: key: "{{HOMEPAGE_VAR_RADARR_KEY}}"
queued: fields: [wanted, queued]
numeric: highlight:
- level: warn queued:
when: gt numeric:
value: 0 - level: warn
- Upcoming Movies: when: gt
icon: sh-radarr value: 0
server: my-docker - Upcoming Movies:
container: radarr icon: sh-radarr
widget: server: my-docker
type: calendar container: radarr
firstDayInWeek: sunday # optional - defaults to monday widget:
view: agenda # optional - possible values monthly, agenda type: calendar
maxEvents: 2 # optional - defaults to 10 firstDayInWeek: sunday # optional - defaults to monday
showTime: true # optional - show time for event happening today - defaults to false view: agenda # optional - possible values monthly, agenda
timezone: America/Los_Angeles maxEvents: 2 # optional - defaults to 10
integrations: # optional showTime: true # optional - show time for event happening today - defaults to false
- type: radarr timezone: America/Los_Angeles
service_name: "Radarr >" integrations: # optional
baseUrl: "{{HOMEPAGE_VAR_RADARR_HOST}}" - type: radarr
unmonitored: true service_name: "Radarr >"
- "Lidarr >": baseUrl: "{{HOMEPAGE_VAR_RADARR_HOST}}"
icon: sh-lidarr unmonitored: true
href: "{{HOMEPAGE_VAR_LIDARR_HOST}}" - "Lidarr >":
description: Music icon: sh-lidarr
server: my-docker href: "{{HOMEPAGE_VAR_LIDARR_HOST}}"
container: lidarr description: Music
widget: server: my-docker
type: lidarr container: lidarr
url: "{{HOMEPAGE_VAR_LIDARR_ADDRESS}}" widget:
key: "{{HOMEPAGE_VAR_LIDARR_KEY}}" type: lidarr
fields: [wanted, queued] url: "{{HOMEPAGE_VAR_LIDARR_ADDRESS}}"
highlight: key: "{{HOMEPAGE_VAR_LIDARR_KEY}}"
queued: fields: [wanted, queued]
numeric: highlight:
- level: warn queued:
when: gt numeric:
value: 0 - level: warn
- "Seerr >": when: gt
icon: sh-overseerr value: 0
href: "{{HOMEPAGE_VAR_SEERR_HOST}}" - "Seerr >":
description: Request icon: sh-overseerr
server: my-docker href: "{{HOMEPAGE_VAR_SEERR_HOST}}"
container: seerr description: Request
widget: server: my-docker
type: seerr container: seerr
url: "{{HOMEPAGE_VAR_SEERR_ADDRESS}}" widget:
key: "{{HOMEPAGE_VAR_SEERR_KEY}}" type: seerr
fields: [completed, pending] url: "{{HOMEPAGE_VAR_SEERR_ADDRESS}}"
highlight: key: "{{HOMEPAGE_VAR_SEERR_KEY}}"
pending: fields: [completed, pending]
numeric: highlight:
- level: warn pending:
when: gt numeric:
value: 0 - level: warn
- "Tdarr Node (Intel Arc Pro B70)": when: gt
icon: sh-tdarr value: 0
server: my-docker - "Bazarr >":
container: tdarr-node icon: sh-bazarr
- "Tdarr Node (Intel Graphics UHD 710)": href: "{{HOMEPAGE_VAR_BAZARR_HOST}}"
icon: sh-tdarr description: Subtitles
server: my-docker server: my-docker
container: tdarr-node container: bazarr
- "Media_Bottom": widget:
- "Tdarr >": type: bazarr
icon: sh-tdarr url: "{{HOMEPAGE_VAR_BAZARR_ADDRESS}}"
href: "{{HOMEPAGE_VAR_TDARR_HOST}}" key: "{{HOMEPAGE_VAR_BAZARR_KEY}}"
description: Transcode # fields: [wanted, queued]
server: my-docker highlight:
container: tdarr queued:
widget: numeric:
type: tdarr - level: warn
url: "{{HOMEPAGE_VAR_TDARR_ADDRESS}}" when: gt
key: "{{HOMEPAGE_VAR_TDARR_KEY}}" value: 0
highlight: - "Spotizerr":
queue: icon: sh-spotify
numeric: href: http://shaan-server:7171
- level: warn server: my-docker
when: gt container: spotizerr
value: 0 - "Media_Bottom":
errored: - "Tdarr >":
numeric: icon: sh-tdarr
- level: danger href: "{{HOMEPAGE_VAR_TDARR_HOST}}"
when: gt description: Transcode
value: 0 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":
- "Network_1": - "Network_1":
- "Portainer": - "Portainer":
icon: sh-portainer-light icon: sh-portainer-light
href: https://shaan-server:9443 href: https://shaan-server:9443
description: Containers description: Containers
server: my-docker server: my-docker
container: portainer container: portainer
widget: widget:
type: portainer type: portainer
url: https://shaan-server:9443 url: https://portainer:9443
env: 3 env: 3
key: "{{HOMEPAGE_VAR_PORTAINER_KEY}}" key: "{{HOMEPAGE_VAR_PORTAINER_KEY}}"
- "Pi-Hole Adblocker": - "Pi-Hole Adblocker":
icon: sh-pi-hole icon: sh-pi-hole
href: "http://192.168.50.2:6060/admin/login" href: "{{HOMEPAGE_VAR_PIHOLE_ADDRESS}}/admin/login"
description: DNS description: DNS
server: my-docker server: my-docker
container: pihole container: pihole
widget: widget:
type: pihole type: pihole
url: http://shaan-server:6060 url: "{{HOMEPAGE_VAR_PIHOLE_ADDRESS}}"
version: 6 # required if running v6 or higher, defaults to 5 version: 6 # required if running v6 or higher, defaults to 5
key: "{{HOMEPAGE_VAR_PIHOLE_PASSWORD}}" key: "{{HOMEPAGE_VAR_PIHOLE_PASSWORD}}"
- "Network_2": - "Network_2":
- "Scrutiny": - "Scrutiny":
icon: sh-scrutiny icon: sh-scrutiny
href: http://192.168.50.2:4545 #"{{HOMEPAGE_VAR_SCRUTINY_ADDRESS}}"" href: "{{HOMEPAGE_VAR_SCRUTINY_HOST}}"
description: S.M.A.R.T. description: S.M.A.R.T.
server: my-docker server: my-docker
container: scrutiny container: scrutiny
widget: widget:
type: scrutiny type: scrutiny
url: http://192.168.50.2:4545 #"{{HOMEPAGE_VAR_SCRUTINY_ADDRESS}}" url: "{{HOMEPAGE_VAR_SCRUTINY_ADDRESS}}"
- "Karakeep": - "Karakeep":
icon: sh-karakeep-light icon: sh-karakeep-light
href: http://192.168.50.2:4545 #"{{HOMEPAGE_VAR_SCRUTINY_ADDRESS}}"" href: "{{HOMEPAGE_VAR_KARAKEEP_HOST}}"
description: Bookmarks description: Bookmarks
server: my-docker server: my-docker
container: karakeep container: karakeep
widget: widget:
type: karakeep type: karakeep
url: http://shaan-server:4621 url: "{{HOMEPAGE_VAR_KARAKEEP_ADDRESS}}"
key: ak2_bfee1806ec533a9557bd_940feeb8fbe798d465ab6f90a3562c43 key: ak2_bfee1806ec533a9557bd_940feeb8fbe798d465ab6f90a3562c43
- "Network_qbit": - "Network_qbit":
- "Prowlarr >": - "Prowlarr >":
icon: sh-prowlarr icon: sh-prowlarr
href: "{{HOMEPAGE_VAR_PROWLARR_HOST}}" href: "{{HOMEPAGE_VAR_PROWLARR_HOST}}"
description: Indexers description: Indexers
server: my-docker server: my-docker
container: prowlarr container: prowlarr
widget: widget:
type: prowlarr type: prowlarr
url: "{{HOMEPAGE_VAR_PROWLARR_ADDRESS}}" url: "{{HOMEPAGE_VAR_PROWLARR_ADDRESS}}"
key: "{{HOMEPAGE_VAR_PROWLARR_KEY}}" key: "{{HOMEPAGE_VAR_PROWLARR_KEY}}"
#fields: ["numberOfGrabs"] #fields: ["numberOfGrabs"]
highlight: highlight:
"numberOfGrabs": "numberOfGrabs":
numeric: numeric:
- level: warn - level: warn
when: lte when: lte
value: 0 value: 0
"numberOfQueries": "numberOfQueries":
numeric: numeric:
- level: warn - level: warn
when: lte when: lte
value: 0 value: 0
"numberOfFailGrabs": "numberOfFailGrabs":
numeric: numeric:
- level: warn - level: warn
when: gt when: gt
value: 0 value: 0
"numberOfFailQueries": "numberOfFailQueries":
numeric: numeric:
- level: warn - level: warn
when: gt when: gt
value: 0 value: 0
- "qBittorrent Active >": - "qBittorrent Active >":
icon: sh-qbittorrent icon: sh-qbittorrent
href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}" href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}"
server: my-docker server: my-docker
container: qbittorrent container: qbittorrent
#description: #description:
widget: widget:
type: customapi type: customapi
url: "{{HOMEPAGE_VAR_QBITTORRENT_ADDRESS}}/api/v2/torrents/info?filter=seeding" url: "{{HOMEPAGE_VAR_QBITTORRENT_ADDRESS}}/api/v2/torrents/info?filter=seeding"
mappings: mappings:
#- field: #- field:
- field: _count - field: _count
label: "Active" label: "Active"
format: integer format: integer
scale: 1 scale: 1
highlight: highlight:
"Active": "Active":
numeric: numeric:
- level: danger - level: danger
when: lte when: lte
value: 20 value: 20
- "qBittorrent Status >": - "qBittorrent Status >":
icon: sh-qbittorrent icon: sh-qbittorrent
href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}" href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}"
server: my-docker server: my-docker
container: qbittorrent container: qbittorrent
widget: widget:
type: customapi type: customapi
url: "{{HOMEPAGE_VAR_QBITTORRENT_ADDRESS}}/api/v2/sync/maindata" url: "{{HOMEPAGE_VAR_QBITTORRENT_ADDRESS}}/api/v2/sync/maindata"
mappings: mappings:
- field: server_state.connection_status - field: server_state.connection_status
label: "status" label: "status"
format: string format: string
- field: server_state.dht_nodes - field: server_state.dht_nodes
label: "DHT" label: "DHT"
format: integer format: integer
scale: 1 scale: 1
- field: server_state.last_external_address_v4 - field: server_state.last_external_address_v4
label: "Address" label: "Address"
format: string format: string
highlight: highlight:
"status": "status":
string: string:
- level: danger - level: danger
when: equals when: equals
value: connected value: connected
negate: true negate: true
"DHT": "DHT":
#valueOnly: true #valueOnly: true
numeric: numeric:
- level: danger - level: danger
when: lte when: lte
value: 0 value: 0
- level: warn - level: warn
when: lte when: lte
value: 200 value: 200
- "qBittorrent Stats >": - "qBittorrent Stats >":
icon: sh-qbittorrent icon: sh-qbittorrent
href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}" href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}"
server: my-docker server: my-docker
container: qbittorrent container: qbittorrent
widget: widget:
type: customapi type: customapi
url: "{{HOMEPAGE_VAR_QBITTORRENT_ADDRESS}}/api/v2/sync/maindata" url: "{{HOMEPAGE_VAR_QBITTORRENT_ADDRESS}}/api/v2/sync/maindata"
mappings: mappings:
- field: server_state.alltime_dl - field: server_state.alltime_dl
label: "T. Down" label: "T. Down"
format: bytes format: bytes
scale: 0.862 scale: 0.862
- field: server_state.alltime_ul - field: server_state.alltime_ul
label: "T. Up" label: "T. Up"
format: bytes format: bytes
scale: 0.862 scale: 0.862
- field: server_state.global_ratio - field: server_state.global_ratio
label: "Ratio" label: "Ratio"
format: percent format: percent
scale: 100 scale: 100
#suffix: "%" #suffix: "%"
highlight: highlight:
"Ratio": "Ratio":
numeric: numeric:
- level: warn - level: warn
when: lt when: lt
value: 100 value: 100
- level: danger - level: danger
when: lte when: lte
value: 60 value: 60
- "qBittorrent Session >": - "qBittorrent Session >":
icon: sh-qbittorrent icon: sh-qbittorrent
href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}" href: "{{HOMEPAGE_VAR_QBITTORRENT_HOST}}"
server: my-docker server: my-docker
container: qbittorrent container: qbittorrent
widget: widget:
type: customapi type: customapi
url: "{{HOMEPAGE_VAR_QBITTORRENT_ADDRESS}}/api/v2/sync/maindata" url: "{{HOMEPAGE_VAR_QBITTORRENT_ADDRESS}}/api/v2/sync/maindata"
key: "{{HOMEPAGE_VAR_QBITTORRENT_KEY}}" key: "{{HOMEPAGE_VAR_QBITTORRENT_KEY}}"
mappings: mappings:
- field: server_state.dl_info_speed - field: server_state.dl_info_speed
label: Down label: Down
format: bitrate format: bitrate
scale: 0.862 scale: 0.862
- field: server_state.dl_info_data - field: server_state.dl_info_data
label: T. Down label: T. Down
format: bytes format: bytes
scale: 0.862 scale: 0.862
- field: server_state.up_info_speed - field: server_state.up_info_speed
label: Up label: Up
format: bitrate format: bitrate
scale: 0.862 scale: 0.862
- field: server_state.up_info_data - field: server_state.up_info_data
label: T. Up label: T. Up
format: bytes format: bytes
scale: 0.862 scale: 0.862
highlight: highlight:
"Down": "Down":
numeric: numeric:
- level: good - level: good
when: gt when: gt
value: 0 value: 0
"Up": "Up":
numeric: numeric:
- level: good - level: good
when: gt when: gt
value: 0 value: 0
Regular → Executable
+4 -4
View File
@@ -6,7 +6,7 @@ instanceName: torrent-stack
# Aesthetics # Aesthetics
background: background:
image: /images/wallhaven-pk997m.jpg image: ./images/wallhaven-pk997m.jpg
#blur: sm # Options: sm, md, lg, xl #blur: sm # Options: sm, md, lg, xl
#saturate: 10 #saturate: 10
#brightness: 10 #brightness: 10
@@ -44,20 +44,20 @@ layout:
tab: Apps tab: Apps
iconsOnly: false iconsOnly: false
header: true header: true
disableCollapse: true initiallyCollapsed: false
style: row style: row
columns: 3 columns: 3
"Admin": "Admin":
tab: Apps tab: Apps
iconsOnly: false iconsOnly: false
header: true header: true
disableCollapse: true initiallyCollapsed: false
style: row style: row
columns: 3 columns: 3
"Bookmarks": "Bookmarks":
tab: Apps tab: Apps
header: true header: true
initiallyCollapsed: true initiallyCollapsed: false
style: row style: row
columns: 3 columns: 3
"Top": "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 sleep 15
cd /home/shaan/torrent-stack || exit cd /home/shaan/torrent-stack || exit
docker compose up -d gluetun & sleep 90 docker compose config ||> /tmp/startup.log && exit 1
docker compose up -d docker compose up -d 2>&1 | tee /tmp/startup.log
sleep 5
cd /home/shaan/torrent-stack/odysseus || exit
git pull . dev
docker compose pull
docker compose up -d
+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