From 3b6fce26a879352fa835d9ed563ca0b58357a810 Mon Sep 17 00:00:00 2001 From: notplants Date: Sun, 22 Feb 2026 18:05:50 +0000 Subject: [PATCH 1/3] remove hardcoded federation defaults, rewrite README quickstart --- .env.sample | 4 +- README.md | 108 ++++++++++++++++++++++++++++++---------------------- compose.yml | 6 --- 3 files changed, 66 insertions(+), 52 deletions(-) diff --git a/.env.sample b/.env.sample index e95dbc9..e0b99e8 100644 --- a/.env.sample +++ b/.env.sample @@ -6,7 +6,9 @@ LETS_ENCRYPT_ENV=production # Blob upload limit in bytes (default: 100MB) #PDS_BLOB_UPLOAD_LIMIT=104857600 -# Federation settings (defaults connect to the main Bluesky network) +# Federation settings +# These are managed by the upstream PDS image with sensible defaults. +# Only set these if you need to override the upstream defaults. #PDS_DID_PLC_URL=https://plc.directory #PDS_BSKY_APP_VIEW_URL=https://api.bsky.app #PDS_BSKY_APP_VIEW_DID=did:web:api.bsky.app diff --git a/README.md b/README.md index da4fd9f..a049f5e 100644 --- a/README.md +++ b/README.md @@ -13,53 +13,45 @@ -## About +## Quickstart -A [Bluesky PDS](https://github.com/bluesky-social/pds) (Personal Data Server) -is a self-hosted server for the AT Protocol, allowing you to own your social -data and federate with the Bluesky network. +1. `abra app new bluesky-pds` (do **not** use `--secrets` yet, see below) +2. Generate secrets: -## Basic usage + The JWT secret and admin password can be generated automatically: -1. Set up Docker Swarm and [`abra`] -2. Deploy [`coop-cloud/traefik`] -3. `abra app new bluesky-pds` (do **not** use `--secrets` yet, see below) -4. `abra app config YOURAPPDOMAIN` - set `DOMAIN` to something that resolves to - your Docker swarm box -5. Generate the PLC rotation key and create secrets (see below) -6. `abra app deploy YOURAPPDOMAIN` -7. Verify the PDS is running: `curl https://YOURAPPDOMAIN/xrpc/_health` + ```bash + abra app secret generate YOURAPPDOMAIN pds_jwt_secret v1 + abra app secret generate YOURAPPDOMAIN pds_admin_password v1 + ``` -## Generating secrets + The PLC rotation key is a secp256k1 private key and must be generated + manually: -The JWT secret and admin password can be generated automatically: + ```bash + openssl ecparam --name secp256k1 --genkey --noout --outform DER | \ + tail --bytes=+8 | head --bytes=32 | xxd --plain --cols 32 + ``` -```bash -abra app secret generate YOURAPPDOMAIN pds_jwt_secret v1 -abra app secret generate YOURAPPDOMAIN pds_admin_password v1 -``` + Then store it as a secret: -The PLC rotation key is a secp256k1 private key and must be generated manually: + ```bash + abra app secret insert YOURAPPDOMAIN pds_plc_rotation_key v1 + ``` -```bash -openssl ecparam --name secp256k1 --genkey --noout --outform DER | \ - tail --bytes=+8 | head --bytes=32 | xxd --plain --cols 32 -``` +3. `abra app deploy YOURAPPDOMAIN` -Then store it as a secret: - -```bash -abra app secret insert YOURAPPDOMAIN pds_plc_rotation_key v1 -``` +Verify the PDS is running: `curl https://YOURAPPDOMAIN/xrpc/_health` ## Account management -Create an account on your PDS: +Create an account on your PDS (use the admin password you stored during secret +generation): ```bash abra app run YOURAPPDOMAIN app -- \ goat pds admin account create \ - --admin-password "$(abra app secret get YOURAPPDOMAIN pds_admin_password v1)" \ + --admin-password YOUR_ADMIN_PASSWORD \ --handle user.YOURAPPDOMAIN \ --email user@example.com \ --password yourpassword @@ -70,9 +62,24 @@ Create an invite code: ```bash abra app run YOURAPPDOMAIN app -- \ goat pds admin account create-invite \ - --admin-password "$(abra app secret get YOURAPPDOMAIN pds_admin_password v1)" + --admin-password YOUR_ADMIN_PASSWORD ``` +## Usage + +Once you've created an account (see above), you can log in with any +ATProto-compatible client: + +1. Open [bsky.app](https://bsky.app) (or another client like Graysky, Sky.app, + etc.) +2. On the login screen, tap **Hosting provider** (or **Custom PDS** depending on + the client) +3. Enter your PDS hostname: `YOURAPPDOMAIN` +4. Log in with the handle and password you used when creating the account + +Your handle will be `user.YOURAPPDOMAIN` by default (a subdomain handle). You +can switch to a custom domain handle — see **Handle configuration** below. + ## Handle configuration User handles on a PDS can work in two ways: @@ -86,6 +93,24 @@ User handles on a PDS can work in two ways: `did=did:plc:`. This works without any additional server configuration. +## DNS setup + +At minimum, create an A record pointing your PDS domain to your server: + +``` +pds.example.com A +``` + +For subdomain handles, also add a wildcard record: + +``` +*.pds.example.com A +``` + +[`abra`]: https://git.coopcloud.tech/coop-cloud/abra +[`coop-cloud/traefik`]: https://git.coopcloud.tech/coop-cloud/traefik + + ## TLS architecture (Caddy sidecar) This recipe uses a **Caddy sidecar** for TLS instead of letting Traefik terminate @@ -114,19 +139,12 @@ Caddy obtains the TLS certificate from Let's Encrypt. Subsequent requests are in No changes to the Traefik recipe are needed — the TCP passthrough is configured entirely via deploy labels on the Caddy service in this recipe's `compose.yml`. -## DNS setup +## About -At minimum, create an A record pointing your PDS domain to your server: +A [Bluesky PDS](https://github.com/bluesky-social/pds) (Personal Data Server) +is a self-hosted server for ATProto. This is a co-op cloud recipe for a PDS +as implemented by bluesky, although other pds implementations exist such as [rsky-pds](https://github.com/blacksky-algorithms/rsky/tree/main/rsky-pds). -``` -pds.example.com A -``` +# ❃ -For subdomain handles, also add a wildcard record: - -``` -*.pds.example.com A -``` - -[`abra`]: https://git.coopcloud.tech/coop-cloud/abra -[`coop-cloud/traefik`]: https://git.coopcloud.tech/coop-cloud/traefik +recipe maintained by @notplants diff --git a/compose.yml b/compose.yml index 88ccb9b..8035b42 100644 --- a/compose.yml +++ b/compose.yml @@ -11,12 +11,6 @@ services: - PDS_DATA_DIRECTORY=/pds - PDS_BLOBSTORE_DISK_LOCATION=/pds/blocks - PDS_BLOB_UPLOAD_LIMIT=${PDS_BLOB_UPLOAD_LIMIT:-104857600} - - PDS_DID_PLC_URL=${PDS_DID_PLC_URL:-https://plc.directory} - - PDS_BSKY_APP_VIEW_URL=${PDS_BSKY_APP_VIEW_URL:-https://api.bsky.app} - - PDS_BSKY_APP_VIEW_DID=${PDS_BSKY_APP_VIEW_DID:-did:web:api.bsky.app} - - PDS_REPORT_SERVICE_URL=${PDS_REPORT_SERVICE_URL:-https://mod.bsky.app} - - PDS_REPORT_SERVICE_DID=${PDS_REPORT_SERVICE_DID:-did:plc:ar7c4by46qjdydhdevvrndac} - - PDS_CRAWLERS=${PDS_CRAWLERS:-https://bsky.network} - PDS_EMAIL_SMTP_URL=${PDS_EMAIL_SMTP_URL:-} - PDS_EMAIL_FROM_ADDRESS=${PDS_EMAIL_FROM_ADDRESS:-} - PDS_INVITE_REQUIRED=${PDS_INVITE_REQUIRED:-true} -- 2.49.0 From 28dee997c39b0419ba05398376a5e1e299dea085 Mon Sep 17 00:00:00 2001 From: notplants Date: Sun, 22 Feb 2026 18:05:58 +0000 Subject: [PATCH 2/3] bump to 0.2.0+v0.4 --- compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose.yml b/compose.yml index 8035b42..313b555 100644 --- a/compose.yml +++ b/compose.yml @@ -36,7 +36,7 @@ services: max_attempts: 5 labels: - "coop-cloud.${STACK_NAME}.timeout=${TIMEOUT:-120}" - - "coop-cloud.${STACK_NAME}.version=0.1.1+v0.4" + - "coop-cloud.${STACK_NAME}.version=0.2.0+v0.4" - "backupbot.backup=true" healthcheck: test: ["CMD", "wget", "-q", "--spider", "http://localhost:3000/xrpc/_health"] -- 2.49.0 From 0ef640eae67b5a56cc9814d949d4ec8215135281 Mon Sep 17 00:00:00 2001 From: notplants Date: Sun, 22 Feb 2026 18:12:08 +0000 Subject: [PATCH 3/3] rename federation settings to network settings --- .env.sample | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.sample b/.env.sample index e0b99e8..c4f7372 100644 --- a/.env.sample +++ b/.env.sample @@ -6,7 +6,7 @@ LETS_ENCRYPT_ENV=production # Blob upload limit in bytes (default: 100MB) #PDS_BLOB_UPLOAD_LIMIT=104857600 -# Federation settings +# Network settings # These are managed by the upstream PDS image with sensible defaults. # Only set these if you need to override the upstream defaults. #PDS_DID_PLC_URL=https://plc.directory -- 2.49.0