# Infrastructure Services # Core services that other services depend on # Place in /opt/stacks/infrastructure/docker-compose.yml # NOTE: Traefik, Authelia, DuckDNS, and Gluetun have their own separate stacks # See /opt/stacks/traefik/, /opt/stacks/authelia/, etc. # SABLIER SESSION DURATION: Set to 5m for testing. Increase to 30m for production in config-templates/traefik/dynamic/sablier.yml # RESTART POLICY GUIDE: # - unless-stopped: Core infrastructure services that should always run # - no: Services with Sablier lazy loading (start on-demand) # - See individual service comments for specific reasoning # Service Access URLs: # - Portainer: https://portainer.${DOMAIN} # - Pi-hole: https://pihole.${DOMAIN} # - Dozzle: https://dozzle.${DOMAIN} # - Glances: https://glances.${DOMAIN} # - Netdata: https://netdata.${DOMAIN} services: dockerproxy: # Docker socket proxy for security - provides safe Docker API access, must always run # REQUIREMENTS FOR SABLIER INTEGRATION: # 1. Docker daemon must be configured to listen on TCP port 2375 (not just unix socket) # 2. Firewall must allow access to port 2375 from Sablier service # 3. Docker daemon config should include: "hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"] # 4. For security, consider restricting access to specific IP ranges or using TLS # 5. dockerproxy runs for additional security but doesn't expose port 2375 (handled by Docker daemon) image: tecnativa/docker-socket-proxy:latest container_name: dockerproxy privileged: true restart: unless-stopped # Note: Port 2375 is handled directly by Docker daemon for Sablier access # dockerproxy provides additional security features but doesn't expose the port volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - CONTAINERS=1 - SERVICES=1 - TASKS=1 - NETWORKS=1 - NODES=1 - EXEC=1 - IMAGES=1 - VOLUMES=1 - SWARM=1 labels: - homelab.category=infrastructure - homelab.description=Docker socket proxy for security # Pi-hole - Network-wide ad blocker and DNS server # Access at: https://pihole.${DOMAIN} # DNS service must always run for network-wide ad blocking pihole: image: pihole/pihole:2024.01.0 deploy: resources: limits: cpus: '0.25' memory: 128M pids: 256 reservations: cpus: '0.10' memory: 64M container_name: pihole restart: unless-stopped networks: - homelab-network - traefik-network ports: - "53:53/tcp" # DNS TCP - "53:53/udp" # DNS UDP volumes: - ./pihole/etc-pihole:/etc/pihole - ./pihole/etc-dnsmasq.d:/etc/dnsmasq.d environment: - TZ=${TZ:-America/New_York} - WEBPASSWORD=${PIHOLE_PASSWORD:-changeme} - FTLCONF_LOCAL_IPV4=${SERVER_IP} dns: - 127.0.0.1 - 1.1.1.1 cap_add: - NET_ADMIN labels: # TRAEFIK CONFIGURATION # ========================================== # Service metadata - "homelab.category=infrastructure" - "homelab.description=Network-wide ad blocking and DNS" # Traefik reverse proxy (comment/uncomment to disable/enable) # If Traefik is on a remote server: these labels are NOT USED; # configure external yml files in /traefik/dynamic folder instead. - "traefik.enable=true" - "traefik.http.routers.pihole.rule=Host(`pihole.${DOMAIN}`)" - "traefik.http.routers.pihole.entrypoints=websecure" - "traefik.http.routers.pihole.tls.certresolver=letsencrypt" - "traefik.http.routers.pihole.middlewares=authelia@docker" - "traefik.http.services.pihole.loadbalancer.server.port=80" # Watchtower - Automatic container updates # Monitors and updates Docker containers to latest versions # Runs daily at 4 AM watchtower: image: containrrr/watchtower:latest container_name: watchtower restart: unless-stopped networks: - homelab-network volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - DOCKER_API_VERSION=1.52 - WATCHTOWER_CLEANUP=true - WATCHTOWER_INCLUDE_RESTARTING=true - WATCHTOWER_SCHEDULE=0 0 4 * * * # 4 AM daily - WATCHTOWER_NOTIFICATIONS=shoutrrr - WATCHTOWER_NOTIFICATION_URL=${WATCHTOWER_NOTIFICATION_URL:-} labels: - "homelab.category=infrastructure" - "homelab.description=Automatic Docker container updates" # Dozzle - Real-time Docker log viewer # Access at: https://dozzle.${DOMAIN} # Uses Sablier lazy loading - starts on-demand, stops after 5min inactivity dozzle: image: amir20/dozzle:latest deploy: resources: limits: cpus: '0.50' memory: 256M pids: 512 reservations: cpus: '0.25' memory: 128M container_name: dozzle restart: no networks: - homelab-network - traefik-network ports: - "8085:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro environment: - DOZZLE_LEVEL=info - DOZZLE_TAILSIZE=300 - DOZZLE_FILTER=status=running labels: # TRAEFIK & SABLIER CONFIGURATION # ========================================== # Service metadata - "homelab.category=infrastructure" - "homelab.description=Real-time Docker log viewer" # Traefik reverse proxy (comment/uncomment to disable/enable) # If Traefik is on a remote server: these labels are NOT USED; # configure external yml files in /traefik/dynamic folder instead. - "traefik.enable=true" - "traefik.http.routers.dozzle.rule=Host(`dozzle.${SERVER_HOSTNAME}.${DOMAIN}`)" - "traefik.http.routers.dozzle.entrypoints=websecure" - "traefik.http.routers.dozzle.tls=true" - "traefik.http.routers.dozzle.middlewares=authelia@docker" - "traefik.http.services.dozzle.loadbalancer.server.port=8085" # Sablier lazy loading (enabled by default - comment out to disable) - "sablier.enable=true" - "sablier.group=${SERVER_HOSTNAME}-dozzle" - "sablier.start-on-demand=true" # Glances - System monitoring # Access at: https://glances.${DOMAIN} # Uses Sablier lazy loading - starts on-demand, stops after 30min inactivity glances: image: nicolargo/glances:latest-full deploy: resources: limits: cpus: '0.50' memory: 256M pids: 512 reservations: cpus: '0.25' memory: 128M container_name: glances restart: no networks: - homelab-network - traefik-network ports: - "61208:61208" pid: host volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./glances/config:/glances/conf environment: - GLANCES_OPT=-w labels: # TRAEFIK & SABLIER CONFIGURATION # ========================================== # Service metadata - "homelab.category=infrastructure" - "homelab.description=System and Docker monitoring" # Traefik reverse proxy (comment/uncomment to disable/enable) # If Traefik is on a remote server: these labels are NOT USED; # configure external yml files in /traefik/dynamic folder instead. - "traefik.enable=true" - "traefik.http.routers.glances.rule=Host(`glances.${SERVER_HOSTNAME}.${DOMAIN}`)" - "traefik.http.routers.glances.entrypoints=websecure" - "traefik.http.routers.glances.tls=true" - "traefik.http.routers.glances.middlewares=authelia@docker" - "traefik.http.services.glances.loadbalancer.server.port=61208" # Sablier lazy loading (enabled by default - comment out to disable) - "sablier.enable=true" - "sablier.group=${SERVER_HOSTNAME}-glances" - "sablier.start-on-demand=true" # Code Server - VS Code in browser # Access at: https://code.${DOMAIN} # Uses Sablier lazy loading - starts on-demand, stops after 30min inactivity code-server: image: lscr.io/linuxserver/code-server:latest deploy: resources: limits: cpus: '1.5' memory: 1G pids: 2048 reservations: cpus: '0.75' memory: 512M container_name: code-server restart: no networks: - homelab-network - traefik-network ports: - "8443:8443" volumes: - ./code-server/config:/config - /opt/stacks:/opt/stacks # Access to all stacks - /mnt:/mnt:ro # Read-only access to data environment: - PUID=${PUID:-1000} - PGID=${PGID:-1000} - TZ=${TZ} - PASSWORD=${CODE_SERVER_PASSWORD} - SUDO_PASSWORD=${CODE_SERVER_SUDO_PASSWORD} labels: # TRAEFIK & SABLIER CONFIGURATION # ========================================== # Service metadata - "homelab.category=infrastructure" - "homelab.description=VS Code in browser" # Traefik reverse proxy (comment/uncomment to disable/enable) # If Traefik is on a remote server: these labels are NOT USED; # configure external yml files in /traefik/dynamic folder instead. - "traefik.enable=true" - "traefik.http.routers.code-server.rule=Host(`code.${DOMAIN}`)" - "traefik.http.routers.code-server.entrypoints=websecure" - "traefik.http.routers.code-server.tls.certresolver=letsencrypt" - "traefik.http.routers.code-server.middlewares=authelia@docker" - "traefik.http.services.code-server.loadbalancer.server.port=8443" # Sablier lazy loading (enabled by default - comment out to disable) - "sablier.enable=true" - "sablier.group=${SERVER_HOSTNAME}-code-server" - "sablier.start-on-demand=true" # ========================================== # DOCKGE URL CONFIGURATION # ========================================== x-dockge: urls: # Proxied URLs (through Traefik) - https://pihole.${DOMAIN} - https://dozzle.${DOMAIN} - https://glances.${DOMAIN} - https://code.${DOMAIN} # Direct IP:Port URLs - http://${SERVER_IP}:2375 # Docker Proxy - http://${SERVER_IP}:19999 # Netdata networks: homelab-network: external: true traefik-network: external: true