kasnodes

kaspad on a rented server

Intermediate7 stepsAbout 15 minutes, then the first sync
1. Choose the server0 of 7 done
  1. Choose the server
  2. Paste the setup file
  3. Watch it start
  4. Check it from outside
  5. Claim it
  6. Day-to-day commands
  7. Troubleshooting

Before you start

1

Choose the server

Plans and prices change, so pick by what the node needs rather than by name. Dedicated vCPUs keep it from falling behind when neighbours get busy.

Image
Ubuntu 24.04
CPU
8 dedicated vCPUs or more
Memory
16 GB or more, 32 GB is comfortable
Volume
700 GB or more, mounted automatically
Location
Any; a less crowded provider or region scores more for hosting

On Hetzner Cloud, add the volume under Volumes while creating the server and leave its mount option on Automatic. On DigitalOcean, add it under Add Storage and keep Automatically Format & Mount.

2

Paste the setup file

This file sets the server up on its first boot: Docker, kaspad, the firewall and time sync.

On Hetzner, paste it into Cloud config near the end of the create page. On DigitalOcean, open Advanced Options, tick Add Initialization scripts and paste it there. Then create the server.

cloud-init.yaml
#cloud-config
# A public Kaspa node: kaspad in Docker on Ubuntu 24.04. From https://kasnodes.com/run/cloud
# Progress: /var/log/kaspad-setup.log
package_update: true
packages:
  - docker.io
  - docker-compose-v2
  - ufw

write_files:
  - path: /opt/kaspad/docker-compose.yml
    content: |
      services:
        kaspad:
          image: kaspanet/rusty-kaspad:latest
          container_name: kaspad
          restart: unless-stopped
          ports:
            - "16111:16111"            # P2P, for other nodes
            - "127.0.0.1:16110:16110"  # RPC, from this server only
          volumes:
            - kaspad-data:/app/data
          env_file:
            - claim.env
          command:
            - kaspad
            - --yes
            - --nologfiles
            - --disable-upnp
            - --utxoindex
            - --rpclisten=0.0.0.0:16110
          logging:
            options:
              max-size: "50m"
              max-file: "3"
      volumes:
        kaspad-data:
  - path: /opt/kaspad/claim.env
    content: |
      # To claim this node on KasNodes, put your code after the = and remove the #, then run
      # cd /opt/kaspad && docker compose up -d
      # KASPAD_USER_AGENT_COMMENTS=
  - path: /opt/kaspad/setup.sh
    permissions: "0755"
    content: |
      #!/bin/bash
      set -euo pipefail
      exec >>/var/log/kaspad-setup.log 2>&1
      echo "Setup started $(date -u)"
      # The chain needs about 640 GB: use an attached volume (mounted under /mnt) when there is one.
      data=""
      for _ in $(seq 60); do
        data=$(findmnt -rn -o TARGET | grep -m1 '^/mnt/' || true)
        [ -n "$data" ] && break
        udevadm trigger || true
        sleep 5
      done
      if [ -n "$data" ]; then
        echo "Keeping the chain on the volume at $data"
        systemctl stop docker docker.socket
        mkdir -p "$data/docker"
        printf '{"data-root": "%s/docker"}\n' "$data" > /etc/docker/daemon.json
      else
        echo "No volume under /mnt after 5 minutes: keeping the chain on the server's own disk"
      fi
      systemctl enable --now docker
      ufw allow OpenSSH
      ufw allow 16111/tcp
      ufw --force enable
      timedatectl set-ntp true || true
      cd /opt/kaspad
      docker compose up -d
      echo "kaspad is running. Follow it with: cd /opt/kaspad && docker compose logs -f kaspad"

runcmd:
  - [bash, /opt/kaspad/setup.sh]

Or download it. It runs kaspad in Docker exactly as the Docker guide does, keeps the chain on the volume, opens port 16111 to other nodes and nothing else but SSH.

3

Watch it start

Setup takes a few minutes after the server boots. Log in with your SSH key and follow it.

ssh root@YOUR-SERVER-IP
tail -f /var/log/kaspad-setup.log
cd /opt/kaspad && docker compose logs -f kaspad
It is running when
  • The setup log ends with kaspad is running
  • It says the chain is kept on the volume
  • kaspad's log shows peers connecting and blocks downloading

No volume found? The log says so if none was mounted within five minutes, and the chain then fills the server's own disk. Attach and mount a volume, then recreate the server with the same file.

4

Check it from outside

The first sync takes one to two hours. It accepts other nodes from the start, so you can check it right away.

Put the server's address into the node doctor: it should accept connections, run the newest kaspad and, once synced, be in step with the network and have a correct clock.

It is public when
  • The node doctor shows it accepts connections
  • kaspad's log shows inbound peers
  • It appears on KasNodes after a crawl or two
5

Claim it

Once it is listed, claim it so your name goes on its row. Start a claim from its page to get a one-time code.

  1. Find the node on KasNodes and choose Claim this node.
  2. Copy the code you are given.
  3. Run this on the server, with your code in place of YOUR-CODE:
echo 'KASPAD_USER_AGENT_COMMENTS=YOUR-CODE' | sudo tee /opt/kaspad/claim.env
cd /opt/kaspad && sudo docker compose up -d

That restarts kaspad with the code in its name tag; the claim confirms within a minute or two. Leave the code in place: it does no harm.

6

Day-to-day commands

Run these in /opt/kaspad.

Follow the log
docker compose logs -f kaspad
Update to the newest version
docker compose pull
docker compose up -d
Restart
docker compose up -d --force-recreate
Disk use
df -h /mnt/*
Resource use
docker stats kaspad
7

Troubleshooting

The usual problems and what fixes them.

The setup log is empty or missing

The file did not run. Check it starts with #cloud-config on its first line, and read /var/log/cloud-init-output.log for the reason.

The node doctor can't connect

Check the provider's own firewall, if you added one: it must allow TCP 16111 inbound. The server's firewall is already open for it.

It falls behind or restarts

The server is short of memory or CPU. Resize it to a larger plan; the volume keeps the chain, so it carries on where it stopped.

The volume is filling up

Grow it in the provider's console, then grow its filesystem with sudo resize2fs and the device findmnt shows for it. Keep at least 100 GB free.

Running? Put your name on it.

Once the node shows up in a crawl you can claim it, pick a public name and follow its rank.