How to Host Foundry (pt 2)

How to Host Foundry (pt 2)

In Part 1 I covered the basic setup to get foundry running on your own server running Ubuntu.

Now, don't get me wrong. A lot of people just won't want to mess with stuff like this, or won't have/want to start a private server up. I get it. For a few bucks a month you can pay the guys at Forge, punch in your license code to foundry, and get a feature set far better than Roll 20 for a lot less, in the long run, without having to maintain your own server.

Anyway - where we left off, we were able to get foundry running, and access it on port 30000. let's go back to the firewall settings and block it off again, as we won't be allowing unencrypted traffic on that port any more.

We still need to:

  • Make foundry start up automatically using PM2
  • Install NGinX
  • Configure NginX for using a URL and SSL
  • Set up foundry
  • And firewall settings, of course.

These instructions lean heavily on these pages at the foundry knowledge base:

Foundry: installation

Foundry: Configuration

Configuring NginX

PM2

PM2 is a node app that allows you to manage applications that don't normally run as services, and make sure they start up automatically.

sudo npm install pm2@latest

You'll need to use sudo for the necessary permissions.

Now, assuming that you have installed the app in the same directories I did, you can use the following (adjust paths as relevant):

pm2 start /home/ubuntu/foundryvtt/resources/app/main.js -- --dataPath=/home/ubuntu/foundrydata

Parsing the above, pm2 start is a node start as if using "node" , and the -- is the flag to pass what follows to the started app as args, so that --datapath gets passed to main.js as per the command at the end of the last post.

To see what is running, enter pm2 list and the output will look like:

pm2 list
┌─────┬─────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id  │ name    │ namespace   │ version │ mode    │ pid      │ uptime │ ↺    │ status    │ cpu      │ mem      │ user     │ watching │
├─────┼─────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0   │ main    │ default     │ 0.7.9   │ fork    │ 803      │ 7D     │ 0    │ online    │ 0%       │ 98.5mb   │ ubuntu   │ disabled │
└─────┴─────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘

Note that teh app shows up with the handle "main.", as a result, we have a few more notable commands:

pm2 stop main # will stop the app that is running with the name/handle "main"

pm2 start main # once registered, the app persists in teh database, and will start up using the same options as originally specified

pm2 delete main  # removes the app from the pm2 list. You'll need to run the full pm2 start again to get it back in

You may also need to run the following to ensure that pm2 starts up , and auto-starts any specified apps, on a reboot:

pm2 startup #generates something similar to the following:

#   sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u ubuntu --hp /home/ubuntu

pm2 save # save the state

See the pm2 quickstart page and docs for more info.

Install NginX

At this time, simply run the following:

sudo apt-get update
sudo apt-get install nginx

With NginX installed, you need to configure it to accept traffic for your domain and hand it off to foundry. Typically, you add a file in /etc/nginx/sites-available/ matching the domain name that tells NginX how to handle requests for your site. We'll assume your foundry server is running on foundry.mydomain.com.

Configure NginX

So, in /etc/nginx/sites-available/ create the needed file:

cd /etc/nginx/sites-available/
nano foundry.mydomain.com

This will swap to the appropriate directory and create/open for editing the proper file for your site. Enter the following:

server {

    # Enter your fully qualified domain name or leave blank
    server_name             foundry.mydomain.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;
    }
}

Yes, this is still unsecure/unencrypted traffic on port 80. We'll fix that soon. The above command tells nginx to act as a reverse proxy, and hand over any requests for foundry.mydomain.com to the requested app, and shunts it over to port 30000, which foundry still expects. We'll fix that as well.

Next, you need to tell nginx that the site is active, by linking the above "available sites" file under "active sites."

sudo ln -s /etc/nginx/sites-available/found.thelastredoubt.com /etc/nginx/sites-enabled/

Then:

# Test your configuration file
sudo service nginx configtest

# Start Nginx
sudo service nginx start

# Stop Nginx
sudo service nginx stop

# Restart Nginx
sudo service nginx restart

To get a free cert, provided by the EFF, you will need to download and install certbot. The most current method is to use the snap installer. Note: you will need a valid email for notifications if there are issues to do the configuration.


# check up to date
sudo snap install core; sudo snap refresh core

# no prior installs, so we can just install certbot
sudo snap install --classic certbot

# try auto config vice certonly
sudo certbot --nginx
# sudo certbot certonly --nginx

# test renewal
sudo certbot renew --dry-run

The certbot site lists several places for checking that an entry is made to schedule the auto-renew, but in my case it was revealed via systemctl list-timers

With SSL in place, the foundry.mydomain.com file under /etc/nginx/sites-available/ will look more like:

server {

    # Enter your fully qualified domain name or leave blank
    server_name             foundry.mydomain.com;

    # Listen on port 80 without SSL certificates

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

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/foundry.mydomain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/foundry.mydomain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}


server {
    if ($host = foundry.mydomain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    server_name             foundry.mydomain.com;
    listen                  80;
    return 404; # managed by Certbot

Note the additional entries that now capture https/SSL traffic on 443 and pass it along to foundry.

Finish Configuring Foundry

If you set up the data path as mentioned in the last post, then you'll find the options.json file under /home/ubuntu/foundrydata/Config - edit it using nano options.json and make it look like the following:

cat options.json
{
  "port": 30000,
  "upnp": false,
  "fullscreen": false,
  "hostname": "foundry.mydomain.com",
  "routePrefix": null,
  "sslCert": null,
  "sslKey": null,
  "awsConfig": null,
  "dataPath": "/home/ubuntu/foundrydata",
  "proxySSL": true,
  "proxyPort": 443,
  "minifyStaticFiles": true,
  "updateChannel": "release",
  "language": "en.core",
  "world": null
}

You'll need to edit the following:

  • port is the port number foundry listens on, 30000 by default.
  • hostname is the full domain nam eof your server
  • unless you're using a subdirectory such as https://foundry.mydomain.com/foundry there is no need for a routePrefix
  • ssl certs and keys are managed by NginX
  • proxyPort and ProxySSL need to be set to 443 and true, respectively, so foundry knows how to handle links.

An aside - yes, you can set up SSL directly in foundry, but this is more flexible, easier to maintain, allows you to use standard tools such as certbot, and allows you to add additional servers or services down the road.

Firewall

Don't forget to enable incoming traffic on port 443 at your VPS host.

Conclusion

At this point, you should have a working foundry tabletop server onto which you can install game systems, modules, and start uploading maps and tokens. You've had the opportunity to spin up a simple, bare-bones VPS, and access it via SSH. Via a few basic linux commands including apt-get, cd, ls , nano, and so on, we installed and did a basic config of nginx - which has a lot of power and is a deep rabbit hole to go down - and installed foundry.

Look up any commands you're not familiar with, and have fun!

About Last Redoubt