Self-hosting a bluesky personal data server on ubuntu vpsThis article provides a guide for self-hosting a Bluesky Personal Data Server on Ubuntu VPS.

Table of Contents

What is Bluesky?

Bluesky is a decentralized social networking protocol designed to create a more open and user-controlled internet. It was initially funded by Twitter in 2019 but later became an independent organization. Bluesky aims to move away from centralized control of social media platforms, allowing users to own their data, choose their algorithms, and self-host their identities.

Bluesky vs. Other Social Media

Feature Bluesky (AT Protocol) Twitter (X) Mastodon (ActivityPub)
Decentralized ✅ Yes ❌ No ✅ Yes
User-Controlled Algorithms ✅ Yes ❌ No ❌ No
Data Ownership ✅ User-Owned ❌ Platform-Owned ✅ User-Owned
Federation ✅ Yes ❌ No ✅ Yes
Self-Hosting Possible ✅ Yes ❌ No ✅ Yes

Step-by-Step Guide: Self-Hosting a Bluesky Personal Data Server on Ubuntu VPS

Bluesky’s decentralized social networking protocol (AT Protocol) allows users to self-host their own personal data servers (PDS). This guide provides a step-by-step process for self-hosting a Bluesky personal data server on Ubuntu VPS.

Prerequisites

Before starting, ensure you have:

Launch 100% ssd ubuntu vps from $2. 49/mo!

  1. Set Up Your Ubuntu VPS

    1. Update and Upgrade Ubuntu

      First, update your system to ensure you have the latest packages:

      sudo apt update && sudo apt upgrade -y
    2. Install Required Dependencies

      Ensure basic tools are installed:

      sudo apt install -y curl git unzip wget build-essential
  2. Set Up a User for Bluesky PDS

    It’s good practice to create a non-root user to manage the server:

    sudo adduser bluesky sudo usermod -aG sudo bluesky

    Switch to the new user:

    su - bluesky
  3. Install Docker and Docker Compose

    Bluesky’s PDS (Personal Data Server) can run inside a Docker container.

    1. Install Docker

      curl -fsSL https://get.docker.com | sudo bash sudo usermod -aG docker $(whoami)

      Log out and log back in for changes to take effect.

    2. Install Docker Compose

      sudo apt install -y docker-compose

      Verify installation:

      docker --version docker-compose --version
  4. Clone the Bluesky PDS Repository

    Navigate to your home directory and clone the official Bluesky PDS repository:

    git clone https://github.com/bluesky-social/pds.git cd pds
  5. Configure Environment Variables

    Copy the sample environment file:

    cp .env.example .env
    

    Edit the .env file using nano or vim:

    nano .env
    

    Modify key variables:

    • ADMIN_PASSWORD (Set a strong admin password)
    • PDS_HOSTNAME (Set your domain, e.g., pds.yourdomain.com)
    • DBHOST, DBUSER, DB_PASSWORD (for PostgreSQL database)
    • EMAIL_SERVER (for user email verification)

    Save and exit (CTRL + X, then Y, then Enter).

  6. Set Up PostgreSQL Database

    Bluesky PDS requires PostgreSQL.

    1. Install PostgreSQL

      sudo apt install -y postgresql postgresql-contrib
    2. Create a Database and User

      Access PostgreSQL:

      sudo -u postgres psql

      Run the following commands:

      CREATE DATABASE bluesky_pds; CREATE USER bluesky_user WITH PASSWORD 'strongpassword'; ALTER DATABASE bluesky_pds OWNER TO bluesky_user; GRANT ALL PRIVILEGES ON DATABASE bluesky_pds TO bluesky_user;

      Exit with:

      \q
    3. Update Database Configuration

      Edit the .env file again to match:

      nano .env

      Set:

      DB_HOST=localhost DB_PORT=5432 DB_USER=bluesky_user DB_PASSWORD=strongpassword DB_NAME=bluesky_pds
  7. Set Up Reverse Proxy with Nginx

    To expose your PDS with a proper domain and HTTPS, set up Nginx.

    1. Install Nginx

      sudo apt install -y nginx
    2. Configure Nginx for Bluesky PDS

      Create a new configuration file:

      sudo nano /etc/nginx/sites-available/bluesky

      Paste the following:

      server { listen 80; server_name pds.yourdomain.com; location / { 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; } }

      Save and exit.

    3. Enable the Configuration

      sudo ln -s /etc/nginx/sites-available/bluesky /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl restart nginx
  8. Obtain an SSL Certificate

    To secure your instance with HTTPS, install Certbot for Let’s Encrypt:

    sudo apt install -y certbot python3-certbot-nginx sudo certbot --nginx -d pds.yourdomain.com

    Follow the prompts and ensure HTTPS works.

  9. Start the Bluesky PDS

    Now, launch the server using Docker:

    docker-compose up -d

    This will download and start the Bluesky PDS.

    Check if the container is running:

    docker ps

    Check logs for errors:

    docker-compose logs -f
  10. Verify the PDS

    1. Check if Bluesky PDS is Running

      Test if the server is accessible:

      curl -X GET https://pds.yourdomain.com/xrpc/com.atproto.server.describeServer

      It should return server details.

    2. Register and Configure Your Server

      • Visit https://pds.yourdomain.com/admin
      • Log in with the admin password set in .env
      • Configure federation settings
  11. Maintain Your Server

    1. Restarting and Stopping PDS

      To restart:

      docker-compose restart

      To stop:

      docker-compose down
    2. Updating Bluesky PDS

      To update:

      cd pds git pull origin main docker-compose up --build -d
    3. Set Up Automatic SSL Renewal

      Let’s Encrypt certificates expire every 90 days. Set up auto-renewal:

      sudo crontab -e

      Add:

      0 3 * * * certbot renew --quiet
  12. Join Bluesky Federation

    To federate your instance:

    1. Register your PDS on Bluesky’s AT Protocol network.
    2. Ensure DNS records are correct for your domain.
    3. Monitor logs for federation activity.

