Nomad, IO, and a PDS
The Bluesky Personal Data Server If you've been using Bluesky, you might have heard of the Personal Data Server . It's the part of the Bluesky architecture that allows us to own our own data. Quoting Bluesky's Federation Architecture : A PDS acts as the participant’s agent in the network. This is what hosts your data (like the posts you’ve created) in your repository. It also handles your account & login, manages your repo’s signing key, stores any of your private data (like which accounts you have muted), and handles the services you talk to for any request. Run your own PDS on a droplet One of the great features of the Bluesky architecture is that we users can run our own PDS instances. We can do this for ourselves, our families, our friends, our clubs, or just any group of people who are willing to trust us with hosting their repositories. Here we're going to describe how to set up and run a Bluesky PDS on the droplet that was presented in Droplet Superpowers . Much of this is based on Justin Garrison's Run a Bluesky PDS From Home and the bluesky-social/pds/README , but here we'll go over the specific steps needed to run a PDS with Nomad and IO on a droplet. We'll use the official Bluesky PDS image Our configuration uses the PDS images that the Bluesky team publishes in the GitHub Container Registry. There's a list of available versions on the Release page , where we can see that ghcr.io/bluesky-social/pds:0.4 tracks the latest patch release of the 0.4 minor version. Nomad configuration for a Bluesky PDS If you've set up a droplet like we did in Droplet Superpowers , you can run your PDS with a Nomad job configuration like this one, which you might save in a file named pds.hcl : You can read more about this configuration format in the Nomad Job Specification Reference . The Bluesky-specific part is all in the env section. What are all those environment variables? There's an example.env on GitHub and a working set of values embedded in the installer.sh script. That is mixed up with lots of opinionated aspects of deployment that we aren't using, so I'm going to try to directly describe these variables here. Many of them can be set to the same values used in the installer script, but we need to set a few for each new PDS instance. Here are the ones we need to customize: TZ Your preferred time zone PDS_ HOSTNAME The domain name of your PDS host PDS_ JWT_ SECRET The key used to sign JWTs issued by your PDS PDS_ ADMIN_ PASSWORD The admin password for your PDS PDS_ PLC_ ROTATION_ KEY_ K256_ PRIVATE_ KEY_ HEX The key used to sign updates that modify hosted DIDs (Reference) Get values for PDS_JWT_SECRET and PDS_ADMIN_PASSWORD by running: Output will look like this: Get PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX by running this: Output looks like this: Here's a discussion of the others, and again, for our purposes, we can set them to the values listed below. PDS_ DATA_ DIRECTORY /pds The docker image expects data to be stored here, so our job configuration maps this to a Nomad host volume. PDS_ BLOBSTORE_ DISK_ LOCATION /pds/blocks A path in our mapped host volume PDS_ BLOBSTORE_ DISK_ TMP_ LOCATION /pds/temp Another path in the mapped host volume PDS_ BLOB_ UPLOAD_ LIMIT 52428800 The maximum size for uploaded blobs (Reference) PDS_ DID_ PLC_ URL https://plc.directory The offical directory of DIDs PDS_ BSKY_ APP_ VIEW_ URL https://api.bsky.app The main Bluesky app PDS_ BSKY_ APP_ VIEW_ DID did:web:api.bsky.app The DID of the Bluesky app PDS_ REPORT_ SERVICE_ URL https://mod.bsky.app The Bluesky moderation service PDS_ REPORT_ SERVICE_ DID did:plc:ar7c4by46qjdydhdevvrndac The DID of the Bluesky moderation service PDS_ CRAWLERS https://bsky.network The official Bluesky crawlers Before we run the Nomad job, we need to also create the host volume and restart Nomad. First add this to the client section in your /etc/nomad.d/nomad.hcl : Then restart Nomad by running systemctl restart nomad on your droplet. Once the restart has settled, we can apply the pds job configuration. IO configuration for a Bluesky PDS The IO ingress for our PDS is really simple: Yep, that's it. Add a similar ingress to your IO configuration and your PDS will be online. Creating users The Bluesky team publishes a tool called pdsadmin for managing PDS instances. I'm using a Go version by Lance Haig that's available at github.com/lhaig/pdsadmin . If you have Go installed, you can get it with go install : You also need a file in your home directory called pds.env with the contents of the env block in your PDS job configuration above. Here I am using pdsadmin to create an account in my new PDS: This next step verifies the new handle by writing a DNS record. My domain is on GoDaddy and I'm using the godaddy-cli tool to create the record: Verifying your Users without Email If you're just hosting a PDS for yourself and a few friends or family members, it's probably not worth the effort to set up an email server, nor is it worth the complexity and risk. You can just create users with pdsadmin and verify them with a line of SQLite. Run this in sqlite on your instance: This sets the confirmation time to whatever value you choose (when you edit the time below): If you want to use the current time, do this instead: Observing your Bluesky PDS with IO Now it gets fun. Use IO to watch your ingress traffic logs when you use pdsadmin . For example, when we run pdsadmin account list , one of the calls that we see is to the sync.listRepos method. Here's the IO view of the request and response headers: Here's the response body: Then log into your PDS from Bluesky. Here's a server.createSession call: Here's the request body (cropped to omit my password): And here's the response body: You can also do things like post or follow users; all of these operations will show up in your PDS traffic log. We'll do more with this later when we look at how IO implements ATProto auth. Other resources The bluesky-social/pds/README Run a Bluesky PDS From Home Notes on Self Hosting a Bluesky PDS Alongside Other Services Self-Hosting a Bluesky Personal Data Server on Ubuntu VPS Self-hosting Bluesky PDS How to set up a Bluesky PDS Self-hosting Bluesky atp.tools pdsls.dev
Discussion in the ATmosphere