Understanding the Need for an ATProto Proxy

The AT Protocol is a decentralized protocol designed to power social networks. It’s the backbone of the Bluesky social network that allows the content to be owned and hosted by the end user’s or networks themselves.

The main issue with self-hosting is that ownership and authorization of data is usually mapped to a domain, and most of the time those domains are already serving some other kind of content. For example, if we wanted our handle to be @mike.rocketbox.ing we would need rocketbox.ing to be reachable via the AT Protocol. However, running the installer as-is means sacrificing the apex hostname for the PDS web server.

You can learn about self-hosting a Bluesky PDS here: https://atproto.com/guides/self-hosting

Getting Started

The PDS service includes a default install of Caddy, which is another type of proxy — an alternative to Nginx. It listens on port 80 and 443 by default, and is expected to be the only service running on those ports. To avoid port conflicts with Nginx, we need to disable it.

Edit the docker-compose.yml file in your PDS directory (/pds/docker-compose.yml) and comment out the Caddy service:

# caddy: 
#   ...

Restart your PDS to apply the changes:

sudo systemctl restart pds.service

Installing and Configuring Nginx

sudo apt-get install nginx

By ditching Caddy, we lose out on some of the features like auto-TLS certificate brokering, but we can achieve something similar using certbot from the Let’s Encrypt project.

In order to route the PDS requests to the PDS while maintaining the normal functionality of Nginx, we need to add a location block within the Nginx configuration file (e.g., /etc/nginx/sites-available/your_domain.conf):

server {      
    listen 80;      
    server_name rocketbox.ing;       
 
    # Serve your existing website content      
    location / {          
        root /var/www/your_website; # Replace with your website's root directory          
        index index.html index.htm index.nginx-debian.html;          
        try_files $uri $uri/ =404;      
    }       
     
    # Proxy requests to the ATProto service      
    location /xrpc { 
         proxy_pass http://localhost:3000; 
         proxy_set_header Host $host; 
         proxy_set_header X-Real-IP $remote_addr; 
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
         proxy_set_header X-Forwarded-Proto $scheme; 
     } 
} 
 
server { 
     # Optional: Redirect HTTP traffic to HTTPS 
     listen 443 ssl;      
      # ... (add your SSL certificate configuration)  
}

The location /xrpc directive defines how Nginx should handle requests to the /xrpc path, required by the PDS. It proxies these requests to the local PDS instance, typically running on port 3000.

Test and Deploy:

Test your Nginx configuration for errors:

sudo nginx -t

Reload Nginx to apply the changes:

sudo systemctl reload nginx

Verifying the Proxy’s Functionality

To verify that your Nginx proxy is working correctly, you can check your Nginx access logs. These logs will show requests being made to your domain and forwarded to your PDS.

Example:

2023/11/22 12:34:56 [info] 192.168.1.100:54454 - - "GET /xrpc/atproto/com/atproto/server/discovery HTTP/1.1" 200 1234 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36" "-"

This log entry indicates that a client with the IP address 192.168.1.100 (example IP) made a GET request to the /xrpc/atproto/com/atproto/server/discovery endpoint. Nginx forwarded this request to your local PDS, which responded with a 200 OK status code.

Conclusion

While the AT Protocol is still fairly new and there are new apps and integrations being developed everyday, this approach allows you to jump in and start exploring the technology.

Share this post