...

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 Grafana β†’ Settings β†’ Data 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 Grafana β†’ Alerting β†’ Notification 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 Alert β†’ Create 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:

Avatar of editorial staff

Editorial Staff

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

One thought on β€œSelf-Hosting a Bluesky Personal Data Server on Ubuntu VPS”

Comments are closed.

lg