Update 03.10.21

While you can use cron to schedule the Foundry instance to start at reboot, apparently there are known errors when using @reboot. See more here. Because of this, I've changed the tutorial to instead show how to use a systemd service. This also allows for easier troublshooting and a better way to start or stop an instance.

Initial Setup

My setup prior to starting this included:

  • Raspberry Pi 4b/4GB with Raspberry Pi OS Lite
  • Domain pointing at my IP
  • Port forwarding (80) from my router to RasPi

The biggest initial setup step for me was figuring out how to update my DNS records with a dynamic IP. I solved this by transitioning to Cloudflare as my DNS name server. I then followed this tutorial which creates a script to auto update your IP address on Cloudflare.

Use Cloudflare as Dynamic DNS with Raspberry Pi - Let’s WP
Make Raspberry Pi automatically update a domain after your IP changes. Gain access to your home server from anywhere with Cloudflare as Dynamic DNS.

There are a few other ways to do this, but this worked great for me.

I also installed and enabled UFW so that I'd have a simple but effective firewall in place.

sudo apt install ufw
sudo ufw allow 22
sudo ufw allow 80
sudo ufw enable

Note that if you plan on using SSL certificates through HTTPS you'll want to also allow 443 for UFW.

I'd highly recommend taking a look at this article to increase your server security just a bit more as well.

Securing your Raspberry Pi - Raspberry Pi Documentation
Documentation in this section includes basic guides to configuring your Raspberry Pi.

Foundry Installation

In order to install Foundry as a server, you first need to install Node.js.

sudo apt install -y libssl-dev
curl -sL https://deb.nodesource.com/setup_14.x | sudo bash -
sudo apt install -y nodejs

After that, create a directory for the application as well as one for the app data. If you want to have multiple worlds running, I've included how to do that at the end. Skip ahead here.

# Create application and user data directories
mkdir foundry
mkdir data

Now, change into the application directory. Then, download and unzip Foundry. For the nodejs-download-url, you'll need to have a foundry license. When you do, access your Purchased Licenses page and click on the chain icon next to the Node.js zip file. This will generate a temporary link to use with wget.

After you've downloaded it with wget and unpacked it, you can then start the Foundry application. Verify it's running by visiting localhost:30000.

# Install the software
cd foundry
wget -O foundryvtt.zip "nodejs-download-url"
unzip foundryvtt.zip

# Start running the server
node resources/app/main.js --dataPath=$HOME/data

You can then click CTRL+C to stop it.

In order to have it launch at reboot, we'll make a systemd service. If you plan on running multiple instances, you'll want to name the systemd services accordingly.

sudo nano /etc/systemd/system/foundry.service

Copy and paste the text below into the new service file. Replace USER with the correct username. CTRL+S and CTRL+X to save and exit.

[Unit]
Description=Foundry VTT Server
# This ensures it starts after network is online
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
# What this service does
ExecStart=node /home/USER/foundry/resources/app/main.js --dataPath=/home/USER/data

[Install]
WantedBy=multi-user.target

After you've saved and exited this file, start it with systemctl and check its status to ensure there are no errors present.

sudo systemctl start foundry.service
sudo systemctl status foundry.service
# press "q" to exit the status

You can stop the service at any point using:

sudo systemctl stop foundry.service

If you need to go back and edit this, run sudo systemctl daemon-reload afterwards to check for and apply any changes made to services.

All that is necessary to start the Foundry instance at boot is to enable it with systemd.

sudo systemctl enable foundry.service

If you need to disable it a boot, use disable instead of enable.

You can read more about systemd services here:

systemd - ArchWiki

Nginx Installation

Now all we have to do is get the proxy server running so you can access Foundry from your domain name.

First, we need to install Nginx.

sudo apt install nginx

Now run sudo systemctl start nginx and visit localhost to verify that it is running correctly. You should see the splash shown below.

The next step is to create the configuration file for your site. Create this file, replacing mysite.com with your domain. Note that if you plan on hosting multiple worlds on different subdomains, you don't have to create a new file for each. You can make the config file be named as the top level domain name and then have multiple subdomain proxy servers within it.

sudo nano /etc/nginx/sites-enabled/mysite.com.conf

Copy and paste the text below into your file, changing mysite.com to your own domain. The proxy_pass line tells Nginx where Foundry is hosted locally. CTRL+S and CTRL+X to save and exit.

# Define Server
server {

    # Enter your fully qualified domain name
    server_name             mysite.com;

    # Listen on port 80 without SSL certificates
    listen                  80;

    # Sets the Max Upload size to 300 MB
    client_max_body_size 300M;

    # Proxy Requests to Foundry VTT
    location / {

        # 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;
    }
}

After setting up the Nginx proxy, you need to edit a few lines in options.json for Foundry. This is located in the data folder created earlier. Open it and change the following lines to make sure they match, replacing mysite.com with your domain. CTRL+S and CTRL+X to save and exit.