Setup Custom Scripts for Personal Data Server Monitoring

To ensure your Bluesky Personal Data Server (PDS) is running smoothly, we can set up custom monitoring scripts using systemd, cron, and a simple health-check script that alerts via email or logs issues.

Follow the steps below to setup custom monitoring and alerting scripts:

  1. Create a Health Check Script

    We will write a script that:

    • Checks if the Bluesky PDS container is running.
    • Pings the PDS endpoint for a valid response.
    • Logs issues and sends an alert if the server is down.
    1. Create the Monitoring Script

      sudo nano /opt/bluesky_pds_monitor.sh

      Paste the following script:

      #!/bin/bash # Variables PDS_URL="https://pds.yourdomain.com/xrpc/com.atproto.server.describeServer" LOG_FILE="/var/log/bluesky_pds_monitor.log" EMAIL="your-email@example.com" # Check if the Docker container is running CONTAINER_NAME="pds" if ! docker ps | grep -q "$CONTAINER_NAME"; then echo "$(date): PDS container is DOWN!" | tee -a "$LOG_FILE" echo "PDS container is DOWN on $(hostname)" | mail -s "Bluesky PDS Alert" $EMAIL docker-compose -f /home/bluesky/pds/docker-compose.yml restart exit 1 fi # Check if the PDS server responds RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" $PDS_URL) if [ "$RESPONSE" -ne 200 ]; then echo "$(date): PDS server is NOT RESPONDING ($RESPONSE)" | tee -a "$LOG_FILE" echo "Bluesky PDS is NOT RESPONDING ($RESPONSE) on $(hostname)" | mail -s "Bluesky PDS Alert" $EMAIL docker-compose -f /home/bluesky/pds/docker-compose.yml restart else echo "$(date): PDS is running fine." >> "$LOG_FILE" fi

      Save and exit (CTRL + X, then Y, then Enter).

  2. Make the Script Executable

    sudo chmod +x /opt/bluesky_pds_monitor.sh
  3. Automate Monitoring Using Cron

    To run the script every 5 minutes, add it to cron:

    sudo crontab -e

    Add the following line:

    */5 * * * * /opt/bluesky_pds_monitor.sh

    Save and exit.

  4. Systemd Service for Persistent Monitoring

    Instead of relying only on cron, we can create a systemd service that ensures the PDS stays active.

    1. Create a Systemd Service File

      sudo nano /etc/systemd/system/bluesky_pds.service

      Paste the following:

      [Unit] Description=Bluesky Personal Data Server After=network.target [Service] User=bluesky WorkingDirectory=/home/bluesky/pds ExecStart=/usr/bin/docker-compose up Restart=always RestartSec=10 KillMode=mixed StandardOutput=syslog StandardError=syslog SyslogIdentifier=bluesky_pds [Install] WantedBy=multi-user.target

      Save and exit.

  5. Enable and Start the Service

    sudo systemctl daemon-reload sudo systemctl enable bluesky_pds sudo systemctl start bluesky_pds

    To check its status:

    sudo systemctl status bluesky_pds

    To restart it manually:

    sudo systemctl restart bluesky_pds
  6. Log Rotation for Monitoring Logs

    Since logs can grow large over time, we set up log rotation.

    Create a logrotate configuration file:

    sudo nano /etc/logrotate.d/bluesky_pds_monitor

    Add:

    /var/log/bluesky_pds_monitor.log { weekly rotate 4 compress missingok notifempty }

    Save and exit.

  7. Test the Monitoring Setup

    Run the monitoring script manually:

    sudo /opt/bluesky_pds_monitor.sh

    Check logs:

    cat /var/log/bluesky_pds_monitor.log

