Self-Hosting Multiple Worlds on Foundry VTT
peaceful-octopus
Posted on December 4, 2020
Introduction
I received several requests on the Foundry VTT Facebook group to document my self-hosting setup for Foundry on Windows that allows me to host multiple worlds simultaneously. With the license terms as of version 0.8.0 of Foundry, you will need a separate key for each instance. This is not a highly scalable approach, but if you're like me and you just want to have several games up at the same time because you want the convenience of being able to switch between them without starting them up and shutting them down, this is the way to go.
What this guide covers
I'm going to go over the minimal setup for this approach. I won't be covering SSL certificates or custom dynamic DNS at this point. I will assume you already have a custom or dynamic domain pointing at your IP address and port 80 (or 443 for HTTPS) forwarded through your router. If you're not there yet you can find other guides that will get you that far. If you have a custom domain and SSL certificate, there are only a few minor changes to enable HTTPS instead, which I will link to at the end.
Downloads
If you don't have Node installed on your host machine, go to the Node website and download the current LTS release.
We're using the Node version of Foundry, not the Windows wrapper, so go to Foundry, log in to your account, and download the Node.js version from the Licenses tab.
We'll also be making a lot of use of NSSM to create easy to manage Windows Services for nginx and Foundry, so download the latest version and unzip it somewhere convenient.
Last, you need nginx to act as your reverse proxy. Go to the downloads page and download the current mainline version.
Structure
Organization will be helpful here, so make a folder somewhere on your computer (ideally with a short path, like at a drive root) for Foundry. We'll assume it's at C:\FoundryVTT. Create a folder inside called Foundry and unzip the Node.js version of Foundry there.
Back at C:\FoundryVTT create another folder called shareddata. This folder will hold the shared data between all the instances - this means that if you install a module or update a system version on one instance, it will be installed or updated on all of them. If you don't want to use a shared data folder you can skip this step, but I highly recommend it as keeping everything in sync becomes very tiresome with as few as 3 instances.
Last, create a folder for each instance of Foundry you want to run. I just call them foundrydata1, foundrydata2, etc. When you're done your folder structure should look like this:
C:\FoundryVTT
Foundry
shareddata
foundrydata1
foundrydata2
...
Installation and Configuration
nginx
Put the contents of the nginx zip file somewhere convenient like C:\nginx. In C:\nginx, create a folder called sites-enabled and inside that create a text file called https.conf. Next, go to the main nginx configuration file, C:\nginx\conf\nginx.conf and open it. The default setup has a lot of things we don't need, so replace the entire body with this:
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
include "../sites-enabled/*.conf";
sendfile on;
keepalive_timeout 65;
}
This configures just the HTTP service, and references the sites-enabled folder we created before for additional configuration.
Now go back to the sites-enabled folder and open https.conf. Fill it with the following configuration, slightly modified from Foundry's nginx directions page. Supply your domain name for server_name, and for each game you want to run, duplicate the location block with a different url (so /game2 or /dnd2 or anything you want) and increment the port number on proxy_pass by 1. So the first game is at the default 30000, then the next is 30001, etc.
server {
# Enter your fully qualified domain name or leave blank
server_name your.hostname.com;
# Listen on port 80 without SSL certificates
listen 80;
# Sets the Max Upload size to 300 MB
client_max_body_size 300M;
location /game1 {
# Set proxy headers
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# These are important to support WebSockets
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
# Make sure to set your Foundry VTT port number
proxy_pass http://localhost:30000;
}
location /game2 {
# Set proxy headers
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# These are important to support WebSockets
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
# Make sure to set your Foundry VTT port number
proxy_pass http://localhost:30001;
}
}
Last, we need to make nginx a service so it can run on startup in the background. Go to the folder where you unzipped NSSM, then Win64, open a command prompt and run:
nssm install nginx
This will bring up the NSSM GUI. Set the Path to nginx.exe in your nginx folder (C:\nginx\nginx.exe in our example) and set the Startup Directory to the nginx folder (C:\nginx). Click Install Service and your service will be created. You can go to the Windows Service panel to start it, and by default it will always start at boot.
Foundry
Before we create our instances, let's set up our shared data folder. Go back to your Foundry folder, and in each one of the foundrydata folders, open a Administrator command prompt and enter:
mklink /d Data ..\shareddata
This will create a directory link in that instance that points back to the shared data folder.
Next we're going to create our Foundry instances. Go back to NSSM\Win64 and open another command prompt and run
nssm install Foundry1
This time for the Path, find node.exe from your Node installation (probably in C:\Program Files\nodejs). For the Startup Directory, supply the resources\app folder inside your Foundry folder (in our example, C:\FoundryVTT\Foundry\resources\app). For Arguments, enter main.js --dataPath=C:\Foundry\foundrydata1 --port=30000. Click Install Service, then repeat that process for each instance you want to run, changing the dataPath and the port each time. The port numbers need to correspond to the ports you mapped in your nginx config earlier.
Now start all those instances in the Windows Service panel, which will create the config files we need in the right places, then stop the services again so we can modify their configs. In each of your foundrydata folders, open Config\options.json. Add or edit the following values:
"hostname": "your.hostname.com",
"routePrefix": "game1 (or whatever you specified)"
"proxyPort": 80
Done!
Now fire all your services back up and if all went well, you should be able to reach your Foundry instance at [your-domain.xyz]/game1. Keep in mind that if you don't have a router that supports loopback (most home routers don't), your external URL will not work inside your network. Edit your Windows hostfile to remap your custom domain to the correct internal IP. You can test the external URL by using a VPN.
Considerations
Remember that any changes made to shared components (modules, systems, or the Foundry engine itself) will propagate to all your instances. So if you do an upgrade on one of them, make sure you restart your other instances so they catch up.
When I set this up, I purchased a custom domain for a few dollars because I wanted to share the Foundry URLs in Facebook events (that's how most of my games are organized), and Facebook bans links from most dynamic DNS providers. I use dynv6 as my dynamic DNS provider with a Windows Task that runs every 5 minutes to keep the IP updated.
I didn't cover SSL certificates or HTTPS, but if you do obtain a certificate, the aforementioned Foundry nginx document contains the changes you need to make for SSL. Essentially just change your "listen" port in nginx to 443 ssl, add your ssl certificates, and optionally redirect non-HTTPS traffic to HTTPS. Then in your Foundry config, just change the proxyPort to 443 and set proxySSL to true.
If you want to use subdomains instead of paths for your different games, you can do that too by setting up different "servers" in nginx, and using those hostnames in the Foundry config without a routePrefix specified. I haven't tried it but I don't see why it wouldn't work.
Lastly, while this is obviously a supported configuration for Foundry, it's pretty niche so if things go wrong you're a bit on your own. I haven't had any trouble yet (aside from a single path resolving incorrectly in the PF1e system), but YMMV.
Good luck!
Posted on December 4, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.