- Enemy entity: full 5e stat block (size/type/subtype/alignment, AC, HP,
speed, six ability scores, CR/XP/prof, saves/skills/senses/languages,
damage & condition modifiers, traits/actions/bonus/reactions/legendary,
description, source) plus a DM game-notes field and updated_at.
- CreatureSize / CreatureType enums.
- /enemies: server-side DataTable (name, size, type, CR, AC, HP, notes),
"Add enemy" button.
- /enemies/{id}: stat block rendered read-only + editable game notes.
- /enemies/new and /enemies/{id}/edit: the full stat-block form (no notes).
- "Enemies" nav item between NPC's and Storyline.
- Table left empty on purpose.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
dmtools
DM tools for the Monday-evening D&D campaign.
Symfony 8 (PHP 8.5) web app with a Bootstrap 5 + DataTables front end served through Symfony AssetMapper (no Node build step). Behind a form-login gate; there is no self-registration.
- Not run in Docker locally (Windows dev box uses the Symfony CLI + local MariaDB).
- Is Dockerized on the testing and live servers, behind the shared Nginx
Proxy Manager at
https://dmtools.fvandenberg.nl.
Repo: https://gitea.fvandenberg.nl/Frank/dmtools.git
Local development (dev box)
Prerequisites: PHP 8.5 at C:\php (on PATH so the Symfony CLI discovers it —
symfony local:php:list should show 8.5), the Symfony CLI, Composer, and a local
MariaDB/MySQL (WAMP is fine). .php-version pins this directory to PHP 8.5.
# 1. Point the app at your local database + dev mode
cp .env .env.local
# then edit .env.local:
# APP_ENV=dev
# DATABASE_URL="mysql://root:@127.0.0.1:3306/dmtools?serverVersion=10.10.2-MariaDB&charset=utf8mb4"
# 2. Install and build
symfony composer install
symfony console doctrine:database:create
symfony console doctrine:migrations:migrate -n
symfony console importmap:install
# 3. First user, then run
symfony console app:user:create you@example.com --admin
symfony serve -d
symfony open:local
serverVersion must match your local engine (SELECT VERSION();).
Servers (testing + live)
Docker only. docker/setup.sh pins the compose project name to dmtools
(containers dmtools-php, dmtools-nginx, dmtools-db).
git pull
cp .env .env.local # first time only
# edit .env.local: real APP_SECRET (or let setup.sh generate it),
# DB_PASSWORD, DB_ROOT_PASSWORD, and NGINX_PORT / DB_PORT if 8085 / 3310 clash
./docker/setup.sh
docker compose -p dmtools exec php php bin/console app:user:create you@example.com --admin
Ports (bound to 127.0.0.1 on the host): nginx 8085 → :80, db 3310 → :3306.
Reverse proxy (Nginx Proxy Manager)
Add a proxy host: dmtools.fvandenberg.nl → forward to host dmtools-nginx,
port 80, scheme http; request a Let's Encrypt certificate. NPM and
dmtools-nginx must share the external docker_default Docker network (the
compose file attaches nginx to it as proxy).
Common commands
docker compose -p dmtools logs -f php
docker compose -p dmtools exec php bash
docker compose -p dmtools exec php php bin/console doctrine:migrations:migrate
./docker/restart.sh # full down + bring-up (no rebuild)
./docker/setup.sh --down # stop the stack
Layout notes
table.datatablein any Twig template is auto-initialised as a DataTable (assets/app.js). Opt out withdata-datatable="false"; pass options as JSON indata-datatable-options.assets/vendor/andpublic/assets/are generated (git-ignored);importmap:installon the server re-downloads vendored packages, so the servers need outbound HTTPS to jsDelivr at deploy time.