Skip to main content

Command Palette

Search for a command to run...

VPS Hosting for FoundryVTT: A Beginner's Guide

Updated
6 min read

Prerequisite Checks

Before you begin, ensure you have:

Required:

  • A valid FoundryVTT license (purchase at https://foundryvtt.com)

  • Basic command-line familiarity

  • VPS hosting ($5-15/month)

  • SSH client installed:

    • Windows: Built into Windows 10/11, or download PuTTY

    • Mac/Linux: Built-in Terminal

Optional but Recommended:

  • A domain name ($10-15/year from Namecheap, Cloudflare, etc.)

  • SFTP client for file uploads (FileZilla, Cyberduck, WinSCP)

Time Estimate: 30-60 minutes for complete setup


Step 1: Get a VPS

Choose a provider like OVHcloud, DigitalOcean, Hetzner, or Linode.

Recommended specs:

  • 2GB RAM minimum (4GB recommended)

  • 2 CPU cores

  • 20GB+ SSD storage

  • Ubuntu 24.04 LTS or Newer

You will need SSH access, most hosts have guides for this

Step 2: Initial Setup

SSH into your server. On Windows, use PuTTY, Windows Terminal, or WSL. On Mac/Linux, open a Terminal and run:

ssh username@your_server_ip

Replace your_server_ip with your VPS IP address and username with your provider's default user:

  • OVHcloud: Usually ubuntu or debian (depending on OS)

  • DigitalOcean: root for some images, ubuntu for Ubuntu droplets

  • Hetzner: root

  • Linode: root

Check your provider's setup email or documentation for the correct username. Accept the host key when prompted.

Authentication:

  • Password: If your VPS uses password authentication, you'll be prompted to enter the password (usually emailed to you by your hosting provider)

  • SSH Key: If you set up SSH keys during VPS creation, the key will be used automatically. No password prompt will appear.

    • For PuTTY users: Load your private key (.ppk file) in Connection > SSH > Auth

    • For OpenSSH users: Specify the key with ssh -i /path/to/private_key username@your_server_ip

Once connected, update packages:

sudo apt update
sudo apt upgrade -y
sudo apt install unzip -y

Step 3: Create a Dedicated User

sudo useradd -r -m -d /opt/foundry -s /bin/bash foundry
sudo passwd foundry  # Set a password for SFTP access

Step 4: Install Node.js via fnm (as foundry user)

sudo -u foundry -i  # Switch to foundry user

curl -fsSL https://fnm.vercel.app/install | bash
source ~/.bashrc
fnm install --lts --corepack-enabled
fnm default lts-latest
fnm use lts-latest

node --version  # Verify installation

Step 5: Install PM2

npm install -g pm2
pm2 --version  # Verify installation

Step 6: Download and Install FoundryVTT

Still as the foundry user:

# Get your timed URL from https://foundryvtt.com/me/licenses
# (Requires a Foundry license)
cd ~
mkdir -p app
curl -L -o foundry.zip "YOUR_TIMED_URL_HERE"
unzip foundry.zip -d ~/app
rm foundry.zip

# Create data directory
mkdir -p data

Step 7: Configure Foundry Options

Create the Foundry configuration file at ~/data/Config/options.json:

Option A: With Domain & HTTPS (Strongly Recommended)

mkdir -p ~/data/Config
cat > ~/data/Config/options.json <<'EOF'
{
  "hostname": "foundry.yourdomain.com",
  "routePrefix": null,
  "sslCert": null,
  "sslKey": null,
  "port": 30000,
  "proxyPort": 443,
  "proxySSL": true,
   "upnp": false
}
EOF

Important: Replace foundry.yourdomain.com with your actual domain name.

This configuration tells Foundry:

  • It's accessible at your domain name

  • To run on port 30000 (internal)

  • That it's behind a reverse proxy (Caddy) on port 443

  • That the proxy handles SSL/TLS

Option B: Without Domain/HTTPS (Not Recommended)

If you want to skip DNS and HTTPS setup, you can use:

mkdir -p ~/data/Config
cat > ~/data/Config/options.json <<'EOF'
{
  "port": 30000,
  "upnp": false
}
EOF

Then open port 30000 in your firewall (sudo ufw allow 30000/tcp) and access via http://your_server_ip:30000.

⚠️ Warning: This is insecure as traffic is unencrypted. Only use for testing or if using a VPN.

Step 8: Configure PM2

Create ~/ecosystem.config.js:

cat > ~/ecosystem.config.js <<'EOF'
module.exports = {
  apps: [{
    name: 'foundry',
    script: '/opt/foundry/app/main.js',
    cwd: '/opt/foundry/app',
    env: {
      NODE_ENV: 'production',
      FOUNDRY_VTT_DATA_PATH: '/opt/foundry/data'
    },
    instances: 1,
    autorestart: true,
    watch: false,
    max_memory_restart: '1G'
  }]
};
EOF

Start Foundry:

pm2 start ecosystem.config.js
pm2 save
pm2 startup  # Copy and run the command it outputs as your regular user

Exit back to your regular user:

exit

Why use Caddy?

  • Automatic HTTPS with free SSL certificates from Let's Encrypt

  • Secure encrypted connections (required for many web features)

  • Professional setup with custom domain

  • Better security for passwords and game data

⚠️ If you skip Caddy: You'll need to use http://your_server_ip:30000 and manually open port 30000. Traffic will be unencrypted.

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install -y caddy

Step 10: Configure Caddy

Replace foundry.yourdomain.com with your actual domain and your-email@example.com with your email:

sudo tee /etc/caddy/Caddyfile > /dev/null <<'EOF'
{
    email email@example.com
}

foundry.example.com {
    reverse_proxy localhost:30000

    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        X-Content-Type-Options "nosniff"
        X-Frame-Options "SAMEORIGIN"
        Referrer-Policy "same-origin"
    }

    request_body {
        max_size 500MB
    }
}
EOF

