More fun with containers
I only recently came across Foundry VTT, and my quick look at it convinced me to try it further. This afternoon, I had it up and running in less than an hour, and you can too!
This assumes you have Docker installed and running, and are comfortable with some basic concepts. I also use traefik for basic routing/termination, but this is optional; it lets me access the service at a nicer looking URL like https://rpg.example.com, but it is accessible without. This also assumes you have access to the Foundry VTT software; if you don’t, go to the Patreon and get it already!
Basic Setup
All it takes to get Foundry VTT running are six simple steps:
- Create a new directory for Foundry on the host running Docker.
- Download the Dockerfile and docker-compose.yml
- Edit the Dockerfile and add the URL to the Foundry VTT zip file
(NB if you already have the zip file, you can use aCOPYstatement as described in the Dockerfile) - Create the directory for data persistence (if you are using a bind mount as described in docker-compose.yml) as
./foundryvtt-data - run
docker-compose build— this will create a minimal image with Node.js based on alpine, pull and extract the zip with the Foundry VTT software - run
docker-compose up— this will run the application in attached mode, you should see console lines like the following:
foundryvtt | FoundryVTT | 2020-04-10 09:56:27 | [info] Foundry Virtual Tabletop - Version 0.5.3 foundryvtt | FoundryVTT | 2020-04-10 09:56:27 | [info] Running on Node.js - Version 12.16.1 (...) foundryvtt | FoundryVTT | 2020-04-10 09:56:27 | [warn] Software license requires signature. foundryvtt | FoundryVTT | 2020-04-10 09:56:27 | [info] Requesting UPnP port forwarding to destination 30000 foundryvtt | FoundryVTT | 2020-04-10 09:56:28 | [info] Server started and listening on port 30000
And at this point you are good to go! Go to the docker host’s IP at port 30000 in your browser — if you are running locally this would be http://localhost:30000 — and you should see the Foundry VTT license page:

If instead you get the following odd errors in the console:
foundryvtt | (node:1) UnhandledPromiseRejectionWarning: TypeError: Cannot destructure property 'app' of '_0x1b0815' as it is undefined.
foundryvtt | at initialize (/home/foundry/app/resources/app/dist/init.js:1:3804)
foundryvtt | at Object. (/home/foundry/app/resources/app/main.js:153:16)
foundryvtt | at Module._compile (internal/modules/cjs/loader.js:1158:30)
foundryvtt | at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
foundryvtt | at Module.load (internal/modules/cjs/loader.js:1002:32)
foundryvtt | at Function.Module._load (internal/modules/cjs/loader.js:901:14)
foundryvtt | at Function.executeUserEntryPoint as runMain
foundryvtt | at internal/main/run_main_module.js:18:47
foundryvtt | (node:1) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch b
lock, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=st rict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
foundryvtt | (node:1) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the
Node.js process with a non-zero exit code.
That arises from not creating the persistence data directory or it having the wrong permissions. (Re) create it and make sure it is owned and read-writeable by UID 1000.
From here you are good to go!
Further Configuration
I have TLS configured in traefik, so by adding labels to the service in the docker-compose.yml file, I can access it via domain, rather host and port.
For example:
labels: - "traefik.enable=true" - "traefik.http.routers.foundryvtt.rule=Host(`rpg.example.com`) && PathPrefix(`/foundry`)" - "traefik.http.services.foundryvtt.loadbalancer.server.port=30000" - "traefik.http.routers.foundryvtt.tls=true" - "traefik.http.routers.foundryvtt.tls.certresolver=myresolver"
WordPress’ preformatted block looks garbage, so see this gist instead with explanatory lines.
Note that this example serves Foundry VTT from https://rpg.example.com/foundry , which requires editing the application’s options.json file and setting "routePrefix": "foundry" (note no slashes!). I also set "hostname": "rpg.exmaple.com" (not strictly needed) and "upnp": false (since ports managed by Docker).
The above labels also set a loadbalancer port for Traefik, since I do not have a ports mapping in my docker-compose.yml.
In my own case I’m tying together Foundry with the other RPG-related services I mentioned recently (Wekan and Bookstack), but this isn’t necessary. I can’t wait to actually use Foundry!
Pingback: Coding Basic Modules For FoundryVTT – Rob's Blog