Skip to content

Instantly share code, notes, and snippets.

@mr-rigden
Last active August 27, 2025 05:38
Show Gist options
  • Select an option

  • Save mr-rigden/4e0f9226bcd86b796bcc27db3d9126e8 to your computer and use it in GitHub Desktop.

Select an option

Save mr-rigden/4e0f9226bcd86b796bcc27db3d9126e8 to your computer and use it in GitHub Desktop.
Jason Rigden's Foundry VTT Install Notes

Jason Rigden's Foundry VTT Install Notes

July 9, 2025 These are my personal notes for running Foundry VTT version 13 behind Caddy 2 on a Debian 12 server in the cloud. I'm using OliveTin as a web interface to restart Foundry VTT, Caddy 2, or just reboot the server. I also use Restic for backups. I'm sure I've made some mistakes, errors, and omissions.

I attempted to use LLMs to help create these notes. I tried ChatGPT, Gemini, and Claude. They were all dog shit. They consistently confused software versions and gave incorrect instructions. Their output of configuration files were needlessly verbose to the point of literally making up parameters and breaking syntax. The generated config files for Caddy 2 were particularly insane, with it often mixing totally different config formats in the same file. All in all, the LLMs only served to waste my time. LLMs: Overrated, unreliable. Would not recommend. Just RFTM

Quick Install

Connect

ssh <user>@<your-server-ip>

Update System

sudo apt update
sudo apt upgrade

Install Some Essential Software

sudo apt install curl htop unzip nano build-essential git

Add User

sudo adduser frank
sudo usermod -aG sudo frank

Login As frank From Remote Client

ssh frank@<server-ip>

Make Some Directories

mkdir -p /home/frank/foundry/rigden/{core,data}

Install Node

curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt update
sudo apt install nodejs

Install Caddy

sudo apt install debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
sudo systemctl enable caddy

Install PM2

sudo npm install -g pm2

Install Foundry

cd /home/frank/foundry/rigden/core
wget -O foundry.zip <timed link>
unzip foundry.zip
rm foundry.zip

Test Foundry

I'm using --max-old-space-size=4096 to give node more memory.

node --max-old-space-size=4096  /home/frank/foundry/rigden/core/main.js --name foundry --dataPath=/home/frank/foundry/rigden/data

Configure PM2

pm2 start "node --max-old-space-size=4096  /home/frank/foundry/rigden/core/main.js --name foundry --dataPath=/home/frank/foundry/rigden/data"  --name rigden-foundry
pm2 save
pm2 startup

Run provided by PM2 command in the output.

Configure Caddy 2

 sudo nano /etc/caddy/Caddyfile

Then edit:

<your-domain> {
    reverse_proxy localhost:30000
}

Restart Caddy with the new Config

sudo service caddy restart

Configure Foundry

nano /home/frank/foundry/rigden/data/Config/options.json

"hostname": " <FoundryInstanceDomainName>

Restart Foundry

pm2 restart rigden-foundry

Utilities and Backup

Install OliveTin

wget https://github.com/OliveTin/OliveTin/releases/latest/download/OliveTin_linux_amd64.deb
sudo dpkg -i OliveTin_linux_amd64.deb
rm OliveTin_linux_amd64.deb

Configure OliveTin

sudo nano /etc/OliveTin/config.yaml

Edit:

listenAddressSingleHTTPFrontend: 0.0.0.0:7331

# Choose from INFO (default), WARN and DEBUG
logLevel: "DEBUG"

# Checking for updates https://docs.olivetin.app/reference/updateChecks.html
checkForUpdates: true

actions:
  - title: Restart Rigden Foundry
    icon: disk
    shell: su - frank -c "pm2 restart rigden-foundry"
    popupOnStart: execution-dialog-stdout-only

  - title: Caddy 2 Web Server
    icon: disk
    shell: sudo service caddy restart
    popupOnStart: execution-dialog-stdout-only


  - title: Reboot Server
    icon: disk
    shell: reboot
    popupOnStart: execution-dialog-stdout-only

