FOSS geek, privacy advocate, digital archivist, mental illness advocate, gamer

Setting up a Bluesky PDS on CentOS Stream

Published on: by hyperreal

4 min read

This is based on the README.md at https://github.com/bluesky-social/pds. I’ll be using modified versions of both the compose.yaml file and the installer.sh file. The modifications include changes to use Podman instead of Docker and DNF instead of APT. I’ll keep SELinux in enforcing mode and provide a policy module to compile and install to allow the PDS to work. CentOS Stream is not an officially supported distribution by the upstream PDS maintainers – this is my own working setup – so please do not bother them with support questions for a CentOS Stream host. In lieu of that, you’re welcome to direct any questions or issues with this setup to me, at @hyperreal@tilde.zone in the fediverse.

Minimum server requirements

Component Requirement
OS CentOS Stream 10
RAM 1 GB
CPU cores 1
Storage 20 GB SSD
Architectures amd64, arm64
Number of PDS users 1-20

Ensure you have a firewall installed along with fail2ban, and that proper security precautions are taken for your server, such as SSH hardening. My custom installer.sh assumes you have firewalld installed, as per the RHEL ecosystem.

Other requirements:

  • Public IPv4 address
  • Public DNS name
  • Public inbound internet access permitted on port 80/tcp and 443/tcp

Refer to https://github.com/bluesky-social/pds for more information on server setup, but adapt it to CentOS.

Preliminary actions

Download the installer from my tildegit.org repo with the following command:

curl https://tildegit.org/hyperreal/gists/raw/branch/main/pds-installer.sh > installer.sh

I recommend perusing the installer.sh file before running it, so that you know what it will do. I also recommend perusing the compose.yaml file at https://tildegit.org/hyperreal/gists/raw/branch/main/pds-compose.yaml.

Before running the installer, ensure the following package dependencies are installed. The installer will install the remaining dependencies.

sudo dnf install -y epel-release
sudo dnf install -y lsb_release

SELinux policy module

You also need to install an SELinux policy module so that SELinux doesn’t deny the PDS processes.

Create the file pds.te:

module pds 1.0;

require {
        type container_runtime_t;
        type var_run_t;
        type container_t;
        type default_t;
        class file { create lock map open read setattr unlink write };
        class dir { add_name remove_name write };
        class unix_stream_socket connectto;
        class sock_file write;
}

#============= container_t ==============
allow container_t container_runtime_t:unix_stream_socket connectto;
allow container_t default_t:dir { add_name remove_name write };
allow container_t default_t:file { create lock map open read setattr unlink write };
allow container_t var_run_t:sock_file write;

Compile and install the module.

checkmodule -M -m -o pds.mod pds.te
semodule_package -o pds.pp -m pds.mod
sudo semodule -i pds.pp

Installer

Now you can run the installer. The installer will do the following general actions:

  • Check for supported architecture
  • Check for supported distribution
  • Determine the server’s public IP
  • Install dependency packages
  • Create the PDS data directory at /pds
  • Configure the Caddy container
  • Create the PDS env config
  • Download and install the PDS compose file
  • Create the pds.service systemd service
  • Enable firewall access to ports 80/tcp and 443/tcp if firewalld is in use
  • Download and install the pdsadmin binary to /usr/local/bin/pdsadmin
  • Prompt you for your PDS’s public domain name and your email address
  • Prompt you to create a PDS user account
sudo bash installer.sh

If the installer completed successfully, you should receive output similar to the following:

========================================================================
PDS installation successful!
------------------------------------------------------------------------

Check service status      : sudo systemctl status pds
Watch service logs        : sudo podman logs -f pds
Backup service data       : /pds
PDS Admin command         : pdsadmin

Required Firewall Ports
------------------------------------------------------------------------
Service                Direction  Port   Protocol  Source
-------                ---------  ----   --------  ----------------------
HTTP TLS verification  Inbound    80     TCP       Any
HTTP Control Panel     Inbound    443    TCP       Any

Required DNS entries
------------------------------------------------------------------------
Name                         Type       Value
-------                      ---------  ---------------
your-domain.net              A          your-ip-address
*.your-domain.net            A          your-ip-address

Detected public IP of this server: your-ip-address

To see pdsadmin commands, run "pdsadmin help"

========================================================================

If PDS user account creation completed successfully, you should receive output similar to the following:

Account created successfully!
-----------------------------
Handle   : handle.your-domain.net
DID      : did:plc:your-did
Password : your-password
-----------------------------
Save this password, it will not be displayed again.

If you receive any errors, you can check if there are SELinux denials with the following command:

sudo ausearch -ts recent | sudo audit2allow

Verifying your PDS is online and accessible

Visit https://your-domain.net/xrpc/_health in your browser. Or run the following command from your terminal:

curl https://your-domain.net/xrpc/_health

You should receive a JSON response with a version:

{"version":"0.4.204"}

You’ll also need to check that WebSockets are working. You can do this with the wsdump tool. You’ll need the latest version of Golang to install it.

sudo dnf install -y golang

Now to install the wsdump tool:

go install github.com/nrxr/wsdump@latest

Then run it:

wsdump "wss://your-domain.net/xrpc/com.atproto.sync.subscribeRepos?cursor=0"

Note that there will be no events on the WebSocket until they are created in the PDS, so the above command may continue to run with no output. You’ll have to press CTRL-C to stop it.

Closing

That’s the gist of how to setup a Bluesky PDS on CentOS Stream. I recommend reading the README.md at https://github.com/bluesky-social/pds for more information on using the pdsadmin command, setting up SMTP, and troubleshooting.

If you have any questions or issues with this setup, feel free to reach out to me at @hyperreal@tilde.zone. Please don’t bother the upstream PDS developers, as they don’t officially support a CentOS setup.