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 onessh-keygen -t ed25519 -C "your_email@example.com"
# Display your public keycat ~/.ssh/id_ed25519.pub # On Mac/Linux# ortype $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 rootssh root@your_server_ip
2. Create a Deployment User
# Create new user (replace YOUR_USERNAME with your preferred username)adduser YOUR_USERNAMEusermod -aG sudo YOUR_USERNAME
# Set up SSH for the new usermkdir -p /home/YOUR_USERNAME/.sshcp ~/.ssh/authorized_keys /home/YOUR_USERNAME/.ssh/chown -R YOUR_USERNAME:YOUR_USERNAME /home/YOUR_USERNAME/.sshchmod 700 /home/YOUR_USERNAME/.sshchmod 600 /home/YOUR_USERNAME/.ssh/authorized_keys
# Exit and reconnect as your userexitssh 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 configurationsudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
# Edit the SSH configurationsudo nano /etc/ssh/sshd_config
Make the following changes in the configuration file:
# Disable root loginPermitRootLogin no
# Disable password authenticationPasswordAuthentication no
# Enable public key authenticationPubkeyAuthentication yes
# Specify which users can connect via SSHAllowUsers YOUR_USERNAME
# Optional but recommended: Limit SSH access attemptsMaxAuthTries 3
Apply the changes:
# Test the configuration for syntax errorssudo sshd -t
# Restart the SSH servicesudo systemctl restart sshd
If something goes wrong, you can restore the backup:
sudo cp /etc/ssh/sshd_config.bak /etc/ssh/sshd_configsudo systemctl restart sshd
4. Install Node.js Via NVM
# Install required build toolssudo apt updatesudo apt install -y curl git build-essential
# Install NVMcurl -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 defaultnvm alias default 22
4. Install PM2 and Nginx
# Install PM2 globallynpm install -g pm2
# Install Nginxsudo apt install -y nginx
Deploying Your Hyperfy World
1. Clone and Setup Your World
# Go to your home directorycd ~
# Clone the repositorygit clone https://github.com/hyperfy-xyz/hyperfy.git my-worldcd my-world
# Copy environment filecp .env.example .env
# Install dependenciesnpm install
2. Configure Environment Variables
change the environment variables to point to your domain url
# Edit your environment filenano .env
PUBLIC_WS_URL=https://YOUR_DOMAIN.com/wsPUBLIC_API_URL=https://YOUR_DOMAIN.com/apiPUBLIC_ASSETS_URL=https://YOUR_DOMAIN.com/assets
3. Start Your Application with PM2
# Start the applicationpm2 start npm --name "hyperfy" --interpreter bash -- start
# Set PM2 to start on system bootpm2 startuppm2 save
4. Configure Nginx as Reverse Proxy
# Remove default configsudo 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 sitesudo ln -s /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-enabled/
# Test configurationsudo nginx -t
# Start Nginxsudo systemctl restart nginx
5. Configure Your Domain’s DNS
Before enabling HTTPS, you need to point your domain to your server:
- Go to your domain registrar’s website (like Namecheap, GoDaddy, etc.)
- Find the DNS settings or DNS management section
- Add or modify the following records:
Type | Name | ValueA | @ | your_server_ipCNAME | www | your_domain
- 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 pluginsudo apt install certbot python3-certbot-nginx
# Obtain and install the certificatesudo 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 HTTPSsudo ufw allow OpenSSHsudo ufw allow 'Nginx Full'
# Enable firewallsudo ufw enable
Updating Your World
When you need to update your world:
# Go to your world directorycd ~/my-world
# Pull latest changesgit pull
# Install any new dependenciesnpm install
# Restart the applicationpm2 restart hyperfy
Monitoring and Troubleshooting
View Application Status
# Check statuspm2 status
# View logspm2 logs hyperfy
# Monitor CPU/Memory usagepm2 monit
Check Nginx Status
# View Nginx statussudo systemctl status nginx
# Check error logssudo tail -f /var/log/nginx/error.log
Common Issues
- Port 3000 already in use:
# Find what's using the portsudo lsof -i :3000
# Kill the processsudo kill -9 <PID>
- Node version issues:
# Verify Node versionnode -v
# Switch version if needednvm use 22
- Permission issues:
# Fix ownership if neededsudo chown -R YOUR_USERNAME:YOUR_USERNAME ~/my-world
- SSL Certificate issues:
# Check certificate statussudo certbot certificates
# Renew certificates manually if neededsudo certbot renew
# View Certbot logssudo 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.gitcd 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 | bashnvm install 22.11.0nvm 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 .envnano .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 installnpm 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 updatesudo apt install nginxsudo 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 -tsudo 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