Then:

sudo systemctl enable --now OliveTin

Configure Reverse Proxy

We will be using BasicAuth to protect OliveTin. So need to hash a password.

caddy hash-password --plaintext <your-password>

Copy the output for later. Now let Caddy proxy OliveTin.

sudo nano /etc/caddy/Caddyfile

Add:

<your-control-domain> {
    basicauth {
        frank <hashed-password>
    }
    reverse_proxy localhost:7331
}

Now restart Caddy.

sudo service caddy restart

Security and Optimization

Make SSH keys on local computer

ssh-keygen -t ed25519 -b 4096 -C "your_email@example.com"
ssh-copy-id -i ~/.ssh/id_ed25519.pub <user>@<your-server-ip>

Harden SSH

sudo nano /etc/ssh/sshd_config

Change:

PermitRootLogin no
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM no

The restart the SSH service.

sudo systemctl restart ssh

Security and Optimization

Setup firewall

sudo apt install ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Setup Fail2Ban

sudo apt install fail2ban python3-systemd
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

Edit to tell Fail2Ban to use Systemd

 sshd_backend = systemd

And then Enable for SSH.

[sshd]
backend=systemd
enabled = true
port = 22
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600

Then reload and restart the Fail2Ban Service.

sudo systemctl enable fail2ban
sudo systemctl reload fail2ban
sudo systemctl restart fail2ban

You can check on your jails.

sudo fail2ban-client status sshd

Install Restic

To backup our Foundry games, I've chosen Restic and Backblaze 2. Don't use default distro version of restic. It is old. Download current version and make and alias.

Configure Restic

Data Needed: Backblaze B2 Bucket Name='' AWS_ACCESS_KEY_ID='' AWS_SECRET_ACCESS_KEY='' RESTIC_PASSWORD=''

sudo apt install restic
mkdir /home/frank/config
nano /home/frank/config/backup.env

Edit:

AWS_ACCESS_KEY_ID=<AWS_ACCESS_KEY_ID> AWS_SECRET_ACCESS_KEY=<AWS_SECRET_ACCESS_KEY> RESTIC_PASSWORD=<RESTIC_PASSWORD>

Initialize first backup:

source /home/$FoundryUser/backup/backup.env
restic -r s3:https://s3.us-west-004.backblazeb2.com/<bucket-name> init

And now we preform our first backup.

source /home/frank/config/backup.env
pm2 stop rigden-foundry
restic -r s3:https://s3.us-west-004.backblazeb2.com/<bucket-name> --verbose  backup /home/frank/foundry
pm2 start rigden-foundry

Configure Unattended-Upgrades

sudo apt install unattended-upgrades apt-listchanges
sudo nano /etc/apt/apt.conf.d/50unattended-upgrades

Set hostname

hostnamectl set-hostname <server-name>

Set Time

timedatectl list-timezones
sudo timedatectl set-timezone America/Los_Angeles
timedatectl set-ntp true

Create Swap

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf

Allow more connections

sudo nano /etc/security/limits.conf

Add:

* soft nofile 65536
* hard nofile 65536

Optimize TCP Settings for Slow Boys

sudo nano /etc/sysctl.conf

Add these lines at the end:

# TCP optimizations for slow boys
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_slow_start_after_idle = 0
net.core.netdev_max_backlog = 2500
net.ipv4.tcp_congestion_control = bbr

Reload settings.

sudo sysctl -p

Reboot System

sudo reboot

Remove Sudo Privileges

While initially convenient, we don't want to run a program like Foundry with sudo permissions.

sudo deluser frank sudo

Info

IP

Default User's Name

Foundry Instance Name

Secrets

Default User's Password

Frank's Password

Backblaze B2 Bucket Name

AWS_ACCESS_KEY_ID

AWS_SECRET_ACCESS_KEY

RESTIC_PASSWORD

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment