A self contained Bluesky PDS
Find a file
2024-12-10 17:29:05 +00:00
.dockerignore init 2024-12-03 17:47:58 -05:00
.gitignore bump 2024-12-03 17:50:09 -05:00
docker-compose.yaml using traefik and building added 2024-12-10 17:27:55 +00:00
Dockerfile add bsdextrautils, combined some run stages 2024-12-03 17:49:19 -05:00
entrypoint.sh dynamically create the pds.env file 2024-12-03 17:48:54 -05:00
example.env added an example 2024-12-10 17:28:20 +00:00
LICENSE add license 2024-12-02 20:35:09 -05:00
Makefile removed "build" and added variables to the dev .env 2024-12-10 17:29:05 +00:00
README.md Added link to main PDS repo 2024-12-04 21:54:14 -05:00

bluesky-pds-docker

A self-contained Docker image for the Bluesky PDS (Personal Data Server) . 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.

I can confirm it works behind Cloudflare's DNS Proxy with Full (strict).

Deployment

# 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)

# pull and run the container
docker pull forgejo.gravityfargo.dev/gravityfargo/bluesky-pds
docker-compose up -d

# Create an account
docker exec -it bluesky-pds bash
pdsadmin account create
pdsadmin account list
pdsadmin request-crawl bsky.network # useful if you re-deploy the same instance multiple times

In your browser:

Example Docker Compose

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

services:
  bluesky-pds:
    container_name: bluesky-pds
    image: forgejo.gravityfargo.dev/gravityfargo/bluesky-pds
    environment:
      PDS_JWT_SECRET: ...
      PDS_ADMIN_PASSWORD: ...
      PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX: ...
      PDS_HOSTNAME: ...
      PDS_EMAIL_SMTP_URL: ""
      PDS_EMAIL_FROM_ADDRESS: ""
    volumes:
      - ./bluesky-pds:/pds

Example Docker Compose with Traefik

services:
  bluesky-pds:
    container_name: bluesky-pds
    image: forgejo.gravityfargo.dev/gravityfargo/bluesky-pds:latest
    networks:
      - proxy
    env_file:
      PDS_ADMIN_PASSWORD: ""
      PDS_JWT_SECRET: ""
      PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX: ""
      PDS_HOSTNAME: example.com
      PDS_EMAIL_SMTP_URL: ""
      PDS_EMAIL_FROM_ADDRESS: ""
    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.social`)
      traefik.http.routers.bluesky-pds-secure.entrypoints: https
      traefik.http.routers.bluesky-pds-secure.rule: HostRegexp(`^.+\.example\.com$`) || Host(`example.social`)
      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
      traefik.http.routers.bluesky-pds-insecure.middlewares: BlueskyHeaders@file

Middleware

I think file configs are cleaner than having a billion labels.

http:
  middlewares:
    BlueskyHeaders:
      headers:
        accessControlAllowMethods:
          - GET
          - OPTIONS
          - PUT
          - POST
          - DELETE
        accessControlAllowHeaders: "*"
        accessControlAllowOriginList: "*"
        addVaryHeader: true
        stsSeconds: 63072000

Development Notes

pamac install jq