Our Personal Data Server from scratch! tranquil.farm
oauth atproto pds rust postgresql objectstorage fun

chore: small md file updates

+76 -90
+9 -13
README.md
··· 6 6 7 7 This particular PDS thrives under harsh conditions. It is a dandelion growing through the cracks in the sidewalk concrete. 8 8 9 - It has full compatibility with Bluesky's reference PDS: same endpoints, same behavior, same client compatibility. Everything works: repo operations, blob storage, firehose, OAuth, handle resolution, account migration, the lot. 10 - 11 - Another excellent PDS is [Cocoon](https://tangled.org/hailey.at/cocoon), written in go. 9 + It has full compatibility with Bluesky's reference PDS. 12 10 13 11 ## What's different about Tranquil PDS 14 12 15 - It is a superset of the reference PDS, including: passkeys and 2FA (WebAuthn/FIDO2, TOTP, backup codes, trusted devices), SSO login and signup, did:web support (PDS-hosted subdomains or bring-your-own), multi-channel communication (email, discord, telegram, signal) for verification and alerts, granular OAuth scopes with a consent UI showing human-readable descriptions, app passwords with granular permissions (read-only, post-only, or custom scopes), account delegation (letting others manage an account with configurable permission levels), automatic backups (configurable retention and frequency, one-click restore), and a built-in web UI for account management, OAuth consent, repo browsing, and admin. 13 + It is a superset of the reference PDS, including: passkeys and 2FA (WebAuthn/FIDO2, TOTP, backup codes, trusted devices), SSO login and signup, did:web support (PDS-hosted subdomains or bring-your-own), multi-channel communication (email, discord, telegram, signal) for verification and alerts, granular OAuth scopes with a consent UI showing human-readable descriptions, app passwords with granular permissions (read-only, post-only, or custom scopes), account delegation (letting others manage an account with configurable permission levels), and a built-in web UI for account management, repo browsing, and admin. 16 14 17 - The PDS itself is a single small binary with no node/npm runtime. It requires postgres. Blobs are stored on the local filesystem by default (S3 optional). Valkey is optional (supported as an alternative to the built-in cache). 15 + The PDS itself is a single binary with no nodeJS runtime. However, at time of writing, Tranquil requires postgres running separately. Blobs are stored on the local filesystem by default (S3 optional). Valkey is also optional (as an alternative to the built-in cache). 18 16 19 17 ## Quick Start 20 18 21 19 ```bash 22 20 cp .env.example .env 23 - podman compose up -d 21 + podman compose up db -d 24 22 just run 25 23 ``` 26 24 ··· 41 39 42 40 ### Quick Deploy (Docker/Podman Compose) 43 41 44 - Edit `.env.prod` with your values. Generate secrets with `openssl rand -base64 48`. 42 + Edit `.env` with your values. Generate secrets with `openssl rand -base64 48`. 45 43 46 44 ```bash 47 - cp .env.prod.example .env.prod 45 + cp .env.example .env 48 46 podman-compose -f docker-compose.prod.yaml up -d 49 47 ``` 50 48 51 49 ### Installation Guides 52 50 53 - | Guide | Best For | 54 - |-------|----------| 55 - | [Debian](docs/install-debian.md) | Debian 13+ with systemd | 56 - | [Containers](docs/install-containers.md) | Podman with quadlets or OpenRC | 57 - | [Kubernetes](docs/install-kubernetes.md) | You know what you're doing | 51 + - [Debian](docs/install-debian.md) 52 + - [Containers](docs/install-containers.md) 53 + - [Kubernetes](docs/install-kubernetes.md) 58 54 59 55 ## Maintainers to ping 60 56
+42 -48
docs/install-containers.md
··· 1 - # Tranquil PDS Containerized Production Deployment 1 + # Tranquil PDS containerized production deployment 2 2 3 3 This guide covers deploying Tranquil PDS using containers with podman. 4 4 ··· 7 7 8 8 ## Prerequisites 9 9 10 - - A VPS with at least 2GB RAM 10 + - A server :p 11 11 - Disk space for blobs (depends on usage; plan for ~1GB per active user as a baseline) 12 12 - A domain name pointing to your server's IP 13 13 - A **wildcard TLS certificate** for `*.pds.example.com` (user handles are served as subdomains) 14 - - Root or sudo access 14 + - Root/sudo/doas access 15 15 16 - ## Quick Start (Docker/Podman Compose) 16 + ## Quickstart (docker/podman compose) 17 17 18 18 If you just want to get running quickly: 19 19 ··· 38 38 ln -sf live/pds.example.com/privkey.pem certs/privkey.pem 39 39 podman-compose -f docker-compose.prod.yaml restart nginx 40 40 ``` 41 + 42 + The end!!! 43 + 44 + Or wait, you want more? Perhaps a deployment that comes back on server restart? 41 45 42 46 For production setups with proper service management, continue to either the Debian or Alpine section below. 43 47 44 - ## Standalone Containers (No Compose) 48 + ## Standalone containers (no compose) 45 49 46 50 If you already have postgres running on the host (eg. from the [Debian install guide](install-debian.md)), you can run just the app containers. 47 51 ··· 91 95 92 96 --- 93 97 94 - # Debian 13+ with Systemd Quadlets 98 + # Debian with systemd quadlets 95 99 96 - Quadlets are the modern way to run podman containers under systemd. 100 + Quadlets are a nice way to run podman containers under systemd. 97 101 98 - ## Install Podman 102 + ## Install podman 99 103 100 104 ```bash 101 105 apt update 102 106 apt install -y podman 103 107 ``` 104 108 105 - ## Create Directory Structure 109 + ## Create the directory structure 106 110 107 111 ```bash 108 112 mkdir -p /etc/containers/systemd 109 113 mkdir -p /srv/tranquil-pds/{postgres,blobs,backups,certs,acme,config} 110 114 ``` 111 115 112 - ## Create Environment File 116 + ## Create an environment file 113 117 114 118 ```bash 115 119 cp /opt/tranquil-pds/.env.example /srv/tranquil-pds/config/tranquil-pds.env ··· 121 125 openssl rand -base64 48 122 126 ``` 123 127 124 - For quadlets, also add `DATABASE_URL` with the full connection string (systemd doesn't support variable expansion). 125 - 126 - ## Install Quadlet Definitions 128 + ## Install quadlet definitions 127 129 128 130 Copy the quadlet files from the repository: 129 131 ```bash ··· 136 138 137 139 Optional quadlets for valkey and minio are also available in `deploy/quadlets/` if you need them. 138 140 139 - Note: Systemd doesn't support shell-style variable expansion in `Environment=` lines. The quadlet files expect DATABASE_URL to be set in the environment file. 140 - 141 - ## Create nginx Configuration 141 + ## Create nginx configuration 142 142 143 143 ```bash 144 144 cp /opt/tranquil-pds/nginx.frontend.conf /srv/tranquil-pds/config/nginx.conf 145 145 ``` 146 146 147 - ## Clone and Build Images 147 + ## Clone and build images 148 148 149 149 ```bash 150 150 cd /opt ··· 154 154 podman build -t tranquil-pds-frontend:latest ./frontend 155 155 ``` 156 156 157 - ## Create Podman Secrets 157 + ## Create podman secrets 158 158 159 159 ```bash 160 160 source /srv/tranquil-pds/config/tranquil-pds.env 161 161 echo "$DB_PASSWORD" | podman secret create tranquil-pds-db-password - 162 162 ``` 163 163 164 - ## Start Services and Initialize 164 + ## Start services and initialize 165 165 166 166 ```bash 167 167 systemctl daemon-reload ··· 169 169 sleep 10 170 170 ``` 171 171 172 - Run migrations: 173 - ```bash 174 - cargo install sqlx-cli --no-default-features --features postgres 175 - DATABASE_URL="postgres://tranquil_pds:your-db-password@localhost:5432/pds" sqlx migrate run --source /opt/tranquil-pds/migrations 176 - ``` 177 - 178 - ## Obtain Wildcard SSL Certificate 172 + ## Obtain a wildcard SSL cert 179 173 180 174 User handles are served as subdomains (eg. `alice.pds.example.com`), so you need a wildcard certificate. Wildcard certs require DNS-01 validation. 181 175 ··· 209 203 systemctl restart tranquil-pds-nginx 210 204 ``` 211 205 212 - ## Enable All Services 206 + ## Enable all services 213 207 214 208 ```bash 215 209 systemctl enable tranquil-pds-db tranquil-pds-app tranquil-pds-frontend tranquil-pds-nginx 216 210 ``` 217 211 218 - ## Configure Firewall 212 + ## Configure firewall if you're into that sort of thing 219 213 220 214 ```bash 221 215 apt install -y ufw ··· 225 219 ufw enable 226 220 ``` 227 221 228 - ## Certificate Renewal 222 + ## Cert renewal 229 223 230 224 Add to root's crontab (`crontab -e`): 231 225 ``` ··· 234 228 235 229 --- 236 230 237 - # Alpine 3.23+ with OpenRC 231 + # Alpine with OpenRC 238 232 239 - Alpine uses OpenRC, not systemd. We'll use podman-compose with an OpenRC service wrapper. 233 + Alpine uses OpenRC, not systemd. So instead of quadlets we'll use podman-compose with an OpenRC service wrapper. 240 234 241 - ## Install Podman 235 + ## Install podman 242 236 243 237 ```sh 244 238 apk update ··· 253 247 rc-service podman start 254 248 ``` 255 249 256 - ## Create Directory Structure 250 + ## Create the directory structure 257 251 258 252 ```sh 259 253 mkdir -p /srv/tranquil-pds/{data,config} 260 254 mkdir -p /srv/tranquil-pds/data/{postgres,blobs,backups,certs,acme} 261 255 ``` 262 256 263 - ## Clone Repository and Build Images 257 + ## Clone the repo and build images 264 258 265 259 ```sh 266 260 cd /opt ··· 270 264 podman build -t tranquil-pds-frontend:latest ./frontend 271 265 ``` 272 266 273 - ## Create Environment File 267 + ## Create an environment file 274 268 275 269 ```sh 276 270 cp /opt/tranquil-pds/.env.example /srv/tranquil-pds/config/tranquil-pds.env ··· 282 276 openssl rand -base64 48 283 277 ``` 284 278 285 - ## Set Up Compose and nginx 279 + ## Set up compose and nginx 286 280 287 281 Copy the production compose and nginx configs: 288 282 ```sh ··· 297 291 Edit `/srv/tranquil-pds/config/nginx.conf` to update cert paths: 298 292 - Change `/etc/nginx/certs/live/${PDS_HOSTNAME}/` to `/etc/nginx/certs/` 299 293 300 - ## Create OpenRC Service 294 + ## Create OpenRC service 301 295 302 296 ```sh 303 297 cat > /etc/init.d/tranquil-pds << 'EOF' 304 298 #!/sbin/openrc-run 305 299 name="tranquil-pds" 306 - description="Tranquil PDS AT Protocol PDS (containerized)" 300 + description="Tranquil PDS AT Protocol PDS" 307 301 command="/usr/bin/podman-compose" 308 302 command_args="-f /srv/tranquil-pds/docker-compose.yml up" 309 303 command_background=true ··· 331 325 chmod +x /etc/init.d/tranquil-pds 332 326 ``` 333 327 334 - ## Initialize Services 328 + ## Initialize services 335 329 336 330 Start services: 337 331 ```sh ··· 349 343 DATABASE_URL="postgres://tranquil_pds:$DB_PASSWORD@$DB_IP:5432/pds" sqlx migrate run --source /opt/tranquil-pds/migrations 350 344 ``` 351 345 352 - ## Obtain Wildcard SSL Certificate 346 + ## Obtain wildcard SSL cert 353 347 354 348 User handles are served as subdomains (eg. `alice.pds.example.com`), so you need a wildcard certificate. Wildcard certs require DNS-01 validation. 355 349 ··· 381 375 rc-service tranquil-pds restart 382 376 ``` 383 377 384 - ## Enable Service at Boot 378 + ## Enable service at boot time 385 379 386 380 ```sh 387 381 rc-update add tranquil-pds 388 382 ``` 389 383 390 - ## Configure Firewall 384 + ## Configure firewall if you're into that sort of thing 391 385 392 386 ```sh 393 387 apk add iptables ip6tables ··· 409 403 /etc/init.d/ip6tables save 410 404 ``` 411 405 412 - ## Certificate Renewal 406 + ## Cert renewal 413 407 414 408 Add to root's crontab (`crontab -e`): 415 409 ``` ··· 418 412 419 413 --- 420 414 421 - # Verification and Maintenance 415 + # Verification and maintenance 422 416 423 - ## Verify Installation 417 + ## Verify installation 424 418 425 419 ```sh 426 420 curl -s https://pds.example.com/xrpc/_health | jq 427 421 curl -s https://pds.example.com/.well-known/atproto-did 428 422 ``` 429 423 430 - ## View Logs 424 + ## View logs 431 425 432 426 **Debian:** 433 427 ```bash ··· 462 456 rc-service tranquil-pds restart 463 457 ``` 464 458 465 - ## Backup Database 459 + ## Backup database 466 460 467 461 **Debian:** 468 462 ```bash ··· 474 468 podman exec tranquil-pds-db-1 pg_dump -U tranquil_pds pds > /var/backups/pds-$(date +%Y%m%d).sql 475 469 ``` 476 470 477 - ## Custom Homepage 471 + ## Custom homepage 478 472 479 473 The frontend container serves `homepage.html` as the landing page. To customize it, either: 480 474
+21 -25
docs/install-debian.md
··· 1 - # Tranquil PDS Production Installation on Debian 1 + # Tranquil PDS production installation on debian 2 2 3 - This guide covers installing Tranquil PDS on Debian 13. 3 + This guide covers installing Tranquil PDS on Debian. 4 + 5 + It is a "compile the thing on the server itself" -style guide. 6 + This cop-out is because Tranquil isn't built and released via CI as of yet. 4 7 5 8 ## Prerequisites 6 9 7 - - A VPS with at least 2GB RAM 8 - - Disk space for blobs (depends on usage; plan for ~1GB per active user as a baseline) 10 + - A server :p 11 + - Disk space enough for blobs (depends on usage; plan for ~1GB per active user as a baseline) 9 12 - A domain name pointing to your server's IP 10 13 - A wildcard TLS certificate for `*.pds.example.com` (user handles are served as subdomains) 11 - - Root or sudo access 14 + - Root/sudo/doas access 12 15 13 - ## System Setup 16 + ## System setup 14 17 15 18 ```bash 16 19 apt update && apt upgrade -y 17 20 apt install -y curl git build-essential pkg-config libssl-dev 18 21 ``` 19 22 20 - ## Install Rust 23 + ## Install rust 21 24 22 25 ```bash 23 26 curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y ··· 38 41 sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE pds TO tranquil_pds;" 39 42 ``` 40 43 41 - ## Create Blob Storage Directories 44 + ## Create blob storage directories 42 45 43 46 ```bash 44 47 mkdir -p /var/lib/tranquil/blobs /var/lib/tranquil/backups ··· 54 57 echo 'export PATH="$HOME/.deno/bin:$PATH"' >> ~/.bashrc 55 58 ``` 56 59 57 - ## Clone and Build Tranquil PDS 60 + ## Clone and build Tranquil PDS 58 61 59 62 ```bash 60 63 cd /opt ··· 66 69 cargo build --release 67 70 ``` 68 71 69 - ## Install sqlx-cli and Run Migrations 70 - 71 - ```bash 72 - cargo install sqlx-cli --no-default-features --features postgres 73 - export DATABASE_URL="postgres://tranquil_pds:your-secure-password@localhost:5432/pds" 74 - sqlx migrate run 75 - ``` 76 - 77 72 ## Configure Tranquil PDS 78 73 79 74 ```bash ··· 87 82 openssl rand -base64 48 88 83 ``` 89 84 90 - ## Install Frontend Files 85 + ## Install frontend files 91 86 92 87 ```bash 93 88 mkdir -p /var/www/tranquil-pds ··· 95 90 chown -R www-data:www-data /var/www/tranquil-pds 96 91 ``` 97 92 98 - ## Create Systemd Service 93 + ## Create systemd service 99 94 100 95 ```bash 101 96 useradd -r -s /sbin/nologin tranquil-pds ··· 127 122 systemctl start tranquil-pds 128 123 ``` 129 124 130 - ## Install and Configure nginx 125 + ## Install and configure nginx 131 126 132 127 ```bash 133 128 apt install -y nginx certbot python3-certbot-nginx ··· 264 259 systemctl reload nginx 265 260 ``` 266 261 267 - ## Obtain Wildcard SSL Certificate 262 + ## Obtain a wildcard SSL cert 268 263 269 264 User handles are served as subdomains (eg., `alice.pds.example.com`), so you need a wildcard certificate. 270 265 ··· 289 284 systemctl reload nginx 290 285 ``` 291 286 292 - ## Configure Firewall 287 + ## Configure firewall if you're into that sort of thing 293 288 294 289 ```bash 295 290 apt install -y ufw ··· 299 294 ufw enable 300 295 ``` 301 296 302 - ## Verify Installation 297 + ## Verify installation 303 298 304 299 ```bash 305 300 systemctl status tranquil-pds ··· 323 318 systemctl stop tranquil-pds 324 319 cp target/release/tranquil-pds /usr/local/bin/ 325 320 cp -r frontend/dist/* /var/www/tranquil-pds/ 326 - DATABASE_URL="postgres://tranquil_pds:your-secure-password@localhost:5432/pds" sqlx migrate run 327 321 systemctl start tranquil-pds 328 322 ``` 323 + 324 + Tranquil should auto-migrate if there are any new migrations to be applied to the db, so you don't need to worry. 329 325 330 326 Backup database: 331 327 ```bash 332 328 sudo -u postgres pg_dump pds > /var/backups/pds-$(date +%Y%m%d).sql 333 329 ``` 334 330 335 - ## Custom Homepage 331 + ## Custom homepage 336 332 337 333 Drop a `homepage.html` in `/var/www/tranquil-pds/` and it becomes your landing page. Account dashboard is at `/app/` so you won't break anything. 338 334
+2 -2
docs/install-kubernetes.md
··· 1 - # Tranquil PDS on Kubernetes 1 + # Tranquil PDS on kubernetes 2 2 3 3 If you're reaching for kubernetes for this app, you're experienced enough to know how to spin up: 4 4 ··· 19 19 20 20 Health check: `GET /xrpc/_health` 21 21 22 - ## Custom Homepage 22 + ## Custom homepage 23 23 24 24 Mount a ConfigMap with your `homepage.html` into the container's frontend directory and it becomes your landing page. Go nuts with it. Account dashboard is at `/app/` so you won't break anything. 25 25
+2 -2
frontend/public/homepage.html
··· 420 420 and alerts, granular OAuth scopes with human-readable descriptions, 421 421 app passwords with configurable permissions (read-only, post-only, 422 422 or custom scopes), account delegation with permission levels and 423 - audit logging, and a built-in web UI for account management, OAuth 424 - consent, repo browsing, and admin. 423 + audit logging, and a built-in web UI for account management, 424 + repo browsing, and admin. 425 425 </p> 426 426 </div> 427 427 </section>