# ============================================================================= # Torrent Stack - Docker Compose # ============================================================================= 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 # ============================================================================= # Key ordering per service: # image → container_name → env_file → networks/network_mode # → depends_on → cap_add → ports → volumes → environment # → labels → healthcheck → security_opt → mem_limit → cpus # → devices → restart # ============================================================================= services: # --------------------------------------------------------------------------- # VPN & Download # --------------------------------------------------------------------------- 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/.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