Bluesky PDS

#tech #selfhost #web

Bluesky is built on the open ATProto network. The Personal Data Server is the network unit that serves as a repository for user data, identity, and media on the network.

I would just like to inject in everyone's imaginations that at least one (1) path to a network of many networks, a fediverse of many fediverses, is a community of many communities. And that might mean more people should found new communities. And tools should be developed to make that easier.

— Rudy wants revolution. (@rudyfraser.com) Jul 19, 2025 at 8:39 AM

Why self host?

Resources

Setting up the PDS

Running the official PDS Docker container is pretty simple. It's pretty lightweight, so you don't need a fancy server to run it. I use the OCI Free Tier for both my server and their object storage (S3). You could definitely do this on something like a Raspberry Pi.

Before starting this process, you'll want to set up DNS records with your domain provider and give them some time to propagate.

The Github repo has a script you can use to set all this up automatically. You probably just want to do that!

I already have a server and proxy running with some other software, so I just need to add the PDS to my existing Docker Compose stack.

The relevant portion of my Compose file:

  pds:
    container_name: pds
    image: ghcr.io/bluesky-social/pds:latest
    networks:
      - public-proxy
    restart: unless-stopped
    volumes:
      - /home/ubuntu/pds/data:/pds
    env_file:
      - /home/ubuntu/pds/pds.env

Running the container will create a template pds.env file at that location specified, which you can then fill out with your secrets and SMTP credentials.

OCI S3

I also set up S3 storage, which Bayley Townsend's howto was helpful for figuring out (also the OCI S3 compatibility doc). Doing so stores the media in the cloud, so our server's disk space doesn't get eaten up with user content like photos or videos.

Getting set up with OCI S3 was, of course, not that straightforward:

  1. Make note of your Region Identifier ex: us-sanjose-1
  2. Make a new Object Storage bucket on your account.
  3. On Bucket Details page, change visibility to Public
  4. Make note of the Namespace on the Bucket Details page
  5. Go to your User Profile -> User Settings. Select Tokens and Keys
  6. Scroll down to Customer secret keys
  7. Generate a Secret key it will only be shown once
  8. Back on the previous page, you now need to copy the Access key from ...

Now we have everything we need to add our secrets to our pds.env file:

PDS_BLOBSTORE_S3_BUCKET=<bucket name>
PDS_BLOBSTORE_S3_REGION=<region>
PDS_BLOBSTORE_S3_ENDPOINT=https://<namespace>.objectstorage.<region>.oraclecloud.com
PDS_BLOBSTORE_S3_ACCESS_KEY_ID=<accesskey>
PDS_BLOBSTORE_S3_SECRET_ACCESS_KEY=<secretkey>
PDS_BLOBSTORE_S3_FORCE_PATH_STYLE=true

Once you have done so and started the service you'll see this message in your browser:

         __                         __
        /\ \__                     /\ \__
    __  \ \ ,_\  _____   _ __   ___\ \ ,_\   ___
  /'__'\ \ \ \/ /\ '__'\/\''__\/ __'\ \ \/  / __'\
 /\ \L\.\_\ \ \_\ \ \L\ \ \ \//\ \L\ \ \ \_/\ \L\ \
 \ \__/.\_\\ \__\\ \ ,__/\ \_\\ \____/\ \__\ \____/
  \/__/\/_/ \/__/ \ \ \/  \/_/ \/___/  \/__/\/___/
                   \ \_\
                    \/_/

This is an AT Protocol Personal Data Server (aka, an atproto PDS)...

You should now be able to browse your PDS at it's URL with pdsls. Here's mine. If you haven't set up an account though there won't be any records.

Creating Accounts

The PDS container doesn't include pdsadmin tool, so we'll need another way to make invite codes. You can use pdsadmin-web to do so easily. Before I was aware of that tool, I did an API call via Postman:

Once you have the code, you can go to the Bluesky app, enter your PDS and invite, and create an account as normal. Now, moment of truth, make a test post with some media:

it is me

[image or embed]

— scribe.brad.quest (@scribe.brad.quest) Aug 15, 2025 at 2:09 PM

You'll get a 500 error if something goes wrong with uploading an image, meaning S3 isn't working. Double check values in the pds.env and permissions in your OCI account.

Migrating Accounts

I used PDS MOOver and it worked perfectly for consolidating 4 accounts on my new PDS. I migrated from Bluesky servers and my own old server. I yolo'ed it and did not follow the precautions, although that seems like a good idea. The process went like this:

Entry 31 - Migrating from the Bluesky PDS to the #BlackSky PDS with PDS MOOver #SharpieVLOG

[image or embed]

— dapurplesharpie 🔜 #ATProto_NYC (@sharpiepls.com) Aug 10, 2025 at 4:39 PM

You receive the final PLC code via email. If you are moving from an old self hosted PDS, double check that your SMTP is working properly on that server before attempting this or you won't receive the PLC.

did:web

By default, accounts are created with did:plc. It also possible to create accounts with did:web

  1. Use didweb tool to create a private key and did.json file.
  2. Place the did.json at yoursite.tld/.well-known/did.json. In my case I'm going to attach it here then proxy redirect to the file:

![[did.json]]

Future

More ATProto


Page Visits