A community based topic aggregation platform built on atproto
1version: '3.8' 2 3# Coves Local Development Stack 4# All-in-one setup: PDS + PostgreSQL + optional Relay 5# 6# Usage: 7# make dev-up # Start PDS + PostgreSQL 8# make dev-down # Stop everything 9# docker-compose up relay # Optional: start with relay 10# 11# Profiles: 12# - default: PDS + PostgreSQL (dev database on port 5433) 13# - test: PostgreSQL test database (port 5434) 14# - relay: BigSky relay (optional, will crawl entire network!) 15 16services: 17 # PostgreSQL Database (Port 5435) 18 # Used by Coves AppView for indexing data from firehose 19 postgres: 20 image: postgres:15 21 container_name: coves-dev-postgres 22 ports: 23 - "5435:5432" 24 environment: 25 POSTGRES_DB: ${POSTGRES_DB:-coves_dev} 26 POSTGRES_USER: ${POSTGRES_USER:-dev_user} 27 POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-dev_password} 28 volumes: 29 - postgres-data:/var/lib/postgresql/data 30 networks: 31 - coves-dev 32 healthcheck: 33 test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-dev_user} -d ${POSTGRES_DB:-coves_dev}"] 34 interval: 5s 35 timeout: 5s 36 retries: 5 37 38 # PostgreSQL Test Database (Port 5434) - Optional 39 # Use with: docker-compose --profile test up postgres-test 40 postgres-test: 41 image: postgres:15 42 container_name: coves-test-postgres 43 ports: 44 - "${POSTGRES_TEST_PORT:-5434}:5432" 45 environment: 46 POSTGRES_DB: ${POSTGRES_TEST_DB:-coves_test} 47 POSTGRES_USER: ${POSTGRES_TEST_USER:-test_user} 48 POSTGRES_PASSWORD: ${POSTGRES_TEST_PASSWORD:-test_password} 49 volumes: 50 - postgres-test-data:/var/lib/postgresql/data 51 networks: 52 - coves-dev 53 healthcheck: 54 test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_TEST_USER:-test_user} -d ${POSTGRES_TEST_DB:-coves_test}"] 55 interval: 5s 56 timeout: 5s 57 retries: 5 58 profiles: 59 - test 60 61 # Bluesky Personal Data Server (PDS) 62 # Handles user repositories, DIDs, and CAR files 63 pds: 64 image: ghcr.io/bluesky-social/pds:latest 65 container_name: coves-dev-pds 66 ports: 67 - "3001:3001" # PDS XRPC API (avoiding production PDS on :3000) 68 environment: 69 # PDS Configuration 70 PDS_HOSTNAME: ${PDS_HOSTNAME:-localhost} 71 PDS_PORT: 3001 # Match external port for correct DID registration 72 PDS_DATA_DIRECTORY: /pds 73 PDS_BLOBSTORE_DISK_LOCATION: /pds/blocks 74 PDS_DID_PLC_URL: ${PDS_DID_PLC_URL:-https://plc.directory} 75 # PDS_CRAWLERS not needed - we're not using a relay for local dev 76 77 # Note: PDS uses its own internal SQLite database and CAR file storage 78 # Our PostgreSQL database is only for the Coves AppView 79 80 # JWT secrets (for local dev only) 81 PDS_JWT_SECRET: ${PDS_JWT_SECRET:-local-dev-jwt-secret-change-in-production} 82 PDS_ADMIN_PASSWORD: ${PDS_ADMIN_PASSWORD:-admin} 83 PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX: ${PDS_PLC_ROTATION_KEY:-af514fb84c4356241deed29feb392d1ee359f99c05a7b8f7bff2e5f2614f64b2} 84 85 # Service endpoints 86 # Allow both user handles (.local.coves.dev) and community handles (.community.coves.social) 87 PDS_SERVICE_HANDLE_DOMAINS: ${PDS_SERVICE_HANDLE_DOMAINS:-.local.coves.dev,.community.coves.social} 88 89 # Dev mode settings (allows HTTP instead of HTTPS) 90 PDS_DEV_MODE: "true" 91 92 # Disable invite codes for testing 93 PDS_INVITE_REQUIRED: "false" 94 95 # Development settings 96 NODE_ENV: development 97 LOG_ENABLED: "true" 98 LOG_LEVEL: ${LOG_LEVEL:-debug} 99 volumes: 100 - pds-data:/pds 101 networks: 102 - coves-dev 103 healthcheck: 104 test: ["CMD", "wget", "--spider", "-q", "http://localhost:3001/xrpc/_health"] 105 interval: 10s 106 timeout: 5s 107 retries: 5 108 109 # Jetstream - Consumes PDS firehose and serves JSON WebSocket 110 # This is the RECOMMENDED approach for local E2E testing 111 # Jetstream converts raw atProto CBOR firehose to clean JSON events 112 # 113 # Flow: PDS firehose → Jetstream (CBOR→JSON) → Your AppView (JSON) 114 # 115 # Usage: 116 # docker-compose --profile jetstream up pds jetstream 117 # Your AppView connects to: ws://localhost:6008/subscribe 118 # 119 # Why use Jetstream instead of direct PDS firehose? 120 # - PDS emits raw CBOR (binary) - hard to parse 121 # - Jetstream converts to clean JSON - easy to consume 122 # - Same format as production Bluesky Jetstream 123 jetstream: 124 image: ghcr.io/bluesky-social/jetstream:sha-306e463693365e21a5ffd3ec051a5a7920000214 125 container_name: coves-dev-jetstream 126 ports: 127 - "6008:6008" # Jetstream WebSocket endpoint 128 - "6009:6009" # Metrics endpoint 129 environment: 130 # Point Jetstream at local PDS firehose 131 JETSTREAM_WS_URL: ws://pds:3001/xrpc/com.atproto.sync.subscribeRepos 132 133 # Server configuration 134 JETSTREAM_LISTEN_ADDR: ":6008" 135 JETSTREAM_METRICS_LISTEN_ADDR: ":6009" 136 137 # Data storage 138 JETSTREAM_DATA_DIR: /data 139 JETSTREAM_EVENT_TTL: 24h 140 141 # Set long liveness TTL for local dev (PDS may be quiet for long periods) 142 JETSTREAM_LIVENESS_TTL: 24h 143 144 # Performance tuning 145 JETSTREAM_WORKER_COUNT: 10 146 JETSTREAM_MAX_QUEUE_SIZE: 1000 147 148 # Development settings 149 LOG_LEVEL: ${LOG_LEVEL:-debug} 150 volumes: 151 - jetstream-data:/data 152 networks: 153 - coves-dev 154 depends_on: 155 pds: 156 condition: service_healthy 157 # Health check disabled for dev - container has no HTTP clients installed 158 # Jetstream logs show it connects and runs successfully 159 healthcheck: 160 disable: true 161 profiles: 162 - jetstream 163 164 # PostgreSQL Database for PLC Directory (Port 5436) 165 # Separate database for local PLC directory to avoid conflicts 166 postgres-plc: 167 image: postgres:15 168 container_name: coves-dev-postgres-plc 169 ports: 170 - "5436:5432" 171 environment: 172 POSTGRES_DB: plc_dev 173 POSTGRES_USER: plc_user 174 POSTGRES_PASSWORD: plc_password 175 volumes: 176 - postgres-plc-data:/var/lib/postgresql/data 177 networks: 178 - coves-dev 179 healthcheck: 180 test: ["CMD-SHELL", "pg_isready -U plc_user -d plc_dev"] 181 interval: 5s 182 timeout: 5s 183 retries: 5 184 profiles: 185 - plc 186 187 # Local PLC Directory - For E2E testing without polluting production plc.directory 188 # This allows dev mode DID registration for testing community provisioning 189 # 190 # Usage: 191 # docker-compose --profile plc up postgres-plc plc-directory 192 # Or with all services: docker-compose --profile jetstream --profile plc up 193 # 194 # Configuration in your tests: 195 # PLC_DIRECTORY_URL=http://localhost:3002 196 # IS_DEV_ENV=false # Use production mode but point to local PLC 197 plc-directory: 198 image: node:18-alpine 199 container_name: coves-dev-plc 200 ports: 201 - "3002:3000" # PLC directory API 202 working_dir: /app 203 command: > 204 sh -c " 205 if [ ! -d '/app/.git' ]; then 206 echo 'First run: Installing PLC directory...' && 207 apk add --no-cache git python3 make g++ yarn && 208 git clone https://github.com/did-method-plc/did-method-plc.git . && 209 yarn install --frozen-lockfile && 210 yarn build && 211 echo 'PLC directory installed successfully!' 212 fi && 213 cd packages/server && 214 yarn start 215 " 216 environment: 217 # Point to dedicated PLC PostgreSQL database 218 DATABASE_URL: postgresql://plc_user:plc_password@postgres-plc:5432/plc_dev?sslmode=disable 219 220 # Development settings 221 DEBUG_MODE: "1" 222 LOG_ENABLED: "true" 223 LOG_LEVEL: debug 224 LOG_DESTINATION: "1" 225 NODE_ENV: development 226 227 # API configuration 228 PORT: 3000 229 volumes: 230 # Persist the PLC repo so we don't rebuild every time 231 - plc-app-data:/app 232 networks: 233 - coves-dev 234 depends_on: 235 postgres-plc: 236 condition: service_healthy 237 healthcheck: 238 test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000/"] 239 interval: 10s 240 timeout: 5s 241 retries: 10 242 start_period: 120s 243 profiles: 244 - plc 245 246 # Indigo Relay (BigSky) - OPTIONAL for local dev 247 # WARNING: BigSky is designed to crawl the entire atProto network! 248 # For local dev, consider using direct PDS firehose instead (see AppView config below) 249 # 250 # To use relay: docker-compose -f docker-compose.dev.yml up pds relay 251 # To skip relay: docker-compose -f docker-compose.dev.yml up pds 252 # 253 # If using relay, you MUST manually configure it to only watch local PDS: 254 # 1. Start relay 255 # 2. Use admin API to block all domains except localhost 256 # curl -X POST http://localhost:2471/admin/pds/requestCrawl \ 257 # -H "Authorization: Bearer dev-admin-key" \ 258 # -d '{"hostname": "localhost:3001"}' 259 relay: 260 image: ghcr.io/bluesky-social/indigo:bigsky-0a2d4173e6e89e49b448f6bb0a6e1ab58d12b385 261 container_name: coves-dev-relay 262 ports: 263 - "2471:2470" # Relay firehose WebSocket (avoiding conflicts) 264 environment: 265 # Relay Configuration 266 BGS_ADMIN_KEY: ${BGS_ADMIN_KEY:-dev-admin-key} 267 BGS_PORT: 2470 268 269 # IMPORTANT: Allow insecure WebSocket for local PDS (ws:// instead of wss://) 270 BGS_CRAWL_INSECURE_WS: "true" 271 272 # Database connection (uses PostgreSQL for relay state) 273 DATABASE_URL: postgresql://${POSTGRES_USER:-dev_user}:${POSTGRES_PASSWORD:-dev_password}@postgres:5432/${POSTGRES_DB:-coves_dev}?sslmode=disable 274 275 # Relay will discover PDSs automatically - use admin API to restrict! 276 # See comments above for how to configure allowlist 277 278 # Development settings 279 LOG_LEVEL: ${LOG_LEVEL:-debug} 280 networks: 281 - coves-dev 282 depends_on: 283 postgres: 284 condition: service_healthy 285 pds: 286 condition: service_healthy 287 healthcheck: 288 test: ["CMD", "wget", "--spider", "-q", "http://localhost:2470/xrpc/_health"] 289 interval: 10s 290 timeout: 5s 291 retries: 5 292 # Mark as optional - start with: docker-compose up pds relay 293 profiles: 294 - relay 295 296 # Coves AppView (Your Go Application) 297 # Subscribes to PDS firehose and indexes Coves-specific data 298 # Note: Uncomment when you have a Dockerfile for the AppView 299 # appview: 300 # build: 301 # context: . 302 # dockerfile: Dockerfile 303 # container_name: coves-dev-appview 304 # ports: 305 # - "8081:8080" # AppView API (avoiding conflicts) 306 # environment: 307 # # Database connection 308 # DATABASE_URL: postgresql://${POSTGRES_USER:-dev_user}:${POSTGRES_PASSWORD:-dev_password}@postgres:5432/${POSTGRES_DB:-coves_dev}?sslmode=disable 309 # 310 # # PDS Firehose subscription (direct, no relay) 311 # FIREHOSE_URL: ws://pds:3000/xrpc/com.atproto.sync.subscribeRepos 312 # 313 # # PDS connection (for XRPC calls) 314 # PDS_URL: http://pds:3000 315 # 316 # # Application settings 317 # PORT: 8080 318 # ENV: development 319 # LOG_LEVEL: ${LOG_LEVEL:-debug} 320 # networks: 321 # - coves-dev 322 # depends_on: 323 # postgres: 324 # condition: service_healthy 325 # pds: 326 # condition: service_healthy 327 328networks: 329 coves-dev: 330 driver: bridge 331 name: coves-dev-network 332 333volumes: 334 postgres-data: 335 name: coves-dev-postgres-data 336 postgres-test-data: 337 name: coves-test-postgres-data 338 postgres-plc-data: 339 name: coves-dev-postgres-plc-data 340 pds-data: 341 name: coves-dev-pds-data 342 jetstream-data: 343 name: coves-dev-jetstream-data 344 plc-app-data: 345 name: coves-dev-plc-app-data