Official bluesky-pds projectGitHub - bluesky-social/pds
Image on ForgejoForgejo
Image on DockerhubDockerhub
Image SourceForgejo
Issue TrackerGitHub - gravityfargo/bluesky-pds-docker
docker pull code.modernleft.org/gravityfargo/bluesky-pds:latest

A self-contained Docker image for the Bluesky PDS (Personal Data Server) for use with Traefik. This image is pinned to v0.4.74.

It is required to run the instance behind a proxy (like Traefik) to generate SSL certificates. This will not work otherwise. The standard pds install includes caddy to handle this. A wildcard DNS assignment along with a wildcard SSL certificate is required. I use Cloudflare for this, see the screenshot below.

This is not intended for production, and I am not responsible for any data loss or security issues. This is a personal project, and I am not affiliated with Bluesky.

Custom Domain

You do not need to setup a PDS to have a custom domain in your username. Bluesky provides documentation for DNS setup.

Data Warning

Before changing images, upgrading, or any other modification always backup your data!

Requirements

I haven’t verified these are the minimum requirements, but they are what I found to be necessary during development. I probably had some dependencies installed already.

Manjaro/Arch
sudo pacman -S jq
# Debian/Ubuntu
sudo apt install make xxd

Setup

Generate secrets and add them to .env file. See example.env as an example.

# Generate secret environment variables
echo PDS_ADMIN_PASSWORD: $(openssl rand --hex 16)
 
echo PDS_JWT_SECRET: $(openssl rand --hex 16)
 
echo 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)

Docker Compose Setup

Full list of additional Environment Variables provided by bluesky upstream can be found in the packages/pds/src/config/env.ts

If you’d like to learn more about my docker setup, head over to Docker - Getting Started

By default, the image uses 1000:1000 as the UID:GID for the user. This can be changed by setting the PUID and PGID environment variables.

Warning

The compose element hostname must be the same value as PDS_HOSTNAME.

traefik

docker-compose.yml
# Traefik Proxy
services:
  bluesky-pds:
    container_name: bluesky-pds
    image: code.modernleft.org/gravityfargo/bluesky-pds:latest
    hostname: example.com
    extra_hosts:
      - "example.com:0.0.0.0" # domain:external_ip
    networks:
      - proxy
    environment:
      # Define variables here or in a .env file
      PDS_JWT_SECRET: ...
      PDS_ADMIN_PASSWORD: ...
      PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX: ...
      PDS_HOSTNAME: example.com
      PDS_EMAIL_SMTP_URL: smtps://resend:<your api key here>@smtp.resend.com:465/
      PDS_EMAIL_FROM_ADDRESS: admin@example.com
      PUID: 1000
      PGID: 1001
    volumes:
      - ./bluesky-pds:/pds
    labels:
      traefik.enable: "true"
      traefik.http.routers.bluesky-pds-insecure.entrypoints: http
      traefik.http.routers.bluesky-pds-insecure.rule: HostRegexp(`^.+\.example\.com$`) || Host(`example.com`)
      # traefik.http.routers.bluesky-pds-insecure.middlewares: BlueskyHeaders@file
      traefik.http.routers.bluesky-pds-secure.entrypoints: https
      traefik.http.routers.bluesky-pds-secure.rule: HostRegexp(`^.+\.example\.com$`) || Host(`example.com`)
      traefik.http.routers.bluesky-pds-secure.tls: "true"
      traefik.http.services.bluesky-pds.loadbalancer.server.scheme: http
      traefik.http.services.bluesky-pds.loadbalancer.server.port: 3000
      # traefik.http.routers.bluesky-pds-secure.middlewares: BlueskyHeaders@file
Link to original

Optionally, you can use the BlueskyHeaders middle ware to set headers.


I do not run this, but it should be possible.

standalone

docker-compose.yml
# Standalone, you'll need to add a proxy in front of this with SSL.
services:
  bluesky-pds:
    container_name: bluesky-pds
    hostname: example.com
    extra_hosts:
      - "example.com:0.0.0.0" # domain:external_ip
    image: code.modernleft.org/gravityfargo/bluesky-pds:latest
    environment:
      # Define variables here or in a .env file
      PDS_JWT_SECRET: ...
      PDS_ADMIN_PASSWORD: ...
      PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX: ...
      PDS_HOSTNAME: example.com
      PDS_EMAIL_SMTP_URL: ""
      PDS_EMAIL_FROM_ADDRESS: ""
      PUID: 1000
      PGID: 1001
    volumes:
      - ./bluesky-pds:/pds
Link to original

Unraid

While I do not use Unraid, a user on Reddit has added this project to the Unraid App store. I won’t be providing any meaningful support it.

Unraid does not include the xxd package. You’ll need another Linux machine for that. I made some instructions for using a temporary alpine container if that helps.

Running Commands

Nothing has changed in this department, other than not needing sudo. The commands are the same as the upstream project. Such as

docker exec -it bluesky-pds bash
pdsadmin account create
pdsadmin create-invite-code

Update Warning

Do not under any circumstances update the image using pdsadmin update. I have not tested this, and it may break the image. Submit an issue to my repository requesting an update, and I will update this image and pin the pds to the new version.

Cloudflare DNS

Cloudflare

Cloudflare

I am moving away from their services after their many controversies. I wont be providing support for any issues that may arise. If you are a CF user and encounter issues, disable DNS proxy and restart the service.

Link to original

DEPRECIATED: After various testing, I have figured out two things.

  1. In order for email verification to work, you cannot have the DNS Proxy enabled or AAAA records active.
  2. After you have verified emails, and do not intend to use the email feature, you can re-enable the DNS Proxy and AAAA records.

SMTP

I use protonmail for my SMTP server. You can use any SMTP server you like, but I figured I’d share this information. These are the environment variables I use.

PDS_EMAIL_SMTP_URL: smtp://user@example.com:TOKEN@smtp.protonmail.ch:587/
PDS_EMAIL_FROM_ADDRESS: user@example.com