···4455## Table of Contents
6677-- [PDS](#pds)
88- - [Table of Contents](#table-of-contents)
99- - [FAQ](#faq)
1010- - [What is Bluesky?](#what-is-bluesky)
1111- - [What is AT Protocol?](#what-is-at-protocol)
1212- - [How can developers get invite codes?](#how-can-developers-get-invite-codes)
1313- - [Where is the code?](#where-is-the-code)
1414- - [What is the current status of federation?](#what-is-the-current-status-of-federation)
1515- - [What should I know about running a PDS in the developer sandbox?](#what-should-i-know-about-running-a-pds-in-the-developer-sandbox)
1616- - [Self-hosting PDS](#self-hosting-pds)
1717- - [Preparation for self-hosting PDS](#preparation-for-self-hosting-pds)
1818- - [Open your cloud firewall for HTTP and HTTPS](#open-your-cloud-firewall-for-http-and-https)
1919- - [Configure DNS for your domain](#configure-dns-for-your-domain)
2020- - [Check that DNS is working as expected](#check-that-dns-is-working-as-expected)
2121- - [Automatic install on Ubuntu 20.04/22.04 or Debian 11/12](#automatic-install-on-ubuntu-20042204-or-debian-1112)
2222- - [Installing manually on Ubuntu 22.04](#installing-manually-on-ubuntu-2204)
2323- - [Open ports on your Linux firewall](#open-ports-on-your-linux-firewall)
2424- - [Install Docker](#install-docker)
2525- - [Uninstall old versions](#uninstall-old-versions)
2626- - [Set up the repository](#set-up-the-repository)
2727- - [Install Docker Engine](#install-docker-engine)
2828- - [Verify Docker Engine installation](#verify-docker-engine-installation)
2929- - [Set up the PDS directory](#set-up-the-pds-directory)
3030- - [Create the Caddyfile](#create-the-caddyfile)
3131- - [Create the PDS env configuration file](#create-the-pds-env-configuration-file)
3232- - [Start the PDS containers](#start-the-pds-containers)
3333- - [Download the Docker compose file](#download-the-docker-compose-file)
3434- - [Create the systemd service](#create-the-systemd-service)
3535- - [Start the service](#start-the-service)
3636- - [Verify your PDS is online](#verify-your-pds-is-online)
3737- - [Obtain your PDS admin password](#obtain-your-pds-admin-password)
3838- - [Generate an invite code for your PDS](#generate-an-invite-code-for-your-pds)
3939- - [Connecting to your server](#connecting-to-your-server)
4040- - [Manually updating your PDS](#manually-updating-your-pds)
4141- - [PDS environment variables](#pds-environment-variables)
77+<!-- markdown-toc -i README.md -->
42899+<!-- toc -->
1010+1111+- [FAQ](#faq)
1212+ * [What is Bluesky?](#what-is-bluesky)
1313+ * [What is AT Protocol?](#what-is-at-protocol)
1414+ * [Where is the code?](#where-is-the-code)
1515+ * [What is the current status of federation?](#what-is-the-current-status-of-federation)
1616+ * [What should I know about running a PDS in the developer sandbox?](#what-should-i-know-about-running-a-pds-in-the-developer-sandbox)
1717+- [Self-hosting PDS](#self-hosting-pds)
1818+ * [Preparation for self-hosting PDS](#preparation-for-self-hosting-pds)
1919+ * [Open your cloud firewall for HTTP and HTTPS](#open-your-cloud-firewall-for-http-and-https)
2020+ * [Configure DNS for your domain](#configure-dns-for-your-domain)
2121+ * [Check that DNS is working as expected](#check-that-dns-is-working-as-expected)
2222+ * [Installer on Ubuntu 20.04/22.04 and Debian 11/12](#installer-on-ubuntu-20042204-and-debian-1112)
2323+ * [Verifying that your PDS is online and accessible](#verifying-that-your-pds-is-online-and-accessible)
2424+ * [Creating an account using pdsadmin](#creating-an-account-using-pdsadmin)
2525+ * [Creating an account using an invite code](#creating-an-account-using-an-invite-code)
2626+ * [Using the Bluesky app with your PDS](#using-the-bluesky-app-with-your-pds)
2727+ * [Updating your PDS](#updating-your-pds)
2828+2929+<!-- tocstop -->
43304431## FAQ
4532···47344835Bluesky is a social media application built on AT Protocol.
49365050-Please visit the [Bluesky website](https://bsky.app/) for more information.
3737+Please visit the [Bluesky website](https://bsky.social/) for more information.
51385239### What is AT Protocol?
5340···55425643Please visit the [AT Protocol docs](https://atproto.com/guides/overview) for additional information.
57445858-### How can developers get invite codes?
5959-6060-There 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.
6161-6245### Where is the code?
63466464-* [Canonical TypeScript code](https://github.com/bluesky-social/atproto)
6565-* [Experimental Go code](https://github.com/bluesky-social/indigo)
4747+* [TypeScript code](https://github.com/bluesky-social/atproto)
4848+* [Go code](https://github.com/bluesky-social/indigo)
66496750### What is the current status of federation?
68516969-We do not currently support PDS federation on the production network but it is now possible to federate in the developer sandbox.
5252+As of Feb, 2024, the AT Protocol data service (PDS) is now open to federation for self-hosters!
5353+5454+✅ Federated domain handles (e.g. `@fda.gov`)
5555+✅ Federated feed generators (custom algorithms)
5656+✅ Federated relays (event firehose)
5757+✅ Federated app views (API service)
5858+✅ Federated data service (PDS hosting)
5959+🟩 Federated moderation (labeling) (coming soon)
70607161### What should I know about running a PDS in the developer sandbox?
6262+6363+Developers may now run self-hosted PDS hosts on the production network!
6464+6565+Though it is still recommended to run experiments in the developer sandbox network.
72667367Read the [SANDBOX.md](https://github.com/bluesky-social/pds/blob/main/SANDBOX.md) for an overview of the sandbox network.
7468···136130137131These should all return your server's public IP.
138132139139-### Automatic install on Ubuntu 20.04/22.04 or Debian 11/12
133133+### Installer on Ubuntu 20.04/22.04 and Debian 11/12
140134141141-On your server via ssh, run the installer script:
135135+On your server via ssh, download the installer script using wget:
142136143137```bash
144138wget https://raw.githubusercontent.com/bluesky-social/pds/main/installer.sh
145139```
146140147147-```bash
148148-sudo bash installer.sh
149149-```
150150-151151-### Installing manually on Ubuntu 22.04
152152-153153-#### Open ports on your Linux firewall
154154-155155-If your server is running a Linux firewall managed with `ufw`, you will need to open these ports:
156156-157157-```bash
158158-$ sudo ufw allow 80/tcp
159159-$ sudo ufw allow 443/tcp
160160-```
161161-162162-#### Install Docker
163163-164164-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](https://docs.docker.com/engine/install/).
165165-166166-**Note:** All of the following commands should be run on your server via ssh.
167167-168168-##### Uninstall old versions
169169-170170-```bash
171171-sudo apt-get remove docker docker-engine docker.io containerd runc
172172-```
173173-174174-##### Set up the repository
175175-176176-```bash
177177-sudo apt-get update
178178-sudo apt-get install \
179179- ca-certificates \
180180- curl \
181181- gnupg
182182-```
183183-184184-```bash
185185-sudo install -m 0755 -d /etc/apt/keyrings
186186-curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
187187-sudo chmod a+r /etc/apt/keyrings/docker.gpg
188188-```
189189-190190-```bash
191191-echo \
192192- "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
193193- "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
194194- sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
195195-```
196196-197197-##### Install Docker Engine
198198-199199-```bash
200200-sudo apt-get update
201201-```
202202-203203-```bash
204204-sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
205205-```
206206-207207-##### Verify Docker Engine installation
208208-209209-```bash
210210-sudo docker run hello-world
211211-```
212212-213213-#### Set up the PDS directory
214214-215215-```bash
216216-sudo mkdir /pds
217217-sudo mkdir --parents /pds/caddy/data
218218-sudo mkdir --parents /pds/caddy/etc/caddy
219219-```
220220-221221-#### Create the Caddyfile
222222-223223-Be sure to replace `example.com` with your own domain.
224224-225225-```bash
226226-cat <<CADDYFILE | sudo tee /pds/caddy/etc/caddy/Caddyfile
227227-{
228228- email you@example.com
229229-}
230230-231231-*.example.com, example.com {
232232- tls {
233233- on_demand
234234- }
235235- reverse_proxy http://localhost:3000
236236-}
237237-CADDYFILE
238238-```
239239-240240-#### Create the PDS env configuration file
241241-242242-You should fill in the first 5 values, but leave the rest untouched unless you have good reason to change it.
243243-244244-See the PDS environment variables section at the end of this README for explanations of each value
245245-246246-Your PDS will need two secp256k1 private keys provided as hex strings. You can securely generate these keys using `openssl` with the following command:
247247-248248-**Note:**
249249-* Replace `example.com` with your domain name.
141141+or download it using curl:
250142251143```bash
252252-PDS_HOSTNAME="example.com"
253253-PDS_JWT_SECRET="$(openssl rand --hex 16)"
254254-PDS_ADMIN_PASSWORD="$(openssl rand --hex 16)"
255255-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)"
256256-257257-cat <<PDS_CONFIG | sudo tee /pds/pds.env
258258-PDS_HOSTNAME=${PDS_HOSTNAME}
259259-PDS_JWT_SECRET=${PDS_JWT_SECRET}
260260-PDS_ADMIN_PASSWORD=${PDS_ADMIN_PASSWORD}
261261-PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX=${PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX}
262262-PDS_DATA_DIRECTORY=/pds
263263-PDS_BLOBSTORE_DISK_LOCATION=/pds/blobs
264264-PDS_DID_PLC_URL=https://plc.directory
265265-PDS_BSKY_APP_VIEW_URL=https://api.bsky.app
266266-PDS_BSKY_APP_VIEW_DID=did:web:api.bsky.app
267267-PDS_CRAWLERS=https://bsky.network
268268-PDS_MOD_SERVICE_URL=https://mod.staging.bsky.dev
269269-PDS_MOD_SERVICE_DID=did:plc:kfiaag3o66qk75mfgwebyyns
270270-PDS_CONFIG
144144+curl https://raw.githubusercontent.com/bluesky-social/pds/main/installer.sh >installer.sh
271145```
272146273273-#### Start the PDS containers
274274-275275-##### Download the Docker compose file
276276-277277-Download the `compose.yaml` to run your PDS, which includes the following containers:
278278-279279-* `pds` Node PDS server running on http://localhost:3000
280280-* `caddy` HTTP reverse proxy handling TLS and proxying requests to the PDS server
281281-* `watchtower` Daemon responsible for auto-updating containers to keep the server secure and federating
147147+And then run the installer using bash:
282148283149```bash
284284-curl https://raw.githubusercontent.com/bluesky-social/pds/main/compose.yaml | sudo tee /pds/compose.yaml
150150+sudo bash installer.sh
285151```
286152287287-##### Create the systemd service
288288-289289-```bash
290290- cat <<SYSTEMD_UNIT_FILE >/etc/systemd/system/pds.service
291291-[Unit]
292292-Description=Bluesky PDS Service
293293-Documentation=https://github.com/bluesky-social/pds
294294-Requires=docker.service
295295-After=docker.service
296296-297297-[Service]
298298-Type=oneshot
299299-RemainAfterExit=yes
300300-WorkingDirectory=/pds
301301-ExecStart=/usr/bin/docker compose --file /pds/compose.yaml up --detach
302302-ExecStop=/usr/bin/docker compose --file /pds/compose.yaml down
303303-304304-[Install]
305305-WantedBy=default.target
306306-SYSTEMD_UNIT_FILE
307307-```
153153+### Verifying that your PDS is online and accessible
308154309309-##### Start the service
155155+You can check if your server is online and healthy by requesting the healthcheck endpoint.
310156311311-**Reload the systemd daemon to create the new service:**
312312-```bash
313313-sudo systemctl daemon-reload
314314-```
157157+You can visit `https://example.com/xrpc/_health` in your browser. You should see a JSON response with a version.
315158316316-**Enable the systemd service:**
317317-```bash
318318-sudo systemctl enable pds
319319-```
159159+For example:
320160321321-**Start the pds systemd service:**
322322-```bash
323323-sudo systemctl start pds
324161```
325325-326326-**Ensure that containers are running**
327327-328328-There should be a caddy, pds, and watchtower container running.
329329-330330-```bash
331331-sudo systemctl status pds
332332-```
333333-334334-```bash
335335-sudo docker ps
336336-```
337337-338338-### Verify your PDS is online
339339-340340-You can check if your server is online and healthy by requesting the healthcheck endpoint.
341341-342342-```bash
343343-curl https://example.com/xrpc/_health
344162{"version":"0.2.2-beta.2"}
345163```
346164347347-### Obtain your PDS admin password
165165+### Creating an account using pdsadmin
348166349349-Your PDS admin password should be in your `pds.env` file if you used the installer script.
350350-351351-**For example:**
167167+Using ssh on your server, use `pdsadmin` to create an account if you haven't already.
352168353169```bash
354354-$ source /pds/pds.env
355355-$ echo $PDS_ADMIN_PASSWORD
356356-a7b5970b6a5077bb41fc68a26d30adda
170170+sudo pdsadmin account create
357171```
358358-### Generate an invite code for your PDS
359172360360-By default, your PDS will require an invite code to create an account.
173173+### Creating an account using an invite code
361174362362-You can generate a new invite code with the following command:
175175+Using ssh on your server, use `pdsadmin` to create an invite code.
363176364177```bash
365365-PDS_HOSTNAME="example.com"
366366-PDS_ADMIN_PASSWORD="<YOUR PDS ADMIN PASSWORD>"
367367-368368-curl --silent \
369369- --show-error \
370370- --request POST \
371371- --user "admin:${PDS_ADMIN_PASSWORD}" \
372372- --header "Content-Type: application/json" \
373373- --data '{"useCount": 1}' \
374374- https://${PDS_HOSTNAME}/xrpc/com.atproto.server.createInviteCode
178178+sudo pdsadmin create-invite-code
375179```
376180377377-**Note:** the `useCount` field specifies how many times an invite code can be used
181181+When creating an account using the app, enter this invite code.
378182379379-### Connecting to your server
183183+### Using the Bluesky app with your PDS
380184381381-You can use the Bluesky app to connect to your server to create an account.
185185+You can use the Bluesky app to connect to your PDS.
3821863831871. Get the Bluesky app
384384- * [Bluesky for Web (sandbox)](https://app.bsky-sandbox.dev/)
188188+ * [Bluesky for Web](https://bsky.app/)
385189 * [Bluesky for iPhone](https://apps.apple.com/us/app/bluesky-social/id6444370199)
386190 * [Bluesky for Android](https://play.google.com/store/apps/details?id=xyz.blueskyweb.app)
3871911. Enter the URL of your PDS (e.g. `https://example.com/`)
388388-1. Create an account using the generated invite code
389389-1. Create a post
390192391391-_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._
392392-393393-Checkout [SANDBOX.md](./SANDBOX.md) for an overview of participating in the sandbox network.
394394-395395-### Manually updating your PDS
193193+_Note: because the subdomain TLS certificate is created on-demand, 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._
396194397397-If 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.
195195+### Updating your PDS
398196399399-**Pull the latest PDS container image:**
400400-```bash
401401-sudo docker pull ghcr.io/bluesky-social/pds:latest
402402-```
197197+It is recommended that you keep your PDS up to date with new versions, otherwise things may break. You can use the `pdsadmin` tool to update your PDS.
403198404404-**Restart PDS with the new container image:**
405199```bash
406406-sudo systemctl restart pds
200200+sudo pdsadmin update
407201```
408408-409409-## PDS environment variables
410410-411411-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.
412412-413413-| Environment Variable | Value | Should update? | Notes |
414414-| ----------------------------------------- | ---------------------------- | -------------- | --------------------------------------------------------------------------- |
415415-| PDS_HOSTNAME | example.com | ✅ | Public domain you intend to deploy your service at |
416416-| PDS_JWT_SECRET | jwt-secret | ✅ | Use a secure high-entropy string that is 32 characters in length |
417417-| PDS_ADMIN_PASSWORD | admin-pass | ✅ | Use a secure high-entropy string that is 32 characters in length |
418418-| PDS_REPO_SIGNING_KEY_K256_PRIVATE_KEY_HEX | 3ee68... | ✅ | See above Generate Keys section - once set, do not change |
419419-| PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX | e049f... | ✅ | See above Generate Keys section - once set, do not change |
420420-| PDS_DB_SQLITE_LOCATION | /pds/pds.sqlite | ❌ | Or use `PDS_DB_POSTGRES_URL` depending on which database you intend to use |
421421-| PDS_BLOBSTORE_DISK_LOCATION | /pds/blocks | ❌ | Only update if you update the mounted volume for your docker image as well |
422422-| PDS_DID_PLC_URL | https://plc.bsky-sandbox.dev | ❌ | Do not adjust if you intend to federate with the Bluesky federation sandbox |
423423-| PDS_BSKY_APP_VIEW_URL | https://api.bsky-sandbox.dev | ❌ | Do not adjust if you intend to federate with the Bluesky federation sandbox |
424424-| PDS_BSKY_APP_VIEW_DID | did:web:api.bsky-sandbox.dev | ❌ | Do not adjust if you intend to federate with the Bluesky federation sandbox |
425425-| PDS_CRAWLERS | https://bgs.bsky-sandbox.dev | ❌ | Do not adjust if you intend to federate with the Bluesky federation sandbox |
426426-427427-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.
428428-429429-Feel free to explore those [Here](https://github.com/bluesky-social/atproto/blob/simplify-pds/packages/pds/src/config/env.ts). However, we will not be providing support for more advanced configurations.