Giter Club home page Giter Club logo

foundryvtt-raspberry-pi-4's Introduction

How to run FoundryVTT on a Raspberry Pi 4 using nginx and foundryvtt-docker

Prerequisites:

Format SSD so you can boot from it

  1. Install Pi OS on the external SSD. I downloaded Raspberry Pi Imager on my adjacent Mac and used that to install the latest Raspbery Pi OS.

Screen Shot 2020-11-17 at 10 05 03 PM

  1. Once the install finishes, unplug the SSD, remove the SD card from your raspberry pi (if it has one), plug in the SSD, and boot it up from the SSD.

Setup Steps

Basically just follow the steps as indicated on the FoundryVTT installation instructions for Node.js, Nginx, and foundryvtt-docker. You can get 5 free subdomains from DuckDNS.

  1. Go to www.duckdns.org, sign in, and create a subdomain of your choice.

Screen Shot 2020-11-17 at 7 41 23 PM

Then go here and follow the installation instructions.

  1. Install Node.js
sudo apt install -y libssl-dev
curl -sL https://deb.nodesource.com/setup_12.x | sudo bash -
sudo apt install -y nodejs
  1. Create a directory for the application data
cd $HOME
mkdir foundrydata
  1. Install nginx:
sudo apt-get update
sudo apt-get install nginx
  1. Create an Nginx configuration file for your domain. Make sure to update the references to your.hostname.com in the configuration file: sudo nano /etc/nginx/sites-available/your.hostname.com and make sure the proxy_pass port number matches the published port in your docker-compose file.
# the filename should be "your.hostname.com"

# Define Server
server {

    # Enter your fully qualified domain name or leave blank
    server_name             your.hostname.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
	# This should match the published port in your docker-compose file
        proxy_pass http://localhost:30000;
    }
}

Save and exit nano with ctrl + x, press Y, then Enter

  1. Use the service utility to manage your Nginx server. Enable the site, test your configuration, fix any errors, and start the service. Don't forget to replace your.hostname.com!
# Enable new site
sudo ln -s /etc/nginx/sites-available/your.hostname.com /etc/nginx/sites-enabled/

# Test your configuration file
sudo service nginx configtest

# View configuration errors (if the configtest was not OK)
sudo nginx -t

# Start Nginx
sudo service nginx start

# Stop Nginx
sudo service nginx stop

# Restart Nginx
sudo service nginx restart
  1. Next, create a docker-compose file to run foundryvtt-docker: nano $HOME/docker-compose.yml. See the foundryvtt-docker for instructions on using secrets, a temporary foundryvtt download url, and other options. Make sure to replace YOUR_FOUNDRY_LICENSE, YOUR_ADMIN_KEY, YOUR_FOUNDRY_USERNAME, and YOUR_FOUNDRY_PASSWORD before saving the file.
version: "3.3"

services:
  foundry_1:
    container_name: foundry
    image: felddy/foundryvtt:release
    hostname: my_foundry_host_1
    restart: "unless-stopped"
    network_mode: webproxy
    volumes:
      - type: bind
        source: ./foundrydata
        target: /data
    environment:
      - CONTAINER_CACHE=/data/container_cache
      - FOUNDRY_USERNAME=YOUR_FOUNDRY_USERNAME
      - FOUNDRY_PASSWORD=YOUR_FOUNDRY_PASSWORD
      - FOUNDRY_LICENSE_KEY=YOUR_FOUNDRY_LICENSE
      - FOUNDRY_ADMIN_KEY=YOUR_ADMIN_KEY
    ports:
      - target: "30000"
        published: "30000"
        protocol: tcp

Note: if you need to run FoundryVTT on a different port, change the published port to the desired port. No need to change the target port. The target is the port inside the container, the published is the publicly exposed port.

  1. Now you should be able to start the container and see FoundryVTT running at http://localhost:30000 and at http://your.hostname.com:
docker-compose up -d

