BlueSky PDS: Self-Host Your Own Social Data
Video
Transcript
Hello everyone, and welcome back to Easy Self Host.
In today’s video, we’re going to self-host the BlueSky Personal Data Server—the service that keeps all the data for your own BlueSky account.
BlueSky is a popular social app that supports data federation.
It implements something called the AT protocol, which lets anyone host their account on their own server, so you can truly own your social data.
PDS, or Personal Data Server, is BlueSky’s first-party implementation of this protocol.
I’ve already hosted my account, @easyselfhost.com, on my own server.
The official BlueSky PDS repository offers an installer script,
but today we’ll deploy it with plain Docker Compose instead.
The reason is that most of us run multiple apps on a single server,
and the script doesn’t play nicely in that setup.
You’ll need a server with a public IP address so BlueSky can reach it,
and a domain name for your PDS—that domain will identify every account you host.
For this demo, I’ll spin up a fresh cloud server on DigitalOcean.
You can use any VPS provider you prefer.
Once the server is running, we’ll configure DNS for our domain.
I’m using pds.ezsh.app for my BlueSky PDS.
BlueSky needs both pds.ezsh.app and *.pds.ezsh.app pointing to the server’s IP address.
After those records are in place, we can SSH into the server.
If Docker isn’t installed yet on the server, we can install it with the official script from get.docker.com.
Let’s run the Docker installer script.
With Docker ready, we can create our Docker Compose file for the BlueSky PDS.
To edit our files directly on the server, we’ll connect with VS Code over SSH.
First, create a folder to hold all the configuration files, and open that folder in VS Code.
Inside that folder, start a new Docker Compose file.
Here’s the compose file we need for our PDS.
It defines two services: the PDS itself and a Caddy reverse proxy.
If you already run a proxy elsewhere, just keep the PDS service and drop Caddy.
For the PDS service we use the latest official image from the BlueSky repo.
We mount a volume at /pds so the data is persisted.
Next come the environment variables.
Set PDS_HOSTNAME to the domain you assigned to this server.
Then we have two secrets that should be configured in a .env file for safety.
We can generate two random secrets with the command “openssl rand -hex 32” and paste them in the .env file.
Let’s also create another variable here for the admin password.
Back to the compose file and let’s set the PDS_ADMIN_PASSWORD with this environment.
Then let’s set the storage location for PDS data.
PDS_DATA_DIRECTORY holds the database files,
PDS_BLOBSTORE_DISK_LOCATION stores blobs like images and videos.
PDS needs email verification for accounts so we need to configure a SMTP server to send emails.
The easiest option is to use Resend, a service for transactional email.
To use Resend, we need to first create an account.
Then we need to set up a domain to send emails from.
I plan to use the same domain as my PDS server, pds.ezsh.app.
For that to work, we have to configure some DNS records.
Let’s add these records to our DNS provider.
Back to Resend, click “I’ve added the records” and wait for Resend to verify that.
This process might take a couple of minutes.
After this, we need to create an API key, so we can use SMTP with Resend.
Let’s paste the API key in the .env file.
And in the compose file, let’s configure PDS_EMAIL_SMTP_URL in this format with the API key.
The PDS_EMAIL_FROM_ADDRESS can be anything at the domain name we used in Resend.
Then leave the remaining environment lines as they are.
Most of them are for connecting our PDS to the BlueSky server.
Now for Caddy, our reverse proxy.
Expose ports 80 and 443 for HTTP and HTTPS.
And mount the Caddyfile from the current directory into the container.
Then we need to create that Caddyfile in the folder.
The only config we need is to reverse_proxy both the domain name and * dot your domain name to the pds service on port 3000.
That’s the whole setup.
Moving to our server terminal, from the project directory, run “docker compose up -d”.
Then wait for the containers to run.
When the containers start, open your browser and go to your PDS domain.
You should see the simple landing page served from your new BlueSky Personal Data Server.
Now let’s create an account on our PDS.
Open BlueSky’s web app at bsky.app.
Click “Create account,” and at the top choose “Custom” to set the server address.
Because our account will not be hosted on the main BlueSky server.
Enter the address of your PDS—mine is pds.ezsh.app.
First, we need an invite code.
We’ll generate one by sending a request to the PDS endpoint with the admin password.
I built a small web app to make invite-code generation easier.
Just go to ezsh.link/pds-invite.
Enter your PDS endpoint and admin password,
then click Generate to get the invite code.
The request is sent directly from your browser, so your credentials are safe.
If you prefer, you can also use the command line to create the code from the terminal.
On the server, run these commands:
Set the admin password as an environment variable.
Then use curl to call the PDS endpoint and get an invite code.
In this command, we are sending requests to our PDS endpoint with the CreateInviteCode method.
And we are authenticating ourselves using the admin password.
Run this command and we can get the invite code.
Back to the BlueSky web app.
Let’s paste in the invite code, and then fill in our email and password.
After that, you will be prompted to choose a username.
Notice that your PDS domain is baked into the handle.
Complete the remaining onboarding steps to finish setting up your BlueSky account.
Next, let’s verify the email address.
Open Settings—if you see “invalid handle,” don’t worry; it just takes a little time to update.
Go to Account, click Verify your email, then Send email.
If SMTP is configured correctly, you’ll receive a message with a verification code.
Paste the code back into BlueSky, and your email is now confirmed.
At this point, your BlueSky account is live and everyone can see your posts.
One last tip—if you want a cleaner handle like @easyselfhost.com.
Go to Account Settings, then Handle.
Choose “I have my own domain.”
Enter your domain name, and BlueSky will give you a DNS record to add.
Add that record at your DNS provider, wait a few minutes, then click Verify.
Once it passes, your handle will switch to your custom domain.
That’s all for this video.