Train Bridge at Swarthmore College crossing Crum Creek

New Site for D&D Material

Record keeping is important in any tabletop game, for posterity and my own personal sanity. If not for decent record keeping, it's impossible to prove something was said. A situation that has bitten me in the past.

I've danced around the idea of a git backed solution for a while. The idea would be a community driven website publicly synced with git. It worked well for me but non-technical players would struggle using it. A better solution needed to be visual and graphical.

I had run an instance of Dokuwiki in college to fulfill a project requirement. It's a PHP app and uses flat files for storage with it's own simple auth layer and a plethora of add-ons to boot. Perfect for what I needed. Hosted on top of Nginx with Let's Encrypt for SSL proved to be a maintainable and a perfect solution for what I needed.

The wiki can be viewed in action Here.

Future work will be getting Dokuwiki fully git backed and living within a Chroot for added secuity.

Hosting Configurations

PHP

Deciding the method Nginx and PHP use to communicate is a complicated process, with conflicting information existing all across the web. php-fpm or fcigwrap would both work, the latter being the language generic version. I used php-fpm in this case, the relevant config changes are below.

Even though Unix sockets can be trickier to configure, always use sockets over loopback TCP when possible. Unix sockets are roughly 50% faster then loopback TCP[1] plus give added security, allowing sysadmins to restrict who/what has access to the service.

;php-fpm.d/www.conf

; Creates a Unix socket in a generic location
listen = /var/run/php-fpm/php-fpm.sock

; Nginx will be the only process talking to the socket
user = nginx
group = nginx

I turned on the ability to upload files to create a virtual library for myself and my players, great for distrusting new material or relevent quest items. Some of these documents can be absolutely massive, some settings had to be upped to prevent Time Out errors.

;php.ini

;;;;;;;;;;;;;;;;
; File Uploads ;
;;;;;;;;;;;;;;;;

; Whether to allow HTTP file uploads.
; http://php.net/file-uploads
file_uploads = On

; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize = 70M

; Maximum number of files that can be uploaded via a single request
max_file_uploads = 20

Web Server

I swear by Nginx for almost everything involving webhosting in my life, easy to use and configure with tons of awesome features. I've included inline comments to annotate important config lines and their purpose.

#nginx/bards_house.conf

server {
        listen 443 ssl;

        server_name bards.house bards.club;
        root /var/www/;
        index index.php index.html index.htm;

        # Let's Encrypt files, will likely differ on your machine
        ssl_certificate /etc/letsencrypt/live/bards.club/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/bards.club/privkey.pem; # managed by Certbot
        ssl_dhparam /etc/ssl/certs/dhparam.pem;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        # Stores entire webdir behind /dndwiki/ URI. Useful for overloaded cnames
        location / {
                rewrite ^/$ https://$host/dndwiki/;
        }

        # Prevents access to binary and config files
        location ~ /(conf|bin|inc)/ {
                deny all;
        }

        # Blocks external direct access but does not restric CGI access.
        # Required if you have ACL'ed data.
        location ~ /data/ {
                internal;
        }

        # Connect to the CGI socket, ensuring all the correct headers are set
        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include fastcgi_params;
        }
}

# Rewrite all non-https connects to https
server {
        listen 80;
        listen [::]:80;
        server_name bards.house bards.club;
        return 301 https://$host$request_uri;
}

Changes have to be made to the parent nginx.conf file to allow large file uploads.

#nginx/nginx.conf

http {
    # ...

    client_max_body_size 70M;
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
}

Let's Encrypt

I am blown away at how simple it's become to get a SSL cert. Everyone should be using Let's Encrypt, especially for personal projects. I followed the Digital Ocean instructions, slightly adjusted for Nginx instead of Apache.

Dokuwiki Configurations

Appearance

The most crucial step, the site has to Feel like a D&D site. Most people are, or at least partial, visual learners so pictures are the easiest way. I went with the Wallpaper Template as a clear choice. After some searching I found a good image with apt permissions to be used for non-commercial use.