How to Set Up a Self-Hosted Bluesky PDS on a VPS
🔍 WiseChecker

How to Set Up a Self-Hosted Bluesky PDS on a VPS

You want to run your own Bluesky Personal Data Server on a VPS instead of using the official hosted service. A self-hosted PDS gives you full control over your data, moderation, and infrastructure. This article walks through the complete setup process using Docker on a Ubuntu 22.04 VPS. By the end, you will have a working Bluesky PDS accessible from any Bluesky client.

Key Takeaways: Self-Hosted Bluesky PDS Setup on a VPS

  • Ubuntu 22.04 VPS with Docker installed: The base requirement for running the Bluesky PDS container.
  • Domain name with DNS A record pointing to your VPS IP: Needed to verify your PDS and serve content over HTTPS.
  • Ports 80 and 443 open in your VPS firewall: Required for Let’s Encrypt certificate renewal and client connections.
  • Bluesky PDS Docker image from ghcr.io/bluesky-social/pds: The official container that runs the PDS software.
  • Environment variables in a .env file: Configures the PDS hostname, admin password, and service handle.

What Is a Bluesky PDS and Why Self-Host It

A Personal Data Server is the core infrastructure of the Bluesky network. It stores your account data, posts, and follows, and it communicates with other PDS instances to relay content. The official hosted service at bsky.social runs a large PDS cluster managed by Bluesky. Self-hosting a PDS means you run your own instance on a VPS you control. This gives you privacy benefits because your data never touches Bluesky’s servers. You also get the ability to set custom moderation rules and keep your account alive even if the official service goes offline. The setup requires a VPS with a public IP, a domain name, and basic familiarity with the Linux command line.

Prerequisites for the Setup

Before you start, you need the following items ready:

  • A VPS running Ubuntu 22.04 with at least 2 GB RAM and 20 GB SSD storage. Providers like DigitalOcean, Linode, or Hetzner work well.
  • Root SSH access to the VPS.
  • A domain name that you control, for example pds.yourdomain.com. You will create a DNS A record pointing to your VPS IP address.
  • Docker and Docker Compose installed on the VPS. If they are not installed, the setup script will install them.
  • Ports 80 and 443 open in the VPS firewall. The setup uses Let’s Encrypt to obtain a TLS certificate automatically.

Steps to Set Up a Self-Hosted Bluesky PDS on a VPS

The following steps use the official Bluesky PDS setup script. This script downloads the Docker image, creates environment files, and configures Caddy as a reverse proxy with automatic HTTPS. You will run all commands as a non-root user with sudo privileges.

Step 1: Connect to Your VPS and Update the System

  1. Open an SSH connection
    Run ssh root@your-vps-ip from your local terminal. Replace your-vps-ip with the actual IP address of your VPS.
  2. Update package lists and upgrade existing packages
    Run apt update && apt upgrade -y. This ensures all system packages are current.
  3. Reboot the VPS if the kernel was updated
    Run reboot and reconnect after the server comes back online.

Step 2: Configure DNS for Your Domain

  1. Log in to your domain registrar or DNS provider
    Go to the DNS management panel for your domain.
  2. Create an A record
    Set the hostname to pds or any subdomain you prefer. Set the value to your VPS public IP address. Set the TTL to 300 seconds or the lowest value allowed.
  3. Wait for DNS propagation
    Use a tool like dig pds.yourdomain.com from your local machine to verify the record resolves to your VPS IP. Propagation usually takes a few minutes.

Step 3: Clone the Bluesky PDS Repository

  1. Install git if it is not already installed
    Run apt install git -y.
  2. Clone the official PDS repository
    Run git clone https://github.com/bluesky-social/pds.git. This creates a directory named pds in your current working directory.
  3. Change into the pds directory
    Run cd pds.

Step 4: Run the Setup Script

  1. Make the setup script executable
    Run chmod +x setup.sh.
  2. Execute the setup script
    Run sudo ./setup.sh. The script will prompt you for several pieces of information.
  3. Provide the required values when prompted
    Enter your domain name (for example pds.yourdomain.com), an admin email address for Let’s Encrypt notifications, and a strong admin password. The script will also ask for the service handle domain. This is the domain used for your Bluesky handles. It can be the same as your PDS domain or a different domain like bsky.yourdomain.com.
  4. Wait for the script to finish
    The script installs Docker and Docker Compose if needed, sets up environment variables, and starts the PDS container. It also configures Caddy to handle HTTPS automatically.

Step 5: Verify the PDS Is Running

  1. Check the Docker container status
    Run docker ps. You should see a container named pds with the status Up.
  2. Test the PDS health endpoint
    Run curl https://pds.yourdomain.com/xrpc/_health. You should receive a JSON response with {"version":"0.4.0"} or a similar version number.
  3. Create your first account on the PDS
    Use a Bluesky client like the official app or a third-party client. When signing up, enter your PDS domain as the server URL. For example, in the official Bluesky app, tap the three dots in the top-right corner, select Advanced, and enter https://pds.yourdomain.com as the server URL. Then create your account with your desired handle, for example @yourhandle.pds.yourdomain.com.

Common Issues After Setting Up a Self-Hosted PDS

HTTPS Certificate Fails to Generate

If the Let’s Encrypt certificate does not issue, the most common cause is that port 80 is not reachable from the internet. Verify your VPS firewall allows inbound traffic on port 80. Also check that your DNS A record points to the correct VPS IP. Run curl -v http://pds.yourdomain.com/.well-known/acme-challenge/test from a different machine to confirm the domain is reachable on port 80.

Docker Container Exits Immediately

If the PDS container exits right after starting, check the logs with docker logs pds. The most frequent cause is a missing or incorrect environment variable in the .env file. Open the pds directory and edit the .env file. Verify that PDS_HOSTNAME matches your domain exactly, PDS_ADMIN_PASSWORD is not empty, and PDS_SERVICE_HANDLE_DOMAIN is set to a valid domain. After editing, restart the container with docker-compose down && docker-compose up -d.

Cannot Create Account from a Client

If the client shows an error when you try to create an account, ensure that the PDS is running and that the server URL you entered is correct. Some clients require the full URL with https:// prefix. Also confirm that the handle domain you configured matches the domain part of the handle you are trying to create. For example, if your handle domain is pds.yourdomain.com, your handle must be @username.pds.yourdomain.com.

Self-Hosted PDS vs Official Bluesky Service

Item Self-Hosted PDS Official Bluesky Service
Data storage Your own VPS Bluesky’s servers
Setup effort Requires Linux and Docker knowledge No setup required
Cost VPS hosting cost (typically $5-$20 per month) Free
Control over moderation Full control via admin API Limited to Bluesky’s moderation policies
Uptime responsibility You manage the server Bluesky manages uptime
Handle format Custom domain handle bsky.social handle

Running your own PDS gives you complete data sovereignty and the ability to set your own moderation rules. The trade-off is that you must maintain the server, apply security updates, and monitor disk space. If you prefer a hands-off experience, the official service remains a good choice. For users who want maximum privacy and control, a self-hosted PDS on a VPS is the correct path.