Home Bluesky Personal Data Servers - Important, well constructed and boring as hell

Bluesky Personal Data Servers - Important, well constructed and boring as hell

My experience as a weekend tinkerer deploying the new Bluesky PDS. Syndication

What follows are my notes about setting up a new Bluesky Personal Data Server (PDS). Here’s a helpful What is BlueSky and how does it work? primer that summarizes the core concepts.

Let’s get this out of the way early. I’m all in with the fediverse. Both feet, stomping the grapes. Being stubborn, refusing to even look at alternatives, is not productive. What can we learn from the AT protocol? Let’s find out.

Post Summary

Portable Data Servers (PDS) provide individuals and groups the freedom to own their data and their identity. @box464.com can move their data (in theory) to another PDS and still be @box464.com - along with all their posts, followers, and media. We’re not there yet in the fediverse. It’s exciting! It’s simple to setup, too!

But also boring as all get out.

Because that’s where it stops. There is no room for creativity other than a unique avatar and banner once you sign in. No spicy platform flavors, which the fediverse has in spades. Mastodon, Akkoma, Friendica, Sharkey, GoToSocial…the list goes on, take your pick! No custom css for your instance. No local timeline to peruse with a safe, known community that shares a common bond or interest. At least, not yet.

In fact - here. This is what you get by default after a succesful install. 🥱

The homepage of a bluesky pds, which is just a text message saying "This is an AT Protocol Personal Data Server (PDS): https://github.com/bluesky-social/atproto Most API routes are underxrpc/"

Then, your posts get gobbled up into the relays and spit out into a few common apps, following a common look and feel right now, all with the same featuresets. No cat ears. No emoji reactions. No custom skins.

I’m happy where I am, but hope the fediverse takes what it can from PDS (hello ActivityPods) and makes it better.

Still with me? Alight, let’s dive into it.

This week, I saw this headline in my Mastodon feed: “Bluesky now officially supports federated instances.” But for those of us knee deep in all things fediverse, that doesn’t quite mean what you think it means. I want to know more.

Easy install with less control and fewer features

When someone in the fediverse says “I’m going to start my own server!”, it entails many tasks:

  • Setting up a backend to accept and distribute requests
  • Setting up a frontend to allow users to register and interact with content
  • Maybe setting up a relay to get conversations started on a lonely single user instance (or just follow Lisa Melton)
  • Maybe setting up a CDN to handle all of the media coming in
  • Adding more storage as needed to handle all the content
  • Worrying about security and fake accounts / bots
  • Dealing with legal risks
  • Paying the bills as your user count / data storage grows
  • Moderation of users and content

The list goes on…

Basically setting up a fediverse platform handles EVERYTHING related to your social media experience, and forces you to become expert in all the things. You can get pretty cheap hosting for fediverse platforms, but in the end, you’re still responsible for the health of your instance and everyone that relies on it.

Setting up a PDS is pretty simplistic in comparison. It’s just going to host posts in a database. There’s no flashy timeline, no custom css or other pieces of flair to show off. It’s just a place to store data and be freed from a large corporation controlling that content.

Although…as soon as you write something, up it goes into a large corporation’s inbox right now.

Why bother, then?

Being able to control your own content, move it from one PDS to another, and still retain your core identity may be boring but it’s the missing piece in the fediverse right now. Sure, you can move your followers. But not your posts nor your identity (your username changes every time you switch instances). And your posts are important. I want to get a better understanding of how that works.

The promise of everything, everywhere, all at once

The major difference noted in the article is that by default, Bluesky provides access to the entire stream of posts globally. In this world, there’s really no reason for a like minded community to build their own instances - you can have your own PDS account and connect it up to whatever relays you want to find your clique. Just because you’re besties, you all might want the same PDS domain, like besties.lol. But that’s just fun, it’s not necessary.

In the fediverse, your instance and your conversations are hand picked. You choose your instance, you choose who you follow. It’s up to you to do the work to find cool people and a comfy, safe place to call home. You may not see every single post, or even every single reply to a conversation. Once you find that magic space, it’s no wonder people fight to keep them safe and secure.

I find it funny this is represented as a fault of the fediverse, because it’s exactly why I enjoy it. I don’t need to be everywhere all at once - I’m fine having conversations with the people I like and the servers I choose to interact with. My only complaint is when you dive deep into a conversation thread, we do really need a way to pull all messages from that conversation in. There’s already work being done on this, so there’s hope!

The install process

Anyway, back to the PDS install. Here are the docs.

Bluesky is taking a more modular approach to setting up access to the blueyverse.

A Personal Data Server is just a small part of a bigger environment. It’s a way to own your data, kept separate from a large organization’s control. This is really the main reason I wanted to experiment with this configuration, as this is one area I’ve been disappointed with in the fediverse. It’s getting better, slowly, with unofficial post migration processes already in Sharkey and Misskey for instance.

