Press "Enter" to skip to content

FoundryVTT on Fly.io

FoundryVTT is a high quality virtual online tabletop platform. Unlike Roll20, however, there’s not a central server — once you buy a license, you have to run it someplace. There are a few services that will do this for you at a reasonable price, but I’m a geek, so if I start using FoundryVTT I want to host it myself.

Fly.io is a very cool new application hosting cloud. I experimented with it a month ago for hosting an NJPWWorld RSS feed generator and it was awesomely simple. They support persistent disk, so I couldn’t see any reason why it wouldn’t work for FoundryVTT. And it did! Details after the cut.

Setting up Fly.io is really easy. Start with their speedrun guide; do the first couple of steps until you’re logged in. Everything runs through their command line app, flyctl. If that guide is too terse for you, use this one and stop when you get to “Creating an App on Fly.”

Fly.io uses Amazon’s FirecrackerVM technology, but to make life simple, you build a fly.io app using a Docker image. There are a bunch of preconfigured solutions to running FoundryVTT in Docker. I used the simplest one, mikysan’s simple dockerfile, because Fly.io handles all the reverse proxying that’s built into some of these more complex solutions.

That Dockerfile needs you to download FoundryVTT yourself. You want the linux version, as per this page. Download it and unzip it, and then download Dockerfile from mikysan’s repo into the foundryvtt directory.

To verify that everything was working, I wanted to get FoundryVTT up and running locally first. I already had Docker Desktop installed, but if you don’t, you can find it here. It’s a pretty easy install.

OK, so let’s build and run this sucker. Building:

docker build -t foundryvtt .

Lots of build status, and done. Hm; for the sake of testing, it’s going to need a data directory, so I made one:

mkdir ./data

Running the Docker container:

docker run --name fvtt \
  -p 30000:30000 \
  -v `pwd`/data:/home/foundry/data \
  -d foundryvtt

Pulled up my Docker Desktop dashboard, and whoops, it exited. What do the logs say?

[ERROR] You are using Node.js version 12.22.4. Foundry Virtual Tabletop requires Node.js version 14.x or greater.

Easy fix. Edit the Dockerfile. At the very top there’s a line that says FROM node:12-alpine; edit that to read FROM node:14-alpine. This means “use the node.js 14.x base image.” I actually guessed at the right image name here, but if I’d needed to look it up I could have done so here.

OK. Ran the Docker image again using the above command, and everything worked fine. I had a brief problem with being unable to enter the license key, but it turns out that’s a Safari issue and you can just use Chrome. You can also select Develop -> Experimental Features -> WebGL 2.0 in Safari if you like.

Great. Now let’s get it over to fly.io. This is really astoundingly simple. If you have a working Docker image, you just type:

flyctl launch

You may need to select an organization; you can just use personal here. There’s some fun stuff you can do with organizations and buying credits in advance, which helps keep a lid on unexpected costs, but it’s out of scope for this post. You’ll also need to choose a region. The default choice is fine.

It’ll then ask you if you want to deploy. Say no, because we’ve got some config changes to make first.

Edit fly.toml — the launch command just created it in the same directory you’re already working in. You need to make two changes.

First, find the line that reads internal_port = 8080. Change that to read internal_port = 30000. FoundryVTT runs on port 30000 by default, and fly.io needs to know where to forward incoming HTTP traffic.

Second, add a new block to the end of the file. It should look like this:

[[mounts]]
     source="foundryvtt_data"
     destination="/home/foundry/data"

This tells fly.io to mount the persistent volume named “foundryvtt_data” into the container at /home/foundry/data, which is where our FoundryVTT installation expects to save data. The end of the Dockerfile looks like this:

CMD ["node", "./resources/app/main.js", "--headless", "--dataPath=/home/foundry/data" ]

See the dataPath at the end? If you don’t make sure that’s persistent storage, it’ll go away when the container restarts.

However, you haven’t created that persistent volume yet, so let’s do that now:

flyctl volumes create foundryvtt_data --region sea --size 10

This creates a 10 GB volume (the --size parameter) in the Seattle region. If you used a different region when you ran flyctl launch, use that region here. It’ll still work if you don’t but it’ll be slower. foundryvtt_data is the name of the volume. You don’t really need 10 GB for this but that’s the minimum volume size fly.io supports.

By the by, this is the only thing that’s going to cost you any money. Your usage of FoundryVTT on fly.io will fit in the free tier easily, but persistent storage isn’t free. It costs $0.15/GB per month of provisioned capacity, which means this’ll cost you $1.50 a month. Still cheaper than the hosted options!

Now we’re done with configuration changes. Type:

flyctl launch

It’ll churn a bit while building a new image, and eventually you should see something like:

==> Creating release
Release v0 created

You can detach the terminal anytime without stopping the deployment
Monitoring Deployment

1 desired, 1 placed, 1 healthy, 0 unhealthy [health checks: 1 total, 1 passing]
--> v0 deployed successfully

Immediately type:

flyctl open

This will launch the Web site in your browser. Enter your license key and accept the license agreement. Then click on Configuration and enter an Administrator Password. Finally, click the Save Changes button. FoundryVTT will ask you if you’re sure. You are.

I don’t know of any way to preconfigure this password effectively; until you do this, someone else could in theory come along and take over your installation. It’s a minor risk but it’s still wise to close the hole as quickly as possible.

You now have a working FoundryVTT installation. If you’re curious, you can type flyctl ssh console to get a shell on the container. Do df -k and you’ll see /home/foundry/data mounted from the persistent volume. Cool stuff.

Let me know if you have any questions!

Be First to Comment

Leave a Reply

Your email address will not be published.