Monorepo for Aesthetic.Computer
aesthetic.computer
1# PDS Infrastructure Guide
2
3This document provides detailed technical information for deploying and managing the Aesthetic Computer PDS infrastructure.
4
5## Table of Contents
6
71. [Server Requirements](#server-requirements)
82. [Network Configuration](#network-configuration)
93. [Storage Architecture](#storage-architecture)
104. [Security Considerations](#security-considerations)
115. [Scaling Strategy](#scaling-strategy)
12
13## Server Requirements
14
15### Minimum Specifications (1-20 users)
16
17```yaml
18CPU: 1 core (x86_64 or ARM64)
19RAM: 1 GB
20Storage: 20 GB SSD
21OS: Ubuntu 24.04 LTS (recommended)
22Network: 1 Gbps
23IPv4: Required (public)
24IPv6: Optional but recommended
25```
26
27### Recommended Specifications (20-100 users)
28
29```yaml
30CPU: 2 cores
31RAM: 2 GB
32Storage: 40 GB SSD
33OS: Ubuntu 24.04 LTS
34Network: 1 Gbps
35```
36
37### Operating System Support
38
39**Fully Supported:**
40- Ubuntu 24.04 LTS ✅ (Recommended)
41- Ubuntu 22.04 LTS
42- Ubuntu 20.04 LTS
43- Debian 12
44- Debian 11
45
46**Not Recommended:**
47- CentOS/RHEL (limited testing)
48- Alpine Linux (Docker base only)
49- Windows Server (not supported)
50
51## Network Configuration
52
53### Required DNS Records
54
55Configure these DNS records for `aesthetic.computer`:
56
57```dns
58# Root domain
59pds.aesthetic.computer. A <SERVER_IP> 600
60
61# Wildcard for user handles
62*.pds.aesthetic.computer. A <SERVER_IP> 600
63```
64
65**Important Notes:**
66- TTL of 600 (10 minutes) allows for quick changes
67- Wildcard record is **required** for user handle federation
68- Both records must point to the same IP
69
70### Example with dig
71
72```bash
73# Verify root domain
74dig pds.aesthetic.computer A
75
76# Verify wildcard
77dig jeffrey.pds.aesthetic.computer A
78dig test123.pds.aesthetic.computer A
79```
80
81All should return your server's IP address.
82
83### Firewall Rules
84
85#### Inbound Rules (Required)
86
87| Port | Protocol | Source | Purpose |
88|------|----------|--------|---------|
89| 443 | TCP | 0.0.0.0/0 | HTTPS (main traffic) |
90| 80 | TCP | 0.0.0.0/0 | HTTP (Let's Encrypt only) |
91| 22 | TCP | YOUR_IP | SSH (restrict to your IP) |
92
93#### Outbound Rules (Required)
94
95| Port | Protocol | Destination | Purpose |
96|------|----------|-------------|---------|
97| 443 | TCP | Any | HTTPS (federation, relay) |
98| 587 | TCP | SMTP server | Email (STARTTLS) |
99| 465 | TCP | SMTP server | Email (SSL/TLS) |
100
101**Security Notes:**
102- Do NOT expose port 22 to the world
103- Do NOT expose Docker ports (2375, 2376)
104- Do NOT expose PostgreSQL or SQLite ports
105
106### DigitalOcean Firewall Setup
107
108```bash
109# Create firewall
110doctl compute firewall create \
111 --name "pds-aesthetic-computer" \
112 --inbound-rules "protocol:tcp,ports:80,address:0.0.0.0/0 protocol:tcp,ports:443,address:0.0.0.0/0 protocol:tcp,ports:22,address:YOUR_IP/32" \
113 --outbound-rules "protocol:tcp,ports:all,address:0.0.0.0/0 protocol:udp,ports:all,address:0.0.0.0/0"
114```
115
116## Storage Architecture
117
118### SQLite Database
119
120The PDS uses SQLite for all relational data:
121
122```
123/pds/
124├── blocks.sqlite # User data, posts, blocks
125├── accounts.sqlite # User accounts, auth
126└── pds.sqlite # PDS metadata
127```
128
129**Characteristics:**
130- Single-file databases
131- No separate DB server needed
132- Suitable for <100 users
133- Automatic backups recommended
134
135**Backup Strategy:**
136```bash
137# Daily backup script
138sqlite3 /pds/blocks.sqlite ".backup /backups/blocks-$(date +%Y%m%d).sqlite"
139```
140
141### Blob Storage (Images, Videos)
142
143Blobs are stored separately from SQLite:
144
145#### Option 1: DigitalOcean Spaces (Recommended)
146
147```yaml
148Provider: DigitalOcean Spaces
149API: S3-compatible
150Pricing: $5/month for 250GB + CDN
151Regions: NYC3, SFO3, SGP1, FRA1
152```
153
154**Configuration:**
155```env
156# In pds.env
157PDS_BLOBSTORE_DISK_LOCATION=s3
158PDS_BLOBSTORE_S3_ENDPOINT=https://nyc3.digitaloceanspaces.com
159PDS_BLOBSTORE_S3_BUCKET=aesthetic-pds-blobs
160PDS_BLOBSTORE_S3_ACCESS_KEY_ID=<spaces-key>
161PDS_BLOBSTORE_S3_SECRET_ACCESS_KEY=<spaces-secret>
162```
163
164**Advantages:**
165- CDN included (no extra cost)
166- S3-compatible API
167- Simple pricing
168- Integrated with DO droplets
169
170#### Option 2: Google Cloud Storage
171
172```yaml
173Provider: Google Cloud Storage
174API: GCS native
175Pricing: ~$0.02/GB/month + egress
176Regions: Multi-region options
177```
178
179**Configuration:**
180```env
181# In pds.env
182PDS_BLOBSTORE_DISK_LOCATION=gcs
183PDS_BLOBSTORE_GCS_BUCKET=aesthetic-pds-blobs
184PDS_BLOBSTORE_GCS_PROJECT_ID=aesthetic-computer
185GOOGLE_APPLICATION_CREDENTIALS=/pds/gcs-service-account.json
186```
187
188**Advantages:**
189- Better for large scale
190- Advanced features (lifecycle, versioning)
191- Global CDN available
192- Integrated with GCP services
193
194#### Option 3: Local Disk (Not Recommended for Production)
195
196```env
197PDS_BLOBSTORE_DISK_LOCATION=/pds/blobs
198```
199
200**Use Cases:**
201- Development/testing only
202- No redundancy
203- Limited by disk size
204- No CDN
205
206### Storage Growth Estimates
207
208| Users | Posts/Day | Avg Post Size | Blobs/Day | Storage/Month |
209|-------|-----------|---------------|-----------|---------------|
210| 10 | 50 | 2KB + 500KB | 25 images | ~15 GB |
211| 50 | 250 | 2KB + 500KB | 125 images | ~75 GB |
212| 100 | 500 | 2KB + 500KB | 250 images | ~150 GB |
213
214**Notes:**
215- SQLite grows slowly (~50MB/month per 10 users)
216- Blobs dominate storage (images, videos)
217- Plan for 3-6 months of growth
218
219## Security Considerations
220
221### TLS/SSL Certificates
222
223**Automatic via Caddy:**
224- PDS includes Caddy web server
225- Auto-obtains Let's Encrypt certificates
226- Auto-renews before expiration
227- Handles wildcard certificates
228
229**No manual configuration needed!**
230
231### Authentication
232
233**User Authentication:**
234- App passwords (recommended for clients)
235- OAuth (future support)
236- Email verification required
237
238**Admin Authentication:**
239- SSH key-based (disable password auth)
240- pdsadmin CLI (local only)
241- No web admin panel
242
243### Rate Limiting
244
245Built into PDS:
246```env
247PDS_RATE_LIMIT_ENABLED=true
248PDS_RATE_LIMIT_REQUESTS_PER_MINUTE=100
249```
250
251### Backup Security
252
253```bash
254# Encrypt backups
255tar czf - /pds/*.sqlite | gpg --encrypt --recipient admin@aesthetic.computer > backup.tar.gz.gpg
256
257# Store off-site
258rclone copy backup.tar.gz.gpg digitalocean:aesthetic-backups/
259```
260
261## Scaling Strategy
262
263### Vertical Scaling (Easier)
264
265Increase droplet size as needed:
266
267```
2681GB RAM → 2GB RAM → 4GB RAM → 8GB RAM
269$6/mo → $12/mo → $24/mo → $48/mo
270```
271
272**When to scale:**
273- CPU usage > 80% sustained
274- Memory usage > 90%
275- Disk I/O wait times increasing
276
277### Horizontal Scaling (Advanced)
278
279For 100+ users:
280
281```
282┌─────────┐ ┌─────────┐ ┌─────────┐
283│ PDS 1 │────▶│ Relay │◀────│ PDS 2 │
284└─────────┘ └─────────┘ └─────────┘
285 │ │ │
286 └───────────────┴───────────────┘
287 │
288 ┌──────▼──────┐
289 │ Shared Blob │
290 │ Storage │
291 └─────────────┘
292```
293
294**Considerations:**
295- Multiple PDS instances
296- Shared blob storage
297- Custom relay/firehose
298- Load balancer
299- Complex to maintain
300
301**Recommendation:** Start with vertical scaling, consider horizontal only if >100 active users.
302
303## Monitoring Requirements
304
305### Health Checks
306
307Monitor these endpoints:
308
309```bash
310# PDS health
311curl https://pds.aesthetic.computer/xrpc/_health
312
313# WebSocket health
314wsdump "wss://pds.aesthetic.computer/xrpc/com.atproto.sync.subscribeRepos?cursor=0"
315```
316
317### Metrics to Track
318
319| Metric | Threshold | Action |
320|--------|-----------|--------|
321| CPU Usage | > 80% | Scale up |
322| Memory Usage | > 90% | Scale up |
323| Disk Usage | > 80% | Add storage |
324| Response Time | > 500ms | Investigate |
325| Error Rate | > 1% | Alert |
326
327### Log Management
328
329```bash
330# Docker logs
331docker logs pds --tail 100 --follow
332
333# Or file-based
334tail -f /pds/pds.log
335```
336
337**Log Rotation:**
338```env
339LOG_DESTINATION=/pds/pds.log
340LOG_LEVEL=info
341```
342
343Use logrotate or similar to prevent disk fill.
344
345## Maintenance Windows
346
347**Recommended Schedule:**
348- Updates: Weekly, off-peak hours
349- Backups: Daily, automated
350- Full maintenance: Monthly
351
352**Update Process:**
353```bash
354# Simple update
355sudo pdsadmin update
356
357# With backup first
358./scripts/backup.sh && sudo pdsadmin update
359```
360
361## Disaster Recovery
362
363### Backup Strategy
364
365**Daily:**
366- SQLite databases
367- PDS configuration
368
369**Weekly:**
370- Full system snapshot (DigitalOcean)
371
372**Monthly:**
373- Off-site backup verification
374
375### Recovery Procedures
376
377**Database Corruption:**
378```bash
379# Restore from backup
380cp /backups/blocks-20251009.sqlite /pds/blocks.sqlite
381systemctl restart pds
382```
383
384**Server Failure:**
3851. Provision new server
3862. Restore latest snapshot
3873. Update DNS if IP changed
3884. Verify health endpoints
389
390**Blob Storage Loss:**
391- Blobs are stored redundantly in Spaces/GCS
392- No manual recovery needed
393- Verify bucket versioning enabled
394
395## Cost Optimization
396
397### DigitalOcean Tips
398
399**Reserved Instances:**
400- Not available on DO
401- Pay monthly for lower costs
402
403**Spaces Optimization:**
404- Use lifecycle policies to delete old blobs
405- Enable CDN caching (included)
406- Monitor bandwidth usage
407
408**Snapshot Strategy:**
409- Keep 7 daily snapshots: ~$1/month
410- Delete older snapshots: saves $0.10/GB/month
411
412### Bandwidth Savings
413
414```bash
415# Enable compression in Caddy
416# Already enabled in default PDS config
417encode gzip
418```
419
420**CDN Benefits:**
421- Spaces includes CDN
422- Reduces origin bandwidth
423- Faster global delivery
424
425## Next Steps
426
427- Review [DEPLOYMENT.md](./DEPLOYMENT.md) for deployment instructions
428- Review [STORAGE.md](./STORAGE.md) for detailed storage setup
429- Review [MAINTENANCE.md](./MAINTENANCE.md) for ongoing operations
430
431---
432
433**Last Updated**: October 9, 2025