Self-hosting Bluesky PDS from Scratch

Self-hosting Bluesky PDS from Scratch

Yulei Chen - Content-Engineerin bei sliplane.ioYulei Chen
7 min

Bluesky is an open social app, built on top of the philosophy of "file over app". You can store your own social data on your own server. No matter what happens to the social app itself, whether it goes evil or simply shuts down, you still own your data. That's very cool.

In this post, I'll walk you through self-hosting a Bluesky PDS (Personal Data Server): setting it up on your own server, creating an account, signing in through Bluesky, and browsing it with PDSls.

Prerequisites

Before we start, make sure you already have a server and a domain name. This tutorial uses an Ubuntu server from Hetzner and the domain sliplane.dev.

Step 1: Update your server

On your server, update the system to ensure it has the latest security patches and updates:

Terminal
sudo apt update
sudo apt upgrade -y

Once finished, your server is ready for installing the software.

Step 2: Install and configure UFW firewall

Only keep necessary ports open: SSH (22), HTTP (80), HTTPS (443). Install UFW and configure the firewall as follows:

Terminal
sudo apt install ufw -y
sudo ufw allow 22    # SSH
sudo ufw allow 80    # HTTP
sudo ufw allow 443   # HTTPS
sudo ufw enable

Verify the firewall configuration with sudo ufw status verbose. The output should look like this:

Terminal
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22                         ALLOW IN    Anywhere
80                         ALLOW IN    Anywhere
443                        ALLOW IN    Anywhere
22 (v6)                    ALLOW IN    Anywhere (v6)
80 (v6)                    ALLOW IN    Anywhere (v6)
443 (v6)                   ALLOW IN    Anywhere (v6)

Step 3: Install Docker

To install Docker, first set up the dependencies and Docker's GPG key:

Terminal
sudo apt install ca-certificates curl gnupg

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

Next, add the Docker repository:

Terminal
echo \
  "deb [arch=$(dpkg --print-architecture) \
signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo $VERSION_CODENAME) stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update

Finally, install Docker Engine and the Compose plugin:

Terminal
sudo apt install docker-ce docker-ce-cli \
containerd.io docker-buildx-plugin docker-compose-plugin -y

Verify the installation with sudo docker run hello-world. You should see Hello from Docker!.

Step 4: Configure DNS for your domain

Follow these steps to configure DNS:

  1. Log into your domain registrar's dashboard (where you purchased your domain)
  2. Navigate to the DNS settings or DNS management section
  3. Add an A record with the following settings:
    • Type: A
    • Name: @ (for root domain, e.g. "sliplane.dev")
    • Value/Target: Your server's IPv4 address
  4. Add an A record with the following settings:
    • Type: A
    • Name: * (for all subdomains)
    • Value/Target: Your server's IPv4 address

DNS changes can take a few minutes to several hours to propagate. You can check if your DNS is configured correctly using tools like dig or online DNS checkers. Once the DNS record is active, you can proceed with PDS installation.

Step 5: Install PDS

In this step, you'll install the PDS itself. Start by downloading the official install script:

Terminal
curl https://raw.githubusercontent.com/bluesky-social/pds/main/installer.sh > installer.sh

Then run the installer with bash:

Terminal
sudo bash installer.sh

The installer runs the official bluesky-pds Docker image with all required environment variables. It also sets up TLS through Caddy. The Caddyfile is located in /pds/caddy/etc/caddy/Caddyfile. Watchtower is configured as well, which keeps your PDS image up to date automatically.

The installer will ask for your domain name. After that, if you see output like the following, your PDS is up and running 🎉🎉:

========================================================================
PDS installation successful!

---

Check service status : sudo systemctl status pds
Watch service logs : sudo docker logs -f pds
Backup service data : /pds
PDS Admin command : docker exec pds goat pds admin

## Required Firewall Ports

Service Direction Port Protocol Source

---

HTTP TLS verification Inbound 80 TCP Any
HTTP Control Panel Inbound 443 TCP Any

## Required DNS entries

Name Type Value

---

sliplane.dev A 138.199.200.187
\*.sliplane.dev A 138.199.200.187

Detected public IP of this server: 138.199.200.187

To see pds admin commands, run "docker exec pds goat pds admin"

========================================================================

Next, the installer will prompt you to create a PDS user account. Let's do it:

Create a PDS user account? (y/N): y
Enter an email address (e.g. alice@sliplane.dev): yulei@sliplane.io
Enter a handle (e.g. alice.sliplane.dev): hello.sliplane.dev

## Account created successfully!

Handle : hello.sliplane.dev
DID : did:plc:kp7v7canit5l5izhspn5i25h
Password :

---

Save this password, it will not be displayed again.

As you can see, we created a PDS account with the handle hello.sliplane.dev. Make sure to save the auto-generated password, since it won't be shown again. You're now ready to sign in to Bluesky.

Step 6: Sign in to Bluesky with Your PDS

Open Bluesky. Instead of signing in through the default bsky.social server, choose the custom PDS option and enter your domain.

Sign in to Bluesky with custom provider

Sign in with the handle and password from the previous step:

Sign in to Bluesky

If everything is configured correctly, open your Profile or Settings page, you should see your handle with an @ prefix, e.g. @hello.sliplane.dev.

Step 7 (optional): Browse your PDS with PDSls

PDSls is a browser-based tool for inspecting AT Protocol data. To explore your PDS account:

  1. Go to pdsls.dev
  2. Enter your handle (e.g. hello.sliplane.dev) into the search field

If the endpoint and DID resolve correctly, your self-hosted PDS is live and properly federated with the wider Bluesky network.

PDSls search result

The search results show your PDS domain, handle, DID, and AT Protocol collections where your Bluesky collection lies.

Conclusion

You now have your own Bluesky PDS running on your own server. Your posts, likes, and follows live on infrastructure you control.

Besides of data-level infrastructure like a PDS, you can also self host application-level infrastructure like an AppView or Relay. We may cover these topics in the future, so stay tuned!

Welcome to your cloud platform

Sliplane makes it simple to deploy and scale your apps in the cloud. Start with a container or your favorite framework and grow from there. Try it now and get started in minutes!