A PDS only hosts the posts you create (and those of the accounts you are hosting, if any). It doesn’t pull down posts from other instances and store them locally, along with all the media, like most AP servers do.

One thing I’m not clear about is if the PDS stores any interactions with your posts (likes, comments, etc.). I assume since that’s not content you OWN, that is not the case.

There are some pretty major limitations to PDS configurations right now as they see how this is going to work.

If you’re expecting to see a fancy timeline full of interactions and content when you visit my PDS, you’re going to be disappointed. There’s currently nothing shown except a sad little text message:

This is an AT Protocol Personal Data Server (PDS): https://github.com/bluesky-social/atproto

Most API routes are under /xrpc/

There’s not even a way for people to request an account - those have to be generated on the backend right now via a command line interface.

In these early days, Bluesky has set these limits to have better control over the infrastructure:

  • You have to register your domain with Bluesky before your content can be relayed (federated)
  • You are limited to 10 accounts per server
  • You are limited to 1,500 events per hour coming out of your server
  • You are limited to 10,000 events per day coming out of your server

The process of installing a PDS was straight forward if you do it via a cloud hosting service like Hetzner and follow directions as outlined in their repository - and I mean SIMPLE. Compared to even the smallest fediverse install, it just took less than 45 minutes total, and that included setting up a new domain and creating a new account on Hetzner to try this out.

  • You need a domain name
  • You need a server

That’s it.

I’m..not going to run through the steps to install. I was going to, but…I mean…they have it laid out very well in the documentation, and it’s basically two commands after you get the server up:

wget https://raw.githubusercontent.com/bluesky-social/pds/main/installer.sh
sudo bash installer.sh

Everything else is configuration prompts and configuration files…really.

I always find ways to make it difficult - proxies

However, I spent probably 2-3 hours trying to get this to work on my home lab, which has the following basic configuration:

Internet > Firewall > Router > NGINX Proxy Manager > Portainer / ProxMox

That NGINX Proxy Manager piece threw the official Bluesky PDS installer for a loop because it installs docker and a caddy server inside the container. The caddy server and NGINX Proxy Manager weren’t playing nice. I’m sure if I played around with it for a bit longer I could figure something out. But to be honest, I’m not really invested in Bluesky and don’t want to waste my time when I just want to poke on it for a few weeks.

For later: I found some references to a Portainer / NPM config in the official Discord channel. And I really hate having a Discord chat channel as official support. Sounds like I fiddle with the compose.yaml file after install.

Once I gave up on my hopes and dreams of using my new ProxMox VM and moved it to a Hetzner VM, it really took no time at all and I was up and running. The total monthly cost is estimated at less than $7 and that includes daily backups.

I honestly gave up too quickly on running it locally, and I now see people have figured out how to disable the proxy.

Tweaking it

I can’t leave good enough alone, of course.

One thing to note, out of the box, this base configuration does NOT include sending out invitations and new account information through email. You run a command line wizard and it spits out a password. You’d have to provide that directly to someone - and then - they would not be able to reset it because you don’t have email configured.

More than likely, Bluesky was just wanting to keep this as simple as possible, because setting up email is a whole other hurdle. It was probably expected that hobbyists would be loading this up for personal fiddling for now, and only sharing with a few good friends at most.

Someone in the PDS discord channel mentioned the two environment variables that allow you to add an SMTP server (in this case SendGrid, which I am very familiar with already)

Since this was easy for me, I went ahead and did it.

On your server with the PDS running, open the file /pds/pds.env and add these lines with your specific setup. The SMTP url is something specific to SendGrid using SMTP with a Token. username is normally the term apikey and the password is the generated token.

If you do go the SendGrid route, I recommend restricting access for mail delivery to your home and server IPs for access.

PDS_EMAIL_FROM_ADDRESS="[email protected]"
PDS_EMAIL_SMTP_URL="smtp://username:[email protected]:587"

And we’re up and running.



Not even a Bluesky logo? An animated butterfly floating around? Boring.

Two weeks later…

It still works. Very well. No downtime, running like a dream. Still boring.

This post is licensed under CC BY 4.0 by the author.

Breaking things and having fun with ActivityPub

Sending Event RSVPs via Webmentions


Total Interactions: 15
9 Likes 0 Links 0 Posts 5 Re-posts 0 Bookmarks 1 Replies


Posts, Re-Posts and Bookmarks


  1. TLDR - Absolutely solid concept. Reliable. Beneficial. Good idea. Boring as hell.

    After installing, this is what you get.

    No flair. No cat ears. No custom css. No local feed. Not even a home page.

    The fediverse is colorful and diverse. I'm staying here - but never afraid to learn about new concepts.