Something went wrong. Try again.
A community based topic aggregation platform built on atproto
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329# Coves Local Development Stack# All-in-one setup: PDS + PostgreSQL + optional Relay## Usage:# make dev-up # Start PDS + PostgreSQL# make dev-down # Stop everything# docker-compose up relay # Optional: start with relay## Profiles:# - default: PDS + PostgreSQL (dev database on port 5433)# - test: PostgreSQL test database (port 5434)# - relay: BigSky relay (optional, will crawl entire network!)
services: # PostgreSQL Database (Port 5435) # Used by Coves AppView for indexing data from firehose postgres: image: postgres:15 container_name: coves-dev-postgres ports: - "5435:5432" environment: POSTGRES_DB: ${POSTGRES_DB:-coves_dev} POSTGRES_USER: ${POSTGRES_USER:-dev_user} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-dev_password} volumes: - postgres-data:/var/lib/postgresql/data networks: - coves-dev healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-dev_user} -d ${POSTGRES_DB:-coves_dev}"] interval: 5s timeout: 5s retries: 5
# PostgreSQL Test Database (Port 5434) - Optional # Use with: docker-compose --profile test up postgres-test postgres-test: image: postgres:15 container_name: coves-test-postgres # Matches docker-compose.ci.yml's postgres-test (see that file for the full # reasoning): max_connections sets testkit.ConcurrencyBudget's safe # `go test -parallel` value, and durability is off with the data in memory # because every test creates and drops its own clone. The data, including # the template, is gone whenever the container is recreated; # scripts/test-db-prepare.sh rebuilds it. command: ["-c", "max_connections=200", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"] ports: - "${POSTGRES_TEST_PORT:-5434}:5432" environment: POSTGRES_DB: ${POSTGRES_TEST_DB:-coves_test} POSTGRES_USER: ${POSTGRES_TEST_USER:-test_user} POSTGRES_PASSWORD: ${POSTGRES_TEST_PASSWORD:-test_password} # Capped so a clone-leak regression cannot grow this filesystem to the # uncapped default of half of host RAM. Measured peak use is about 240MB; # the estimated peak is about 1.7GB (max_wal_size, a soft target, plus a # full -parallel of clones). tmpfs: - /var/lib/postgresql/data:size=3g networks: - coves-dev healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_TEST_USER:-test_user} -d ${POSTGRES_TEST_DB:-coves_test}"] interval: 5s timeout: 5s retries: 5 profiles: - test
# Bluesky Personal Data Server (PDS) # Handles user repositories, DIDs, and CAR files # NOTE: When using --profile plc, PDS waits for PLC directory to be healthy pds: image: ghcr.io/bluesky-social/pds:0.4.5044@sha256:26ac2c219014bed23e68db7fd37df10766bf6733cb2269e457f9a57d2d5b1fbc container_name: coves-dev-pds ports: - "3001:3001" # PDS XRPC API (avoiding production PDS on :3000) environment: # PDS Configuration PDS_HOSTNAME: ${PDS_HOSTNAME:-localhost} PDS_PORT: 3001 # Match external port for correct DID registration PDS_DATA_DIRECTORY: /pds PDS_BLOBSTORE_DISK_LOCATION: /pds/blocks PDS_BLOB_UPLOAD_LIMIT: 104857600 # 100 MB # IMPORTANT: For local E2E testing, this MUST point to local PLC directory # Default to local PLC (http://plc-directory:3000) for full local stack # The container hostname 'plc-directory' is used for Docker network communication PDS_DID_PLC_URL: ${PDS_DID_PLC_URL:-http://plc-directory:3000} # PDS_CRAWLERS not needed - we're not using a relay for local dev
# Note: PDS uses its own internal SQLite database and CAR file storage # Our PostgreSQL database is only for the Coves AppView
# JWT secrets (for local dev only) PDS_JWT_SECRET: ${PDS_JWT_SECRET:-local-dev-jwt-secret-change-in-production} PDS_ADMIN_PASSWORD: ${PDS_ADMIN_PASSWORD:-admin} PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX: ${PDS_PLC_ROTATION_KEY:-af514fb84c4356241deed29feb392d1ee359f99c05a7b8f7bff2e5f2614f64b2}
# Service endpoints # Allow both user handles (.local.coves.dev) and community handles (c-*.coves.social) PDS_SERVICE_HANDLE_DOMAINS: ${PDS_SERVICE_HANDLE_DOMAINS:-.local.coves.dev,.coves.social}
# Dev mode settings (allows HTTP instead of HTTPS) PDS_DEV_MODE: "true"
# Disable invite codes for testing PDS_INVITE_REQUIRED: "false"
# Development settings NODE_ENV: development LOG_ENABLED: "true" LOG_LEVEL: ${LOG_LEVEL:-debug} volumes: - pds-data:/pds networks: - coves-dev healthcheck: test: ["CMD", "wget", "--spider", "-q", "http://localhost:3001/xrpc/_health"] interval: 10s timeout: 5s retries: 5
# Jetstream - Consumes PDS firehose and serves JSON WebSocket # This is the RECOMMENDED approach for local E2E testing # Jetstream converts raw atProto CBOR firehose to clean JSON events # # Flow: PDS firehose → Jetstream (CBOR→JSON) → Your AppView (JSON) # # Usage: # docker-compose --profile jetstream up pds jetstream # Your AppView connects to: ws://localhost:6008/subscribe # # Why use Jetstream instead of direct PDS firehose? # - PDS emits raw CBOR (binary) - hard to parse # - Jetstream converts to clean JSON - easy to consume # - Same format as production Bluesky Jetstream jetstream: # Latest compatible jetstream-legacy main SHA; current Jetstream v2 uses a # different configuration contract and is a separate migration. image: ghcr.io/bluesky-social/jetstream:sha-8a65de4eda28bed1cafcbcf25b0cd46ac6f2148b container_name: coves-dev-jetstream ports: - "6008:6008" # Jetstream WebSocket endpoint - "6009:6009" # Metrics endpoint environment: # Point Jetstream at local PDS firehose JETSTREAM_WS_URL: ws://pds:3001/xrpc/com.atproto.sync.subscribeRepos
# Server configuration JETSTREAM_LISTEN_ADDR: ":6008" JETSTREAM_METRICS_LISTEN_ADDR: ":6009"
# Data storage JETSTREAM_DATA_DIR: /data JETSTREAM_EVENT_TTL: 24h
# Set long liveness TTL for local dev (PDS may be quiet for long periods) JETSTREAM_LIVENESS_TTL: 24h
# Performance tuning JETSTREAM_WORKER_COUNT: 10 JETSTREAM_MAX_QUEUE_SIZE: 1000
# Development settings LOG_LEVEL: ${LOG_LEVEL:-debug} volumes: - jetstream-data:/data networks: - coves-dev depends_on: pds: condition: service_healthy # Health check disabled for dev - container has no HTTP clients installed # Jetstream logs show it connects and runs successfully healthcheck: disable: true profiles: - jetstream
# PostgreSQL Database for PLC Directory (Port 5436) # Separate database for local PLC directory to avoid conflicts postgres-plc: image: postgres:15 container_name: coves-dev-postgres-plc ports: - "5436:5432" environment: POSTGRES_DB: plc_dev POSTGRES_USER: plc_user POSTGRES_PASSWORD: plc_password volumes: - postgres-plc-data:/var/lib/postgresql/data networks: - coves-dev healthcheck: test: ["CMD-SHELL", "pg_isready -U plc_user -d plc_dev"] interval: 5s timeout: 5s retries: 5 profiles: - plc
# Local PLC Directory - For E2E testing without polluting production plc.directory # This allows dev mode DID registration for testing community provisioning # # Usage: # docker-compose --profile plc up postgres-plc plc-directory # Or with all services: docker-compose --profile jetstream --profile plc up # # Configuration in your tests: # PLC_DIRECTORY_URL=http://localhost:3002 # IS_DEV_ENV=false # Use production mode but point to local PLC plc-directory: # Same pinned image as the CI stack (docker/plc/Dockerfile). Keep it pinned: # do not go back to cloning did-method-plc's main branch at container start. build: context: ./docker/plc container_name: coves-dev-plc ports: - "3002:3000" # PLC directory API environment: # Point to dedicated PLC PostgreSQL database DATABASE_URL: postgresql://plc_user:plc_password@postgres-plc:5432/plc_dev?sslmode=disable
# Development settings DEBUG_MODE: "1" LOG_ENABLED: "true" LOG_LEVEL: debug LOG_DESTINATION: "1" NODE_ENV: development
# API configuration PORT: 3000 networks: - coves-dev depends_on: postgres-plc: condition: service_healthy healthcheck: # /_health, not /: the PLC server redirects / to https://web.plc.directory test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000/_health"] interval: 10s timeout: 5s retries: 10 profiles: - plc
# Indigo Relay (BigSky) - OPTIONAL for local dev # WARNING: BigSky is designed to crawl the entire atProto network! # For local dev, consider using direct PDS firehose instead (see AppView config below) # # To use relay: docker-compose -f docker-compose.dev.yml up pds relay # To skip relay: docker-compose -f docker-compose.dev.yml up pds # # If using relay, you MUST manually configure it to only watch local PDS: # 1. Start relay # 2. Use admin API to block all domains except localhost # curl -X POST http://localhost:2471/admin/pds/requestCrawl \ # -H "Authorization: Bearer dev-admin-key" \ # -d '{"hostname": "localhost:3001"}' relay: image: ghcr.io/bluesky-social/indigo:bigsky-0a2d4173e6e89e49b448f6bb0a6e1ab58d12b385 container_name: coves-dev-relay ports: - "2471:2470" # Relay firehose WebSocket (avoiding conflicts) environment: # Relay Configuration BGS_ADMIN_KEY: ${BGS_ADMIN_KEY:-dev-admin-key} BGS_PORT: 2470
# IMPORTANT: Allow insecure WebSocket for local PDS (ws:// instead of wss://) BGS_CRAWL_INSECURE_WS: "true"
# Database connection (uses PostgreSQL for relay state) DATABASE_URL: postgresql://${POSTGRES_USER:-dev_user}:${POSTGRES_PASSWORD:-dev_password}@postgres:5432/${POSTGRES_DB:-coves_dev}?sslmode=disable
# Relay will discover PDSs automatically - use admin API to restrict! # See comments above for how to configure allowlist
# Development settings LOG_LEVEL: ${LOG_LEVEL:-debug} networks: - coves-dev depends_on: postgres: condition: service_healthy pds: condition: service_healthy healthcheck: test: ["CMD", "wget", "--spider", "-q", "http://localhost:2470/xrpc/_health"] interval: 10s timeout: 5s retries: 5 # Mark as optional - start with: docker-compose up pds relay profiles: - relay
# Jaeger - Distributed tracing UI for OpenTelemetry # Usage: docker compose --profile observability up # Access UI at: http://localhost:16686 jaeger: image: jaegertracing/all-in-one:1.76.0 container_name: coves-dev-jaeger ports: - "16686:16686" # Jaeger UI - "4317:4317" # OTLP gRPC environment: COLLECTOR_OTLP_ENABLED: "true" networks: - coves-dev profiles: - observability
networks: coves-dev: driver: bridge name: coves-dev-network
volumes: postgres-data: name: coves-dev-postgres-data postgres-plc-data: name: coves-dev-postgres-plc-data pds-data: name: coves-dev-pds-data jetstream-data: name: coves-dev-jetstream-data