Skip to content

Deploy on a VPS

This guide covers deploying a Kyushu worker on a fresh VPS. The example uses Hetzner Cloud with Ubuntu 24.04, but any VPS with a recent Ubuntu/Debian works.

  • A VPS with Ubuntu 24.04
  • A domain pointing to the VPS IP (A record)
  • SSH access as root
  1. Update the system and install Caddy

    Terminal window
    apt update && apt upgrade -y
    apt install -y curl caddy
  2. Install the Kyushu CLI

    Terminal window
    curl -fsSL https://kyushu.dev/install | bash
    source ~/.kyu/bin/env
    kyu --version
  3. Deploy your worker

    Copy the worker to the VPS:

    Terminal window
    mkdir -p /opt/myapp
    rsync -av ./worker user@yourserver:/opt/myapp/

    If your worker uses a config file or static assets, copy those too:

    Terminal window
    rsync -av kyushu.toml ./assets/ user@yourserver:/opt/myapp/
    rsync -av ./public user@yourserver:/opt/myapp/
  4. Create a systemd service

    Terminal window
    cat > /etc/systemd/system/myapp.service << 'EOF'
    [Unit]
    Description=My Application
    After=network.target
    [Service]
    ExecStart=/root/.kyu/bin/kyu run
    WorkingDirectory=/opt/myapp
    Restart=on-failure
    RestartSec=5
    [Install]
    WantedBy=multi-user.target
    EOF
    systemctl daemon-reload
    systemctl enable myapp
    systemctl start myapp
    systemctl status myapp

    The service starts automatically on boot and restarts on failure.

  5. Configure Caddy

    Start by adding the DNS records in your domain registrar’s dashboard:

    TypeNameValue
    A@Your VPS IPv4 (curl -4 ifconfig.me)
    AAAA@Your VPS IPv6 (curl -6 ifconfig.me)

    Once your domain’s DNS has propagated, configure Caddy as a reverse proxy. Check propagation first:

    Terminal window
    dig yourdomain.com +short @8.8.8.8

    Then write the Caddyfile:

    Terminal window
    cat > /etc/caddy/Caddyfile << 'EOF'
    yourdomain.com {
    reverse_proxy localhost:5987
    }
    EOF
    systemctl restart caddy

    Caddy automatically provisions and renews a TLS certificate via Let’s Encrypt.

Terminal window
curl https://yourdomain.com

To manually deploy a new release, stop the service, replace the files, and restart:

Terminal window
systemctl stop myapp
# copy your updated artifacts to /opt/myapp
systemctl start myapp