Skip to content

Self Hosting

VPS

Deploying Your Hyperfy World -guide by peezy

Initial VPS Setup

Before connecting to your VPS, you need to upload an SSH key to your provider’s platform.

# Generate an SSH key if you don't have one
ssh-keygen -t ed25519 -C "your_email@example.com"
# Display your public key
cat ~/.ssh/id_ed25519.pub # On Mac/Linux
# or
type $env:USERPROFILE\.ssh\id_ed25519.pub # On Windows PowerShell

Copy the entire key and add it to your VPS provider’s dashboard.

Setting Up Your Server

1. Initial Connection

# Connect to your VPS as root
ssh root@your_server_ip

2. Create a Deployment User

# Create new user (replace YOUR_USERNAME with your preferred username)
adduser YOUR_USERNAME
usermod -aG sudo YOUR_USERNAME
# Set up SSH for the new user
mkdir -p /home/YOUR_USERNAME/.ssh
cp ~/.ssh/authorized_keys /home/YOUR_USERNAME/.ssh/
chown -R YOUR_USERNAME:YOUR_USERNAME /home/YOUR_USERNAME/.ssh
chmod 700 /home/YOUR_USERNAME/.ssh
chmod 600 /home/YOUR_USERNAME/.ssh/authorized_keys
# Exit and reconnect as your user
exit
ssh YOUR_USERNAME@your_server_ip

3. Secure the SSH Configuration

After verifying you can log in as your user, secure the SSH service:

# Make a backup of the original configuration
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
# Edit the SSH configuration
sudo nano /etc/ssh/sshd_config

Make the following changes in the configuration file:

# Disable root login
PermitRootLogin no
# Disable password authentication
PasswordAuthentication no
# Enable public key authentication
PubkeyAuthentication yes
# Specify which users can connect via SSH
AllowUsers YOUR_USERNAME
# Optional but recommended: Limit SSH access attempts
MaxAuthTries 3

Apply the changes:

# Test the configuration for syntax errors
sudo sshd -t
# Restart the SSH service
sudo systemctl restart sshd

If something goes wrong, you can restore the backup:

sudo cp /etc/ssh/sshd_config.bak /etc/ssh/sshd_config
sudo systemctl restart sshd

4. Install Node.js Via NVM

# Install required build tools
sudo apt update
sudo apt install -y curl git build-essential
# Install NVM
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
# Load NVM (or reconnect to your server)
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
# Install required Node version (22.11.0+)
nvm install 22
# Set as default
nvm alias default 22

4. Install PM2 and Nginx

# Install PM2 globally
npm install -g pm2
# Install Nginx
sudo apt install -y nginx

Deploying Your Hyperfy World

1. Clone and Setup Your World

# Go to your home directory
cd ~
# Clone the repository
git clone https://github.com/hyperfy-xyz/hyperfy.git my-world
cd my-world
# Copy environment file
cp .env.example .env
# Install dependencies
npm install

2. Configure Environment Variables

change the environment variables to point to your domain url

# Edit your environment file
nano .env
PUBLIC_WS_URL=https://YOUR_DOMAIN.com/ws
PUBLIC_API_URL=https://YOUR_DOMAIN.com/api
PUBLIC_ASSETS_URL=https://YOUR_DOMAIN.com/assets

3. Start Your Application with PM2

# Start the application
pm2 start npm --name "hyperfy" --interpreter bash -- start
# Set PM2 to start on system boot
pm2 startup
pm2 save

4. Configure Nginx as Reverse Proxy

# Remove default config
sudo rm /etc/nginx/sites-enabled/default
# Create new config (replace yourdomain.com with your actual domain)
sudo nano /etc/nginx/sites-available/yourdomain.com

Add this configuration:

server {
listen 80;
server_name your-domain.com; # Change to your domain
location / {
proxy_pass http://localhost:3000; # Change port if different
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# WebSocket support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}

Enable and start Nginx:

# Enable the site
sudo ln -s /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-enabled/
# Test configuration
sudo nginx -t
# Start Nginx
sudo systemctl restart nginx

5. Configure Your Domain’s DNS

Before enabling HTTPS, you need to point your domain to your server:

  1. Go to your domain registrar’s website (like Namecheap, GoDaddy, etc.)
  2. Find the DNS settings or DNS management section
  3. Add or modify the following records:
    Type | Name | Value
    A | @ | your_server_ip
    CNAME | www | your_domain
  4. Save your changes

DNS changes can take anywhere from a few minutes to 48 hours to propagate. You can check the propagation by going on https://dnschecker.org/ and inserting your domain. it should point to your server ip

6. Set Up HTTPS with Certbot

Let’s secure your site with a free SSL certificate from Let’s Encrypt:

# Install Certbot and its Nginx plugin
sudo apt install certbot python3-certbot-nginx
# Obtain and install the certificate
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
# When prompted:
# 1. Enter your email address
# 2. Agree to terms of service
# 3. Choose whether to redirect HTTP to HTTPS (recommended)

Certbot will automatically modify your Nginx configuration to use HTTPS. It also sets up automatic renewal of your certificates.

You can verify that the SSL certificate is set to auto-renew by checking the Certbot timer

sudo systemctl status certbot.timer

7. Configure Firewall

# Allow SSH, HTTP, and HTTPS
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
# Enable firewall
sudo ufw enable

Updating Your World

When you need to update your world:

# Go to your world directory
cd ~/my-world
# Pull latest changes
git pull
# Install any new dependencies
npm install
# Restart the application
pm2 restart hyperfy

Monitoring and Troubleshooting

View Application Status

# Check status
pm2 status
# View logs
pm2 logs hyperfy
# Monitor CPU/Memory usage
pm2 monit

Check Nginx Status

# View Nginx status
sudo systemctl status nginx
# Check error logs
sudo tail -f /var/log/nginx/error.log

Common Issues

  1. Port 3000 already in use:
# Find what's using the port
sudo lsof -i :3000
# Kill the process
sudo kill -9 <PID>
  1. Node version issues:
# Verify Node version
node -v
# Switch version if needed
nvm use 22
  1. Permission issues:
# Fix ownership if needed
sudo chown -R YOUR_USERNAME:YOUR_USERNAME ~/my-world
  1. SSL Certificate issues:
# Check certificate status
sudo certbot certificates
# Renew certificates manually if needed
sudo certbot renew
# View Certbot logs
sudo tail -f /var/log/letsencrypt/letsencrypt.log

Digital Ocean

Deploy a v2 world - guide by Ash

1. Create droplet

Create your droplet in digital ocean. For this example i’m using a cheap $6/mo droplet which should be plenty for basic worlds:

  • 1 GB Ram
  • Regular SSD

Make sure to set up SSH access you can shell into the server.

Once set up, Digital Ocean gives you the IP address of your droplet.

2. SSH into droplet

ssh root@<ip-address>

3. Create working directory & clone repo

sudo mkdir -p /var/www/
cd /var/www/
git clone https://github.com/hyperfy-xyz/hyperfy.git
cd hyperfy

optionally make this your default ssh directory

nano ~/.bashrc

and add cd /var/www/hyperfy to the bottom of the file

4. Install node

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
nvm install 22.11.0
nvm use

If you run into ‘nvm not found’ or similar, reboot shell or just exit ssh and re-ssh in

5. Configure .env

cp .env.example .env
nano .env

Change the urls to use the public domain host that you’ll be setting up later with cloudflare

6. Install and Start the world

npm install
npm run build

Also install pm2. This will restart the world automatically if it crashes for some reason.

npm install pm2 -g

Then start the world with:

pm2 start "npm run start" --name=app

You can see logs by running pm2 log and restart the server with pm2 restart app etc.

7. Setup NGINX

sudo apt update
sudo apt install nginx
sudo ufw allow 'Nginx Full'
sudo nano /etc/nginx/sites-available/hyperfy

Paste this basic setup into nano, making sure to change your domain

server {
listen 80;
server_name mydomain.xyz;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /api/upload {
client_max_body_size 50m;
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}

Then symlink this site to enabled:

sudo ln -s /etc/nginx/sites-available/hyperfy /etc/nginx/sites-enabled/

Check the nginx is valid and restart nginx

sudo nginx -t
sudo systemctl restart nginx

8. Configure cloudflare

Assuming you already have your domain and DNS managed by cloudflare, go to the DNS page of your domain.

Add a new DNS entry:

  • Type: A
  • Name: either a subdomain or the full domain, depending on where you want the world
  • Content:
  • Proxied: yes