Workload · Running a Foundry VTT campaign

A self-hosted Foundry VTT server your players can reach any night

Yes, Foundry VTT can live on a machine you rent instead of your PC: you install the Node.js version of Foundry Virtual Tabletop, run it as a background service, and put a web server with a free HTTPS certificate in front so your players simply open your address in a browser. You buy one Foundry licence as the game master; your players never need one. Below is what the server needs, how to set it up safely, following Foundry's own knowledge base and saying where we add to it, and how to keep a copy of your worlds that survives a lost server.

The short version
  1. Your world stays online between sessions
  2. Your group needs only your licence, not their own
  3. Small needs: 2 GB of memory minimum, 4 GB recommended
  4. Admin password set privately before anyone can see the server
  5. A full archive of your worlds that you keep off the machine

Why move your game off your own computer

When Foundry runs on your PC, your world exists only while the app is open. Close it to play something else and your players lose access. Foundry's hosting guide lists the main gain of a server in a data center: the world can stay online, so players can update their character sheets between sessions and you can run a quick meeting without booting your desktop.

It also removes the home-network headaches. Hosting from home means forwarding a port on your router, and Foundry says some internet providers make that impossible because they use carrier-grade NAT. A server has a public address of its own, so there is nothing on your router to change.

How much server does Foundry need?

Very little, because your players' own browsers do the heavy lifting, not the server. Foundry's minimums for a dedicated host are:

  • one virtual CPU, with two recommended;
  • 2 GB of memory, with 4 GB recommended;
  • at least 1 GB of disk space;
  • an operating system with glibc 2.28 or later;
  • Node.js 22 if you run V13 or earlier, and Node.js 24 for V14 onwards.

Two things push those numbers up. A rules-heavy system with many add-on modules uses more memory than a light one. And your maps, tokens and music all sit on the server's disk and travel to every player, so a campaign rich in battle maps and ambient audio needs space and a good connection more than it needs processor speed.

What the licence lets you do

You pay for Foundry once, and that single licence hosts one game server for as many players as you like. Your players connect for free. The rule to know is that a key may be in active use in one place: you may keep a second copy for your own prep work if nobody else can log in to it, but if your home copy and your server are both open to the group at the same time, Foundry asks for a second licence.

Your server has to contact Foundry one time, during activation, to check the key and record the agreement. After that it runs on its own.

The server that fits

A Primcast dedicated server is a whole computer that runs your campaign and nobody else's, with root access and no contract: stay as long as the campaign lasts and cancel when any month ends. The small cartridge servers are described on that page as ideal when you have one job to run, and hosting one Foundry world is exactly that. Even the smallest has 8 GB of memory, twice what Foundry recommends.

  • Ready servers are handed over within 30 minutes of payment approval.
  • Bandwidth is unmetered, so a session where everyone downloads a new map pack does not show up on your bill.
  • On rack servers and blades, plus two cartridge models (m510, m710x), you get the console screen and power button even when SSH stops answering. The rest of the cartridges offer a power switch alone; a reinstall through the control panel takes about ten minutes.
  • Your server comes with one IPv4 address, and IPv6 costs nothing, so the firewall steps below protect both kinds of address.

Choose the city closest to most of your players on the data center map. If the group also plays other games together, the game server page shows the rest of the range.

Up and running in an evening

These steps assume Ubuntu. The order matters: the firewall goes up first, so Foundry is never reachable from the internet before you have protected it.

  1. Turn on the firewall with only SSH allowed. These ufw steps are our addition: Foundry's guide only says to let its port through your firewall. Ubuntu's firewall guards IPv6 too as long as /etc/default/ufw says IPV6=yes, as it does out of the box.
  2. Install Node.js 24 from NodeSource, the source Foundry's guide uses. Its example still says version 20, below Foundry's own minimum, so the number is changed here. Running V13 rather than V14? Swap in setup_22.x, because V13 cannot start under Node 24. The setup script runs as root, so you may want to read it before piping it in.
  3. Create a separate foundry account that cannot log in, and let it own the program and your data, so Foundry never runs as root. This step is ours; Foundry's guide never mentions it.
  4. In your Foundry account, pick the Node.js download and press Timed URL. That link works for five minutes. Paste it when our read -rp prompt asks, so it stays out of your shell history (while the download runs, ps can still show it).
sudo ufw default deny incoming
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status verbose

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

sudo useradd --system --create-home --home-dir /srv/foundry \
  --shell /usr/sbin/nologin foundry
sudo -u foundry mkdir -p /srv/foundry/vtt /srv/foundry/userdata
read -rp 'Paste the timed download link: ' URL
sudo -u foundry wget -O /srv/foundry/vtt/foundryvtt.zip "$URL"
sudo -u foundry unzip /srv/foundry/vtt/foundryvtt.zip -d /srv/foundry/vtt

Foundry suggests systemd to keep a standalone server running but gives no unit file, so we wrote the unit below ourselves, including the --noupnp flag and Restart=always. Save the unit as foundryvtt.service in systemd's folder, /etc/systemd/system/, run a daemon-reload, and start Foundry with sudo systemctl enable --now foundryvtt. The restart line is always because Foundry closes itself, cleanly, every time you save its configuration.

[Unit]
Description=Foundry VTT
Wants=network-online.target
After=network-online.target

[Service]
User=foundry
Group=foundry
WorkingDirectory=/srv/foundry/vtt
ExecStart=/usr/bin/node /srv/foundry/vtt/main.js --dataPath=/srv/foundry/userdata --noupnp
Restart=always
RestartSec=5
NoNewPrivileges=true

[Install]
WantedBy=multi-user.target

Lock the Setup screen before anyone else can see it

