For running a PDS on fly.io so you can host your own data, but not have to maintain your own servers.
This assumes you know your way around a command line and BlueSky, generally.
- Pre-reqs
- Sign up for fly.io and install their CLI
- Find or buy a domain name to sacrifice (e.g., example.com)
- Find an e-mail or e-mail service to use (a free gmail works just fine)
git clone
this repo- Modify
fly.toml
with your ownapp
andprimary_region
values. (You can try to use mine, but probably won't work very well.) - Set environmental variables.
- $
cp pds.env.example pds.env
- Fill in the requisite values in pds.env
- $
- Launch the app
- $
fly launch
<== create the app (make sure you picked a cool name!) - $
cat pds.env | fly secrets import
<== move the secrets over to the PDS host - $
fly ips list
<== you'll need this to get the IPv4 xxx.xxx.xxx.xxx for your DNS
- $
- Sacrifice your domain name (set the A-records in your DNS, per instruction)
- Add certs for your domain name
- $
fly certs add example.com
<== root domain - $
fly certs add "*.example.com"
<== wildcard - Add CNAME record to DNS per instructions provided in the command line
- Wait for it (and read the docs while you wait in case something goes wrong, which it did for me because Cloudflare likes to be overly-helpful sometimes)
- $
- Load
example.com/xrpc/_health
in a browser to see if it loads. Should show you a version number in JSON format. (Woo!) - Generate an invitation
- Use the curl command below
- Hold onto the output for the next step
- Sign up for a new account using your custom Server in the BlueSky app
- Change your
Hosting Provider
toCustom
- Enter your PDS's domain name (e.g.,
example.com
) - Enter your invite code
- Change your
You now have an account on your own PDS. How about that?
Replace the ${VALUE}
s (exclusive of the ${}
) from your pds.env
curl \
--fail \
--silent \
--show-error \
--request POST \
--user "admin:${PDS_ADMIN_PASSWORD}" \
--header "Content-Type: application/json" \
--data '{"useCount": 1}' \
"https://${PDS_HOSTNAME}/xrpc/com.atproto.server.createInviteCode" | jq --raw-output '.code'
Because I think all of this is very neat indeed.