└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # RaspberryPi-FoundryVTT-Server 2 | ![image](https://user-images.githubusercontent.com/70184841/153284283-aa073c52-326a-4871-9646-8ef87afc0aaf.png) 3 | 4 | This is the step by step for my video, with links to other videos, hopefully this makes things easier especially for copy and pasting! 5 | 6 | ## Raspberry Pi Setup ## 7 | First things first, setup your Raspberry Pi with any OS you wish, I was using Twister OS but have switched to the latest Raspbein 32bit since it is running on Linux 11, which is necessary for FoundryVTT v9 or later. 8 | Rasbian OS has officially launched the 64bit version which allows you to utilize more than 4gb RAM, commands should be pretty much the same although I haven’t tried it myself. 9 | - [Raspberry Pi Install and Inital Setup](https://www.youtube.com/watch?v=BpJCAafw2qE) 10 | - [Booting from SSD or Thumbdrive](https://www.youtube.com/watch?v=r27WcPRtpWM) 11 | 12 | ### Your First Boot ### 13 | Once you are logged into your Raspberry Pi, open up the terminal and figure out what your IP is, this is going to be necessary to know for the rest of the tutorial: 14 | - hostname -l 15 | 16 | Once you get your Raspberry Pi setup and enable SSH, go ahead and run the following command to make sure everything is updated and ready for the rest of the installation. 17 | - sudo apt-get update && sudo apt-get upgrade 18 | 19 | ### Can't Update Existing FoundryVTT to v9 ### 20 | If you are already setup and can't update, run the following and make sure that you are running a Linux 11 OS. 21 | - cat /etc/issue.net 22 | 23 | Linux 10 and anything before cannot currently run FoundryVTT v9, so you will have to re-flash your system and update to the newest OS image. MAKE SURE YOU BACKUP EVERYTHING! 24 | 25 | ## Docker ## 26 | Docker is very easy to setup and will essentially seperate it's container contents from the rest of the Raspberry Pi through virtualization. This will allow us to manipulate the network ports as we please for some added security as well as keep vital files and processes from overlapping with system processes. 27 | 28 | To install Docker run the following: 29 | - curl -sSL https://get.docker.com | sh 30 | 31 | Give the current user admin rights for Docker: 32 | - sudo usermod -aG docker ${USER} 33 | 34 | To make any other users on the system and admin as well: 35 | - sudo usermod -aG docker [user_name] 36 | 37 | ### Docker-Compose ### 38 | Docker-Compose allows us to use a .yml file to keep our configuration, which allows us to change different parameters without the need to run a long line of commands. 39 | 40 | To install this we need two other program functions, python and pip3, so run the following: 41 | - sudo apt-get install libffi-dev libssl-dev 42 | - sudo apt install python3-dev 43 | - sudo apt-get install -y python3 python3-pip 44 | - sudo pip3 install docker-compose 45 | 46 | ### Docker at Startup ### 47 | We want to make sure that Docker runs anytime we restart our device. 48 | - sudo systemctl enable docker 49 | 50 | ### Docker Install Reference ### 51 | - https://dev.to/elalemanyo/how-to-install-docker-and-docker-compose-on-raspberry-pi-1mo 52 | 53 | ## Portainer ## 54 | If you want a nice easy to see GUI for all of your containers, you'll want to install Portainer. This is a container in Docker that lets you easily see everything running, give you other parameters to change in current containers, and you can view the logs of any containers to see whats going on. 55 | 56 | Installation command: 57 | - sudo docker pull portainer/portainer-ce:latest 58 | - sudo docker pull portainer/portainer-ce:linux-arm (Just in case the latest image fails on the Raspberry Pi) 59 | 60 | Now we can run the container: 61 | - sudo docker run -d -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest (or linux-arm) 62 | 63 | Let's connect to Portainer using the Raspberry Pi's Hostname or IP address in any web broswer: 64 | - http://[PIIPADDRESS]:9000 65 | 66 | Create a new user, and make sure you select Docker for the environment that Portainer is using. 67 | 68 | ### Portainer Install Reference ### 69 | - https://pimylifeup.com/raspberry-pi-portainer/ 70 | 71 | ## Foundry VTT ## 72 | Finally, lets get FoundryVTT setup and ready to run! We are going to make another docker-compose.yml, which you should make a foundry folder for so you don't lose it. 73 | - sudo nano docker-compose.yml 74 | - Place the following data into the newly created .yml, replacing all placeholder information with your own. The volumes > source is where you want your data to be on the raspberry pi, something like the following: /home/pi/foundry 75 | ``` 76 | --- 77 | version: "3.8" 78 | 79 | services: 80 | foundry: 81 | image: felddy/foundryvtt:release 82 | hostname: my_foundry_host 83 | init: true 84 | restart: "unless-stopped" 85 | volumes: 86 | - type: bind 87 | source: 88 | target: /data 89 | environment: 90 | - FOUNDRY_PASSWORD= 91 | - FOUNDRY_USERNAME= 92 | - FOUNDRY_ADMIN_KEY=atropos 93 | ports: 94 | - target: 30000 95 | published: 30000 96 | protocol: tcp 97 | ``` 98 | - If you need help figuring out what to add to the .yml, go to the creates [Github](https://github.com/felddy/foundryvtt-docker) 99 | - Once the .yml is created, lets start it up: docker-compose up -d --force-recreate 100 | 101 | ### Basic Troubleshooting ### 102 | Make sure that your Linux version is 11 or later if you use the latest FoundryVTT image, otherwise it won't work. If you have Linux 10 or less, you will need this image: 103 | - felddy/foundryvtt:0.8.9 104 | 105 | Foundry username and password are for the website where you bought your key to install foundry. 106 | 107 | ### Foundry VTT Image REference ### 108 | 109 | https://github.com/felddy/foundryvtt-docker 110 | 111 | ## Cloudflare Tunnels ## 112 | 113 | ### Getting A Domain ### 114 | In order to self host, you're going to need a domain name so you can hide your public IP behind Cloudflare. [Freenom](https://www.freenom.com/en/index.html?lang=en) can provide you a free domain name of your choice, if it is avilable. The steps to getting it are simple enough and privded in the video. Thing to note Cloudflare now allows you to purchase Domain Names form them which is neat, and they are pretty cheap. 115 | 116 | Once you have your domain name, you will need to change the name servers to the ones you get in your [Cloudflare](https://dash.cloudflare.com/login) account which you setup after adding your website. 117 | - DNS Tab, scroll down 118 | - ![image](https://user-images.githubusercontent.com/70184841/153463749-fd0db05f-d71c-4bf2-a019-c2c73f2c9a5c.png) 119 | - Copy these name servers over the ones at the site you got your domain name from. 120 | 121 | ### Creating The Tunnel ### 122 | Once the name servers have propogated and your website is in "Active Status" you''ll need to go to the "Access" tab and click on "Launch Zero Trust" 123 | 124 | ![image](https://user-images.githubusercontent.com/70184841/178129284-8b710f10-9e96-4a93-9397-b42bfc75e19b.png) 125 | 126 | Now go to the "Access" tab again, and click "Tunnels" 127 | 128 | ![image](https://user-images.githubusercontent.com/70184841/178129303-cd20420e-1996-40ee-ad23-cff2f8079ca6.png) 129 | 130 | Create a new tunnel 131 | 132 | ![image](https://user-images.githubusercontent.com/70184841/178129315-340d1fa4-a151-4171-af80-0a079208ca2f.png) 133 | 134 | Name your tunnel and save it, then you'll select an installer. Since we are using a Raspberry Pi in this tutorial and have the 64-bit OS installed, we choose "Debian > arm64-bit" but you can use whatever you want. The docker image didn't work with arm processors at the time of this recording just FYI! 135 | 136 | ![image](https://user-images.githubusercontent.com/70184841/178129370-2a36bfd0-9b1b-4728-a2ce-6d263d851b5a.png) 137 | 138 | All you have to do is copy and paste the box into your Raspberry Pi, it will begin the install of the tunnel and run it at the end. 139 | 140 | Next you will be creating the subdomain if you want, select your domain name from the drop down, select HTTP, input the local network address of the Raspberry Pi, and click Save. 141 | 142 | ![image](https://user-images.githubusercontent.com/70184841/178129421-1b366d38-b335-4616-bde7-5524f1b6d03a.png) 143 | 144 | You should get the tunnel up and running at this point and see the "Active" status. 145 | 146 | ![image](https://user-images.githubusercontent.com/70184841/178129454-1cf97b76-70cf-4b3c-b471-f9091ea4bda4.png) 147 | 148 | You can then go into Configure for the tunnel, Public Hostnames, and see your link for the new domain of foundry you just created! 149 | 150 | ![image](https://user-images.githubusercontent.com/70184841/178129481-28892cd0-dd88-4573-923d-0496296c12ad.png) 151 | 152 | ### Application Secuirty (OPTIONAL)### 153 | 154 | If you want to add those Access Lists I was atalking about, go to the "Access" tab and then "Applications" and click "Add an application". 155 | 156 | ![image](https://user-images.githubusercontent.com/70184841/178129540-10cc10ef-aa60-4d4f-b79a-3c0df1fdfe05.png) 157 | 158 | Click on "Self Hosted" 159 | 160 | ![image](https://user-images.githubusercontent.com/70184841/178129558-9c487dbf-7633-416b-839f-910a2a805216.png) 161 | 162 | Add in the information as needed, you can also edit the logo of the app for the Cloudflare Dashboard if you want, as well as add additional authentication paths in the future if you'd like. Otherwise the "One-Time Password" should already be selected. 163 | 164 | ![image](https://user-images.githubusercontent.com/70184841/178129576-e6715b94-f925-40fc-a8e1-1f212ced0c9f.png) 165 | 166 | Now you will create a name for the policy, and torwards the bottom you can change the people that are allowed. If you use emails, make sure you get all the emails of the players and your own included in the values box. Any email that is not in that box will never get a one-time code. 167 | 168 | ![image](https://user-images.githubusercontent.com/70184841/178129661-280312c0-8edc-4291-a081-e46d53c98e57.png) 169 | 170 | That's a pretty basic ACL, go ahead and tinker with it and add additional checks or methods of authentication as you see fit! 171 | 172 | ## Old Way ## 173 | ### Nginx Proxy Manager ### 174 | Nginx Proxy Manager is a reverse proxy that allows us to only expose 2 ports on our modem/router instead of a bunch. In terms of security, you want as few ports forwarded on your modem/router since those forwarded ports allow all traffic regaurdless of its origin. 175 | 176 | First lets make a folder to store all of the necessary files for this, you can place it in any directory, just keep in mind that this setup will place it in the /home/pi directory, pi being the current user running. 177 | - mkdir nginx 178 | 179 | Get into the new folder: 180 | - cd nginx 181 | 182 | Create a config file, and then put information into that config file: 183 | - nano config.json 184 | 185 | If you change any of the information besides the "changeme" portions keep it in mind for the rest of the install! 186 | ```console 187 | { 188 | "database": { 189 | "engine": "mysql", 190 | "host": "db", 191 | "name": "npm", 192 | "user": "changeme", 193 | "password": "changeme", 194 | "port": 3306 195 | } 196 | } 197 | ``` 198 | Save the new contents in the folder: 199 | - ctrl + x then Y then Enter 200 | 201 | ### Compose File ### 202 | Next while we are in the nginx folder, we need to make our .yml file that will hold all the docker container information and parameters. Make sure the information matches that of the config.json file we made before. 203 | - nano docker-compose.yml 204 | 205 | ```console 206 | version: '3' 207 | services: 208 | app: 209 | image: 'jc21/nginx-proxy-manager:latest' 210 | restart: unless-stopped 211 | ports: 212 | - '80:80' 213 | - '81:81' 214 | - '443:443' 215 | environment: 216 | DB_MYSQL_HOST: "db" 217 | DB_MYSQL_PORT: 3306 218 | DB_MYSQL_USER: "changeme" 219 | DB_MYSQL_PASSWORD: "changeme" 220 | DB_MYSQL_NAME: "npm" 221 | volumes: 222 | - ./data:/data 223 | - ./letsencrypt:/etc/letsencrypt 224 | db: 225 | image: 'yobasystems/alpine-mariadb:latest' 226 | restart: unless-stopped 227 | environment: 228 | MYSQL_ROOT_PASSWORD: 'changeme' 229 | MYSQL_DATABASE: 'npm' 230 | MYSQL_USER: 'changeme' 231 | MYSQL_PASSWORD: 'changeme' 232 | volumes: 233 | - ./data/mysql:/var/lib/mysql 234 | ``` 235 | There is a chance that the image we use for the db portion doesn't work depending on your OS, so you can try changing the "latest" to "10.4.17" instead. 236 | 237 | ### Deploying The Container ### 238 | This is where everything comes together. The following command has to be ran in the same folder as our docker-compose.yml file, otherwise it won't do anything. When the command is ran, you'll see the system reach out to grab the images we specified in the .yml file, and fill those containers with all the parameters we specified. It should be noted that the --force-recreate doesn't do anything if there isn't a container already running, if there was a container running, it will take it down and remake it completely, which is useful for troubleshooting the .yml and trying new parameters. 239 | - docker-compose up -d --force-recreate 240 | 241 | ### Connect To The Web GUI ### 242 | Just like getting to Portainer, you'll connect to Nginx Proxy Manager using your hostname or IP and the port 81. 243 | - http://[PIIPADDRESS]:81 244 | 245 | The default credentials to login are as follows: 246 | - Username: admin@example.com 247 | - Password: changeme 248 | 249 | ### Port Forwarding ### 250 | Now that we have Nginx Proxy Manager up and running, we need to forward all traffic on ports 80 and 443 (HTTP and HTTPS) to your Raspberry Pi running the container. Get into your modem/router, go to the port forwarding tab, and forward port 80 and 443 (TCP or BOTH) to the IP address of your Raspberry Pi. 251 | 252 | ### Nginx Proxy Manager Reference ### 253 | - https://www.addictedtotech.net/nginx-proxy-manager-tutorial-raspberry-pi-4/ 254 | 255 | ## Cloudflare & SSL ## 256 | Cloudflare is my DNS service of choice, the free option adds a lot of security tools that can protect you and your now web hosted apps from people that wish to do harm. There are some key things that must be done in order for this to all work, so this might be the most important part of the guide. 257 | 258 | ### Getting A Domain ### 259 | In order to self host, you're going to need a domain name so you can hide your public IP behind Cloudflare. [Freenom](https://www.freenom.com/en/index.html?lang=en) can provide you a free domain name of your choice, if it is avilable. The steps to getting it are simple enough and privded in the video. Thing to note Cloudflare now allows you to purchase Domain Names form them which is neat, and they are pretty cheap. 260 | 261 | Once you have your domain name, you will need to change the name servers to the ones you get in your [Cloudflare](https://dash.cloudflare.com/login) account which you setup after adding your website. 262 | - DNS Tab, scroll down 263 | - ![image](https://user-images.githubusercontent.com/70184841/153463749-fd0db05f-d71c-4bf2-a019-c2c73f2c9a5c.png) 264 | - Copy these name servers over the ones at the site you got your domain name from. 265 | 266 | ### A and CName Records ### 267 | In the DNS tab of Cloudflare you will need to make a new A record, this will point the domain you have setup to your Public IP. Make sure it is Proxied as well. 268 | ![image](https://user-images.githubusercontent.com/70184841/153464511-0e8e362e-016c-4603-8b1c-1375c5bc3a9d.png) 269 | Once you have the A record, we now need to make a subdomain CName Record for foundry itself. 270 | ![image](https://user-images.githubusercontent.com/70184841/153464743-16c991cf-f00c-48b5-962c-985c2f772868.png) 271 | - Note: This can be done as many times as you want, for as many different services or containers you are hosting. 272 | 273 | ### Security Settings ### 274 | Now that Cloudflare is forwarding all traffic for your domain name to your public IP, we have to make sure the security settings are in place. Go to the SSL/TLS tab, and in the overview settins you will need to change to either Full or Full(Strict). Keep in mind that the Strict setting might slow down your instance just a little bit. Anything less most likely won't allow connections to your foundry. 275 | 276 | ![image](https://user-images.githubusercontent.com/70184841/153465509-4586159c-21b9-4d4a-9394-ee9a8abd8dc1.png) 277 | 278 | ### Creating An SSL Cert For Nginx ### 279 | While we are in Cloudflare, lets go ahead and create our own certificate for SSL instead of using one from Let's Encrypt. These certs last for longer than Let's Encrypt. 280 | - In the SSL/TLS go to "Client Certificate" and click on "Create Certificate". 281 | image 282 | - The next page we only really need to change the leangth, everything else meets our needs. 283 | - Now we need to make 2 notepad files, copy and paste the contents of the boxes you see, and name them Certificate.com.pem (Certificate Text Box) and PrivateKey.com.key (Private Key Text Box) 284 | 285 | ![image](https://user-images.githubusercontent.com/70184841/153468303-6e693287-c20c-40ac-942f-b8e6e889ec9d.png) 286 | 287 | - These files we will upload to Nginx Proxy Manager in the SSL tab so that we can use our cert for any services we create. 288 | 289 | ### Nginx SSL Cert Upload ### 290 | Once you have your cert files download, head to your Nginx Proxy Manager, go the the SSL Certificates page, and create a new custom SSL Certificate. 291 | 292 | ![image](https://user-images.githubusercontent.com/70184841/153481708-ecbfa177-1190-4771-9f9c-dc65c099cefa.png) 293 | 294 | Name your cert whatever, this is for Nginx only, and upload the appropriate files using the browse button. 295 | 296 | ![image](https://user-images.githubusercontent.com/70184841/153482040-b99fe35a-1a11-4628-ab4c-2b5e80a63d9d.png) 297 | 298 | Now you should have an SSL cert for all of your subdomains to use through Nginx! 299 | 300 | 301 | ## Port-Forwading Workaround ## 302 | 303 | DB Tech released a video a few months ago on how to use Cloudflare Tunnels to add more security to your self-hosting needs. I've started to implement it myself to test some things, and the neat part is it gets rid of the port forwarding requirement for Nginx and your router. 304 | 305 | This not only allows you to protect your network and give you that ease of mind, but now for those of you that live in locations where you can't port forward, like a dorm or apartment with shared Wifi, you can use Cloudflare Tunnels and still self host! Really neat how it all works, so far I haven't found any issues with how my videos go through the process, but I will make a new video sometime soon to go through a new installation process utilizing this method. 306 | 307 | Link to the video: 308 | https://www.youtube.com/watch?v=VrV0udRUi8A 309 | 310 | I'll go through and screenshot the steps in the coming days and update this portion accordingly. 311 | --------------------------------------------------------------------------------