Welcome to the repository for the official Bluesky PDS (Personal Data Server). This repository includes container images and documentation designed to assist technical people with self-hosting a Bluesky PDS.
Bluesky is a social media application built on AT Protocol.
Please visit the Bluesky website for more information.
The Authenticated Transfer Protocol, aka atproto, is a protocol for large-scale distributed social applications.
Please visit the AT Protocol docs for additional information.
Self-hosting a Bluesky PDS means running your own Personal Data Server that is capable of federating with the wider Bluesky social network.
Launch a server on any cloud provider, Digital Ocean and Vultr are two popular choices.
Server Requirements
- Public IPv4 address
- Public DNS name
- Public inbound internet access permitted on port 80/tcp and 443/tcp
Server Recommendations
| Operating System | Ubuntu 22.04 LTS |
| Memory (RAM) | 2+ GB |
| CPU Cores | 2+ |
| Storage | 40+ GB SSD |
| Architectures | amd64, arm64 |
Install your Ubuntu 22.04 server, and then ensure that you can ssh to it.
Note: It is a good security practice to restrict inbound ssh access (port 22/tcp) to your own computer's public IP address. You can check your current public IP address using ifconfig.me.
One of the most common sources of misconfiguration is not opening firewall ports correctly. Please be sure to double check this step.
It may be helpful to use a remote port scanning service to verify that access is permitted. Once your server is fully configured, this service should display the ports as open.
In your cloud provider's console, the following ports should be open to inbound access from the public internet.
- 80/tcp (Used only for TLS certification verification)
- 443/tcp (Used for all application requests)
Note: there is no need to set up TLS or redirect requests from port 80 to 443 because the Caddy web server, included in the Docker compose file, will handle this for you.
If your server is running a Linux firewall managed with ufw, you will also need to open these same ports on the server itself.
$ sudo ufw allow 80/tcp
$ sudo ufw allow 443/tcpFrom your DNS provider's control panel, set up a domain with records pointing to your server.
| Name | Type | Value | TTL |
|---|---|---|---|
example.com |
A |
12.34.56.78 |
600 |
*.example.com |
A |
12.34.56.78 |
600 |
Note:
- Replace
example.comwith your domain name. - Replace
12.34.56.78with your server's IP address. - Some providers may use the
@symbol to represent the root of your domain. - The wildcard record is required when allowing users to create new accounts on your PDS.
On your server, install Docker CE (Community Edition), using the the following instructions. For other operating systems you may reference the official Docker install guides.
Note: All of the following commands should be run on your server via ssh.
sudo apt-get remove docker docker-engine docker.io containerd runcsudo apt-get update
sudo apt-get install \
ca-certificates \
curl \
gnupgsudo 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.gpgecho \
"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/nullsudo apt-get updatesudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginsudo docker run hello-worldsudo mkdir /data
sudo mkdir --parents /data/caddy/data
sudo mkdir --parents /data/caddy/etc/caddyBe sure to replace example.com with your own domain.
cat <<CADDYFILE | sudo tee /data/caddy/etc/caddy/Caddyfile
{
email you@example.com
}
*.example.com, example.com {
tls {
on_demand
}
reverse_proxy http://localhost:3000
}
CADDYFILEYou should fill in the first 5 values, but leave the rest untouched unless you have good reason to change it.
See the PDS environment variables section at the end of this README for explanations of each value
Your PDS will need two secp256k1 private keys provided as hex strings. You can securely generate these keys using openssl with the following command:
Note:
- Replace
example.comwith your domain name.
PDS_HOSTNAME="example.com"
PDS_JWT_SECRET="$(openssl rand --hex 16)"
PDS_ADMIN_PASSWORD="$(openssl rand --hex 16)"
PDS_REPO_SIGNING_KEY_K256_PRIVATE_KEY_HEX="$(openssl ecparam --name secp256k1 --genkey --noout --outform DER | tail --bytes=+8 | head --bytes=32 | xxd --plain --cols 32)"
PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX="$(openssl ecparam --name secp256k1 --genkey --noout --outform DER | tail --bytes=+8 | head --bytes=32 | xxd --plain --cols 32)"
cat <<PDS_CONFIG | sudo tee /data/pds.env
PDS_HOSTNAME=${PDS_HOSTNAME}
PDS_JWT_SECRET=${PDS_JWT_SECRET}
PDS_ADMIN_PASSWORD=${PDS_ADMIN_PASSWORD}
PDS_REPO_SIGNING_KEY_K256_PRIVATE_KEY_HEX=${PDS_REPO_SIGNING_KEY_K256_PRIVATE_KEY_HEX}
PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX=${PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX}
PDS_DB_SQLITE_LOCATION=/data/pds.sqlite
PDS_BLOBSTORE_DISK_LOCATION=/data/blocks
PDS_DID_PLC_URL=https://plc.bsky-sandbox.dev
PDS_BSKY_APP_VIEW_ENDPOINT=https://api.bsky-sandbox.dev
PDS_BSKY_APP_VIEW_DID=did:web:api.bsky-sandbox.dev
PDS_CRAWLERS=https://bgs.bsky-sandbox.dev
PDS_CONFIGDownload the compose.yaml to run your PDS, which includes the following containers:
pdsNode PDS server running on http://localhost:3000caddyHTTP reverse proxy handling TLS and proxying requests to the PDS serverwatchtowerDaemon responsible for auto-updating containers to keep the server secure and federating
curl https://raw.githubusercontent.com/bluesky-social/pds/main/compose.yaml >compose.yamlRun docker compose up to start the three required containers.
sudo docker compose up --wait --detachYou should see output similar to this:
[+] Running 3/3
✔ Container watchtower Healthy 1.1s
✔ Container pds Healthy 1.1s
✔ Container caddy Healthy 1.0s
You can check if your server is online and healthy by requesting the healthcheck endpoint.
curl https://example.com/xrpc/_health
{"version":"0.2.2-beta.2"}You can use the Bluesky app to connect to your server to create an account.
- Download the Bluesky app
- Enter the URL of your PDS (e.g.
https://example.com/) - Create an account
You will need to customize various settings configured through the PDS environment variables. See the below table to find the variables you'll need to set.
| Environment Variable | Value | Should update? | Notes |
|---|---|---|---|
| PDS_HOSTNAME | example.com | ✅ | Public domain you intend to deploy your service at |
| PDS_JWT_SECRET | jwt-secret | ✅ | Use a secure high-entropy string that is 32 characters in length |
| PDS_ADMIN_PASSWORD | admin-pass | ✅ | Use a secure high-entropy string that is 32 characters in length |
| PDS_REPO_SIGNING_KEY_K256_PRIVATE_KEY_HEX | 3ee68... | ✅ | See above Generate Keys section - once set, do not change |
| PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX | e049f... | ✅ | See above Generate Keys section - once set, do not change |
| PDS_DB_SQLITE_LOCATION | /data/pds.sqlite | ❌ | Or use PDS_DB_POSTGRES_URL depending on which database you intend to use |
| PDS_BLOBSTORE_DISK_LOCATION | /data/blocks | ❌ | Only update if you update the mounted volume for your docker image as well |
| PDS_DID_PLC_URL | https://plc.bsky-sandbox.dev | ❌ | Do not adjust if you intend to federate with the Bluesky federation sandbox |
| PDS_BSKY_APP_VIEW_URL | https://api.bsky-sandbox.dev | ❌ | Do not adjust if you intend to federate with the Bluesky federation sandbox |
| PDS_BSKY_APP_VIEW_DID | did:web:api.bsky-sandbox.dev | ❌ | Do not adjust if you intend to federate with the Bluesky federation sandbox |
| PDS_CRAWLERS | https://bgs.bsky-sandbox.dev | ❌ | Do not adjust if you intend to federate with the Bluesky federation sandbox |
There are additional environment variables that can be tweaked depending on how you're running your service. For instance, storing blobs in AWS S3, keys in AWS KMS, or setting up an email service.
Feel free to explore those Here. However, we will not be providing support for more advanced configurations.