# This is a sample docker-compose file for setting up a server with several addons and services you can use with Stremio. # # The following addons are included in this compose project: # - AIOStreams: https://github.com/Viren070/AIOStreams # - TMDB Addon: https://github.com/mrcanelas/tmdb-addon # - EasyNews+: https://github.com/sleeyax/stremio-easynews-addon # - Comet: https://github.com/g0ldyy/comet # - MediaFusion: https://github.com/mhdzumair/mediafusion # - StremThru: https://github.com/MunifTanjim/stremthru # - Jackettio: https://github.com/arvida42/jackettio # - Stremio-Jackett: https://github.com/aymene69/stremio-jackett # # As well as the following services which the addons are already configured to work with: # - MediaFlow Proxy: https://github.com/mhdzumair/mediaflow-proxy - To proxy your streams # - Zilean: https://github.com/ipromknight/zilean - DMM scraper # - Prowlarr: https://github.com/prowlarr/prowlarr - https://github.com/hotio/prowlarr - Indexer manager used by Comet, MediaFusion. (Need to add indexers manually) # - Jackett: https://github.com/Jackett/Jackett - https://github.com/linuxserver/docker-jackett - Indexer manager used by MediaFusion, Jackettio, Stremio-Jackett (Need to add indexers manually) # - FlareSolverr: https://github.com/flaresolverr/flaresolverr - Proxy for solving Cloudflare challenges # - Warp for SOCKS5 proxy to bypass VPS blocks # - Watchtower for auto-updating services # # Finally, Traefik is used as a reverse proxy to route traffic to the services and addons. # # This file is only a template and it requires the .env file to be set up with the necessary environment variables. # # Tips: # # May need sudo perms to run docker compose commands, so run `sudo su` to switch to root user # or run each command with the `sudo` prefix. # # - Run `docker compose up -d` to start the services # - Run `docker compose down` to stop the services # - Run `docker compose logs -f` to view the logs of all services live (Ctrl+C to exit without stopping the services) # - Run `docker compose logs -f ` to view the logs of a specific service live (Ctrl+C to exit without stopping the services) # - Run `docker compose ps` to view the status of all services # - Run `docker compose ps ` to view the status of a specific service # services: # AIOStreams service aiostreams: image: ghcr.io/viren070/aiostreams:dev container_name: aiostreams restart: unless-stopped expose: - 3000 environment: - ADDON_PROXY=http://warp:1080 # or http://gluetun:8888 - ADDON_PROXY_CONFIG=*:false,*.strem.fun:true # only route requests to any strem.fun subdomain through the proxy - API_KEY=${AIOSTREAMS_API_KEY:-} - EASYNEWS_PLUS_URL=http://easynews-plus:1337/ - MEDIAFUSION_URL=http://mediafusion:8000/ - MEDIAFUSION_API_PASSWORD=${MEDIAFUSION_API_PASSWORD} - MEDIAFUSION_CONFIG_TIMEOUT=3000 - COMET_URL=http://comet:2020/ - FORCE_COMET_HOSTNAME=${COMET_HOSTNAME} - COMET_INDEXERS=${COMET_INDEXERS:+${COMET_INDEXERS}} - JACKETTIO_URL=http://jackettio:4000/ - STREMIO_JACKETT_URL=http://stremio-jackett:3000/ - JACKETT_URL=http://jackett:9117/ - JACKETT_API_KEY=${JACKETT_API_KEY:-} - SECRET_KEY=${AIOSTREAMS_SECRET_KEY} # openssl rand -hex 16 - DEFAULT_TIMEOUT=5000 - TMDB_API_KEY=${TMDB_API_KEY} - LOG_FORMAT=text - LOG_LEVEL=debug - LOG_SENSITIVE_INFO=true labels: - "traefik.enable=true" - "traefik.http.routers.aio.rule=Host(`${AIOSTREAMS_HOSTNAME}`)" - "traefik.http.routers.aio.entrypoints=websecure" - "traefik.http.routers.aio.tls.certresolver=myresolver" - "flame.type=app" - "flame.name=AIOStreams" - "flame.url=https://${AIOSTREAMS_HOSTNAME}" healthcheck: test: wget -qO- http://localhost:3000/health interval: 1m timeout: 10s retries: 5 start_period: 10s tmdb-addon: image: mrcanelas/tmdb-addon:latest container_name: tmdb-addon restart: unless-stopped expose: - 3232 environment: - PORT=3232 - TMDB_API=${TMDB_API_KEY} # https://www.themoviedb.org/settings/api - FANART_API=${FANART_API_KEY} # https://fanart.tv/get-an-api-key/ - HOST_NAME=tmdb-${TMDB_ADDON_HOSTNAME} - MONGODB_URI=mongodb://mongodb:27017/tmdb - META_TTL=604800 # 1 week - CATALOG_TTL=86400 # 1 day - NO_CACHE=false # Enable cache, set to true to disable labels: - "traefik.enable=true" - "traefik.http.routers.tmdb.rule=Host(`${TMDB_ADDON_HOSTNAME}`)" - "traefik.http.routers.tmdb.entrypoints=websecure" - "traefik.http.routers.tmdb.tls.certresolver=myresolver" - "traefik.http.services.tmdb.loadbalancer.server.port=3232" - "flame.type=app" - "flame.name=TMDB Addon" - "flame.url=https://${TMDB_ADDON_HOSTNAME}" depends_on: mongodb: condition: service_healthy easynews-plus: image: ghcr.io/sleeyax/stremio-easynews-addon:latest container_name: easynews-plus restart: unless-stopped expose: - 1337 labels: - "traefik.enable=true" - "traefik.http.routers.easynews.rule=Host(`${EASYNEWS_PLUS_HOSTNAME}`)" - "traefik.http.routers.easynews.entrypoints=websecure" - "traefik.http.routers.easynews.tls.certresolver=myresolver" - "flame.type=app" - "flame.name=Easynews+" - "flame.url=https://${EASYNEWS_PLUS_HOSTNAME}" comet: container_name: comet image: g0ldyy/comet:rewrite restart: unless-stopped expose: - 2020 environment: - FASTAPI_HOST=0.0.0.0 - FASTAPI_PORT=2020 - FASTAPI_WORKERS=-1 - DATABASE_TYPE=sqlite - DATABASE_URL=data/comet.db - DASHBOARD_ADMIN_PASSWORD=${COMET_ADMIN_PASSWORD} - DEBRID_PROXY_URL=http://warp:1080 - INDEXER_MANAGER_TYPE=prowlarr # or jackett - INDEXER_MANAGER_URL=http://prowlarr:9696 # or http://jackett:9117 - INDEXER_MANAGER_API_KEY=${PROWLARR_API_KEY:-} # or ${JACKETT_API_KEY:-} - INDEXER_MANAGER_INDEXERS=${COMET_INDEXERS:-[]} # comma separated list of indexer ids # for jackett, get the names from https://github.com/Jackett/Jackett/tree/master/src/Jackett.Common/Definitions - for prowlarr you can write them like on the web dashboard - SCRAPE_ZILEAN=True - ZILEAN_URL=http://zilean:8181 # or https://zilean.elfhosted.com if not hosting zilean locally - ZILEAN_TAKE_FIRST=500 - SCRAPE_TORRENTIO=False - SCRAPE_MEDIAFUSION=False - MEDIAFUSION_URL=http://mediafusion:8000 # or https://mediafusion.elfhosted.com if not hosting mediafusion locally - STREMTHRU_URL=http://stremthru:8080 # or https://stremthru.13377001.xyz if not hosting stremthru locally - DOWNLOAD_TORRENT_FILES=False - REMOVE_ADULT_CONTENT=True labels: - "traefik.enable=true" - "traefik.http.routers.comet.rule=Host(`${COMET_HOSTNAME}`)" - "traefik.http.routers.comet.entrypoints=websecure" - "traefik.http.routers.comet.tls.certresolver=myresolver" - "flame.type=app" - "flame.name=Comet" - "flame.url=https://${COMET_HOSTNAME}" volumes: - ./data/comet:/app/data healthcheck: test: wget -qO- http://127.0.0.1:2020/health interval: 1m timeout: 10s retries: 5 start_period: 10s # Mediaflow Proxy service mediaflow-proxy: image: mhdzumair/mediaflow-proxy container_name: mediaflow-proxy restart: unless-stopped expose: - 8888 environment: API_PASSWORD: ${MEDIAFLOW_API_PASSWORD} PROXY_URL: http://warp:1080 TRANSPORT_ROUTES: '{ "https://torrentio.strem.fun": { "proxy": true } }' labels: - "traefik.enable=true" - "traefik.http.routers.mediaflow.rule=Host(`${MEDIAFLOW_HOSTNAME}`)" - "traefik.http.routers.mediaflow.entrypoints=websecure" - "traefik.http.routers.mediaflow.tls.certresolver=myresolver" - "flame.type=app" - "flame.name=MediaFlow Proxy" - "flame.url=https://${MEDIAFLOW_HOSTNAME}" healthcheck: test: python3 -c "import urllib.request; print(urllib.request.urlopen('http://127.0.0.1:8888/health').read().decode())" interval: 1m timeout: 10s retries: 5 start_period: 10s # MediaFusion mediafusion: image: mhdzumair/mediafusion:latest container_name: mediafusion restart: unless-stopped expose: - 8000 environment: - HOST_URL=https://${MEDIAFUSION_HOSTNAME} - POSTER_HOST_URL=https://${MEDIAFUSION_HOSTNAME} - MONGO_URI=mongodb://mongodb:27017/mediafusion - REDIS_URL=redis://redis:6379 - IS_SCRAP_FROM_TORRENTIO=true - IS_SCRAP_FROM_MEDIAFUSION=true - IS_SCRAP_FROM_ZILEAN=true - IS_SCRAP_FROM_PROWLARR=true - IS_SCRAP_FROM_JACKETT=true - IS_SCRAP_FROM_YTS=false - PROWLARR_API_KEY=${PROWLARR_API_KEY:-} - PROWLARR_URL=http://prowlarr:9696 - PROWLARR_IMMEDIATE_MAX_PROCESS=30 - PROWLARR_IMMEDIATE_MAX_PROCESS_TIME=30 - PROWLARR_SEARCH_INTERVAL_HOUR=24 - PROWLARR_LIVE_TITLE_SEARCH=true - JACKETT_URL=http://jackett:9117 - JACKETT_API_KEY=${JACKETT_API_KEY:-} - JACKETT_IMMEDIATE_MAX_PROCESS=30 - JACKETT_IMMEDIATE_MAX_PROCESS_TIME=30 - JACKETT_SEARCH_INTERVAL_HOUR=24 - JACKETT_LIVE_TITLE_SEARCH=true - ENABLE_RATE_LIMIT=false - TORRENTIO_URL=https://torrentio.strem.fun - MEDIAFUSION_URL=https://mediafusion.elfhosted.com - ZILEAN_URL=http://zilean:8181 - STORE_STREMTHRU_MAGNET_CACHE=false - REQUESTS_PROXY_URL=http://warp:1080 - FLARESOLVERR_URL=http://flaresolverr:8191 - TMDB_API_KEY=${TMDB_API_KEY} # https://www.themoviedb.org/settings/api - SECRET_KEY=${MEDIAFUSION_SECRET_KEY} # openssl rand -hex 32 - API_PASSWORD=${MEDIAFUSION_API_PASSWORD} # random password for API # - LOGGING_LEVEL="DEBUG" healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 1m timeout: 10s retries: 5 start_period: 10s depends_on: mongodb: condition: service_healthy redis: condition: service_healthy warp: condition: service_healthy labels: - "traefik.enable=true" - "traefik.http.routers.mediafusion.rule=Host(`${MEDIAFUSION_HOSTNAME?}`)" - "traefik.http.routers.mediafusion.entrypoints=websecure" - "traefik.http.routers.mediafusion.tls.certresolver=myresolver" - "flame.type=app" - "flame.name=MediaFusion" - "flame.url=https://${MEDIAFUSION_HOSTNAME?}" dramatiq-worker: image: mhdzumair/mediafusion:latest container_name: dramatiq-worker command: ["pipenv", "run", "dramatiq", "api.task", "-p", "1", "-t", "4"] environment: - HOST_URL=https://${MEDIAFUSION_HOSTNAME?} - POSTER_HOST_URL=https://${MEDIAFUSION_HOSTNAME?} - MONGO_URI=mongodb://mongodb:27017/mediafusion - REDIS_URL=redis://redis:6379 - IS_SCRAP_FROM_TORRENTIO=true - IS_SCRAP_FROM_MEDIAFUSION=true - IS_SCRAP_FROM_ZILEAN=true - IS_SCRAP_FROM_PROWLARR=true - IS_SCRAP_FROM_JACKETT=true - IS_SCRAP_FROM_YTS=false - PROWLARR_API_KEY=${PROWLARR_API_KEY:-} - PROWLARR_URL=http://prowlarr:9696 - PROWLARR_IMMEDIATE_MAX_PROCESS=30 - PROWLARR_IMMEDIATE_MAX_PROCESS_TIME=30 - PROWLARR_SEARCH_INTERVAL_HOUR=24 - PROWLARR_LIVE_TITLE_SEARCH=true - JACKETT_URL=http://jackett:9117 - JACKETT_API_KEY=${JACKETT_API_KEY:-} - JACKETT_IMMEDIATE_MAX_PROCESS=30 - JACKETT_IMMEDIATE_MAX_PROCESS_TIME=30 - JACKETT_SEARCH_INTERVAL_HOUR=24 - JACKETT_LIVE_TITLE_SEARCH=true - ENABLE_RATE_LIMIT=false - TORRENTIO_URL=https://torrentio.strem.fun - MEDIAFUSION_URL=https://mediafusion.elfhosted.com - ZILEAN_URL=http://zilean:8181 - STORE_STREMTHRU_MAGNET_CACHE=false - REQUESTS_PROXY_URL=http://warp:1080 - FLARESOLVERR_URL=http://flaresolverr:8191 - TMDB_API_KEY=${TMDB_API_KEY} # https://www.themoviedb.org/settings/api - SECRET_KEY=${MEDIAFUSION_SECRET_KEY?} # openssl rand -hex 32 - API_PASSWORD=${MEDIAFUSION_API_PASSWORD} # random password for API # - LOGGING_LEVEL="DEBUG" depends_on: mongodb: condition: service_healthy redis: condition: service_healthy restart: unless-stopped browserless: image: ghcr.io/browserless/chromium container_name: browserless environment: - TIMEOUT=-1 restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/json/version"] interval: 30s timeout: 10s retries: 3 stremthru: image: muniftanjim/stremthru:latest-heavy container_name: stremthru restart: unless-stopped expose: - 8080 environment: - STREMTHRU_HTTP_PROXY=http://warp:1080 - STREMTHRU_TUNNEL=*:false,torrentio.strem.fun:true # Only tunnel hostnames that block VPS access (e.g. Torrentio) - STREMTHRU_PROXY_AUTH=user1:pass1,user2:pass2 - STREMTHRU_STORE_AUTH=*:realdebrid:abc...xyz # Add apikey - STREMTHRU_STORE_TUNNEL=realdebrid:api # Only send RD API via tunnel, not all access (e.g playback) - STREMTHRU_STORE_CONTENT_PROXY=*:true,easydebrid:false,premiumize:false - STREMTHRU_PEER_URI=https://stremthru.13377001.xyz - STREMTHRU_DATABASE_URI=sqlite://./data/stremthru.db - STREMTHRU_REDIS_URI=redis://redis:6379 # redis://garnet:6379 depends_on: warp: condition: service_healthy volumes: - ./data/stremthru:/app/data labels: - "traefik.enable=true" - "traefik.http.routers.stremthru.rule=Host(`${STREMTHRU_HOSTNAME?}`)" - "traefik.http.routers.stremthru.entrypoints=websecure" - "traefik.http.routers.stremthru.tls.certresolver=myresolver" - "traefik.http.services.stremthru.loadbalancer.server.port=8080" - "flame.type=app" - "flame.name=StremThru" - "flame.url=https://${STREMTHRU_HOSTNAME}" stremio-jackett: image: belmeg/stremio-addon-jackett container_name: stremio-jackett restart: unless-stopped expose: - 3000 environment: - PUID=1000 - PGID=1000 - TZ=${TZ:-UTC} # Add timezone support labels: - "traefik.enable=true" - "traefik.http.routers.stremiojackett.rule=Host(`${STREMIO_JACKETT_HOSTNAME}`)" - "traefik.http.routers.stremiojackett.entrypoints=websecure" - "traefik.http.routers.stremiojackett.tls.certresolver=myresolver" - "flame.type=app" - "flame.name=Stremio-Jackett" - "flame.url=https://${STREMIO_JACKETT_HOSTNAME}" jackettio: image: arvida42/jackettio:latest container_name: jackettio restart: unless-stopped expose: - 4000 environment: - JACKETT_URL=http://jackett:9117 - JACKETT_API_KEY=${JACKETT_API_KEY:-} - TMDB_ACCESS_TOKEN=${TMDB_ACCESS_TOKEN} volumes: - ./data/jackettio:/data labels: - "traefik.enable=true" - "traefik.http.routers.jackettio.rule=Host(`${JACKETTIO_HOSTNAME?}`)" - "traefik.http.routers.jackettio.entrypoints=websecure" - "traefik.http.routers.jackettio.tls.certresolver=myresolver" - "flame.type=app" - "flame.name=Jackettio" - "flame.url=https://${JACKETTIO_HOSTNAME}" zilean: image: ipromknight/zilean:latest restart: unless-stopped container_name: zilean tty: true environment: Zilean__Database__ConnectionString: Host=postgres;Database=zilean;Username=${POSTGRES_USER};Password=${POSTGRES_PASSWORD};Include Error Detail=true;Timeout=30;CommandTimeout=3600 Zilean__Imdb__UseAllCores: true Zilean__Imdb__UseLucene: true healthcheck: test: curl --connect-timeout 10 --silent --show-error --fail http://localhost:8181/healthchecks/ping timeout: 60s interval: 30s retries: 10 depends_on: postgres: condition: service_healthy volumes: - zilean-tmp:/tmp prowlarr: image: ghcr.io/hotio/prowlarr:latest container_name: prowlarr environment: - PUID=1000 - PGID=1000 - UMASK=002 - TZ=${TZ:-UTC} # Add timezone support expose: - 9696 volumes: - ./data/prowlarr:/config restart: unless-stopped labels: - "traefik.enable=true" - "traefik.http.routers.prowlarr.rule=Host(`${PROWLARR_HOSTNAME?}`)" - "traefik.http.routers.prowlarr.entrypoints=websecure" - "traefik.http.routers.prowlarr.tls.certresolver=myresolver" - "flame.type=app" - "flame.name=Prowlarr" - "flame.url=https://${PROWLARR_HOSTNAME}" jackett: image: linuxserver/jackett:latest container_name: jackett environment: - PUID=1000 - PGID=1000 - TZ=${TZ:-UTC} # Add timezone support expose: - 9117 volumes: - ./data/jackett:/config restart: unless-stopped labels: - "traefik.enable=true" - "traefik.http.routers.jackett.rule=Host(`${JACKETT_HOSTNAME?}`)" - "traefik.http.routers.jackett.entrypoints=websecure" - "traefik.http.routers.jackett.tls.certresolver=myresolver" - "flame.type=app" - "flame.name=Jackett" - "flame.url=https://${JACKETT_HOSTNAME}" healthcheck: test: curl -f http://localhost:9117/health interval: 30s timeout: 10s retries: 3 start_period: 30s nzbhydra2: container_name: nzbhydra2 image: ghcr.io/hotio/nzbhydra2:latest expose: - 5076 environment: - PUID=1000 - PGID=1000 - UMASK=002 - TZ=${TZ:-UTC} volumes: - ./data/nzbhydra/config:/config restart: unless-stopped labels: - "traefik.enable=true" - "traefik.http.routers.nzbhydra2.rule=Host(`${NZBHYDRA2_HOSTNAME}`)" - "traefik.http.routers.nzbhydra2.entrypoints=websecure" - "traefik.http.routers.nzbhydra2.tls.certresolver=myresolver" - "flame.type=app" - "flame.name=NZBHydra2" - "flame.url=https://${NZBHYDRA2_HOSTNAME}" flaresolverr: image: ghcr.io/flaresolverr/flaresolverr:latest container_name: flaresolverr restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8191/health"] interval: 30s timeout: 10s retries: 3 # byparr: # image: ghcr.io/thephaseless/byparr # container_name: byparr # restart: unless-stopped # environment: # - LOG_LEVEL=INFO # volumes: # - ./data/byparr/screenshots:/app/screenshots # healthcheck: # test: wget -qO- http://localhost:8191/health # interval: 5m # timeout: 10s # retries: 3 # start_period: 10s stremio-server: image: stremio/server:latest container_name: stremio-server expose: - 11470 restart: unless-stopped labels: - "traefik.enable=true" - "traefik.http.routers.stremio-server.rule=Host(`${STREMIO_SERVER_HOSTNAME}`)" - "traefik.http.routers.stremio-server.entrypoints=websecure" - "traefik.http.routers.stremio-server.tls.certresolver=myresolver" - "flame.type=app" - "flame.name=Stremio Server" - "flame.url=https://${STREMIO_SERVER_HOSTNAME}" # Warp for SOCKS5 proxy for AIOStreams, MediaFlow Proxy, and Prowlarr, MediaFusion warp: image: caomingjun/warp container_name: warp restart: unless-stopped device_cgroup_rules: - 'c 10:200 rwm' expose: - 1080 environment: - WARP_SLEEP=5 cap_add: - NET_ADMIN sysctls: - net.ipv6.conf.all.disable_ipv6=0 - net.ipv4.conf.all.src_valid_mark=1 volumes: - ./data/warp:/var/lib/cloudflare-warp healthcheck: test: curl -x "socks5h://127.0.0.1:1080" -fsSL "https://www.cloudflare.com/cdn-cgi/trace" | grep -qE "warp=(plus|on)" || exit 1 interval: 15s timeout: 5s retries: 3 start_period: 5s mongodb: image: mongo:latest container_name: mongodb restart: unless-stopped volumes: - mongodb-data:/data/db healthcheck: test: echo 'db.runCommand("ping").ok' | mongosh localhost:27017/test --quiet interval: 10s timeout: 10s retries: 5 start_period: 40s postgres: image: postgres:17.2-alpine container_name: postgres restart: unless-stopped shm_size: 2G environment: PGDATA: /var/lib/postgresql/data/pgdata POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: postgres volumes: - postgres-data:/var/lib/postgresql/data/pgdata healthcheck: test: [ "CMD-SHELL", "pg_isready -U postgres" ] interval: 10s timeout: 5s retries: 5 redis: image: redis:latest container_name: redis restart: unless-stopped volumes: - redis-data:/data command: redis-server --appendonly yes --save 60 1 healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 # garnet: # image: 'ghcr.io/microsoft/garnet' # ulimits: # memlock: -1 # container_name: garnet # restart: unless-stopped # # To avoid docker NAT, consider `host` mode. # # https://docs.docker.com/compose/compose-file/compose-file-v3/#network_mode # # network_mode: "host" # volumes: # - garnet-data:/data # Start page for your server flame: image: pawelmalak/flame:multiarch container_name: flame restart: unless-stopped expose: - 5005 environment: - PASSWORD=${FLAME_PASSWORD} labels: - "traefik.enable=true" - "traefik.http.routers.flame.rule=Host(`${FLAME_HOSTNAME?}`)" - "traefik.http.routers.flame.entrypoints=websecure" - "traefik.http.routers.flame.tls.certresolver=myresolver" volumes: - /var/run/docker.sock:/var/run/docker.sock - ./data/flame:/app/data dash: image: mauricenino/dashdot:latest container_name: dash restart: unless-stopped expose: - 3001 privileged: true environment: DASHDOT_PAGE_TITLE: ${DASHDOT_PAGE_TITLE:-dash.} DASHDOT_ALWAYS_SHOW_PERCENTAGES: true DASHDOT_SHOW_HOST: true DASHDOT_CUSTOM_HOST: ${DASHDOT_PAGE_TITLE:-} DASHDOT_ACCEPT_OOKLA_EULA: true DASHDOT_NETWORK_SPEED_AS_BYTES: true volumes: - /:/mnt/host:ro labels: - "traefik.enable=true" - "traefik.http.routers.dash.rule=Host(`${DASHDOT_HOSTNAME?}`)" - "traefik.http.routers.dash.entrypoints=websecure" - "traefik.http.routers.dash.tls.certresolver=myresolver" - "flame.type=app" - "flame.name=Dash" - "flame.url=https://${DASHDOT_HOSTNAME?}" honey: image: ghcr.io/dani3l0/honey:latest container_name: honey restart: unless-stopped volumes: - ./data/honey:/app/dist/config - ./data/honey/img:/app/dist/img/custom expose: - 4173 labels: - "traefik.enable=true" - "traefik.http.routers.honey.rule=Host(`${HONEY_HOSTNAME?}`)" - "traefik.http.routers.honey.entrypoints=websecure" - "traefik.http.routers.honey.tls.certresolver=myresolver" - "flame.type=app" - "flame.name=Honey" - "flame.url=https://${HONEY_HOSTNAME?}" # Status page for monitoring uptime uptime-kuma: image: louislam/uptime-kuma:latest container_name: kuma restart: unless-stopped expose: - 3001 labels: - "traefik.enable=true" - "traefik.http.routers.uptime-kuma.rule=Host(`${UPTIME_KUMA_HOSTNAME?}`)" - "traefik.http.routers.uptime-kuma.entrypoints=websecure" - "traefik.http.routers.uptime-kuma.tls.certresolver=myresolver" - "traefik.http.routers.status-page.rule=Host(`${STATUS_PAGE_HOSTNAME?}`)" - "traefik.http.routers.status-page.entrypoints=websecure" - "traefik.http.routers.status-page.tls.certresolver=myresolver" - "flame.type=app" - "flame.name=Uptime Kuma" - "flame.url=https://${UPTIME_KUMA_HOSTNAME?}" volumes: - ./data/kuma:/app/data - /var/run/docker.sock:/var/run/docker.sock # Watchtower for auto-updating services watchtower: image: containrrr/watchtower container_name: watchtower restart: unless-stopped environment: TZ: ${TZ:-UTC} WATCHTOWER_CLEANUP: "true" WATCHTOWER_SCHEDULE: ${AUTO_UPDATE_SCHEDULE:-0 0 6 * * *} # Run at 6am daily WATCHTOWER_NOTIFICATION_URL: ${AUTO_UPDATE_NOTIFICATION_URL:-} WATCHTOWER_NOTIFICATION_REPORT: "true" WATCHTOWER_NOTIFICATION_TEMPLATE: | {{- if .Report -}} {{- with .Report -}} {{- if ( or .Updated .Failed ) -}} {{len .Scanned}} Scanned, {{len .Updated}} Updated, {{len .Failed}} Failed {{- range .Updated}} - {{.Name}} ({{.ImageName}}): {{.CurrentImageID.ShortID}} updated to {{.LatestImageID.ShortID}} {{- end -}} {{- range .Skipped}} - {{.Name}} ({{.ImageName}}): {{.State}}: {{.Error}} {{- end -}} {{- range .Failed}} - {{.Name}} ({{.ImageName}}): {{.State}}: {{.Error}} {{- end -}} {{- end -}} {{- end -}} {{- else -}} {{range .Entries -}}{{.Message}}{{"\n"}}{{- end -}} {{- end -}} volumes: - /var/run/docker.sock:/var/run/docker.sock # Web UI for viewing logs dozzle: image: amir20/dozzle:latest container_name: dozzle restart: unless-stopped expose: - 8080 environment: DOZZLE_ENABLE_ACTIONS: "true" DOZZLE_NO_ANALYTICS: "true" volumes: - /var/run/docker.sock:/var/run/docker.sock labels: - "traefik.enable=true" - "traefik.http.routers.dozzle.rule=Host(`${DOZZLE_HOSTNAME?}`)" - "traefik.http.routers.dozzle.entrypoints=websecure" - "traefik.http.routers.dozzle.tls.certresolver=myresolver" - "traefik.http.routers.dozzle.middlewares=dozzle-auth" - "traefik.http.middlewares.dozzle-auth.basicauth.users=${DOZZLE_USERNAME?}:${DOZZLE_HASHED_PASSWORD?}" - "flame.type=app" - "flame.name=Dozzle" - "flame.url=https://${DOZZLE_HOSTNAME?}" healthcheck: test: ["CMD", "/dozzle", "healthcheck"] interval: 3s timeout: 30s retries: 5 start_period: 30s traefik: image: traefik:v3 container_name: traefik restart: unless-stopped ports: - 443:443 - 127.0.0.1:8080:8080 command: - "--api.insecure=true" - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--entryPoints.websecure.address=:443" - "--certificatesresolvers.myresolver.acme.tlschallenge=true" - "--certificatesresolvers.myresolver.acme.email=${LETSENCRYPT_EMAIL}" - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" - "--log.level=INFO" - "--ping" volumes: - "/var/run/docker.sock:/var/run/docker.sock" - "./data/letsencrypt:/letsencrypt" healthcheck: test: ["CMD", "traefik", "healthcheck", "--ping"] interval: 10s timeout: 5s retries: 3 # https://github.com/5rahim/seanime # App/Server for anime. # seanime: # image: umagistr/seanime # container_name: seanime # command: # volumes: # - /mnt/user/anime:/anime # - /mnt/user/downloads:/downloads # - ./data/seanime:/root/.config/Seanime # expose: # - 43211 # restart: unless-stopped # labels: # - "traefik.enable=true" # - "traefik.http.routers.seanime.rule=Host(`${SEANIME_HOSTNAME}`)" # - "traefik.http.routers.seanime.entrypoints=websecure" # - "traefik.http.routers.seanime.tls.certresolver=myresolver" # - "traefik.http.routers.seanime.middlewares=seanime-auth" # - "traefik.http.middlewares.seanime-auth.basicauth.users=${SEANIME_USERNAME}:${SEANIME_HASHED_PASSWORD}" # - "flame.type=app" # - "flame.name=Seanime" # - "flame.url=https://${SEANIME_HOSTNAME}" # healthcheck: # test: wget -qO- http://localhost:43211/api/v1/status # interval: 5m # timeout: 10s # retries: 5 # start_period: 10s aiostremio: image: viren070/aiostremio:latest container_name: aiostremio restart: unless-stopped expose: - 8469 volumes: - ./data/aiostremio:/app/data environment: ADMIN_USERNAME: ${AIOSTREMIO_ADMIN_USERNAME} ADMIN_PASSWORD: ${AIOSTREMIO_ADMIN_PASSWORD} MEDIAFLOW_API_PASSWORD: ${MEDIAFLOW_API_PASSWORD} REDIS_HOST: redis REDIS_PORT: 6379 REDIS_PASSWORD: DEBRID_API_KEY: ${DEBRID_API_KEY} labels: - "traefik.enable=true" - "traefik.http.routers.aiostremio.rule=Host(`${AIOSTREMIO_HOSTNAME}`)" - "traefik.http.routers.aiostremio.entrypoints=websecure" - "traefik.http.routers.aiostremio.tls.certresolver=myresolver" - "flame.type=app" - "flame.name=AIOStreams" - "flame.url=https://${AIOSTREMIO_HOSTNAME}" addon-manager: image: reddravenn/stremio-addon-manager:latest container_name: addon-manager restart: unless-stopped expose: - 80 labels: - "traefik.enable=true" - "traefik.http.routers.addon-manager.rule=Host(`${ADDON_MANAGER_HOSTNAME}`)" - "traefik.http.routers.addon-manager.entrypoints=websecure" - "traefik.http.routers.addon-manager.tls.certresolver=myresolver" - "flame.type=app" - "flame.name=Stremio Addon Manager" - "flame.url=https://${ADDON_MANAGER_HOSTNAME}" ravenn-catalogs: image: reddravenn/stremio-catalog-providers container_name: ravenn-catalogs expose: - 7000 environment: PORT: 7000 BASE_URL: https://${RAVENN_CATALOGS_HOSTNAME?} DB_USER: ${POSTGRES_USER} DB_HOST: ravenn-postgres DB_NAME: stremio_catalog_db DB_PASSWORD: ${POSTGRES_PASSWORD} DB_PORT: 5432 DB_MAX_CONNECTIONS: 20 DB_IDLE_TIMEOUT: 30000 DB_CONNECTION_TIMEOUT: 2000 REDIS_HOST: ravenn-redis REDIS_PORT: 6379 REDIS_PASSWORD: TRAKT_CLIENT_ID: ${TRAKT_CLIENT_ID} TRAKT_CLIENT_SECRET: ${TRAKT_CLIENT_SECRET} TRAKT_HISTORY_FETCH_INTERVAL: 1d CACHE_CATALOG_CONTENT_DURATION_DAYS: 1 CACHE_POSTER_CONTENT_DURATION_DAYS: 7 LOG_LEVEL: info LOG_INTERVAL_DELETION: 3d NODE_ENV: production depends_on: ravenn-postgres: condition: service_healthy ravenn-redis: condition: service_healthy volumes: - ./data/ravenn/catalogs/db:/usr/src/app/db - ./data/ravenn/catalogs/log:/usr/src/app/log labels: - "traefik.enable=true" - "traefik.http.routers.ravenn-catalogs.rule=Host(`${RAVENN_CATALOGS_HOSTNAME?}`)" - "traefik.http.routers.ravenn-catalogs.entrypoints=websecure" - "traefik.http.routers.ravenn-catalogs.tls.certresolver=myresolver" - "flame.type=app" - "flame.name=Stremio Catalogs" - "flame.url=https://${RAVENN_CATALOGS_HOSTNAME}" ravenn-trakt: image: reddravenn/stremio-trakt-addon container_name: ravenn-trakt expose: - 7000 environment: PORT: 7000 BASE_URL: https://${RAVENN_TRAKT_HOSTNAME?} DB_USER: ${POSTGRES_USER} DB_HOST: ravenn-postgres DB_NAME: stremio_trakt_db DB_PASSWORD: ${POSTGRES_PASSWORD} DB_PORT: 5432 DB_MAX_CONNECTIONS: 20 DB_IDLE_TIMEOUT: 30000 DB_CONNECTION_TIMEOUT: 2000 REDIS_HOST: ravenn-redis REDIS_PORT: 6379 REDIS_PASSWORD: TRAKT_CLIENT_ID: ${TRAKT_CLIENT_ID} TRAKT_CLIENT_SECRET: ${TRAKT_CLIENT_SECRET} TMDB_CACHE_DURATION: 1d TRAKT_CACHE_DURATION: 1d TRAKT_HISTORY_FETCH_INTERVAL: 1d LOG_LEVEL: info LOG_INTERVAL_DELETION: 3d NODE_ENV: production restart: unless-stopped depends_on: ravenn-postgres: condition: service_healthy ravenn-redis: condition: service_healthy volumes: - ./data/ravenn/trakt/cache:/usr/src/app/cache - ./data/ravenn/trakt/log:/usr/src/app/log labels: - "traefik.enable=true" - "traefik.http.routers.ravenn-trakt.rule=Host(`${RAVENN_TRAKT_HOSTNAME?}`)" - "traefik.http.routers.ravenn-trakt.entrypoints=websecure" - "traefik.http.routers.ravenn-trakt.tls.certresolver=myresolver" - "flame.type=app" - "flame.name=Stremio Trakt" - "flame.url=https://${RAVENN_TRAKT_HOSTNAME}" ravenn-postgres: container_name: ravenn-postgres image: postgres:16.4 environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} volumes: - ravenn-postgres:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 30s timeout: 10s retries: 5 start_period: 10s ravenn-redis: container_name: ravenn-redis image: redis:6 volumes: - ravenn-redis:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 30s timeout: 10s retries: 5 # plausible_db: # image: postgres:16-alpine # restart: unless-stopped # container_name: plausible-db # volumes: # - plausible-db:/var/lib/postgresql/data # environment: # POSTGRES_USER: ${POSTGRES_USER} # POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} # healthcheck: # test: ["CMD-SHELL", "pg_isready -U postgres"] # start_period: 1m # plausible_events_db: # image: clickhouse/clickhouse-server:24.3.3.102-alpine # restart: unless-stopped # container_name: plausible-events-db # volumes: # - plausible-event-db:/var/lib/clickhouse # - plausible-event-logs:/var/log/clickhouse-server # - ./data/plausible/clickhouse/logs.xml:/etc/clickhouse-server/config.d/logs.xml:ro # - ./data/plausible/clickhouse/ipv4-only.xml:/etc/clickhouse-server/config.d/ipv4-only.xml:ro # - ./data/plausible/clickhouse/low-resources.xml:/etc/clickhouse-server/config.d/low-resources.xml:ro # ulimits: # nofile: # soft: 262144 # hard: 262144 # healthcheck: # test: ["CMD-SHELL", "wget --no-verbose --tries=1 -O - http://127.0.0.1:8123/ping || exit 1"] # start_period: 1m # plausible: # image: ghcr.io/plausible/community-edition:latest # container_name: plausible # restart: unless-stopped # command: sh -c "/entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh run" # depends_on: # plausible_db: # condition: service_healthy # plausible_events_db: # condition: service_healthy # volumes: # - plausible-data:/var/lib/plausible # ulimits: # nofile: # soft: 65535 # hard: 65535 # expose: # - 8000 # environment: # TMPDIR: /var/lib/plausible/tmp # BASE_URL: https://${PLAUSIBLE_HOSTNAME} # SECRET_KEY_BASE: ${PLAUSIBLE_SECRET_KEY_BASE} # HTTP_PORT: 8000 # labels: # - "traefik.enable=true" # - "traefik.http.routers.plausible.rule=Host(`${PLAUSIBLE_HOSTNAME}`)" # - "traefik.http.routers.plausible.entrypoints=websecure" # - "traefik.http.routers.plausible.tls.certresolver=myresolver" # - "traefik.http.services.plausible.loadbalancer.server.port=8000" # - "flame.type=app" # - "flame.name=Plausible" # - "flame.url=https://${PLAUSIBLE_HOSTNAME}" # searxng: # container_name: searxng # image: docker.io/searxng/searxng:latest # restart: unless-stopped # expose: # - 8080 # volumes: # - ./data/searxng:/etc/searxng:rw # environment: # - SEARXNG_BASE_URL=https://${SEARXNG_HOSTNAME:-localhost}/ # - UWSGI_WORKERS=${SEARXNG_UWSGI_WORKERS:-4} # - UWSGI_THREADS=${SEARXNG_UWSGI_THREADS:-4} # logging: # driver: "json-file" # options: # max-size: "1m" # max-file: "1" # labels: # - "traefik.enable=true" # - "traefik.http.routers.searxng.rule=Host(`${SEARXNG_HOSTNAME}`)" # - "traefik.http.routers.searxng.entrypoints=websecure" # - "traefik.http.routers.searxng.tls.certresolver=myresolver" # - "flame.type=app" # - "flame.name=SearxNG" # - "flame.url=https://${SEARXNG_HOSTNAME}" volumes: zilean-tmp: redis-data: postgres-data: mongodb-data: ravenn-postgres: ravenn-redis: # plausible-db: # plausible-data: # plausible-event-db: # plausible-event-logs: # # garnet-data: