Custom Domain
You do not need to setup a PDS to have a custom domain in your username. Bluesky provides documentation for DNS setup.
Official bluesky-pds project | GitHub - bluesky-social/pds |
Image on Forgejo | Forgejo |
Image on Dockerhub | Dockerhub |
Image Source | Forgejo |
Issue Tracker | GitHub - gravityfargo/bluesky-pds-docker |
docker pull code.modernleft.org/gravityfargo/bluesky-pds:v0.4.74
A self-contained Docker image for the Bluesky PDS (Personal Data Server) for use with Traefik.
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.
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.
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)
Compose File
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.
Traefik
# Traefik Proxy
services:
bluesky-pds:
image: code.modernleft.org/gravityfargo/bluesky-pds:v0.4.74
networks:
- proxy
environment:
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:
EUID: 1000
EGID: 1000
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
Optionally, you can use the BlueskyHeaders middle ware to set headers.
Standalone
I do not run this, but it should be possible. You must setup SSL for it to connect to the Bluesky network. I have not tested this.
# Standalone, you'll need to add a proxy in front of this with SSL.
services:
bluesky-pds:
container_name: bluesky-pds
image: code.modernleft.org/gravityfargo/bluesky-pds:v0.4.74
environment:
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:
EUID: 1000
EGID: 1000
volumes:
- ./bluesky-pds:/pds
Environment Variables
Full list of additional Environment Variables provided by Bluesky upstream can be found in the packages/pds/src/config/env.ts
Variable | Description | Default | Required |
---|---|---|---|
PDS_JWT_SECRET | JWT secret for the PDS server | "" | * |
PDS_ADMIN_PASSWORD | Password for the admin account | "" | * |
PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX | Private key for the PDS server | "" | * |
PDS_HOSTNAME | Hostname for the PDS server | "" | * |
PDS_EMAIL_SMTP_URL | SMTP URL and authentication for email | "" | |
PDS_EMAIL_FROM_ADDRESS | Email address for email notifications | "" | |
EUID | User ID for the container | 1000 | |
EGID | Group ID for the container | 1000 | |
LOG_ENABLED | If the stdout will be shown in the console | true | |
LOG_DESTINATION | Where the logs will be sent | stdout | |
LOG_LEVEL | The level of logging | info |
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.
Check your work
This is just a reiteration of Verifying that your PDS is online and accessible from the pds docs.
If you go to https://example.com/xrpc/_health
you should be greeted with the JSON
{ "version": "0.4.74" }
To check that WebSockets are working use the go package wsdump
or go to PieSoket’s online websocket tester
wsdump "wss://example.com/xrpc/com.atproto.sync.subscribeRepos?cursor=0"
Running Commands
Nothing has changed in this department other than not needing sudo
. The commands are the same as those for the upstream project. Such as
docker exec -it bluesky-pds bash
pdsadmin account create
pdsadmin create-invite-code
Updating
Don’t use
pdsadmin update
. I have not tested this, and it may break things. Submit an issue to my repository requesting an update, and I will release a new image version.
Networking
Container Hostname
If you set the container hostname to the domain of your pds server,
services:
bluesky-pds:
hostname: example.com
you will get the error curl: (7) Failed to connect to example.com port 443 after 0 ms: Couldn't connect to server
. You have two options.
- Do not set the hostname.
- Add the
extra_hosts:
section to your compose file to act as an entry to /etc/hosts that manually points the FQDN to your external IP. See the Cloudflare DNS section for an example.
Cloudflare DNS
Cloudflare
Link to originalCloudflare
I do not use their services after their many controversies. Theo - t3.gg has a good video on the topic. 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.
This container does not work well with Cloudflare. I won’t provide support. However, here are some notes. In the Cloudflare control panel, you need to enable WebSockets. You also need to set
services:
bluesky-pds:
image: forgejo.gravityfargo.dev/gravityfargo/bluesky-pds:latest
extra_hosts:
- "example.com:0.0.0.0" # must be the external IP to bypass cloudflare.
I stopped using Cloudflare around the same time I was messing with this. So I don’t have any more information than this.
A user on reddit commented with a setup for using cloudflared if that helps.
FAQ
Why does command pdsadmin ...
give me curl: (7) Failed to connect
?
The pds server is unable to resolve itself. See the Networking section for more information.
I keep getting “/pds/pds.env: line N: $N: unbound variable”
You have not set all of the required environment variables.
Error: Resource URL must use the https scheme
PDS_HOSTNAME
is not set.