Check that your container is running using docker container ls, view the container logs using docker logs foundry. If needed you can stop the container docker stop foundry, remove it docker rm foundry, and run it again after making any necessary changes to your docker compose file docker-compose up -d. Alternately, docker-compose down will stop all containers and removes containers, networks, volumes, and images created by the previous docker-compose up in a single command.

  1. Now it's time to setup HTTPS for your domain. Create SSL certificates using Certbot. Follow the instructions here.
  2. Update the nginx config file to use port 443 and the SSL certificates you created. Again, make sure to replace your.hostname.com: sudo nano /etc/nginx/sites-available/your.hostname.com and make sure the proxy_pass port number matches the published port in your docker-compose file.
# the filename should be "your.hostname.com"

# Define Server
server {

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

    # Listen on port 443 using SSL certificates
    listen                  443 ssl;
    ssl_certificate         "/etc/letsencrypt/live/your.hostname.com/fullchain.pem";
    ssl_certificate_key     "/etc/letsencrypt/live/your.hostname.com/privkey.pem";

    # 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
	# This should match the published port in your docker-compose file
        proxy_pass http://localhost:30000;
    }
}

# Optional, but recommend. Redirects all HTTP requests to HTTPS for you
server {
    if ($host = your.hostname.com) {
        return 301 https://$host$request_uri;
    }

    listen 80;
	listen [::]:80;

    server_name your.hostname.com;
    return 404;
}

Save and exit nano with ctrl + x, press Y, then Enter

  1. Don't forget to setup Port Forwarding on your router. You'll need to forward ports 80 and 443 to your raspberry pi. Every router is different, but you can find specific instructions here.

Now your site should be accessible at https://your.hostname.com!

Enable Audio/Video Chat with Jitsi

  1. Log on to the admin page of your foundryvtt instance, go to Add-on Modules and install JitsiWebRTC: Screen Shot 2020-11-25 at 7 30 21 PM

  2. Launch your world, join the game session as GM, go to Game Settings -> Manage Modules, enable Jitsi Web RTC client and then Save Module Settings

  1. Once your world reloads, go to Game Settings -> Configure Settings -> click on Configure Audio/Video -> change Audio/Video Conferencing Mode to Audio/Video Enabled

Screen Shot 2020-11-25 at 7 32 54 PM

Screen Shot 2020-11-25 at 7 34 28 PM

Note: you don't need to setup your own Jitsi server

  1. Save changes and once the page reloads, you should get a popup in your browser to enable your site to use your microphone and camera. That's it!

Sync your pi with Google Drive for automatic backups

Be aware that you shouldn't have your foundry instance referencing data in a cloud sync/backup service as it could cause data corruption. What you can do is create a tar archive of your foundry data, compress it with gzip and move it to your cloud sync/backup folder on a regular basis.

  1. Follow this guide to mount google drive using rclone.

Note: install the latest version of rclone using curl https://rclone.org/install.sh | sudo bash

a. I recommend modifying your [email protected] file so it auto-restarts: nano ~/.config/systemd/user/[email protected]. Add the Restart and RestartSec options to the [Service] and StartLimitIntervalSec and StartLimitBurst in the [Unit] section prevent a failing service from being restarted every 5 seconds. This will give it 5 attempts, if it still fails, systemd will stop trying to start the service.

[Unit]
Description=rclone: Remote FUSE filesystem for cloud storage config %i
Documentation=man:rclone(1)
StartLimitIntervalSec=500
StartLimitBurst=5
[Service]
Type=notify
Restart=on-failure
RestartSec=5s
ExecStartPre=/bin/mkdir -p %h/mnt/%i
ExecStart= \
  /usr/bin/rclone mount \
    --fast-list \
    --vfs-cache-mode writes \
    --vfs-cache-max-size 100M \
    %i: %h/mnt/%i
[Install]
WantedBy=default.target
  1. Follow this guide to schedule automatic backups of your foundrydata folder (Config, Data, and Logs folders).

a. I recommend creating a local /bin folder to store the backup script and add it to your PATH, instead of the /usr/bin folder which requires sudo access:

mkdir ~/bin
export PATH=home/pi/bin:$PATH 

b. This is what my backup script looks like. I used rclone move to copy files to google drive and rclone delete to automatically delete older files.