Overview of Monitoring Behavior

Now, your Bluesky PDS server is actively monitored. If the server crashes, it:

  1. Auto-restarts using docker-compose.
  2. Logs errors and keeps a history.
  3. Sends email alerts when issues occur.

Integrating Grafana Monitoring and Telegram Notifications for Bluesky PDS

To enhance monitoring for your Bluesky Personal Data Server (PDS), we will:

  1. Set up Prometheus for system and Docker metrics
  2. Use Grafana to visualize metrics
  3. Set up Telegram alerts for critical failures

To get started, please follow the steps provided:

  1. Install and Configure Prometheus

    1. Install Prometheus

      sudo useradd --no-create-home --shell /bin/false prometheus sudo mkdir /etc/prometheus /var/lib/prometheus sudo chown prometheus:prometheus /etc/prometheus /var/lib/prometheus

      Download and install Prometheus:

      cd /tmp curl -LO "https://github.com/prometheus/prometheus/releases/latest/download/prometheus-$(uname -m)-linux-gnu.tar.gz" tar -xvzf prometheus-*-linux-gnu.tar.gz sudo mv prometheus-*/prometheus /usr/local/bin/ sudo mv prometheus-*/promtool /usr/local/bin/ sudo mv prometheus-*/consoles /etc/prometheus/ sudo mv prometheus-*/console_libraries /etc/prometheus/
    2. Configure Prometheus

      sudo nano /etc/prometheus/prometheus.yml

      Paste the following:

      global: scrape_interval: 15s scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090'] - job_name: 'docker' static_configs: - targets: ['localhost:9323']

      Save and exit.

    3. Create a Systemd Service for Prometheus

      sudo nano /etc/systemd/system/prometheus.service

      Paste:

      [Unit] Description=Prometheus Monitoring Wants=network-online.target After=network-online.target [Service] User=prometheus ExecStart=/usr/local/bin/prometheus --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/var/lib/prometheus --web.listen-address="0.0.0.0:9090" Restart=always [Install] WantedBy=multi-user.target

      Enable and start Prometheus:

      sudo systemctl daemon-reload sudo systemctl enable prometheus sudo systemctl start prometheus
  2. Install and Configure Grafana

    1. Install Grafana

      sudo apt install -y software-properties-common sudo add-apt-repository "deb https://packages.grafana.com/oss/deb stable main" sudo apt update && sudo apt install -y grafana

      Start Grafana:

      sudo systemctl enable --now grafana-server
    2. Access Grafana

      Visit http://your-server-ip:3000 and login with:

      • Username: admin
      • Password: admin

      Change the password after logging in.

  3. Add Prometheus Data Source to Grafana

    1. Go to GrafanaSettingsData Sources
    2. Click Add Data Source
    3. Choose Prometheus
    4. Set URL: http://localhost:9090
    5. Click Save & Test
  4. Install and Configure Node Exporter

    To monitor CPU, RAM, and disk usage:

    cd /tmp curl -LO "https://github.com/prometheus/node_exporter/releases/latest/download/node_exporter-$(uname -m)-linux-gnu.tar.gz" tar -xvzf node_exporter-*-linux-gnu.tar.gz sudo mv node_exporter-*/node_exporter /usr/local/bin/

    Create a service:

    sudo nano /etc/systemd/system/node_exporter.service

    Paste:

    [Unit] Description=Node Exporter After=network.target [Service] ExecStart=/usr/local/bin/node_exporter Restart=always User=root [Install] WantedBy=default.target

    Enable and start:

    sudo systemctl daemon-reload sudo systemctl enable node_exporter sudo systemctl start node_exporter
  5. Configure Telegram Alerts in Grafana

    1. Create a Telegram Bot

        1. Open Telegram and search for @BotFather
        2. Send /newbot
        3. Follow the instructions and get the Bot Token
        4. Add the bot to a Telegram group and get the Chat ID using:
          curl "https://api.telegram.org/bot/getUpdates"
        5. Save the Bot Token and Chat ID.
  6. Configure Telegram in Grafana

    1. Go to GrafanaAlertingNotification Channels
    2. Click Add Channel
    3. Name: Telegram
    4. Type: Telegram
    5. Bot API Token:
    6. Chat ID:
    7. Click Save & Test
  7. Create Alerts for Bluesky PDS

    1. Add an Alert in Grafana

      1. Open Grafana and go to Dashboards.
      2. Create a new panel with:
        query: up{job="node"}
      3. Click AlertCreate Alert Rule
      4. Set:
        • Condition: When value < 1
        • For: 1m
        • Notification Channel: Telegram
      5. Click Save & Apply
  8. Verify Monitoring & Alerts

    1. Restart Bluesky PDS and check Prometheus metrics:
      systemctl restart bluesky_pds
    2. Simulate a failure:
      docker stop pds
    3. Check if Grafana triggers a Telegram alert.

