services: # Netbird client for VPN access to Mochi and other hosts netbird-client: image: netbirdio/netbird:latest container_name: claude-webui-netbird restart: unless-stopped hostname: claude-webui cap_add: - NET_ADMIN - SYS_ADMIN - SYS_RESOURCE environment: - NB_SETUP_KEY=${NETBIRD_SETUP_KEY} - NB_MANAGEMENT_URL=https://gw.sneakercloud.de volumes: - netbird-data:/var/lib/netbird # Redis for session storage (shares network with netbird for localhost access) redis: image: redis:7-alpine container_name: claude-webui-redis restart: unless-stopped network_mode: container:claude-webui-netbird depends_on: - netbird-client volumes: - redis-data:/data command: redis-server --appendonly yes backend: build: context: ./backend dockerfile: Dockerfile network: host container_name: claude-webui-backend restart: unless-stopped # Share network with netbird-client for VPN access network_mode: container:claude-webui-netbird depends_on: - netbird-client - redis deploy: resources: limits: memory: 2G cpus: '2' reservations: memory: 512M volumes: # Claude CLI binary (read-only from host) - /home/sumdex/.local/share/claude:/home/node/.local/share/claude:ro # Separate config for WebUI Claude (NOT Neko's config!) - ./config/.claude:/home/node/.claude:rw - ./config/.config/claude:/home/node/.config/claude:rw # Hosts configuration - ./config/hosts.json:/app/config/hosts.json:ro # SSH keys for remote execution - /home/sumdex/.ssh/id_rsa:/home/node/.ssh/id_rsa:ro - /home/sumdex/.ssh/known_hosts:/home/node/.ssh/known_hosts:ro # Project directories for Claude to work in - /home/sumdex/projects:/projects:rw - /home/sumdex/docker:/docker:rw - /opt/stacks:/stacks:rw environment: - NODE_ENV=production # Listen on all interfaces - NPM handles SSL termination - HOST=0.0.0.0 - PORT=3001 - PATH=/home/node/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin # OIDC Authentication - OIDC_ISSUER=${OIDC_ISSUER} - OIDC_CLIENT_ID=${OIDC_CLIENT_ID} - OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET} - OIDC_REDIRECT_URI=${OIDC_REDIRECT_URI} # Session - SESSION_SECRET=${SESSION_SECRET} - SESSION_DOMAIN=${SESSION_DOMAIN} - SESSION_SECURE=${SESSION_SECURE} - SESSION_MAX_AGE=${SESSION_MAX_AGE} - REDIS_URL=redis://localhost:6379 - FRONTEND_URL=${FRONTEND_URL} - AUTH_ENABLED=${AUTH_ENABLED} frontend: build: context: ./frontend dockerfile: Dockerfile network: host args: # Production: Use domain with SSL via NPM # /ws is proxied to backend by frontend nginx - VITE_WS_URL=wss://agents.sneakercloud.de/ws - VITE_API_URL=https://agents.sneakercloud.de container_name: claude-webui-frontend restart: unless-stopped # Share network with netbird-client - Frontend reaches Backend via localhost # NPM reaches Frontend via Netbird IP (100.105.153.111:80) network_mode: container:claude-webui-netbird depends_on: - backend networks: npm: external: true claude-webui: name: claude-webui volumes: netbird-data: redis-data: