rtw.run pds

0 1 pulls 5 Updated 10h
linux/amd64 linux/arm64 Multi-arch
docker pull atcr.io/rtw.run/pds:latest
Image Size Layers
478.4 MB 85
Pushed 10h
Vulnerabilities
Loading...
Pulls
1 total
Last pull 10h

pds

ATProto Personal Data Server (the Bluesky reference PDS, @atproto/pds) for rtw.run.
Hosts ATProto accounts on pds.rtw.run (handles like user.pds.rtw.run) and federates publicly via the bsky.network relay. Serves the ATProto XRPC API on port 3000.

The PDS reads all configuration from PDS_* environment variables. It never generates or persists secrets and this image ships none; the container runs as uid 1000 and persists all account data under /data (mount a volume there).

Secrets

Three secrets are required in production (set via systemd EnvironmentFile= or -e, never baked into the image):

Var Example generation
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
PDS_JWT_SECRET openssl rand --hex 16
PDS_ADMIN_PASSWORD openssl rand --hex 16

ENV=development generates throwaway secrets at startup and logs a warning — the instance is ephemeral and its data is not recoverable. Production (ENV unset) fails fast if any secret is missing.

Running the container

Multiarch image (amd64 + arm64): atcr.io/rtw.run/pds:latest

mkdir -p /srv/rtw/pds

podman run -d --name pds --userns=keep-id \
  -p 127.0.0.1:3000:3000 \
  -v /srv/rtw/pds:/data \
  -e PDS_HOSTNAME=pds.rtw.run \
  -e PDS_CRAWLERS=https://bsky.network \
  -e PDS_INVITE_REQUIRED=true \
  -e PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX=<64-hex> \
  -e PDS_JWT_SECRET=<secret> \
  -e PDS_ADMIN_PASSWORD=<secret> \
  atcr.io/rtw.run/pds:latest

Environment

Var Default Meaning
PDS_HOSTNAME localhost (dev) Fully-qualified hostname; required in production
PDS_DATA_DIRECTORY /data Data dir on the volume (sqlite DBs)
PDS_BLOBSTORE_DISK_LOCATION $PDS_DATA_DIRECTORY/blobs Uploaded blobs (disk store)
PDS_PORT 3000 Listening port
PDS_CRAWLERS unset e.g. https://bsky.network for public federation
PDS_INVITE_REQUIRED unset true to require an invite code to sign up
PDS_SERVICE_DID did:web:<hostname> Service DID override
PDS_DEV_MODE false true relaxes the https-only URL requirement and disables SSRF protection (auto-set in dev)
PDS_SERVICE_NAME / PDS_SERVICE_DESC / PDS_BRANDING_* Branding shown on the web UI

Admin access is HTTP basic auth with user admin and PDS_ADMIN_PASSWORD (e.g. for com.atproto.server.createInviteCode).

Health check: curl http://localhost:3000/xrpc/_health.

Source: bluesky-social/atproto · Docs: https://atproto.com/guides/self-hosting