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:3000" # PDS XRPC API (avoiding production PDS on :3000)
68 environment:
69 # PDS Configuration
70 PDS_HOSTNAME: ${PDS_HOSTNAME:-localhost}
71 PDS_PORT: 3000
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 (.communities.coves.social)
87 PDS_SERVICE_HANDLE_DOMAINS: ${PDS_SERVICE_HANDLE_DOMAINS:-.local.coves.dev,.communities.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:3000/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:3000/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 healthcheck:
158 test: ["CMD", "wget", "--spider", "-q", "http://localhost:6009/metrics"]
159 interval: 10s
160 timeout: 5s
161 retries: 5
162 profiles:
163 - jetstream
164
165 # Indigo Relay (BigSky) - OPTIONAL for local dev
166 # WARNING: BigSky is designed to crawl the entire atProto network!
167 # For local dev, consider using direct PDS firehose instead (see AppView config below)
168 #
169 # To use relay: docker-compose -f docker-compose.dev.yml up pds relay
170 # To skip relay: docker-compose -f docker-compose.dev.yml up pds
171 #
172 # If using relay, you MUST manually configure it to only watch local PDS:
173 # 1. Start relay
174 # 2. Use admin API to block all domains except localhost
175 # curl -X POST http://localhost:2471/admin/pds/requestCrawl \
176 # -H "Authorization: Bearer dev-admin-key" \
177 # -d '{"hostname": "localhost:3001"}'
178 relay:
179 image: ghcr.io/bluesky-social/indigo:bigsky-0a2d4173e6e89e49b448f6bb0a6e1ab58d12b385
180 container_name: coves-dev-relay
181 ports:
182 - "2471:2470" # Relay firehose WebSocket (avoiding conflicts)
183 environment:
184 # Relay Configuration
185 BGS_ADMIN_KEY: ${BGS_ADMIN_KEY:-dev-admin-key}
186 BGS_PORT: 2470
187
188 # IMPORTANT: Allow insecure WebSocket for local PDS (ws:// instead of wss://)
189 BGS_CRAWL_INSECURE_WS: "true"
190
191 # Database connection (uses PostgreSQL for relay state)
192 DATABASE_URL: postgresql://${POSTGRES_USER:-dev_user}:${POSTGRES_PASSWORD:-dev_password}@postgres:5432/${POSTGRES_DB:-coves_dev}?sslmode=disable
193
194 # Relay will discover PDSs automatically - use admin API to restrict!
195 # See comments above for how to configure allowlist
196
197 # Development settings
198 LOG_LEVEL: ${LOG_LEVEL:-debug}
199 networks:
200 - coves-dev
201 depends_on:
202 postgres:
203 condition: service_healthy
204 pds:
205 condition: service_healthy
206 healthcheck:
207 test: ["CMD", "wget", "--spider", "-q", "http://localhost:2470/xrpc/_health"]
208 interval: 10s
209 timeout: 5s
210 retries: 5
211 # Mark as optional - start with: docker-compose up pds relay
212 profiles:
213 - relay
214
215 # Coves AppView (Your Go Application)
216 # Subscribes to PDS firehose and indexes Coves-specific data
217 # Note: Uncomment when you have a Dockerfile for the AppView
218 # appview:
219 # build:
220 # context: .
221 # dockerfile: Dockerfile
222 # container_name: coves-dev-appview
223 # ports:
224 # - "8081:8080" # AppView API (avoiding conflicts)
225 # environment:
226 # # Database connection
227 # DATABASE_URL: postgresql://${POSTGRES_USER:-dev_user}:${POSTGRES_PASSWORD:-dev_password}@postgres:5432/${POSTGRES_DB:-coves_dev}?sslmode=disable
228 #
229 # # PDS Firehose subscription (direct, no relay)
230 # FIREHOSE_URL: ws://pds:3000/xrpc/com.atproto.sync.subscribeRepos
231 #
232 # # PDS connection (for XRPC calls)
233 # PDS_URL: http://pds:3000
234 #
235 # # Application settings
236 # PORT: 8080
237 # ENV: development
238 # LOG_LEVEL: ${LOG_LEVEL:-debug}
239 # networks:
240 # - coves-dev
241 # depends_on:
242 # postgres:
243 # condition: service_healthy
244 # pds:
245 # condition: service_healthy
246
247networks:
248 coves-dev:
249 driver: bridge
250 name: coves-dev-network
251
252volumes:
253 postgres-data:
254 name: coves-dev-postgres-data
255 postgres-test-data:
256 name: coves-test-postgres-data
257 pds-data:
258 name: coves-dev-pds-data
259 jetstream-data:
260 name: coves-dev-jetstream-data