Validate and start Caddy:

sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl enable caddy
sudo systemctl restart caddy

Step 11: Configure SFTP for File Uploads

Edit SSH config:

sudo tee -a /etc/ssh/sshd_config > /dev/null <<'EOF'

# Foundry SFTP configuration
Match User foundry
    ForceCommand internal-sftp
    PasswordAuthentication yes
    ChrootDirectory /opt/foundry
    PermitTunnel no
    AllowAgentForwarding no
    AllowTcpForwarding no
    X11Forwarding no
EOF

Fix permissions for chroot:

sudo chown root:root /opt/foundry
sudo chmod 755 /opt/foundry
sudo chown -R foundry:foundry /opt/foundry/data

Restart SSH:

sudo systemctl restart sshd

Step 12: Configure Firewall (if using ufw)

sudo ufw allow 22/tcp   # SSH/SFTP
sudo ufw allow 80/tcp   # HTTP
sudo ufw allow 443/tcp  # HTTPS
sudo ufw enable

Why use a custom domain?

  • Easy to remember address instead of IP:port

  • Required for automatic HTTPS/SSL certificates

  • Professional appearance

  • Easier to share with players

⚠️ If you skip DNS: You can access Foundry via http://your_server_ip:30000 (requires opening port 30000 in firewall and skipping Caddy setup).

To set up DNS:

  1. Go to your domain registrar or DNS provider

  2. Add an A record pointing foundry.yourdomain.com to your VPS IP address

  3. Wait for DNS propagation (can take up to 24 hours, usually much faster)

Step 14: Access Your Foundry Instance

  1. Visit https://foundry.yourdomain.com

  2. Complete the Foundry setup wizard

  3. Enter your license key

Uploading Files via SFTP

Use any SFTP client (FileZilla, Cyberduck, WinSCP):

  • Host: Your domain or server IP

  • Port: 22

  • Username: foundry

  • Password: The password you set in Step 3

  • Remote path: /data

Upload worlds, modules, and assets to the appropriate subdirectories.

Useful Commands

Check Foundry status:

sudo -u foundry pm2 status

View Foundry logs:

sudo -u foundry pm2 logs foundry

Restart Foundry:

sudo -u foundry pm2 restart foundry

Check Caddy status:

sudo systemctl status caddy

Reload Caddy config:

sudo systemctl reload caddy

View Caddy logs:

sudo journalctl -u caddy -f

Updating Foundry

  1. Download new version as foundry user

  2. Stop PM2: pm2 stop foundry

  3. Backup: cp -r resources resources.backup

  4. Extract new version over existing files

  5. Start PM2: pm2 start foundry

Troubleshooting

Foundry not accessible:

  • Check PM2 is running: sudo -u foundry pm2 status

  • Check Caddy is running: sudo systemctl status caddy

  • Verify DNS points to your server IP

  • Check firewall allows ports 80 and 443

Can't connect via SFTP:

  • Verify SSH is running: sudo systemctl status sshd

  • Check firewall allows port 22

  • Verify foundry user password is correct

SSL certificate issues:

  • Check DNS is properly configured

  • View Caddy logs: sudo journalctl -u caddy -f

  • Ensure ports 80 and 443 are accessible from the internet