nano data/Config/options.json
"hostname": "mysite.com",
"routePrefix": null,
"sslCert": null,
"sslKey": null,
"port": 30000,
"proxyPort": 80

After this, run a test of your Nginx config, and if there are no errors, then reload Nginx with systemctl.

sudo nginx -t
sudo systemctl reload nginx

If you get the error: "could not build the server_names_hash, you should increase server_names_hash_bucket_size: 32", edit nginx.conf and uncomment the line below which will change it to 64. If the error repeats with 64, increase the number by the power of two. Read more here. CTRL+S and CTRL+X to save and exit.

sudo nano /etc/nginx/nginx.conf
server_names_hash_bucket_size: 64 #uncomment this line

Congrats! You've now got a Foundry server hosted on your Raspberry Pi.

Running Simultaneous Worlds

In order to run multiple worlds at the same time, you will need separate Foundry licenses for each.

Essentially, you'll have multiple Foundry applications running at the same time. This means that you'll need separate application directories for each as well as separate ones for data. However, Foundry does support symbolic links, which means that you can share certain data directories between different Foundry instances. You will also want to setup additional domains for each Foundry instance.

First, you'll want to create the additional directories needed, i.e. foundry2 and data2. You can do this easily by copying the original directories. Using cp -r we can duplicate the folders needed.

# make sure that you're in the home directory
cd

# copy app and data directories
cp -r foundry foundry2
cp -r data data2

If you want to use some of the same data for multiple instances (art assets, modules, systems, or worlds), you can do this using symbolic links. Below is an example of sharing modules from the original data directory to the additional data2 directory, which you can replicate with anything else in the Data directory.

# change to directory where duplicates will be linked
cd data2/Data

# delete the directories you want to link,
# then link them from the original data directory
rm -rf modules && ln -s $HOME/data/Data/modules/

Before starting the new instance, we need to edit the options.json file in the new data folder as well as add the new site to the Nginx config file.

Edit the options.json file in the new data directory and change the port number, hostname, and data path. CTRL+S and CTRL+X to save and exit.

nano data2/Config/options.json
"port": 30001,
"hostname": "mysecondsite.com",
"dataPath": "/home/USER/data",

Next, you'll want to open up your Nginx config file, mysite.com.conf.

sudo nano /etc/nginx/sites-enabled/mysite.com.conf

Below is an example of one Foundry instance running on mysite.com over port 30000 and an additional instance running on mysecondsite.com over port 30001.

# First Server
server {

    # Enter your fully qualified domain name
    server_name             mysite.com;

    # Listen on port 80 without SSL certificates
    listen                  80;

    # Sets the Max Upload size to 300 MB
    client_max_body_size 300M;

    # Proxy Requests to Foundry VTT
    location / {

        # 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;
    }
}

# Second Server
server {

    # Enter your fully qualified domain name
    server_name             mysecondsite.com;

    # Listen on port 80 without SSL certificates
    listen                  80;

    # Sets the Max Upload size to 300 MB
    client_max_body_size 300M;

    # Proxy Requests to Foundry VTT
    location / {

        # 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;
    }
}

After that, all you need to do is reload Nginx and setup the additonal server to start at reboot, and add the new Foundry license.

If you copied over the data folder before entering your license, you can move on to the next step. Otherwise, you need to delete the license.json file located in the new data directory. In this example, that would look like this:

rm data2/Config/license.json

Now after you access the new site, you can enter the correct license.

The next step is to reload Nginx.

sudo systemctl reload nginx

And the last step is to add a new systemd service for your additional instance. Make sure you have the correct foundry and data locations. CTRL+S and CTRL+X to save and exit.

sudo nano /etc/systemd/system/foundry2.service
----------------------------------------------
[Unit]
Description=Foundry VTT Server
# This ensures it starts after network is online
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
# What this service does
ExecStart=node /home/USER/foundry2/resources/app/main.js --dataPath=/home/USER/data2

[Install]
WantedBy=multi-user.target

Enable it and reboot, and you'll have two instances of Foundry running on your Pi!

sudo systemctl enable foundry2.service

Final Thoughts

Technically, these instances will be running over HTTP. Personally I have Cloudflare handling the SSL for HTTPS, but you can use Certbot to make your own SSL certificate to use with Nginx. I'd recommend checking out this tutorial if you'd like to go that route:

Self-Hosting Foundry VTT on a Raspberry Pi
How to set up Foundry VTT behind a webserver on a Raspberry Pi, with nginx and SSL.

Transferring files to and from your server can be accomplished through FileZilla or Samba. If you want to back up each Foundry instance, you can simply copy the data folders for each.

Sources:

https://foundryvtt.com/article/installation/

https://foundryvtt.com/article/nginx/

Photo by Harrison Broadbent on Unsplash