services: gluetun: image: qmcgaw/gluetun:latest container_name: gluetun cap_add: - NET_ADMIN devices: - /dev/net/tun:/dev/net/tun environment: - VPN_SERVICE_PROVIDER=protonvpn # Or mullvad, protonvpn, surfshark, etc. - VPN_TYPE=wireguard # WireGuard, openvpn - WIREGUARD_PRIVATE_KEY=${PROTONVPN_API_KEY} - 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 - TZ=America/Los_Angeles - 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). Since we aren't making any weird DNS requests... we are: prowlarr ports: # YOU MUST SPECIFY A PORT PER SERVICE ROUTED THROUGH GLUETUN! - 8888:8888/tcp - 2161:2161 # qBittorrent Web UI - 9696:9696 # Prowlarr - 8989:8989 # Sonarr - 7878:7878 # Radarr - 8686:8686 # Lidarr #- 5055:5055/tcp # Seerr # took this out of gluetun, as it could cause issues with starting the container, and it was unecessary - 6881:6881 # Torrent port # to be honest, I forgot what this was I dont even have this listed in the universal firewall (ufw) - 6881:6881/udp healthcheck: test: wget --spider -q http://1.1.1.1 || exit 1 # ACTUALLY DUMB FUCK! gluetun itself DOES NOT NEED DNS! # the comment afterwards is stupid, if gluetun can't resolve some DNS name, then the other services can't either, they need to be able to look up databases # dont use google.com, since that requires DNS. if it fails to resolve, the container is forced to restart. This is bad, since we mostly don't need dns for things such as qbittorrent, or prowlarr itself interval: 30s timeout: 15s retries: 3 start_period: 1m volumes: - ./gluetun-data:/tmp/gluetun:rw 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. restart: always qbittorrent: image: lscr.io/linuxserver/qbittorrent:latest container_name: qbittorrent network_mode: "container:gluetun" # vpn bunker environment: - PUID=1000 - PGID=1000 - TZ=America/Los_Angeles - WEBUI_PORT=2161 volumes: - ./qbittorrent:/config - /mnt/media/downloads:/downloads - /mnt/media/downloads:/media/downloads - ./gluetun-data:/tmp/gluetun - /etc/localtime:/etc/localtime:ro - /etc/timezone:/etc/timezone:ro - /mnt/11tb_ext/downloads:/11tb_ext/downloads - ./lidarr:/music:ro - ./lidarr/downloads:/music/downloads:rw labels: - "autoheal=true" depends_on: gluetun: condition: service_healthy 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" curl -s -X POST -d "json={\"listen_port\":$$CLEAN_PORT}" http://localhost:2161/api/v2/app/setPreferences; # 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 environment: - PUID=1000 - PGID=1000 - TZ=America/Los_Angeles volumes: - ./prowlarr:/config - ./notify.sh:/notify.sh:ro - /etc/localtime:/etc/localtime:ro - /etc/timezone:/etc/timezone:ro labels: - "autoheal=true" network_mode: "container:gluetun" depends_on: gluetun: condition: service_healthy 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 environment: - PUID=1000 - PGID=1000 - TZ=America/Los_Angeles volumes: - /var/lib/sonarr:/config - /mnt/media:/media - /mnt/11tb_ext:/11tb_ext labels: - "autoheal=true" network_mode: "container:gluetun" depends_on: gluetun: condition: service_healthy 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 environment: - PUID=1000 - PGID=1000 - TZ=America/Los_Angeles volumes: - /var/lib/radarr:/config - /mnt/media:/media - /mnt/11tb_ext:/11tb_ext labels: - "autoheal=true" network_mode: "container:gluetun" depends_on: gluetun: condition: service_healthy 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 environment: - PUID=1000 - PGID=1000 - TZ=America/Los_Angeles volumes: - /home/shaan/torrent-stack/lidarr:/music - /var/lib/lidarr:/config - /mnt/media:/media - /mnt/11tb_ext:/11tb_ext labels: - "autoheal=true" network_mode: "container:gluetun" depends_on: gluetun: condition: service_healthy 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 volumes: #- /mnt/media/media:/config - ./tautulli:/config environment: - PUID=1000 - PGID=1000 - TZ=America/Los_Angeles ports: - 8181:8181 restart: always tdarr: container_name: tdarr image: haveagitgat/tdarr:latest networks: - tdarr-net ports: - 8265:8265 # WebUI - 8266:8266 # local tdarr-node environment: - TZ=America/Los_Angeles - PUID=1000 - PGID=1000 - UMASK_SET=002 - serverIP=0.0.0.0 volumes: - ./tdarr/server:/app/server - ./tdarr/configs:/app/configs - ./tdarr/temp:/temp - /mnt/media:/media # dont ever do this again > - /mnt/media/tdarr-temp:/temp - /mnt/11tb_ext:/11tb_ext devices: - /dev/dri:/dev/dri # Intel UHD Graphics 710 restart: always tdarr-node: container_name: tdarr-node image: haveagitgat/tdarr_node:latest networks: - tdarr-net environment: - TZ=America/Los_Angeles - PUID=1000 - PGID=1000 - nodeID=ShaanNode - nodeIP=0.0.0.0 - serverIP=tdarr # Points to the server container - serverPort=8266 volumes: - ./tdarr/configs:/app/configs - ./tdarr/logs:/app/logs - /home/shaan/torrent-stack/tdarr/temp:/temp - /mnt/media:/media - /mnt/11tb_ext:/11tb_ext devices: - /dev/dri:/dev/dri # only works if user 'shaan' is a part of the 'video' or 'render' group. restart: always homepage: image: ghcr.io/gethomepage/homepage:latest container_name: homepage ports: - 3000:3000 volumes: #- /home/shaan/homepage/config:/app/config #- /home/shaan/homepage/config/images:/app/public/images - # Map images to the public folder - ./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 - /:/root:ro - /mnt/media:/mnt/media:ro - /mnt/shaimpy:/mnt/shaimpy:ro - /mnt/11tb_ext:/mnt/11tb_ext:ro environment: HOMEPAGE_ALLOWED_HOSTS: gethomepage.dev,192.168.50.2:3000,shaan-server:3000,100.76.249.110:3000,ss:3000,shaan-server.tail:3000 # required, may need port. See gethomepage.dev/installation/#homepage_allowed_hosts extra_hosts: - "host.docker.internal:host-gateway" restart: always glances: image: nicolargo/glances:latest-full container_name: glances network_mode: host devices: - /dev/dri:/dev/dri volumes: - /:/root:ro environment: - GLANCES_OPT=-w - PUID=1000 - PGID=1000 restart: unless-stopped autoheal: image: willfarrell/autoheal:latest container_name: autoheal environment: - AUTOHEAL_CONTAINER_LABEL=all - AUTOHEAL_INTERVAL=30 - AUTOHEAL_START_PERIOD=60 volumes: - /var/run/docker.sock:/var/run/docker.sock restart: always seerr: image: ghcr.io/seerr-team/seerr:latest init: true container_name: seerr environment: - LOG_LEVEL=debug - TZ=America/Los_Angeles - PUID=1000 - PGID=1000 - PORT=5055 #optional volumes: - "/home/shaan/seerr-config:/app/config" - "./seerr:/app/config" working_dir: "/app" labels: - "autoheal=true" 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 MySpeed: command: - "node" - "server" container_name: "MySpeed" entrypoint: - "docker-entrypoint.sh" 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=Etc/UTC" hostname: "4b5e3178fcc4" image: "germannewsmaker/myspeed" ipc: "private" logging: driver: "json-file" options: {} mac_address: "02:42:ac:11:00:03" network_mode: "bridge" ports: - "5216:5216/tcp" volumes: - "myspeed:/myspeed/data" working_dir: "/myspeed" restart: unless-stopped termix: image: ghcr.io/lukegus/termix:latest container_name: termix cap_add: - NET_ADMIN - SYS_ADMIN ports: - "8080:8080" volumes: - termix-data:/app/data environment: PORT: "8080" networks: - termix-net restart: unless-stopped networks: tdarr-net: driver: bridge termix-net: driver: bridge volumes: 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... termix-data: driver: local