












I take a lot of pleasure in running my own services. Self-hosting is a lot of fun and I keep accumulating more and more things on my server, from a feed reader to uptime monitoring (as backup to larm.dev), not to mention all of my toy projects.
I’ve been writing a lot about atproto recently and it’s frankly a very fertile area for self-hosting. Not only are there lots of open source components you can run, but the nature of atproto decentralization means that you can run your own services while seamlessly participating in shared systems. For example, you can run your own PDS (Personal Data Server) and create an account on it, and then log into Bluesky and post and participate with everyone else. Your account will work across the ATmosphere.
So, let’s talk about what it takes to self-host a PDS. Follow along and by the end of this you're posting on Bluesky from your own self-hosted account.
There are multiple PDS implementations out there. The original and probably most common one is the Bluesky reference PDS, but when I was researching options I came across one that matches the reference feature set but adds useful features on top: tranquil-pds. It’s implemented in Rust, comes with a nice admin panel, invite code management, passkeys, granular OAuth scopes, and a lot more.
There are plenty of instructions in the repo, but they’re a bit spread out, and some parts can get a bit tricky around wildcard certs, so I thought I’d write a bit of a getting started guide. This will be very similar to the setup I have for cove.town, with some simplifications.
There are a few things going on under the hood here that are worth highlighting:
.well-known/atproto-did. The PDS is built to handle this, but it requires getting the right DNS records and TLS certificates in place.Before we get to the code, we need a few things.
A or CNAME wildcard record pointing at your server. For example, if your domain is example.com, the record would be *.example.com. This is because the accounts will get handles like alice.example.com. Alternatively, if you’re happy to add each subdomain manually, you can skip the wildcard record and just create pds.example.com.docker login atcr.io or docker login atcr.io -u <HANDLE> --password-stdin, using an app password.Armed with those things, we’re ready to go.
A PDS needs to serve HTTPS traffic, and it needs to be able to serve that traffic on subdomains. That means the subdomains need TLS certificates issued. Caddy (unlike Traefik) comes with the ability to provision TLS certificates for domains on demand, so we’ll start by setting this up.
If you’ve opted not to use a DNS wildcard, and instead manually create each record for each account, you can skip the on_demand_tls and hardcode the subdomains instead.
Create a file called Caddyfile where you want the project.
{
on_demand_tls {
interval 2m
burst 5
}
}
*.example.com {
reverse_proxy pds:3000
tls {
on_demand
}
}
This is mostly an adapted version of the example compose from the Tangled repo, with the configuration moved into the environment section. Create compose.yml with this content.
services:
pds:
image: atcr.io/tranquil.farm/tranquil-pds:latest
restart: always
environment:
SERVER_HOST: "[::]"
PDS_HOSTNAME: pds.example.com
PDS_USER_HANDLE_DOMAINS: example.com
INVITE_CODE_REQUIRED: "true"
DATABASE_URL: postgres://tranquil_pds:${POSTGRES_PASSWORD}@db:5432/pds
JWT_SECRET: ${JWT_SECRET}
MASTER_KEY: ${MASTER_KEY}
DPOP_SECRET: ${DPOP_SECRET}
DISABLE_ACCOUNT_VERIFICATION_GATE: "true"
volumes:
- blob_data:/var/lib/tranquil-pds/blobs
depends_on: [db]
db:
image: postgres:18-alpine
restart: always
environment:
POSTGRES_USER: tranquil_pds
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: pds
volumes:
- pg_data:/var/lib/postgresql
caddy:
image: caddy:2
restart: always
ports: ["80:80", "443:443"]
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
volumes:
blob_data:
pg_data:
caddy_data:
You’ll want to replace the example.com domain name with your own, and you’re going to need to set up some secrets. Create a file called .env and fill it with these keys, running openssl rand -hex 32 for each and filling in the value.
JWT_SECRET=<openssl rand -hex 32>
MASTER_KEY=<openssl rand -hex 32>
DPOP_SECRET=<openssl rand -hex 32>
POSTGRES_PASSWORD=<openssl rand -hex 32>
Ok, that should be everything now. Try to start it up!
docker compose up -d
Take a look at the start up logs, they contain an important thing: your first invite code.
docker compose logs pds | grep -i invite
Now go to your PDS and create your account, choosing password or passkey for auth. Paste the invite code in the appropriate field. Congratulations, you now have your very own self-hosted atproto identity. Check it out!
curl https://you.example.com/.well-known/atproto-did
Assuming everything has gone to plan, that should return your did, looking something like did:plc:string. And next, for the real test, try logging into a service that uses atproto OAuth, like Bluesky, annot.at, or Standard Reader.
Now create a bunch of accounts for all the things you need! Get some cool custom domains and update your handles through the tranquil-pds dashboard. Live your best life.
The first thing you might want to consider to do is set up a verification flow. The compose has DISABLE_ACCOUNT_VERIFICATION_GATE: "true" which means you can sign up without email or another verification channel, but without those channels you can’t do things like password resets or PLC 2FA tokens. Tranquil supports a few different good options, including Discord and email. For the former you need to create a Discord bot, invite it to your server, and set DISCORD_BOT_TOKEN. And for the latter you’ll need these values.
MAIL_FROM_ADDRESS: pds@example.com
MAIL_SMARTHOST_HOST: smtp.provider.com
MAIL_SMARTHOST_PORT: "587"
MAIL_SMARTHOST_USERNAME: ...
MAIL_SMARTHOST_PASSWORD: ...
MAIL_REQUIRE_TLS: "true"
And there’s a lot more you could do to improve on this set up. Check out the cove.town repo for a more complete reference. Some examples of things you could do:
.env file you could look at some secret management tools, like OpenBao.Additionally tranquil-pds supports advanced features like running multiple instances clustered, and the maintainers are super friendly!
The world’s your oyster.cafe.
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。