Foundry now answers on port 30000, but only you can reach it, through an SSH tunnel from your own computer: ssh -N -L 30000:localhost:30000 you@your.server. Open http://localhost:30000 in your browser and:

  1. paste the key from your Foundry account and agree to the licence terms;
  2. go to the Configuration tab and set the Administrator Password, which Foundry strongly recommends and which guards the Setup screen;
  3. save, give the service a moment to come back, and check that a password prompt now guards the Setup screen.

Foundry also accepts an --adminPassword flag at launch. Skip it: anything on a command line can be read by other users through ps, and the service file is readable by everyone on the machine. Foundry keeps the password you set in the browser encrypted in its Config folder.

Give your players a proper web address

Players should type a name like vtt.example.com, not an IP and a port, and the connection should be HTTPS: browsers only hand a page your webcam and mic when it is served over HTTPS, and Foundry's built-in audio and video chat needs both. Install nginx and create /etc/nginx/sites-available/foundryvtt from Foundry's example, plus an IPv6 line of our own (listen [::]:80):

server {
    server_name vtt.example.com;
    listen 80;
    listen [::]:80;
    client_max_body_size 300M;

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass http://localhost:30000;
    }
}
  1. Enable it with a link in /etc/nginx/sites-enabled/, let sudo nginx -t look for typos, and restart nginx if it is happy.
  2. Let web traffic in on IPv4 and IPv6 using sudo ufw allow 'Nginx Full' (our rule, not Foundry's). Port 30000 itself stays shut.
  3. Once your domain's A record (IPv4) and AAAA record (IPv6) lead to the server, install certbot and python3-certbot-nginx, then run sudo certbot --nginx --redirect -d vtt.example.com for a free certificate and an automatic HTTP-to-HTTPS redirect. That command is our choice: Foundry recommends Certbot but shows a hand-written HTTPS block instead.
  4. Stop Foundry, copy Config/options.json somewhere safe, then set hostname to your domain, proxyPort to 443 and proxySSL to true, so the invitation links you send are correct. Start it again.

Keeping your campaign safe

Months of session notes and handmade maps deserve two kinds of backup. Foundry's own backup tool, the Manage Backups button on the Setup screen, takes a Snapshot: make one before every big update. It is stored inside your user data on the same disk, though, and it leaves out media files kept outside your worlds, systems and modules, so also keep a full copy somewhere else.

For that copy, Foundry's guide shuts the server down first, then packs the Data and Config folders into one archive with tar. On this setup that is sudo systemctl stop foundryvtt, then sudo tar -czf /root/vtt-backup-$(date +%F).tar.gz -C /srv/foundry/userdata Data Config, then sudo systemctl start foundryvtt. The archive lands in root's private home because Config holds sensitive settings; that location and the steps to fetch it are ours. Since /root is mode 700, your own login cannot copy it from there, so run sudo install -m 600 -o "$USER" /root/vtt-backup-$(date +%F).tar.gz ~/, scp it to your computer, then remove the one left in your home directory. Do not aim Dropbox-style sync tools at a live user data folder, which Foundry warns can corrupt worlds.

As for updates, Foundry never makes you take one. Stick to Stable releases for real games, wait until your game system and favourite modules show compatibility with the new version, and know that the two generations want different Node.js releases: Node 24 is required by V14, and V13 cannot run on it. Our own order for the move: take a Snapshot, stop the service, rerun the NodeSource script as setup_24.x, reinstall the nodejs package, rename the old program folder (sudo mv /srv/foundry/vtt /srv/foundry/vtt-old, then sudo -u foundry mkdir /srv/foundry/vtt), download the V14 Node.js zip into the new folder with a fresh timed link, repeating the download lines from the install step (read -rp, then wget), unpack it with sudo -u foundry unzip /srv/foundry/vtt/foundryvtt.zip -d /srv/foundry/vtt, and start it again. Keep vtt-old until the new version has run a session: together with the Snapshot it is your route back, but the older release needs Node 22 again first. To go back: stop the service, remove the nodejs package, rerun the NodeSource script as setup_22.x and install nodejs again; then move the V14 folder aside (sudo mv /srv/foundry/vtt /srv/foundry/vtt-v14), move vtt-old back (sudo mv /srv/foundry/vtt-old /srv/foundry/vtt), start the service and restore your Snapshot from Manage Backups.

If your group only plays a few hours a week and your home upload is decent, the desktop app is still a fine choice: Foundry's guide suggests an upload speed of 12 Mbps or more when you host from home. A server is worth it when you want the world always on, with no router to fight.

Questions people ask

Is Foundry free for the players in my group?
Yes. Only the person hosting buys a licence. Everyone else opens your address in a browser and logs in with the user and access key you give them.
What port does Foundry use, and should I open it?
Foundry listens on TCP 30000 by default. On this setup you keep that port closed and open only 80 and 443 for nginx, which passes traffic to Foundry on the same machine. That way every player connects over HTTPS.
Where are my worlds stored on the server?
In the folder the service file names with --dataPath, here /srv/foundry/userdata. Your worlds, systems, modules and uploaded media are in its Data folder, and settings such as options.json are in Config.
Can I run my weekly game and a private prep world on one licence?
Yes, if only you can get into the prep copy. Foundry's FAQ allows that, but two servers your players can use simultaneously require a second licence.
What happens if I lock myself out with the firewall?
If your server has a console (rack servers, blades, and the m510 or m710x cartridge), open it from your dashboard and fix the rule. Without one you only get a power switch, so you would reinstall the operating system and restore your backup archive.

Give your campaign a permanent home

A whole server for your table, month to month, with a person on our team a chat message away.

Get a server for your campaign

Read next