Files
torrent-stack/compose.yml
T

748 lines
22 KiB
YAML
Raw Normal View History

2026-08-06 17:17:10 -07:00
# =============================================================================
# Torrent Stack - Docker Compose
# =============================================================================
2026-08-06 14:38:05 -07:00
networks:
2026-08-06 17:17:10 -07:00
caddy_net:
external: true
tdarr-net:
driver: bridge
default:
name: portainer_network
2026-08-06 14:38:05 -07:00
volumes:
2026-08-07 22:52:55 -07:00
#caddy_config:
#caddy_data:
# external: true
2026-08-06 17:17:10 -07:00
myspeed:
external: true
portainer_data:
2026-08-07 22:52:55 -07:00
name: portainer_data
2026-08-06 14:38:05 -07:00
2026-08-06 17:17:10 -07:00
# =============================================================================
# Key ordering per service:
2026-08-07 22:52:55 -07:00
# image → container_name → env_file → networks/network_mode
# → depends_on → cap_add → ports → volumes → environment
# → labels → healthcheck → security_opt → mem_limit → cpus
# → devices → restart
2026-08-06 17:17:10 -07:00
# =============================================================================
2026-08-06 14:38:05 -07:00
services:
2026-08-06 17:17:10 -07:00
# ---------------------------------------------------------------------------
# VPN & Download
# ---------------------------------------------------------------------------
2026-08-06 17:17:10 -07:00
gluetun:
image: qmcgaw/gluetun:latest
container_name: gluetun
2026-08-07 22:52:55 -07:00
env_file:
- .env
- ./env/.gluetun.env
2026-08-06 17:17:10 -07:00
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
2026-08-07 22:52:55 -07:00
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
2026-08-06 17:17:10 -07:00
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:
2026-08-07 22:52:55 -07:00
test: ["CMD-SHELL", "wget --spider -q http://1.1.1.1 || exit 1"]
2026-08-06 17:17:10 -07:00
interval: 30s
timeout: 15s
retries: 3
start_period: 1m
2026-08-07 22:52:55 -07:00
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
2026-08-06 17:17:10 -07:00
extra_hosts:
- "host.docker.internal:host-gateway"
devices:
- /dev/net/tun:/dev/net/tun
restart: always
2026-08-06 17:17:10 -07:00
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
2026-08-07 22:52:55 -07:00
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
2026-08-06 17:17:10 -07:00
environment:
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
- WEBUI_PORT=${QBITTORRENT_PORT}
labels:
- "autoheal=true"
healthcheck:
2026-08-07 22:52:55 -07:00
test:
[
"CMD-SHELL",
"curl -sf http://localhost:${QBITTORRENT_PORT}/api/v2/app/version || exit 1",
]
2026-08-06 17:17:10 -07:00
interval: 1m
timeout: 10s
retries: 3
start_period: 30s
2026-08-07 22:52:55 -07:00
security_opt:
- no-new-privileges:true
mem_limit: 512m
cpus: 2.0
2026-08-06 17:17:10 -07:00
restart: unless-stopped
2026-08-06 17:17:10 -07:00
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
2026-08-06 17:17:10 -07:00
read -r PORT_VAL < /tmp/gluetun/forwarded_port;
CLEAN_PORT=$$(echo "$$PORT_VAL" | tr -d '\r\n ');
2026-08-06 17:17:10 -07:00
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:
2026-08-07 22:52:55 -07:00
test: ["CMD-SHELL", "curl -sf https://1.1.1.1 || exit 1"]
2026-08-06 17:17:10 -07:00
interval: 1m
timeout: 10s
retries: 3
start_period: 30s
2026-08-07 22:52:55 -07:00
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp
mem_limit: 64m
cpus: 0.25
restart: unless-stopped
2026-08-06 17:17:10 -07:00
# ---------------------------------------------------------------------------
# *arr Stack
# ---------------------------------------------------------------------------
2026-08-06 17:17:10 -07:00
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
2026-08-07 22:52:55 -07:00
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
2026-08-06 17:17:10 -07:00
environment:
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
labels:
- "autoheal=true"
healthcheck:
2026-08-07 22:52:55 -07:00
test:
[
"CMD-SHELL",
"curl -sf http://localhost:${PROWLARR_PORT}/ping || exit 1",
]
interval: 1m
timeout: 10s
2026-08-06 17:17:10 -07:00
retries: 3
start_period: 30s
2026-08-07 22:52:55 -07:00
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
restart: unless-stopped
2026-08-06 17:17:10 -07:00
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}
2026-08-07 22:52:55 -07:00
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
2026-08-06 17:17:10 -07:00
environment:
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
labels:
- "autoheal=true"
healthcheck:
2026-08-07 22:52:55 -07:00
test:
["CMD-SHELL", "curl -sf http://localhost:${SONARR_PORT}/ping || exit 1"]
interval: 1m
timeout: 10s
2026-08-06 17:17:10 -07:00
retries: 3
start_period: 60s
2026-08-07 22:52:55 -07:00
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
restart: unless-stopped
2026-08-06 17:17:10 -07:00
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}
2026-08-07 22:52:55 -07:00
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
2026-08-06 17:17:10 -07:00
environment:
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
labels:
- "autoheal=true"
healthcheck:
2026-08-07 22:52:55 -07:00
test:
["CMD-SHELL", "curl -sf http://localhost:${RADARR_PORT}/ping || exit 1"]
2026-08-06 17:17:10 -07:00
interval: 1m
timeout: 10s
retries: 3
start_period: 30s
2026-08-07 22:52:55 -07:00
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
restart: unless-stopped
2026-08-06 17:17:10 -07:00
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}
2026-08-07 22:52:55 -07:00
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
2026-08-06 17:17:10 -07:00
environment:
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
labels:
- "autoheal=true"
healthcheck:
2026-08-07 22:52:55 -07:00
test:
["CMD-SHELL", "curl -sf http://localhost:${LIDARR_PORT}/ping || exit 1"]
2026-08-06 17:17:10 -07:00
interval: 1m
timeout: 10s
retries: 3
start_period: 30s
2026-08-07 22:52:55 -07:00
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
2026-08-06 17:17:10 -07:00
restart: unless-stopped
2026-08-06 17:17:10 -07:00
# ---------------------------------------------------------------------------
# Media
# ---------------------------------------------------------------------------
2026-08-06 14:38:05 -07:00
2026-08-06 17:17:10 -07:00
tautulli:
image: ghcr.io/tautulli/tautulli
container_name: tautulli
networks:
- caddy_net
ports:
- ${TAUTULLI_PORT}:${TAUTULLI_PORT}
volumes:
- ./tautulli:/config
2026-08-07 22:52:55 -07:00
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
2026-08-06 17:17:10 -07:00
environment:
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
- TZ=${TIMEZONE}
2026-08-07 22:52:55 -07:00
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
2026-08-06 17:17:10 -07:00
restart: unless-stopped
2026-08-06 17:17:10 -07:00
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}
2026-08-07 22:52:55 -07:00
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
2026-08-06 17:17:10 -07:00
environment:
- TZ=${TIMEZONE}
- PUID=${HOST_PUID:-1000}
2026-08-07 22:52:55 -07:00
- PGID=${HOST_PGID:-1000}
2026-08-06 17:17:10 -07:00
- UMASK_SET=002
- serverIP=0.0.0.0
2026-08-07 22:52:55 -07:00
security_opt:
- no-new-privileges:true
mem_limit: 512m
cpus: 2.0
2026-08-06 17:17:10 -07:00
restart: unless-stopped
2026-08-06 17:17:10 -07:00
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}
2026-08-07 22:52:55 -07:00
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
2026-08-06 17:17:10 -07:00
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}
2026-08-07 22:52:55 -07:00
security_opt:
- no-new-privileges:true
mem_limit: 2g
cpus: 4.0
2026-08-06 17:17:10 -07:00
devices:
2026-08-07 22:52:55 -07:00
- /dev/dri:/dev/dri
2026-08-06 17:17:10 -07:00
restart: unless-stopped
2026-08-06 17:17:10 -07:00
seerr:
image: ghcr.io/seerr-team/seerr:latest
container_name: seerr
networks:
- caddy_net
ports:
- ${SEERR_PORT}:${SEERR_PORT}
volumes:
- ./seerr:/app/config
2026-08-07 22:52:55 -07:00
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
2026-08-06 17:17:10 -07:00
environment:
2026-08-07 22:52:55 -07:00
- LOG_LEVEL=info
- TZ=${TIMEZONE}
2026-08-06 17:17:10 -07:00
- PUID=${HOST_PUID:-1000}
- PGID=${HOST_PGID:-1000}
labels:
- "autoheal=true"
init: true
working_dir: "/app"
healthcheck:
2026-08-07 22:52:55 -07:00
test:
[
"CMD-SHELL",
"wget -qO- http://127.0.0.1:${SEERR_PORT}/api/v1/status || exit 1",
]
2026-08-06 17:17:10 -07:00
interval: 1m
timeout: 10s
retries: 3
start_period: 60s
2026-08-07 22:52:55 -07:00
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
2026-08-06 17:17:10 -07:00
restart: unless-stopped
2026-08-07 22:52:55 -07:00
# 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
2026-08-06 17:17:10 -07:00
# ---------------------------------------------------------------------------
# Monitoring
# ---------------------------------------------------------------------------
2026-07-10 21:07:13 -07:00
2026-08-06 17:17:10 -07:00
homepage:
image: ghcr.io/gethomepage/homepage:latest
container_name: homepage
2026-08-07 22:52:55 -07:00
env_file:
- .env
- ./env/.homepage.env
2026-08-06 17:17:10 -07:00
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
2026-08-07 22:52:55 -07:00
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
2026-08-06 17:17:10 -07:00
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}"
2026-08-07 22:52:55 -07:00
- "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}"
2026-08-06 17:17:10 -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_ODYSSEUS_HOST=${WEB_PROTOCOL}://${SERVER_NAME}:${ODYSSEUS_PORT}"
2026-08-07 22:52:55 -07:00
- "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}"
2026-08-06 17:17:10 -07:00
- TZ=${TIMEZONE}
2026-08-07 22:52:55 -07:00
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
2026-08-06 17:17:10 -07:00
extra_hosts:
- "host.docker.internal:host-gateway"
restart: unless-stopped
2026-08-07 22:52:55 -07:00
# 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
2026-08-06 17:17:10 -07:00
autoheal:
image: willfarrell/autoheal:latest
container_name: autoheal
volumes:
- /var/run/docker.sock:/var/run/docker.sock
2026-08-07 22:52:55 -07:00
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
2026-08-06 17:17:10 -07:00
environment:
- AUTOHEAL_CONTAINER_LABEL=all
- AUTOHEAL_INTERVAL=30
- AUTOHEAL_START_PERIOD=60
2026-08-07 22:52:55 -07:00
- TZ=${TIMEZONE}
security_opt:
- no-new-privileges:true
read_only: true
mem_limit: 64m
cpus: 0.25
restart: unless-stopped
2026-06-21 01:50:35 -07:00
2026-08-06 17:17:10 -07:00
myspeed:
image: germannewsmaker/myspeed
container_name: myspeed
ports:
- ${MYSPEED_PORT}:${MYSPEED_PORT}/tcp
volumes:
- myspeed:/myspeed/data
2026-08-07 22:52:55 -07:00
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
2026-08-06 17:17:10 -07:00
environment:
- TZ=${TIMEZONE}
2026-08-07 22:52:55 -07:00
security_opt:
- no-new-privileges:true
mem_limit: 256m
cpus: 1.0
2026-08-06 17:17:10 -07:00
restart: unless-stopped
2026-06-21 01:50:35 -07:00
2026-08-06 17:17:10 -07:00
scrutiny:
image: ghcr.io/analogj/scrutiny:nightly-omnibus
container_name: scrutiny
cap_add:
- SYS_RAWIO
ports:
2026-08-07 22:52:55 -07:00
- ${SCRUTINY_PORT}:8080
- ${SCRUTINY_ADMIN_PORT}:8086
2026-08-06 17:17:10 -07:00
volumes:
- /run/udev:/run/udev:ro
2026-08-07 22:52:55 -07:00
- ./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
2026-08-06 17:17:10 -07:00
devices:
- /dev/nvme0n1
- /dev/sda
restart: unless-stopped
2026-07-02 15:28:58 -07:00
2026-08-06 17:17:10 -07:00
# ---------------------------------------------------------------------------
# Infrastructure
# ---------------------------------------------------------------------------
2026-07-02 15:28:58 -07:00
2026-08-06 17:17:10 -07:00
pihole:
image: pihole/pihole:latest
container_name: pihole
cap_add:
2026-08-07 22:52:55 -07:00
- 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
2026-08-06 17:17:10 -07:00
network_mode: host
ports:
- 53:53/tcp
- 53:53/udp
- 67:67/udp
2026-08-07 22:52:55 -07:00
- ${PIHOLE_PORT}:${PIHOLE_PORT}/tcp
2026-08-06 17:17:10 -07:00
volumes:
- ./etc-pihole:/etc/pihole
- ./etc-dnsmasq.d:/etc/dnsmasq.d
2026-08-07 22:52:55 -07:00
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
2026-08-06 17:17:10 -07:00
environment:
2026-08-07 22:52:55 -07:00
- TZ=${TIMEZONE}
2026-08-06 17:17:10 -07:00
- FTLCONF_misc_etc_dnsmasq_d=true
2026-08-07 22:52:55 -07:00
# security_opt:
# - no-new-privileges:true
mem_limit: 256m
cpus: 1.0
2026-08-06 17:17:10 -07:00
restart: unless-stopped
2026-08-06 17:17:10 -07:00
cloudflared:
image: cloudflare/cloudflared:latest
container_name: cloudflared
2026-08-07 22:52:55 -07:00
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
2026-08-06 17:17:10 -07:00
restart: always
2026-08-06 17:17:10 -07:00
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
2026-08-07 22:52:55 -07:00
#- /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
2026-06-21 01:50:35 -07:00
2026-08-06 17:17:10 -07:00
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
2026-08-07 22:52:55 -07:00
#- /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
2026-08-06 17:17:10 -07:00
restart: unless-stopped
2026-08-06 17:17:10 -07:00
# ---------------------------------------------------------------------------
# Karakeep
# ---------------------------------------------------------------------------
2026-08-06 14:38:05 -07:00
2026-08-06 17:17:10 -07:00
karakeep:
image: ghcr.io/karakeep-app/karakeep:${KARAKEEP_VERSION:-release}
container_name: karakeep
env_file:
2026-08-07 22:52:55 -07:00
- ./env/.karakeep.env
2026-08-06 17:17:10 -07:00
ports:
2026-08-07 22:52:55 -07:00
- ${KARAKEEP_PORT}:3000 # must be 3000 as per the dev
2026-08-06 17:17:10 -07:00
volumes:
2026-08-07 22:52:55 -07:00
- ./karakeep-data:/data
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
2026-08-06 17:17:10 -07:00
environment:
2026-08-07 22:52:55 -07:00
- MEILI_ADDR=http://meilisearch:${MEILI_PORT}
- BROWSER_WEB_URL=http://chrome:${KARAKEEP_CHROME_PORT}
2026-08-06 17:17:10 -07:00
- DATA_DIR=/data
2026-08-07 22:52:55 -07:00
security_opt:
- no-new-privileges:true
mem_limit: 512m
cpus: 2.0
2026-08-06 17:17:10 -07:00
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
2026-08-07 22:52:55 -07:00
- --remote-debugging-port=${KARAKEEP_CHROME_PORT}
2026-08-06 17:17:10 -07:00
- --hide-scrollbars
- --disable-blink-features=AutomationControlled
- --window-size=1440,900
2026-08-07 22:52:55 -07:00
security_opt:
- no-new-privileges:true
mem_limit: 512m
cpus: 1.0
2026-08-06 17:17:10 -07:00
restart: unless-stopped
meilisearch:
image: getmeili/meilisearch:v1.41.0
container_name: karakeep-meilisearch
env_file:
- .env
volumes:
2026-08-07 22:52:55 -07:00
- ./meilisearch:/meili_data
#- /etc/localtime:/etc/localtime:ro
#- /etc/timezone:/etc/timezone:ro
2026-08-06 17:17:10 -07:00
environment:
2026-08-07 22:52:55 -07:00
- MEILI_NO_ANALYTICS=true
security_opt:
- no-new-privileges:true
mem_limit: 512m
cpus: 1.0
2026-08-06 17:17:10 -07:00
restart: unless-stopped