Summary of Grafana Monitors and Telegram Notifications

🎉 You now have Bluesky PDS monitoring with:
Prometheus for metrics
Grafana for dashboards
Telegram alerts for failures

Create Auto-Recovery Scripts for Bluesky PDS

To ensure Bluesky Personal Data Server (PDS) recovers automatically from failures, we will:

  • Monitor PDS health
  • Restart the service if down
  • Trigger Telegram alerts
  • Set up systemd and cron for self-healing
  1. Create the Auto-Recovery Script

    The script will:
    Check if the Docker container is running
    Restart the container if needed
    Log failures
    Send Telegram alerts

    1. Create the Script

      sudo nano /opt/bluesky_auto_recovery.sh

      Paste the following:

      #!/bin/bash # Configuration PDS_CONTAINER="pds" PDS_URL="https://pds.yourdomain.com/xrpc/com.atproto.server.describeServer" LOG_FILE="/var/log/bluesky_auto_recovery.log" TELEGRAM_BOT_TOKEN="your_bot_token" TELEGRAM_CHAT_ID="your_chat_id" # Function to send Telegram alerts send_telegram_alert() { MESSAGE="$1" curl -s -X POST "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage" \ -d chat_id="$TELEGRAM_CHAT_ID" \ -d text="$MESSAGE" } # Check if Docker is running if ! systemctl is-active --quiet docker; then echo "$(date): Docker is DOWN. Restarting..." | tee -a "$LOG_FILE" send_telegram_alert "🚨 ALERT: Docker is DOWN on $(hostname). Restarting..." sudo systemctl restart docker fi # Check if the PDS container is running if ! docker ps | grep -q "$PDS_CONTAINER"; then echo "$(date): PDS container is DOWN! Restarting..." | tee -a "$LOG_FILE" send_telegram_alert "⚠️ WARNING: Bluesky PDS is DOWN! Restarting now..." docker-compose -f /home/bluesky/pds/docker-compose.yml up -d fi # Check if PDS is responding HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$PDS_URL") if [ "$HTTP_STATUS" -ne 200 ]; then echo "$(date): PDS is NOT RESPONDING ($HTTP_STATUS). Restarting..." | tee -a "$LOG_FILE" send_telegram_alert "❌ Bluesky PDS is NOT RESPONDING ($HTTP_STATUS). Restarting..." docker-compose -f /home/bluesky/pds/docker-compose.yml restart else echo "$(date): PDS is running fine." >> "$LOG_FILE" fi

      Save and exit (CTRL + X, then Y, then Enter).

  2. Make the Script Executable

    sudo chmod +x /opt/bluesky_auto_recovery.sh
  3. Automate Recovery Using Cron

    To check every 5 minutes, add it to cron:

    sudo crontab -e

    Add:

    */5 * * * * /opt/bluesky_auto_recovery.sh

    Save and exit.

  4. Set Up Systemd for Automatic Restart

    Instead of relying only on cron, we use systemd to ensure PDS restarts if it crashes.

    1. Create a Systemd Service File

      sudo nano /etc/systemd/system/bluesky_auto_recovery.service

      Paste:

      [Unit] Description=Bluesky PDS Auto-Recovery Service After=network.target docker.service [Service] ExecStart=/opt/bluesky_auto_recovery.sh Restart=always RestartSec=30 User=root [Install] WantedBy=multi-user.target

      Save and exit.

  5. Enable and Start the Service

    sudo systemctl daemon-reload sudo systemctl enable bluesky_auto_recovery sudo systemctl start bluesky_auto_recovery

    To check its status:

    sudo systemctl status bluesky_auto_recovery

    To restart manually:

    sudo systemctl restart bluesky_auto_recovery
  6. Test the Auto-Recovery System

    1. Simulate a Failure

      Stop the PDS container manually:

      docker stop pds

      Check logs:

      tail -f /var/log/bluesky_auto_recovery.log

      It should detect the failure, restart PDS, and send a Telegram alert.

    2. Simulate an Unresponsive PDS

      Block PDS temporarily:

      iptables -A INPUT -p tcp --dport 3000 -j DROP

      Wait 5 minutes and check logs & Telegram alerts.

      To unblock:

      iptables -D INPUT -p tcp --dport 3000 -j DROP

Self-Healing Sequence Summary

Auto-recovery script to restart PDS
Telegram alerts for failures
Systemd service for persistent monitoring
Cron job for regular health checks

Now, your Bluesky PDS is self-healing! 🎉

Conclusion

Congratulations! 🎉 You’ve successfully self-hosted a Bluesky Personal Data Server on an Ubuntu VPS. Your server is now part of the decentralized Bluesky network.

Additionally, you’ve enabled:

  • Automated Service monitors via custom scripting
  • Grafana Dashboard monitoring and Telegram notifications
  • Self-healing: Automatic service recovery in case of failure.

Launch 100% ssd ubuntu vps from $2. 49/mo!

Resources

Further resources for managing your Bluesky personal data server:

Share this:
Avatar of editorial staff

Editorial Staff

Rad Web Hosting is a leading provider of web hosting, Cloud VPS, and Dedicated Servers in Dallas, TX.
lg