services: # Caddy - reverse proxy with automatic TLS caddy: image: ${REGISTRY_HOST:-localhost}:5000/weaver-caddy:latest container_name: weaver-caddy ports: - "80:80" - "443:443" - "2019:2019" # Admin API with metrics volumes: - ./infra/caddy/Caddyfile:/etc/caddy/Caddyfile:ro - caddy_data:/data - caddy_config:/config environment: CLOUDFLARE_API_TOKEN: ${CLOUDFLARE_API_TOKEN} ACME_EMAIL: ${ACME_EMAIL:-contact@weaver.sh} depends_on: - weaver-app - index restart: unless-stopped # ClickHouse - analytics database clickhouse: image: clickhouse/clickhouse-server:25.11 container_name: weaver-clickhouse ports: - "8123:8123" - "9000:9000" - "9363:9363" # Prometheus metrics volumes: - ~/data/clickhouse:/var/lib/clickhouse - ~/data/clickhouse-logs:/var/log/clickhouse-server - ~/data/clickhouse-config:/etc/clickhouse-server/config.d - ./infra/clickhouse/prometheus.xml:/etc/clickhouse-server/config.d/prometheus.xml:ro environment: CLICKHOUSE_DB: ${CLICKHOUSE_DATABASE:-weaver} CLICKHOUSE_USER: ${CLICKHOUSE_USER:-default} CLICKHOUSE_PASSWORD: ${CLICKHOUSE_PASSWORD} CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: 1 ulimits: nofile: soft: 262144 hard: 262144 healthcheck: test: ["CMD", "wget", "--spider", "-q", "http://localhost:8123/ping"] interval: 10s timeout: 5s retries: 3 restart: unless-stopped # Docker registry for local image hosting registry: image: registry:2 container_name: weaver-registry ports: - "5000:5000" volumes: - registry_data:/var/lib/registry restart: unless-stopped # Tap - AT Protocol sync utility tap: container_name: weaver-tap image: ghcr.io/bluesky-social/indigo/tap:latest ports: - "2480:2480" - "2481:2481" volumes: - tap_data:/data/tap environment: TAP_DATABASE_URL: sqlite:///data/tap/tap.db TAP_BIND: ":2480" TAP_METRICS_LISTEN: ":2481" TAP_DISABLE_ACKS: "false" TAP_LOG_LEVEL: debug TAP_OUTBOX_PARALLELISM: 5 #TAP_FULL_NETWORK: true #TAP_SIGNAL_COLLECTION: place.stream.chat.profile TAP_SIGNAL_COLLECTION: sh.weaver.actor.profile TAP_COLLECTION_FILTERS: "sh.weaver.*,app.bsky.actor.profile,sh.tangled.*,pub.leaflet.*,net.anisota.*,place.stream.*,site.standard.*" healthcheck: test: ["CMD", "wget", "-q", "--spider", "http://localhost:2480/health"] interval: 20s timeout: 5s retries: 3 restart: unless-stopped # Weaver indexer - consumes from tap index: container_name: weaver-index image: ${REGISTRY_HOST:-localhost}:5000/weaver-index:latest ports: - "3000:3000" command: ["run"] volumes: - index_data:/app/data environment: RUST_LOG: info,weaver_index=debug,hyper_util::client::legacy::pool=info LOKI_URL: ${LOKI_URL:-} CLICKHOUSE_URL: http://clickhouse:8123 CLICKHOUSE_DATABASE: ${CLICKHOUSE_DATABASE:-weaver} CLICKHOUSE_USER: ${CLICKHOUSE_USER:-default} CLICKHOUSE_PASSWORD: ${CLICKHOUSE_PASSWORD} INDEXER_SOURCE: tap TAP_URL: ws://tap:2480/channel TAP_SEND_ACKS: "true" FIREHOSE_RELAY_URL: wss://bsky.network INDEXER_COLLECTIONS: "sh.weaver.*,app.bsky.actor.profile,sh.tangled.*,pub.leaflet.*,net.anisota.*,place.stream.*,site.standard.*" depends_on: tap: condition: service_healthy clickhouse: condition: service_healthy healthcheck: test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://localhost:3000/xrpc/_health"] interval: 20s timeout: 5s retries: 3 restart: unless-stopped # Weaver app - web frontend weaver-app: container_name: weaver-app image: ${REGISTRY_HOST:-localhost}:5000/weaver-app:latest ports: - "8080:8080" environment: PORT: 8080 IP: 0.0.0.0 RUST_LOG: info,weaver-app=debug,weaver-common=debug,hyper=warn,hyper_util=warn,tower=warn,h2=warn,rustls=warn,reqwest=info,dioxus_core=warn,dioxus_signals=warn LOKI_URL: ${LOKI_URL:-} healthcheck: test: ["CMD", "wget", "-q", "--spider", "http://localhost:8080/"] interval: 20s timeout: 5s retries: 3 restart: unless-stopped # ============ OBSERVABILITY STACK ============ # Node exporter - host metrics (CPU, memory, disk, network) node-exporter: image: prom/node-exporter:latest container_name: weaver-node-exporter ports: - "9100:9100" volumes: - /proc:/host/proc:ro - /sys:/host/sys:ro - /:/rootfs:ro command: - "--path.procfs=/host/proc" - "--path.sysfs=/host/sys" - "--path.rootfs=/rootfs" - "--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)" restart: unless-stopped # cAdvisor - container metrics (per-container CPU, memory, network) cadvisor: image: gcr.io/cadvisor/cadvisor:latest container_name: weaver-cadvisor ports: - "9080:8080" volumes: - /:/rootfs:ro - /var/run:/var/run:ro - /sys:/sys:ro - /var/lib/docker/:/var/lib/docker:ro - /dev/disk/:/dev/disk:ro privileged: true restart: unless-stopped # Promtail - ship container logs to Loki promtail: image: grafana/promtail:latest container_name: weaver-promtail volumes: - ./infra/promtail/config.yml:/etc/promtail/config.yml:ro - /var/lib/docker/containers:/var/lib/docker/containers:ro - /var/run/docker.sock:/var/run/docker.sock:ro command: -config.file=/etc/promtail/config.yml -config.expand-env=true environment: LOKI_URL: ${LOKI_URL:-http://localhost:3100} restart: unless-stopped volumes: registry_data: tap_data: index_data: caddy_data: caddy_config: