Bluesky PDS Manual Install
Introduction
I have a functional Docker system with routing provided by Traefik v3. Because of this, I didn’t want to spin up a dedicated Ubuntu VM just for Bluesky. These are the bare minimum steps I needed to get the PDS container running in my environment.
Requirements
- OpenSSL - Used to generate secrets
- SMTP Provider - I like Postmark; They give you 100 E-mails/month free.
Files
generate_envs.sh
The names and values in generate_envs.sh were sourced from Bluesky’s PDS installer script and writes the following variables to pds.env.
My script is best reasonable effort, lol.
# Generated
PDS_HOSTNAME=
PDS_JWT_SECRET=
PDS_ADMIN_PASSWORD=
PDS_EMAIL_SMTP_URL=
PDS_EMAIL_FROM_ADDRESS=
PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX=
# Defaults
PDS_DATA_DIRECTORY=/var/lib/pds
PDS_BLOBSTORE_DISK_LOCATION=/var/lib/pds/blocks
PDS_BLOB_UPLOAD_LIMIT=52428800
PDS_DID_PLC_URL=https://plc.directory
PDS_BSKY_APP_VIEW_URL=https://api.bsky.app
PDS_BSKY_APP_VIEW_DID=did:web:api.bsky.app
PDS_REPORT_SERVICE_URL=https://mod.bsky.app
PDS_REPORT_SERVICE_DID=did:plc:ar7c4by46qjdydhdevvrndac
PDS_CRAWLERS=https://bsky.network
LOG_ENABLED=truedocker-compose.yml
You will need to update this compose file to meet the needs of your own setup.
services:
pds:
image: ghcr.io/bluesky-social/pds:latest
container_name: pds
restart: unless-stopped
env_file:
- pds.env
volumes:
- pds_data:/var/lib/pds
- pds_blocks:/var/lib/pds/blocks
networks:
- traefik_traffic
labels:
- "traefik.enable=true"
# This mess is required *only* if you are doing other stuff with the domain
- "traefik.http.routers.pds.rule=(Host(`example.com`) || HostRegexp(`^.+\\.example\\.com$`)) && (PathPrefix(`/xrpc`) || PathPrefix(`/.well-known/atproto-did`))"
- "traefik.http.routers.pds.entrypoints=websecure"
- "traefik.http.routers.pds.tls=true"
- "traefik.http.routers.pds.tls.certresolver=letsencrypt"
- "traefik.http.routers.pds.service=pds-service"
- "traefik.http.services.pds-service.loadbalancer.server.port=3000"
- "traefik.http.services.pds-service.loadbalancer.healthcheck.path=/xrpc/_health"
volumes:
pds_data:
pds_blocks:
networks:
traefik_traffic:
external: trueRun this mess
Both your edited docker-compose.yml and the generated pds.env files should be placed in an appropriately named folder, I suggest “bluesky”.
$ cd ~/bluesky
$ docker compose up -dCreate an account
The easiest way to create your account is with an invite. You will need a copy of the pds.env file and export the PDS_ENV_FILE variable containing the path to it. If you can do this in your compose folder, that’ll work fine.
$ export PDS_ENV_FILE="~/bluesky/pds.env"
$ cd ~/bluesky
$ curl https://raw.githubusercontent.com/bluesky-social/pds/refs/heads/main/pdsadmin/create-invite-code.sh -o create-invite-code.sh
$ sh create-invite-code.shNotes
- If you get a Server Error 500 when validating your E-mail, make sure you have the correct SMTP details for your provider Bluesky PDS SMTP documentation.
- The default setup assumes users will by default be given a subdomain. Create a wildcard DNS entry to accommodate this.
- Your users will automatically be verified by the atproto .well-known provided by the PDS. If a user wants to change their domain, they can do so via the TXT record method.
- The Bluesky Debug Page was super helpful.
- Thanks to @ameo.dev for his Note that got me going!