[{"data":1,"prerenderedAt":153},["ShallowReactive",2],{"seo-verification":3,"blog-host-your-bluesky-pds-on-a-vps-with-the-at-protocol-en":6},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"id":7,"slug":8,"slugs":9,"title":12,"excerpt":13,"readTime":14,"views":15,"isPinned":16,"publishedAt":17,"category":18,"categories":24,"featuredImage":26,"bgImage":27,"posterImage":28,"relatedSolution":29,"intro":32,"sections":33,"ctaTitle":91,"ctaBody":92,"ctaButton":93,"ctaUrl":94,"relatedPosts":95},305,"host-your-bluesky-pds-on-a-vps-with-the-at-protocol",{"fr":10,"en":8,"ar":11},"heberger-son-pds-bluesky-at-protocol-vps","استضافة-pds-bluesky-على-vps-بواسطة-بروتوكول-at","Host your Bluesky PDS on a VPS with the AT Protocol","Deploy your Bluesky Personal Data Server on a VPS: portable DID, wildcard DNS, automatic Caddy TLS and Watchtower. 512 MB RAM is enough.",9,0,false,"2026-08-26T00:00:00+00:00",{"id":19,"name":20,"slug":21,"color":22,"icon":23},7,"Self-hosting","self-hosting","bg-indigo-500\u002F10 text-indigo-400","cloud",[25],{"id":19,"name":20,"slug":21,"color":22,"icon":23},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fheberger-son-pds-bluesky-at-protocol-vps-poster.svg",{"categorySlug":30,"appSlug":31},"development","docker-starter","The AT Protocol (atproto) decouples your Bluesky identity from the server that hosts it. As long as your account lives on bsky.social, Bluesky Inc. controls your DID. Hosting your own Personal Data Server on a VPS transfers that control: your posts, follows and handle travel with you regardless of the platform's future. The official repository github.com\u002Fbluesky-social\u002Fpds ships a ready-to-use Compose stack with Caddy (automatic TLS) and Watchtower (automatic updates), for a maintenance overhead comparable to any other Docker service.",[34,38,50,53,78,81,85,88],{"type":35,"title":36,"body":37},"h2","Owning your Bluesky identity","The AT Protocol's portability rests on a strict separation between the DID (Decentralized Identifier), the PDS that stores your data, and the network relay. Your DID doc, cryptographically signed by your server, lists the signing keys and the service endpoint holding your repository. Changing your PDS updates that document without modifying the DID itself: your followers see nothing, your profile links remain valid, and your handle stays the same.\n\nAs long as you delegate this hosting to bsky.social, portability remains theoretical. Moving it to a VPS you administer makes it real: you control the keys, you set the registration rules, and no external policy decision can deprive you of your post repository.",{"type":39,"title":40,"items":41},"ul","Benefits of a self-hosted PDS",[42,43,44,45,46,47,48,49],"Your Bluesky handle becomes a subdomain of your own domain, for example `you.your-domain.com`.","Your posts, likes and follows are stored in a cryptographically signed repository on your server — you are the sole owner.","If bsky.social changes its policies, a migration costs you neither followers nor posts: the AT Protocol transfers the entire repository.","You manage the list of admitted accounts via an invite code system: a strictly personal instance is possible.","Watchtower monitors the PDS image and triggers updates automatically, without manual intervention.","Caddy handles TLS and certificate renewal, including for the wildcard DNS required by handle subdomains.","Memory usage at rest is around 512 MB: compatible with most entry-level VPS.","The code is published under the MIT licence at github.com\u002Fbluesky-social\u002Fpds; no paid enterprise edition exists.",{"type":35,"title":51,"body":52},"Minimum requirements","A VPS with at least 512 MB of RAM and 1 vCPU is enough for personal use (one to five accounts). Plan for at least 20 GB of SSD storage for media and post history. For an association-scale instance with around ten accounts, 1 GB of RAM and 40 GB of storage provide more headroom.\n\nOn the network side, ports 80 and 443 must be reachable from the outside. The PDS maintains a persistent WebSocket connection to the Bluesky network: make sure your firewall does not time out idle long-lived connections.\n\nDNS: a wildcard A record `*.your-domain.com` pointing to your VPS IP is mandatory. It lets every handle subdomain resolve without a separate DNS entry per account. If your registrar does not support wildcards, manually configuring a handle via a `_atproto.your-domain.com` TXT record remains possible, but more cumbersome.\n\nRequired software: Docker and Docker Compose v2. No other dependency is needed; the official Compose bundles Caddy, Watchtower and the PDS in an isolated internal network.",{"type":54,"title":55,"steps":56},"steps","Step-by-step installation",[57,60,63,66,69,72,75],{"title":58,"body":59},"Clone the official repository","SSH into your VPS and clone the reference repository. The `main` branch is the stable branch recommended by the maintainers: `git clone https:\u002F\u002Fgithub.com\u002Fbluesky-social\u002Fpds \u002Fopt\u002Fpds`. Then enter the directory with `cd \u002Fopt\u002Fpds`.",{"title":61,"body":62},"Create the environment file","Copy the example file from the repository: `cp .env.example .env`.\n\nSet at minimum `PDS_HOSTNAME` (your root domain, without the wildcard, e.g. `your-domain.com`), `PDS_JWT_SECRET` and `PDS_ADMIN_PASSWORD`. Generate strong random values: `openssl rand -hex 32` produces a 64-character string suitable for each secret.",{"title":64,"body":65},"Configure the wildcard DNS","In your registrar's or Cloudflare's interface, create an A record `*.your-domain.com` pointing to your VPS IP address.\n\nPropagation usually takes a few minutes, sometimes up to 24 h. Verify with `dig +short test.your-domain.com @1.1.1.1` before moving on: an empty response means the entry is not yet propagated.",{"title":67,"body":68},"Start the services","The official Compose stack starts the PDS, Caddy and Watchtower in a single command: `docker compose up -d`.\n\nCaddy automatically obtains a TLS certificate for `your-domain.com` and `*.your-domain.com`. Follow the logs with `docker compose logs -f caddy` to confirm the challenge succeeded before creating your first account.",{"title":70,"body":71},"Create the first account","The PDS image exposes an administration command. Create your account: `docker compose exec pds \u002Fpds\u002Fbin\u002Fcreate-account --handle you.your-domain.com --email you@your-domain.com --password \u003Cpassword>`.\n\nOpen the Bluesky app, choose \"Custom server\" (address: `https:\u002F\u002Fyour-domain.com`), enter the returned invite code and complete account creation.",{"title":73,"body":74},"Migrate from bsky.social (if applicable)","If you already have an account on bsky.social, the AT Protocol allows a lossless migration. In the Bluesky app: Settings → Manage account → Migrate account. Enter your PDS address (`https:\u002F\u002Fyour-domain.com`) and follow the steps. Your DID is updated to point to your server; your followers have nothing to do — they still see you in their feed.",{"title":76,"body":77},"Verify the installation","Open `https:\u002F\u002Fyour-domain.com\u002Fxrpc\u002Fcom.atproto.server.describeServer` in a browser.\n\nThe JSON response confirms your PDS is reachable and that TLS is valid. Then search for `@you.your-domain.com` in the Bluesky app to verify the handle resolves correctly.",{"type":35,"title":79,"body":80},"Post-installation configuration","Invite codes. By default, registrations are closed: only accounts created with an invite code can join your PDS. Generate additional codes with `docker compose exec pds \u002Fpds\u002Fbin\u002Fcreate-invite-code`. For strictly personal use, this restriction is the recommended configuration.\n\nMonitoring with Watchtower. Watchtower is already in the official Compose stack and monitors the PDS image. As soon as a new version is published to the image registry, it pulls the image and restarts the service, without any action on your part. To receive a notification with each update, add `WATCHTOWER_NOTIFICATION_EMAIL=you@your-domain.com` to your `.env` file.\n\nBackups. The `data\u002F` directory (configurable via `PDS_DATA_DIRECTORY`) contains the SQLite database and media. Schedule regular backups: the directory is consistent when cold if you stop the services with `docker compose stop` before copying it.",{"type":82,"title":83,"body":84},"tip","Recommended hardening","Add `PDS_REGISTRATION_DISABLED=true` to `.env` to require an invite code for any registration. Restart the PDS with `docker compose restart pds` after the change.\n\nRegularly test restoring your backups by starting an ephemeral PDS against a second directory: an untested backup is not a backup. A corrupted SQLite database with no valid restore means losing all posts.",{"type":35,"title":86,"body":87},"Common troubleshooting","DNS not yet propagated. If Caddy cannot obtain a certificate, `docker compose logs caddy` shows `failed to obtain certificate`. Check wildcard resolution with `dig *.your-domain.com @1.1.1.1`: an empty response means the DNS entry does not exist yet or has not propagated.\n\nCertificate error (blocked ports). If the DNS record exists but the TLS-ALPN challenge fails, a firewall is likely blocking port 80 or 443. On a VPS with `ufw`, check `ufw status` and allow both ports: `ufw allow 80\u002Ftcp && ufw allow 443\u002Ftcp`.\n\nDID migration failed. If the Bluesky app returns an error during migration, confirm your PDS responds from the outside (the `describeServer` endpoint above). The migration contacts your server from bsky.social's servers: a timeout points to a network issue or an invalid certificate.\n\nHandle not resolving. If `@you.your-domain.com` does not resolve in the Bluesky app, check that the wildcard DNS is propagated and that the `\u002F.well-known\u002Fatproto-did` endpoint on your handle responds with the correct DID (`curl https:\u002F\u002Fyou.your-domain.com\u002F.well-known\u002Fatproto-did`).",{"type":35,"title":89,"body":90},"Going further","A self-hosted PDS fits naturally into an existing Docker infrastructure. The guide on \u003Ca href=\"\u002Fblog\u002Fdeployer-avec-caddy\">deploying with Caddy\u003C\u002Fa> covers more advanced multi-service reverse proxy scenarios on the same VPS. If you also want to host your own Git forge, the \u003Ca href=\"\u002Fblog\u002Fheberger-forgejo\">Forgejo on VPS\u003C\u002Fa> guide follows the same Compose model. To secure administrative access to your self-hosted services without exposing them directly to the internet, the \u003Ca href=\"\u002Fblog\u002Fself-host-headscale-tailscale-vps\">Headscale\u002FTailscale on VPS\u003C\u002Fa> guide offers an alternative to a plain SSH bastion.","A VPS ready for your Bluesky PDS","Deploy your Personal Data Server on a performant VPS, configurable in minutes. Your data, your infrastructure.","Explore developer solutions","\u002Fsolutions\u002Fdeveloppeurs",[96,116,131],{"id":97,"slug":98,"slugs":99,"title":102,"excerpt":103,"readTime":104,"views":15,"isPinned":16,"publishedAt":105,"category":106,"categories":110,"featuredImage":26,"bgImage":27,"posterImage":112,"relatedSolution":113},39,"deploy-your-applications-with-caddy-on-a-vps",{"fr":100,"en":98,"ar":101},"deployer-avec-caddy","انشر-تطبيقاتك-باستخدام-caddy-على-خادم-vps","Deploy your applications with Caddy on a VPS","Deploy Caddy on your VPS: web server and reverse proxy with automatic HTTPS. A Caddyfile of a few lines is enough to go into production.",3,"2026-05-12T00:00:00+00:00",{"id":104,"name":107,"slug":108,"color":109,"icon":108},"Deployment","deploiement","bg-success\u002F10 text-success",[111],{"id":104,"name":107,"slug":108,"color":109,"icon":108},"\u002Fblog\u002Fcovers\u002Fdeployer-avec-caddy-poster.svg",{"categorySlug":114,"appSlug":115},"application-deployment-devops","caddy",{"id":117,"slug":118,"slugs":119,"title":122,"excerpt":123,"readTime":124,"views":125,"isPinned":16,"publishedAt":126,"category":127,"categories":128,"featuredImage":26,"bgImage":27,"posterImage":130,"relatedSolution":26},75,"host-forgejo-on-your-own-vps",{"fr":120,"en":118,"ar":121},"heberger-forgejo","استضافة-forgejo-على-خادم-vps-الخاص-بك","Self-Host Forgejo on Your VPS: Complete 2025 Guide","Deploy Forgejo on your VPS with Docker, SSL, Actions runners and hardened security. Step-by-step guide for a sovereign Git forge.",10,1,"2026-04-06T00:00:00+00:00",{"id":19,"name":20,"slug":21,"color":22,"icon":23},[129],{"id":19,"name":20,"slug":21,"color":22,"icon":23},"\u002Fblog\u002Fcovers\u002Fheberger-forgejo-poster.svg",{"id":132,"slug":133,"slugs":134,"title":137,"excerpt":138,"readTime":139,"views":15,"isPinned":16,"publishedAt":140,"category":141,"categories":147,"featuredImage":26,"bgImage":27,"posterImage":149,"relatedSolution":150},164,"self-host-headscale-on-a-vps-your-own-tailscale-control-server",{"fr":135,"en":133,"ar":136},"self-host-headscale-tailscale-vps","استضافة-headscale-على-vps-خادم-تحكم-tailscale-خاص-بك","Self-Host Headscale on a VPS: Your Own Tailscale Control Server","Replace Tailscale's cloud control server with Headscale on your own VPS — unlimited users, full WireGuard mesh networking, magic DNS and ACLs, with no SaaS dependency.",5,"2026-07-05T00:00:00+00:00",{"id":142,"name":143,"slug":144,"color":145,"icon":146},8,"Security & Monitoring","securite-monitoring","bg-rose-500\u002F10 text-rose-400","security",[148],{"id":142,"name":143,"slug":144,"color":145,"icon":146},"\u002Fblog\u002Fcovers\u002Fself-host-headscale-tailscale-vps-poster.svg",{"categorySlug":151,"appSlug":152},"networking-vpn","headscale",1787744378338]