#!/bin/bash
BACKUP_FOLDER='/home/pi/backups/'
BACKUP_CMD='/bin/tar -rvf'

counter=1
while [ $counter -le 4 ]
do
	SECONDS=0
	NOW=`date '+%F_%H%M'`	
	DEST_FILE="foundrydata$counter-backup-$NOW.tar"
	DEST_FOLDER="/home/pi/mnt/gdrive/foundrydata$counter/"
	rclone delete --min-age 56d $DEST_FOLDER 
	$BACKUP_CMD $BACKUP_FOLDER/$DEST_FILE -P /home/pi/foundrydata$counter
	echo compressing..
	/bin/gzip $BACKUP_FOLDER/$DEST_FILE
	echo copying..
	rclone move --update --verbose --transfers 30 --checkers 8 --contimeout 60s --timeout 300s --retries 3 --drive-chunk-size 128M --low-level-retries 10 --fast-list --stats 1s $BACKUP_FOLDER/$DEST_FILE.gz gdrive:foundrydata$counter	
	echo foundrydata$counter backup completed in $SECONDS seconds
	((counter++))
done
echo all backups complete

c. You can use Crontab Generator to find the syntax for whatever backup schedule you want in crontab. I used this to run backups each Wednesday at 2 am and output the log to a log file with the date (and the backup script above deletes backups after 8 weeks):

0 2 * * 3 ~/bin/backup.sh > ~/backups/backup__`date +\%y\%m\%d`.log

Run multiple FoundryVTT instances

If you have multiple FoundryVTT licenses, it's easy to modify the docker-compose file to spin up multiple foundry instances and have each instance be accessible from its own URL. You'll need to:

  1. Create a directory for the application data.
cd $HOME
mkdir foundrydata2
  1. Create another subdomain on www.duckdns.org
  2. From Setup Step 5 above, follow the same process again but for your new URL. Create the Nginx config file.
  3. Add the additional service to your existing docker-compose file (rather than creating another docker-compose file) and start it up to ensure it’s setup correctly. Here I have it setup for 3 foundry instances:
---
version: "3.3"

