Mirror from bluesky-social/pds
at update-versions 430 lines 17 kB view raw view rendered
1# PDS 2 3Welcome 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. 4 5## Table of Contents 6 7* [FAQ](#faq) 8 * [What is Bluesky?](#what-is-bluesky) 9 * [What is AT Protocol?](#what-is-at-protocol) 10 * [How can developers get invite codes?](#how-can-developers-get-invite-codes) 11 * [Where is the code?](#where-is-the-code) 12 * [What is the current status of federation?](#what-is-the-current-status-of-federation) 13 * [What should I know about running a PDS in the developer sandbox?](#what-should-i-know-about-running-a-pds-in-the-developer-sandbox) 14* [Self\-hosting PDS](#self-hosting-pds) 15 * [Preparation for self\-hosting PDS](#preparation-for-self-hosting-pds) 16 * [Open your cloud firewall for HTTP and HTTPS](#open-your-cloud-firewall-for-http-and-https) 17 * [Configure DNS for your domain](#configure-dns-for-your-domain) 18 * [Check that DNS is working as expected](#check-that-dns-is-working-as-expected) 19 * [Automatic install on Ubuntu 20\.04/22\.04 or Debian 11/12](#automatic-install-on-ubuntu-20042204-or-debian-1112) 20 * [Installing manually on Ubuntu 22\.04](#installing-manually-on-ubuntu-2204) 21 * [Open ports on your Linux firewall](#open-ports-on-your-linux-firewall) 22 * [Install Docker](#install-docker) 23 * [Uninstall old versions](#uninstall-old-versions) 24 * [Set up the repository](#set-up-the-repository) 25 * [Install Docker Engine](#install-docker-engine) 26 * [Verify Docker Engine installation](#verify-docker-engine-installation) 27 * [Set up the PDS directory](#set-up-the-pds-directory) 28 * [Create the Caddyfile](#create-the-caddyfile) 29 * [Create the PDS env configuration file](#create-the-pds-env-configuration-file) 30 * [Start the PDS containers](#start-the-pds-containers) 31 * [Download the Docker compose file](#download-the-docker-compose-file) 32 * [Create the systemd service](#create-the-systemd-service) 33 * [Start the service](#start-the-service) 34 * [Verify your PDS is online](#verify-your-pds-is-online) 35 * [Obtain your PDS admin password](#obtain-your-pds-admin-password) 36 * [Generate an invite code for your PDS](#generate-an-invite-code-for-your-pds) 37 * [Connecting to your server](#connecting-to-your-server) 38 * [Manually updating your PDS](#manually-updating-your-pds) 39* [PDS environment variables](#pds-environment-variables) 40 41 42## FAQ 43 44### What is Bluesky? 45 46Bluesky is a social media application built on AT Protocol. 47 48Please visit the [Bluesky website](https://bsky.app/) for more information. 49 50### What is AT Protocol? 51 52The Authenticated Transfer Protocol, aka atproto, is a protocol for large-scale distributed social applications. 53 54Please visit the [AT Protocol docs](https://atproto.com/guides/overview) for additional information. 55 56### How can developers get invite codes? 57 58There is no invite required to join the sandbox network. Simply set up your own PDS and generate your own invite codes to create accounts. If you desire an account on the production network (on the official Bluesky PDS) please check out the [Bluesky Developer Waitlist](https://docs.google.com/forms/d/e/1FAIpQLSfCuguykw3HaPxIZMJQKRu8_-vsRew90NALVTDOjCSPDmsGNg/viewform) which prioritizes access for developers wanting to build software on atproto. 59 60### Where is the code? 61 62* [Canonical TypeScript code](https://github.com/bluesky-social/atproto) 63* [Experimental Go code](https://github.com/bluesky-social/indigo) 64 65### What is the current status of federation? 66 67We do not currently support PDS federation on the production network but it is now possible to federate in the developer sandbox. 68 69### What should I know about running a PDS in the developer sandbox? 70 71Read the [SANDBOX.md](https://github.com/bluesky-social/pds/blob/main/SANDBOX.md) for an overview of the sandbox network. 72 73## Self-hosting PDS 74 75Self-hosting a Bluesky PDS means running your own Personal Data Server that is capable of federating with the wider Bluesky social network. 76 77### Preparation for self-hosting PDS 78 79Launch a server on any cloud provider, [Digital Ocean](https://digitalocean.com/) and [Vultr](https://vultr.com/) are two popular choices. 80 81Ensure that you can ssh to your server and have root access. 82 83**Server Requirements** 84* Public IPv4 address 85* Public DNS name 86* Public inbound internet access permitted on port 80/tcp and 443/tcp 87 88**Server Recommendations** 89| | | 90| ---------------- | ------------ | 91| Operating System | Ubuntu 22.04 | 92| Memory (RAM) | 2+ GB | 93| CPU Cores | 2+ | 94| Storage | 40+ GB SSD | 95| Architectures | amd64, arm64 | 96 97**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](https://ifconfig.me/). 98 99### Open your cloud firewall for HTTP and HTTPS 100 101One of the most common sources of misconfiguration is not opening firewall ports correctly. Please be sure to double check this step. 102 103In your cloud provider's console, the following ports should be open to inbound access from the public internet. 104 105* 80/tcp (Used only for TLS certification verification) 106* 443/tcp (Used for all application requests) 107 108**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. 109 110### Configure DNS for your domain 111 112From your DNS provider's control panel, set up a domain with records pointing to your server. 113 114| Name | Type | Value | TTL | 115| --------------- | ---- | ------------- | --- | 116| `example.com` | `A` | `12.34.56.78` | 600 | 117| `*.example.com` | `A` | `12.34.56.78` | 600 | 118 119**Note:** 120* Replace `example.com` with your domain name. 121* Replace `12.34.56.78` with your server's IP address. 122* Some providers may use the `@` symbol to represent the root of your domain. 123* The wildcard record is required when allowing users to create new accounts on your PDS. 124* The TTL can be anything but 600 (10 minutes) is reasonable 125 126### Check that DNS is working as expected 127 128Use a service like [DNS Checker](https://dnschecker.org/) to verify that you can resolve domain names. 129 130Examples to check (record type `A`): 131* `example.com` 132* `random.example.com` 133* `test123.example.com` 134 135These should all return your server's public IP. 136 137### Automatic install on Ubuntu 20.04/22.04 or Debian 11/12 138 139On your server via ssh, run the installer script: 140 141```bash 142wget https://raw.githubusercontent.com/bluesky-social/pds/main/installer.sh 143``` 144 145```bash 146sudo bash installer.sh 147``` 148 149### Installing manually on Ubuntu 22.04 150 151#### Open ports on your Linux firewall 152 153If your server is running a Linux firewall managed with `ufw`, you will need to open these ports: 154 155```bash 156$ sudo ufw allow 80/tcp 157$ sudo ufw allow 443/tcp 158``` 159 160#### Install Docker 161 162On your server, install Docker CE (Community Edition), using the the following instructions. For other operating systems you may reference the [official Docker install guides](https://docs.docker.com/engine/install/). 163 164**Note:** All of the following commands should be run on your server via ssh. 165 166##### Uninstall old versions 167 168```bash 169sudo apt-get remove docker docker-engine docker.io containerd runc 170``` 171 172##### Set up the repository 173 174```bash 175sudo apt-get update 176sudo apt-get install \ 177 ca-certificates \ 178 curl \ 179 gnupg 180``` 181 182```bash 183sudo install -m 0755 -d /etc/apt/keyrings 184curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg 185sudo chmod a+r /etc/apt/keyrings/docker.gpg 186``` 187 188```bash 189echo \ 190 "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ 191 "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ 192 sudo tee /etc/apt/sources.list.d/docker.list > /dev/null 193``` 194 195##### Install Docker Engine 196 197```bash 198sudo apt-get update 199``` 200 201```bash 202sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin 203``` 204 205##### Verify Docker Engine installation 206 207```bash 208sudo docker run hello-world 209``` 210 211#### Set up the PDS directory 212 213```bash 214sudo mkdir /pds 215sudo mkdir --parents /pds/caddy/data 216sudo mkdir --parents /pds/caddy/etc/caddy 217``` 218 219#### Create the Caddyfile 220 221Be sure to replace `example.com` with your own domain. 222 223```bash 224cat <<CADDYFILE | sudo tee /pds/caddy/etc/caddy/Caddyfile 225{ 226 email you@example.com 227 on_demand_tls { 228 ask http://localhost:3000 229 } 230} 231 232*.example.com, example.com { 233 tls { 234 on_demand 235 } 236 reverse_proxy http://localhost:3000 237} 238CADDYFILE 239``` 240 241#### Create the PDS env configuration file 242 243You should fill in the first 5 values, but leave the rest untouched unless you have good reason to change it. 244 245See the PDS environment variables section at the end of this README for explanations of each value 246 247Your PDS will need two secp256k1 private keys provided as hex strings. You can securely generate these keys using `openssl` with the following command: 248 249**Note:** 250* Replace `example.com` with your domain name. 251 252```bash 253PDS_HOSTNAME="example.com" 254PDS_JWT_SECRET="$(openssl rand --hex 16)" 255PDS_ADMIN_PASSWORD="$(openssl rand --hex 16)" 256PDS_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)" 257PDS_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)" 258 259cat <<PDS_CONFIG | sudo tee /pds/pds.env 260PDS_HOSTNAME=${PDS_HOSTNAME} 261PDS_JWT_SECRET=${PDS_JWT_SECRET} 262PDS_ADMIN_PASSWORD=${PDS_ADMIN_PASSWORD} 263PDS_REPO_SIGNING_KEY_K256_PRIVATE_KEY_HEX=${PDS_REPO_SIGNING_KEY_K256_PRIVATE_KEY_HEX} 264PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX=${PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX} 265PDS_DB_SQLITE_LOCATION=/pds/pds.sqlite 266PDS_BLOBSTORE_DISK_LOCATION=/pds/blocks 267PDS_DID_PLC_URL=https://plc.bsky-sandbox.dev 268PDS_BSKY_APP_VIEW_URL=https://api.bsky-sandbox.dev 269PDS_BSKY_APP_VIEW_DID=did:web:api.bsky-sandbox.dev 270PDS_CRAWLERS=https://bgs.bsky-sandbox.dev 271PDS_CONFIG 272``` 273 274#### Start the PDS containers 275 276##### Download the Docker compose file 277 278Download the `compose.yaml` to run your PDS, which includes the following containers: 279 280* `pds` Node PDS server running on http://localhost:3000 281* `caddy` HTTP reverse proxy handling TLS and proxying requests to the PDS server 282* `watchtower` Daemon responsible for auto-updating containers to keep the server secure and federating 283 284```bash 285curl https://raw.githubusercontent.com/bluesky-social/pds/main/compose.yaml | sudo tee /pds/compose.yaml 286``` 287 288##### Create the systemd service 289 290```bash 291cat <<SYSTEMD_UNIT_FILE | sudo tee /etc/systemd/system/pds.service 292[Unit] 293Description=Bluesky PDS Service 294Documentation=https://github.com/bluesky-social/pds 295Requires=docker.service 296After=docker.service 297 298[Service] 299Type=oneshot 300RemainAfterExit=yes 301WorkingDirectory=/pds 302ExecStart=/usr/bin/docker compose --file /pds/compose.yaml up --detach 303ExecStop=/usr/bin/docker compose --file /pds/compose.yaml down 304 305[Install] 306WantedBy=default.target 307SYSTEMD_UNIT_FILE 308``` 309 310##### Start the service 311 312**Reload the systemd daemon to create the new service:** 313```bash 314sudo systemctl daemon-reload 315``` 316 317**Enable the systemd service:** 318```bash 319sudo systemctl enable pds 320``` 321 322**Start the pds systemd service:** 323```bash 324sudo systemctl start pds 325``` 326 327**Ensure that containers are running** 328 329There should be a caddy, pds, and watchtower container running. 330 331```bash 332sudo systemctl status pds 333``` 334 335```bash 336sudo docker ps 337``` 338 339### Verify your PDS is online 340 341You can check if your server is online and healthy by requesting the healthcheck endpoint. 342 343```bash 344curl https://example.com/xrpc/_health 345{"version":"0.2.2-beta.2"} 346``` 347 348### Obtain your PDS admin password 349 350Your PDS admin password should be in your `pds.env` file if you used the installer script. 351 352**For example:** 353 354```bash 355$ source /pds/pds.env 356$ echo $PDS_ADMIN_PASSWORD 357a7b5970b6a5077bb41fc68a26d30adda 358``` 359### Generate an invite code for your PDS 360 361By default, your PDS will require an invite code to create an account. 362 363You can generate a new invite code with the following command: 364 365```bash 366PDS_HOSTNAME="example.com" 367PDS_ADMIN_PASSWORD="<YOUR PDS ADMIN PASSWORD>" 368 369curl --silent \ 370 --show-error \ 371 --request POST \ 372 --user "admin:${PDS_ADMIN_PASSWORD}" \ 373 --header "Content-Type: application/json" \ 374 --data '{"useCount": 1}' \ 375 https://${PDS_HOSTNAME}/xrpc/com.atproto.server.createInviteCode 376``` 377 378**Note:** the `useCount` field specifies how many times an invite code can be used 379 380### Connecting to your server 381 382You can use the Bluesky app to connect to your server to create an account. 383 3841. Get the Bluesky app 385 * [Bluesky for Web (sandbox)](https://app.bsky-sandbox.dev/) 386 * [Bluesky for iPhone](https://apps.apple.com/us/app/bluesky-social/id6444370199) 387 * [Bluesky for Android](https://play.google.com/store/apps/details?id=xyz.blueskyweb.app) 3881. Enter the URL of your PDS (e.g. `https://example.com/`) 3891. Create an account using the generated invite code 3901. Create a post 391 392_Note: because we use on-the-fly TLS certs, it may take 10-30s for your handle to be accessible. If you aren't seeing your first post/profile, wait 30s and try to make another post._ 393 394Checkout [SANDBOX.md](./SANDBOX.md) for an overview of participating in the sandbox network. 395 396### Manually updating your PDS 397 398If you use use Docker `compose.yaml` file in this repo, your PDS will automatically update nightly. To manually update to the latest version use the following commands. 399 400**Pull the latest PDS container image:** 401```bash 402sudo docker pull ghcr.io/bluesky-social/pds:latest 403``` 404 405**Restart PDS with the new container image:** 406```bash 407sudo systemctl restart pds 408``` 409 410## PDS environment variables 411 412You 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. 413 414| Environment Variable | Value | Should update? | Notes | 415| ----------------------------------------- | ---------------------------- | -------------- | --------------------------------------------------------------------------- | 416| PDS_HOSTNAME | example.com | ✅ | Public domain you intend to deploy your service at | 417| PDS_JWT_SECRET | jwt-secret | ✅ | Use a secure high-entropy string that is 32 characters in length | 418| PDS_ADMIN_PASSWORD | admin-pass | ✅ | Use a secure high-entropy string that is 32 characters in length | 419| PDS_REPO_SIGNING_KEY_K256_PRIVATE_KEY_HEX | 3ee68... | ✅ | See above Generate Keys section - once set, do not change | 420| PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX | e049f... | ✅ | See above Generate Keys section - once set, do not change | 421| PDS_DB_SQLITE_LOCATION | /pds/pds.sqlite | ❌ | Or use `PDS_DB_POSTGRES_URL` depending on which database you intend to use | 422| PDS_BLOBSTORE_DISK_LOCATION | /pds/blocks | ❌ | Only update if you update the mounted volume for your docker image as well | 423| PDS_DID_PLC_URL | https://plc.bsky-sandbox.dev | ❌ | Do not adjust if you intend to federate with the Bluesky federation sandbox | 424| PDS_BSKY_APP_VIEW_URL | https://api.bsky-sandbox.dev | ❌ | Do not adjust if you intend to federate with the Bluesky federation sandbox | 425| PDS_BSKY_APP_VIEW_DID | did:web:api.bsky-sandbox.dev | ❌ | Do not adjust if you intend to federate with the Bluesky federation sandbox | 426| PDS_CRAWLERS | https://bgs.bsky-sandbox.dev | ❌ | Do not adjust if you intend to federate with the Bluesky federation sandbox | 427 428There 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. 429 430Feel free to explore those [Here](https://github.com/bluesky-social/atproto/blob/main/packages/pds/src/config/env.ts). However, we will not be providing support for more advanced configurations.