2026-08-06 14:38:05 -07:00
networks :
caddy_net :
external : true
tdarr-net :
driver : bridge
default :
name : portainer_network
volumes :
meilisearch :
karakeep-data :
caddy_config :
caddy_data :
external : true
myspeed :
external : true # docker compose will fail creating myspeed if the volume hasn't been manually created, which we have done. unless you deleted it...
portainer_data :
name : portainer_data
##### ORGANIZATION FOR EVERY CONTAINER
# services:
# container:
# image: <...>
# container_name: <...>
# env_file: <...>
# networks: <...>
# cap_add: <...>
# ports: <...>
# volumes: <...>
# environment: <...>
# labels: <...>
# healthcheck: <...>
# extra_hosts: <...>
# restart: <...>
#
2026-05-24 20:41:08 -07:00
services :
gluetun :
image : qmcgaw/gluetun:latest
container_name : gluetun
cap_add :
- NET_ADMIN
2026-08-06 14:38:05 -07:00
ports : # YOU MUST SPECIFY A PORT PER SERVICE ROUTED THROUGH GLUETUN!
- 8888 : 8000 /tcp # gluetun control server, i dont think you should change this
- ${QBITTORRENT_PORT}:${QBITTORRENT_PORT} # qBittorrent Web UI
- ${PROWLARR_PORT}:${PROWLARR_PORT} # Prowlarr
- ${SONARR_PORT}:${SONARR_PORT} # Sonarr
- ${RADARR_PORT}:${RADARR_PORT} # Radarr
- ${LIDARR_PORT}:${LIDARR_PORT} # Lidarr
#- ${SEERR_PORT}:${SEERR_PORT}/tcp # Seerr # took this out of gluetun, as it could cause issues with starting the container, and it was unecessary
volumes :
- ./gluetun-data:/tmp/gluetun:rw
2026-05-24 20:41:08 -07:00
environment :
- VPN_SERVICE_PROVIDER=protonvpn # Or mullvad, protonvpn, surfshark, etc.
- VPN_TYPE=wireguard # WireGuard, openvpn
2026-05-25 03:03:29 -07:00
- HTTP_CONTROL_SERVER=ON
- HTTP_CONTROL_SERVER_AUTH_DEFAULT_ROLE='{"auth":"apikey","apikey":"${GLUETUN_KEY}"}' # generate by running `docker run --rm qmcgaw/gluetun genkey`, then adding this to your `.env` file
- WIREGUARD_PRIVATE_KEY=${VPN_PRIVATE_KEY}
2026-05-24 20:41:08 -07:00
- WIREGUARD_MTU=1280
- VPN_PORT_FORWARDING=on
- VPN_PORT_FORWARDING_PROVIDER=protonvpn
#- OPENVPN_USER=user
#- OPENVPN_PASSWORD=password
- SERVER_COUNTRIES=Netherlands # choose fast P2P friendly countries
- NETWORK_LOCAL_ADDRESSES=192.168.50.0/24,172.16.0.0/12
- FIREWALL_OUTBOUND_SUBNETS=192.168.50.0/24
2026-05-25 03:03:29 -07:00
- TZ=${TIMEZONE}
- DNS_UPSTREAM_RESOLVER_TYPE=doh # DNS over TLS is an extra layer of security so your isp can not look at what you're doing through your DNS requests, even if your using a vpn (very vague, I don't know how this syustem works with a vpn).
2026-05-24 20:41:08 -07:00
healthcheck :
2026-05-29 00:28:48 -07:00
test : wget --spider -q http://1.1.1.1 || exit 1
2026-05-24 20:41:08 -07:00
interval : 30s
timeout : 15s
retries : 3
start_period : 1m
extra_hosts :
- "host.docker.internal:host-gateway" # host-gateway is a docker variable that automatically grabs the 172.XX.0.1 address, this is to be used by prowlarr to communicate with sonarr and radarr.
2026-08-06 14:38:05 -07:00
devices :
- /dev/net/tun:/dev/net/tun
2026-05-24 20:41:08 -07:00
restart : always
qbittorrent :
image : lscr.io/linuxserver/qbittorrent:latest
container_name : qbittorrent
network_mode : "container:gluetun" # vpn bunker
2026-08-06 14:38:05 -07:00
depends_on :
gluetun :
condition : service_healthy
labels :
- "autoheal=true"
2026-05-24 20:41:08 -07:00
volumes :
- ./qbittorrent:/config
2026-06-09 01:53:07 -07:00
- ${DISK1}:${DISK1}
- ${DISK2}:${DISK2}
2026-05-24 20:41:08 -07:00
- ./gluetun-data:/tmp/gluetun
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
2026-08-06 14:38:05 -07:00
environment :
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
- WEBUI_PORT=${QBITTORRENT_PORT}
2026-05-24 20:41:08 -07:00
healthcheck : # if gluetun is slow to start, it's over
test : [ "CMD-SHELL" , wget --spider -q https://1.1.1.1 || exit 1] # use 1.1.1.1, we don't need dns around here
interval : 1m
timeout : 10s
retries : 3
start_period : 30s
restart : unless-stopped
port-updater :
# use an image that already has curl/wget to skip the 'apk add' step
image : curlimages/curl:latest
container_name : port-updater
volumes :
- ./gluetun-data:/tmp/gluetun:ro
# using 'exec' format and 'trap' allows the container to stop instantly
entrypoint : [ "/bin/sh" , "-c" ]
command : # loololloloolol gemini did this for me
- |
trap 'exit 0' SIGTERM;
while true; do
# 1. Wait for Gluetun to actually create the file with a number
while [ ! -s /tmp/gluetun/forwarded_port ]; do
echo "Waiting for Gluetun to provide a port..."
sleep 5
done
# 2. Read and clean the port
read -r PORT_VAL < /tmp/gluetun/forwarded_port;
CLEAN_PORT=$$(echo "$$PORT_VAL" | tr -d '\r\n ');
# 3. Only update if the port isn't empty
if [ -n "$$CLEAN_PORT" ]; then
echo "Updating qBit to port: $$CLEAN_PORT";
sleep 10;
echo "Updated to $$CLEAN_PORT"
2026-05-25 04:38:46 -07:00
curl -s -X POST -d "json={\"listen_port\":$$CLEAN_PORT}" http://localhost:${QBITTORRENT_PORT}/api/v2/app/setPreferences;
2026-05-24 20:41:08 -07:00
# 4. Success! Now sleep for a long time (e.g., 1 hour)
sleep 3600 & wait $$!;
else
# If for some reason it's still blank, retry quickly
sleep 10
fi
done
labels :
- "autoheal=true"
network_mode : "container:gluetun"
depends_on :
gluetun :
condition : service_healthy
healthcheck :
test : [ "CMD-SHELL" , "curl -f https://1.1.1.1 || exit 1" ]
interval : 1m
timeout : 10s
retries : 3
start_period : 30s
restart : always
prowlarr :
image : lscr.io/linuxserver/prowlarr:latest
container_name : prowlarr
2026-08-06 14:38:05 -07:00
network_mode : "container:gluetun"
depends_on :
gluetun :
condition : service_healthy
labels :
- "autoheal=true"
2026-05-24 20:41:08 -07:00
volumes :
- ./prowlarr:/config
- ./notify.sh:/notify.sh:ro
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
2026-08-06 14:38:05 -07:00
environment :
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
2026-05-24 20:41:08 -07:00
healthcheck :
test : [ "CMD-SHELL" , wget --spider -q https://google.com || exit 1] # needs DNS
interval : 5m
timeout : 60s
retries : 3
start_period : 30s
restart : always
sonarr :
image : lscr.io/linuxserver/sonarr:latest
container_name : sonarr
2026-08-06 14:38:05 -07:00
network_mode : "container:gluetun"
depends_on :
gluetun :
condition : service_healthy
labels :
- "autoheal=true"
2026-05-24 20:41:08 -07:00
volumes :
2026-05-25 03:03:29 -07:00
- /var/lib/sonarr:/config # had migrated into docker compose
2026-05-27 13:48:35 -07:00
- ${DISK1}:${DISK1}
- ${DISK2}:${DISK2}
2026-07-06 15:25:38 -07:00
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
2026-08-06 14:38:05 -07:00
environment :
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
2026-05-24 20:41:08 -07:00
healthcheck :
test : [ "CMD-SHELL" , "curl -f http://1.1.1.1 || exit 1" ]
interval : 5m
timeout : 60s
retries : 3
start_period : 60s
restart : always
radarr :
image : lscr.io/linuxserver/radarr:latest
container_name : radarr
2026-08-06 14:38:05 -07:00
network_mode : "container:gluetun"
labels :
- "autoheal=true"
depends_on :
gluetun :
condition : service_healthy
2026-05-24 20:41:08 -07:00
volumes :
2026-05-25 03:03:29 -07:00
- /var/lib/radarr:/config # had migrated into docker compose
2026-05-27 13:48:35 -07:00
- ${DISK1}:${DISK1}
- ${DISK2}:${DISK2}
2026-07-06 15:25:38 -07:00
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
2026-08-06 14:38:05 -07:00
environment :
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
2026-05-24 20:41:08 -07:00
healthcheck :
test : [ "CMD-SHELL" , "curl -f http://1.1.1.1 || exit 1" ]
interval : 1m
timeout : 10s
retries : 3
start_period : 30s
restart : always
lidarr :
image : lscr.io/linuxserver/lidarr:latest
container_name : lidarr
2026-08-06 14:38:05 -07:00
network_mode : "container:gluetun"
depends_on :
gluetun :
condition : service_healthy
labels :
- "autoheal=true"
2026-05-24 20:41:08 -07:00
volumes :
2026-08-06 14:38:05 -07:00
- ./lidarr:/music
2026-05-24 20:41:08 -07:00
- /var/lib/lidarr:/config
2026-05-25 04:38:46 -07:00
- ${DISK1}:${DISK1}
- ${DISK2}:${DISK2}
2026-07-06 15:25:38 -07:00
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
2026-08-06 14:38:05 -07:00
environment :
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
2026-05-24 20:41:08 -07:00
healthcheck :
test : [ "CMD-SHELL" , "curl -f http://1.1.1.1 || exit 1" ]
interval : 1m
timeout : 10s
retries : 3
start_period : 30s
restart : unless-stopped
tautulli : # has no network bridge between containers. this is fine, as it only needs to get from plex, which is outside this container
image : ghcr.io/tautulli/tautulli
container_name : tautulli
2026-08-06 14:38:05 -07:00
networks :
- caddy_net
ports :
- ${TAUTULLI_PORT}:${TAUTULLI_PORT}
2026-05-24 20:41:08 -07:00
volumes :
#- /mnt/media/media:/config
- ./tautulli:/config
environment :
2026-08-06 14:38:05 -07:00
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
2026-05-25 03:03:29 -07:00
- TZ=${TIMEZONE}
2026-08-06 14:38:05 -07:00
restart : unless-stopped
2026-05-24 20:41:08 -07:00
tdarr :
image : haveagitgat/tdarr:latest
2026-08-06 14:38:05 -07:00
container_name : tdarr
2026-05-24 20:41:08 -07:00
networks :
- tdarr-net
ports :
2026-05-25 03:03:29 -07:00
- ${TDARR_PORT}:${TDARR_PORT} # WebUI
- ${TDARR_NODE_PORT}:${TDARR_NODE_PORT} # local tdarr-node
2026-05-24 20:41:08 -07:00
volumes :
- ./tdarr/server:/app/server
- ./tdarr/configs:/app/configs
- ./tdarr/temp:/temp
2026-05-25 03:03:29 -07:00
- ${DISK1}:${DISK1}
- ${DISK2}:${DISK2}
2026-05-24 20:41:08 -07:00
environment :
2026-05-25 03:03:29 -07:00
- TZ=${TIMEZONE}
2026-08-06 14:38:05 -07:00
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-100}
- UMASK_SET=002
- serverIP=0.0.0.0
# dont put temp files onto a HARD DISK DRIVE! > - ${DISK1}/tdarr-temp:/temp
#devices: #? I don't think this is needed
# - /dev/dri:/dev/dri # Intel UHD Graphics 710
restart : unless-stopped
tdarr-node :
image : haveagitgat/tdarr_node:latest
container_name : tdarr-node
networks :
- tdarr-net
2026-05-24 20:41:08 -07:00
volumes :
- ./tdarr/configs:/app/configs
- ./tdarr/logs:/app/logs
- /home/shaan/torrent-stack/tdarr/temp:/temp
2026-05-25 03:03:29 -07:00
- ${DISK1}:${DISK1}
- ${DISK2}:${DISK2}
2026-08-06 14:38:05 -07:00
environment :
- TZ=${TIMEZONE}
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- nodeID=${TDARR_NODE_ID}
- nodeIP=0.0.0.0
- serverIP=tdarr # Points to the server container
- serverPort=${TDARR_NODE_PORT}
2026-05-24 20:41:08 -07:00
devices :
2026-08-06 14:38:05 -07:00
- /dev/dri/:/dev/dri/ # only works if user 'shaan' is a part of the 'video' or 'render' group.
restart : unless-stopped
2026-05-24 20:41:08 -07:00
homepage :
image : ghcr.io/gethomepage/homepage:latest
container_name : homepage
2026-08-06 14:38:05 -07:00
networks :
- caddy_net
2026-05-24 20:41:08 -07:00
ports :
2026-05-25 03:03:29 -07:00
- ${HOMEPAGE_PORT}:${HOMEPAGE_PORT}
2026-05-24 20:41:08 -07:00
volumes :
- ./homepage:/app/config
- ./homepage/images:/app/public/images
- /var/run/docker.sock:/var/run/docker.sock:ro # (optional) For docker integrations
- ./gluetun-data:/tmp/gluetun:ro # get the port from port-updater
2026-07-06 15:25:38 -07:00
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
2026-05-24 20:41:08 -07:00
environment :
2026-08-06 14:38:05 -07:00
# INIT
- "HOMEPAGE_ALLOWED_HOSTS=gethomepage.dev,${LOCAL_IPV4}:${HOMEPAGE_PORT},${SERVER_NAME}:${HOMEPAGE_PORT},${SERVER_NAME}.${TAILNET_NAME}:${HOMEPAGE_PORT}" # required, may need port. See gethomepage.dev/installation/#homepage_allowed_hosts
#\- "HOMEPAGE_ALLOWED_HOSTS=*"
2026-05-25 03:03:29 -07:00
- "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}"
2026-08-06 14:38:05 -07:00
# KEYS
2026-05-25 03:03:29 -07:00
- "HOMEPAGE_VAR_PLEX_KEY=${PLEX_KEY}"
- "HOMEPAGE_VAR_PROWLARR_KEY=${PROWLARR_KEY}"
- "HOMEPAGE_VAR_RADARR_KEY=${RADARR_KEY}"
- "HOMEPAGE_VAR_SONARR_KEY=${SONARR_KEY}"
- "HOMEPAGE_VAR_LIDARR_KEY=${LIDARR_KEY}"
- "HOMEPAGE_VAR_TAUTULLI_KEY=${TAUTULLI_KEY}"
- "HOMEPAGE_VAR_SEERR_KEY=${SEERR_KEY}"
- "HOMEPAGE_VAR_QBITTORRENT_KEY=${QBITTORRENT_KEY}"
- "HOMEPAGE_VAR_TAILSCALE_KEY=${TAILSCALE_KEY}"
- "HOMEPAGE_VAR_TAILSCALE_DEVICE_KEY=${TAILSCALE_DEVICE_KEY}"
2026-08-06 14:38:05 -07:00
# WEB ADDRESSES
2026-05-25 03:03:29 -07:00
- "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_TERMIX_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${TERMIX_PORT}"
2026-07-08 17:44:10 -07:00
- "HOMEPAGE_VAR_ODYSSEUS_ADDRESS=${WEB_PROTOCOL}://${LOCAL_IPV4}:${ODYSSEUS_PORT}"
2026-08-06 14:38:05 -07:00
# WEB NAMES
2026-05-25 03:03:29 -07:00
- "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_TERMIX_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${TERMIX_PORT}"
2026-07-08 17:44:10 -07:00
- "HOMEPAGE_VAR_ODYSSEUS_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${ODYSSEUS_PORT}"
2026-07-06 15:25:38 -07:00
- TZ=${TIMEZONE}
2026-05-24 20:41:08 -07:00
extra_hosts :
- "host.docker.internal:host-gateway"
restart : always
glances :
image : nicolargo/glances:latest-full
container_name : glances
2026-05-25 03:03:29 -07:00
pid : host
2026-05-24 20:41:08 -07:00
network_mode : host
volumes :
2026-05-25 03:03:29 -07:00
- /var/run/docker.sock:/var/run/docker.sock
- /etc/os-release:/etc/os-release:ro
- /:/host:ro
2026-07-06 15:25:38 -07:00
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
2026-05-24 20:41:08 -07:00
environment :
- GLANCES_OPT=-w
2026-08-06 14:38:05 -07:00
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
2026-07-06 15:25:38 -07:00
- TZ=${TIMEZONE}
2026-08-06 14:38:05 -07:00
devices :
- /dev/dri:/dev/dri
2026-05-24 20:41:08 -07:00
restart : unless-stopped
autoheal :
image : willfarrell/autoheal:latest
container_name : autoheal
volumes :
- /var/run/docker.sock:/var/run/docker.sock
2026-07-06 15:25:38 -07:00
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
2026-08-06 14:38:05 -07:00
environment :
- AUTOHEAL_CONTAINER_LABEL=all
- AUTOHEAL_INTERVAL=30
- AUTOHEAL_START_PERIOD=60
2026-05-24 20:41:08 -07:00
restart : always
seerr :
image : ghcr.io/seerr-team/seerr:latest
container_name : seerr
2026-08-06 14:38:05 -07:00
working_dir : "/app" # something idk
init : true
networks :
- caddy_net
labels :
- "autoheal=true"
2026-05-25 03:03:29 -07:00
ports :
2026-07-10 21:07:13 -07:00
- ${SEERR_PORT}:${SEERR_PORT}
2026-05-24 20:41:08 -07:00
volumes :
- "./seerr:/app/config"
2026-07-06 15:25:38 -07:00
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
2026-08-06 14:38:05 -07:00
environment :
- LOG_LEVEL=debug
- TZ=America/Los_Angeles
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
2026-05-24 20:41:08 -07:00
healthcheck :
test : [ "CMD-SHELL" , "wget --spider -q http://1.1.1.1 || exit 1" ]
interval : 1m
timeout : 10s
retries : 3
start_period : 60s
restart : unless-stopped
2026-08-06 14:38:05 -07:00
seerr-anubis :
2026-07-10 21:07:13 -07:00
image : ghcr.io/techarohq/anubis:latest
2026-08-06 14:38:05 -07:00
container_name : seerr_anubis
networks :
- caddy_net
2026-07-10 21:07:13 -07:00
environment :
BIND : ":55055"
TARGET : http://seerr:${SEERR_PORT}
restart : unless-stopped
2026-05-24 20:41:08 -07:00
MySpeed :
image : "germannewsmaker/myspeed"
2026-08-06 14:38:05 -07:00
container_name : "MySpeed"
2026-05-24 20:41:08 -07:00
network_mode : "bridge"
ports :
2026-05-25 03:03:29 -07:00
- "${MYSPEED_PORT}:${MYSPEED_PORT}/tcp"
2026-05-24 20:41:08 -07:00
volumes :
- "myspeed:/myspeed/data"
2026-07-06 15:25:38 -07:00
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
2026-08-06 14:38:05 -07:00
environment :
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- "NODE_VERSION=18.20.3"
- "YARN_VERSION=1.22.19"
- "NODE_ENV=production"
- TZ=${TIMEZONE}
hostname : "4b5e3178fcc4"
ipc : "private"
logging :
driver : "json-file"
options : {}
mac_address : "02:42:ac:11:00:03"
2026-05-24 20:41:08 -07:00
working_dir : "/myspeed"
2026-08-06 14:38:05 -07:00
entrypoint :
- "docker-entrypoint.sh"
command :
- "node"
- "server"
2026-05-24 20:41:08 -07:00
restart : unless-stopped
2026-08-06 14:38:05 -07:00
# termix:
# image: ghcr.io/lukegus/termix:latest
# container_name: termix
# cap_add:
# - NET_ADMIN
# - SYS_ADMIN
# networks:
# - termix-net
# ports:
# - "${TERMIX_PORT}:${TERMIX_PORT}"
# volumes:
# - termix-data:/app/data
# environment:
# - "PORT: ${TERMIX_PORT}"
# - "TZ: {TIMEZONE}"
# restart: unless-stopped
2026-05-24 20:41:08 -07:00
2026-07-08 17:44:10 -07:00
pihole :
image : pihole/pihole:latest
2026-08-06 14:38:05 -07:00
container_name : pihole
cap_add :
- NET_ADMIN
2026-07-08 17:44:10 -07:00
network_mode : "host"
ports :
- "53:53/tcp"
- "53:53/udp"
- "67:67/udp"
2026-08-06 14:38:05 -07:00
- "6060:6060/tcp" # original port '80' changed to '6060' within in the webui, be careful changing this
2026-07-08 17:44:10 -07:00
volumes :
- "./etc-pihole:/etc/pihole"
- "./etc-dnsmasq.d:/etc/dnsmasq.d"
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
2026-08-06 14:38:05 -07:00
environment :
TZ : "America/Los_Angeles"
WEBPASSWORD : "password123"
FTLCONF_misc_etc_dnsmasq_d : "true"
2026-07-08 17:44:10 -07:00
restart : unless-stopped
2026-06-21 01:50:35 -07:00
cloudflared :
image : cloudflare/cloudflared:latest
2026-08-06 14:38:05 -07:00
container_name : cloudflared
2026-07-08 17:44:10 -07:00
command : tunnel --no-autoupdate run --token ${CLOUDFLARED_KEY}
2026-08-06 14:38:05 -07:00
restart : always
2026-06-21 01:50:35 -07:00
2026-08-06 14:38:05 -07:00
# torrents-csv:
# image: dessalines/torrents-csv-server:latest
# container_name: torrents-csv
# depends_on:
# - db # search at 'http://shaan-server:8902/service/search?q={SEARCH_TERM'
# ports:
# - "8902:8902"
# environment:
# TORRENTS_CSV_DB_HOST: "postgres://postgres:password@db"
# TORRENTS_CSV_FRONT_END_DIR: /app/dist
# RUST_LOG: DEBUG
# TIMEZONE: ${TIMEZONE}
# restart: unless-stopped
2026-07-02 15:28:58 -07:00
2026-08-06 14:38:05 -07:00
# db:
# image: pgautoupgrade/pgautoupgrade:17-alpine
# container_name: torrents-csv-db
# shm_size: 4gb
# ports:
# - "127.0.0.1:5433:5432"
# volumes:
# - ./init-database.sh:/docker-entrypoint-initdb.d/init-database.sh
# - ./init-database.sql:/var/lib/postgresql/init-database.sql
# - ./torrents.csv:/var/lib/postgresql/torrents.csv
# - /etc/localtime:/etc/localtime:ro
# - /etc/timezone:/etc/timezone:ro
# environment:
# POSTGRES_PASSWORD: password
# POSTGRES_USER: postgres
# TIMEZONE: ${TIMEZONE}
# restart: unless-stopped
2026-07-02 15:28:58 -07:00
2026-07-08 17:44:10 -07:00
portainer :
image : portainer/portainer-ce:lts
2026-08-06 14:38:05 -07:00
container_name : portainer
2026-07-08 17:44:10 -07:00
restart : always
2026-08-06 14:38:05 -07:00
ports :
- ${PORTAINER_PORT}:${PORTAINER_PORT}
2026-07-08 17:44:10 -07:00
volumes :
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
caddy :
image : caddy:latest
container_name : caddy
2026-08-06 14:38:05 -07:00
networks :
- caddy_net
2026-07-08 17:44:10 -07:00
ports :
- 80 : 80
- 443 : 443
volumes :
- /var/run/docker.sock:/var/run/docker.sock
- /home/shaan/torrent-stack/caddy/Caddyfile:/etc/caddy/Caddyfile
- /home/shaan/torrent-stack/caddy/site:/srv
- /home/shaan/torrent-stack/caddy/caddy_data:/data
- /home/shaan/torrent-stack/caddy/caddy_config:/config
2026-08-06 14:38:05 -07:00
restart : unless-stopped
2026-07-08 17:44:10 -07:00
scrutiny :
image : ghcr.io/analogj/scrutiny:nightly-omnibus
2026-08-06 14:38:05 -07:00
container_name : scrutiny
2026-07-08 17:44:10 -07:00
cap_add :
2026-08-06 14:38:05 -07:00
- SYS_RAWIO
2026-07-08 17:44:10 -07:00
ports :
- "${SCRUTINY_PORT:-54321}:8080" # webapp
- "${SCRUTINY_ADMIN_PORT:-12345}:8086" # influxDB admin
volumes :
- /run/udev:/run/udev:ro
- ./config:/opt/scrutiny/config
- ./influxdb:/opt/scrutiny/influxdb
devices :
- "/dev/nvme0n1"
- "/dev/sda"
2026-08-06 14:38:05 -07:00
#- "/dev/sdb"
restart : unless-stopped
2026-06-21 01:50:35 -07:00
2026-08-06 14:38:05 -07:00
karakeep :
image : ghcr.io/karakeep-app/karakeep:${KARAKEEP_VERSION:-release}
container_name : karakeep
env_file :
- .env
ports :
- 4621 : 3000
volumes :
# By default, the data is stored in a docker volume called "data".
# If you want to mount a custom directory, change the volume mapping to:
# - /path/to/your/directory:/data
- karakeep-data:/data
environment :
MEILI_ADDR : http://meilisearch:7700
BROWSER_WEB_URL : http://chrome:9222
# OPENAI_API_KEY: ...
# You almost never want to change the value of the DATA_DIR variable.
# If you want to mount a custom directory, change the volume mapping above instead.
DATA_DIR : /data # DON'T CHANGE THIS
restart : unless-stopped
2026-05-24 20:41:08 -07:00
2026-08-06 14:38:05 -07:00
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=9222
- --hide-scrollbars
- --disable-blink-features=AutomationControlled
- --window-size=1440,900
restart : unless-stopped
meilisearch : # karakeep vector coord. support for karakeep. allows semantic search
image : getmeili/meilisearch:v1.41.0
container_name : karakeep-meilisearch
env_file :
- .env
volumes :
- meilisearch:/meili_data
environment :
MEILI_NO_ANALYTICS : "true"
restart : unless-stopped