services:
  foundry_1:
    container_name: foundry1
    image: felddy/foundryvtt:release
    hostname: my_foundry_host_1
    restart: "unless-stopped"
    network_mode: webproxy
    volumes:
      - type: bind
        source: ./foundrydata1
        target: /data
    environment:
      - FOUNDRY_USERNAME=YOUR_USERNAME
      - FOUNDRY_PASSWORD=YOUR_PASSWORD
      - CONTAINER_CACHE=/data/container_cache
      - FOUNDRY_LICENSE_KEY=YOUR_LICENSE_KEY
      - VIRTUAL_HOST=KEY=YOUR_URL.duckdns.org
      - FOUNDRY_ADMIN_KEY=YOUR_ADMIN_KEY
    ports:
      - target: "30000"
        published: "30000"
        protocol: tcp
  foundry_2:
    container_name: foundry2
    image: felddy/foundryvtt:release
    hostname: my_foundry_host_2
    restart: "unless-stopped"
    network_mode: webproxy
    volumes:
      - type: bind
        source: ./foundrydata2
        target: /data
      - '/home/pi/foundrydata1/Data/maps/:/home/pi/foundrydata1/Data/maps/'
      - '/home/pi/foundrydata1/Data/modules/:/home/pi/foundrydata1/Data/modules/'
      - '/home/pi/foundrydata1/Data/systems/:/home/pi/foundrydata1/Data/systems/'
      - '/home/pi/foundrydata1/Data/audio/:/home/pi/foundrydata1/Data/audio/'
      - '/home/pi/foundrydata1/Data/tokens/:/home/pi/foundrydata1/Data/tokens/'
      - '/home/pi/foundrydata1/Data/dndbeyond/:/home/pi/foundrydata1/Data/dndbeyond/'
      - '/home/pi/foundrydata1/Data/dragupload/:/home/pi/foundrydata1/Data/dragupload/'
      - '/home/pi/foundrydata1/Data/uploaded-chat-images/:/home/pi/foundrydata1/Data/uploaded-chat-images/'
    environment:
      - FOUNDRY_USERNAME=YOUR_USERNAME
      - FOUNDRY_PASSWORD=YOUR_PASSWORD
      - CONTAINER_CACHE=/data/container_cache
      - FOUNDRY_LICENSE_KEY=YOUR_LICENSE_KEY
      - VIRTUAL_HOST=KEY=YOUR_URL.duckdns.org
      - FOUNDRY_ADMIN_KEY=YOUR_ADMIN_KEY
    ports:
      - target: "30000"
        published: "30001"
        protocol: tcp
  foundry_3:
    container_name: foundry3
    image: felddy/foundryvtt:release
    hostname: my_foundry_host_2
    restart: "unless-stopped"
    network_mode: webproxy
    volumes:
      - type: bind
        source: ./foundrydata3
        target: /data
      - '/home/pi/foundrydata1/Data/maps/:/home/pi/foundrydata1/Data/maps/'
      - '/home/pi/foundrydata1/Data/modules/:/home/pi/foundrydata1/Data/modules/'
      - '/home/pi/foundrydata1/Data/systems/:/home/pi/foundrydata1/Data/systems/'
      - '/home/pi/foundrydata1/Data/audio/:/home/pi/foundrydata1/Data/audio/'
      - '/home/pi/foundrydata1/Data/tokens/:/home/pi/foundrydata1/Data/tokens/'
      - '/home/pi/foundrydata1/Data/dndbeyond/:/home/pi/foundrydata1/Data/dndbeyond/'
      - '/home/pi/foundrydata1/Data/dragupload/:/home/pi/foundrydata1/Data/dragupload/'
      - '/home/pi/foundrydata1/Data/uploaded-chat-images/:/home/pi/foundrydata1/Data/uploaded-chat-images/'
    environment:
      - FOUNDRY_USERNAME=YOUR_USERNAME
      - FOUNDRY_PASSWORD=YOUR_PASSWORD
      - CONTAINER_CACHE=/data/container_cache
      - FOUNDRY_LICENSE_KEY=YOUR_LICENSE_KEY
      - VIRTUAL_HOST=KEY=YOUR_URL.duckdns.org
      - FOUNDRY_ADMIN_KEY=YOUR_ADMIN_KEY
    ports:
      - target: "30000"
        published: "30002"
        protocol: tcp

Some things to note:

  • Make sure to replace YOUR_USERNAME, YOUR_PASSWORD, YOUR_LICENSE_KEY, YOUR_URL.duckdns.org, and YOUR_ADMIN_KEY for each service.
  • Each new Foundry instance will need its own published port number (but the target port will always be 30000)
  • Foundry supports symbolic links (aka symlinks) as of v0.5.0: "The software can now support symbolic links inside the user data location which can point to art assets, module, systems, or worlds which are stored in other locations." I've added symlinks so that all foundry instances share a bunch of folders, including modules and systems, with the foundrydata1 folder. That way I don't have to backup, maintain and update duplicate modules, worlds, and other assets. In addition to including each volume in the volumes section of the docker-compose file, you'll need to run the command ln -s /home/pi/foundrydata1/Data/modules /home/pi/foundrydata2/Data/modules for each folder you want to link. This command creates a link to /home/pi/foundrydata1/Data/modules in /home/pi/foundrydata2/Data/. For example, if you wanted to have the modules and systems shared between all instances, you'd need to run these commands:
ln -s /home/pi/foundrydata1/Data/modules /home/pi/foundrydata2/Data/modules
ln -s /home/pi/foundrydata1/Data/modules /home/pi/foundrydata3/Data/modules
ln -s /home/pi/foundrydata1/Data/systems /home/pi/foundrydata2/Data/systems
ln -s /home/pi/foundrydata1/Data/systems /home/pi/foundrydata3/Data/systems
  1. Setup HTTPS using Certbot and Nginx per Setup Steps 9 and 10 above.

foundryvtt-raspberry-pi-4's People

Contributors

btruemn avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.