From fbec5733545cb227fb6da7f7c8b29a9fda12c39d Mon Sep 17 00:00:00 2001 From: James Mortemore Date: Sat, 18 Apr 2026 20:49:18 +0100 Subject: [PATCH] docs(webui): restructure install guide into hub-and-spoke + add deployment page Splits the monolithic install.mdx into a hub at /docs/webui/install/ that covers prerequisites, the WebEnhancer plugin, env-var reference, security notes, and troubleshooting, plus three dedicated pages for the Docker Compose, browser /setup, and CLI wizard install paths. Adds a separate /docs/webui/deployment guide for production concerns: running under systemd or Docker, reverse-proxy snippets for Caddy, Apache and nginx (with Let's Encrypt), sub-directory installs via BASE_PATH, and the /health endpoint for monitoring. Teaches scripts/generate-navigation.mjs to honour an optional numeric navOrder front-matter field so the sidebar lists Install -> Docker -> Web installer -> CLI -> Deployment in that order; falls back to the existing alphabetical sort when navOrder is absent. --- content/docs/webui/deployment.mdx | 171 ++++++++++++++++++++ content/docs/webui/install.mdx | 176 --------------------- content/docs/webui/install/cli.mdx | 113 +++++++++++++ content/docs/webui/install/docker.mdx | 156 ++++++++++++++++++ content/docs/webui/install/index.mdx | 220 ++++++++++++++++++++++++++ content/docs/webui/install/web.mdx | 124 +++++++++++++++ data/navigation.json | 84 +++++++++- scripts/generate-navigation.mjs | 19 +++ 8 files changed, 882 insertions(+), 181 deletions(-) create mode 100644 content/docs/webui/deployment.mdx delete mode 100644 content/docs/webui/install.mdx create mode 100644 content/docs/webui/install/cli.mdx create mode 100644 content/docs/webui/install/docker.mdx create mode 100644 content/docs/webui/install/index.mdx create mode 100644 content/docs/webui/install/web.mdx diff --git a/content/docs/webui/deployment.mdx b/content/docs/webui/deployment.mdx new file mode 100644 index 00000000..678c1f03 --- /dev/null +++ b/content/docs/webui/deployment.mdx @@ -0,0 +1,171 @@ +--- +layout: 'docs' +title: 'Deployment' +navTitle: 'Deployment' +navOrder: 14 +category: 'Web UI' +description: 'Run the BanManager WebUI in production: keep it alive with systemd or Docker, and serve it over HTTPS with Caddy, Apache, or nginx.' +--- +This page covers everything you need to take a working WebUI install (see [Install](/docs/webui/install)) and put it in front of real users: a process manager so the WebUI restarts automatically on crash or reboot, and a reverse proxy so you can serve it over HTTPS on a real domain. + +## Run as a service + +You almost certainly want the WebUI to come back up after a crash or reboot. Pick whichever option matches your install: + +### systemd (recommended for non-Docker installs) + +The WebUI ships a setup helper that generates a `systemd` unit, enables it, starts it, and tails the journal so you can see whether the boot was successful: + +```bash +npx bmwebui setup systemd +``` + +You'll be asked which user to run the service as (defaults to your current user — pick a non-root, non-sudo user for safety). The helper: + +- Writes `/etc/systemd/system/bmwebui.service` based on the [bundled template](https://github.com/BanManagement/BanManager-WebUI/blob/master/cli/commands/setup/bmwebui.service.template). +- Runs `sudo systemctl enable bmwebui.service` so it starts on boot. +- Starts the service and waits up to 60 seconds for `http://localhost:PORT/` to respond. +- Streams `journalctl -f` so you can watch the first boot. + +The service uses `Restart=always`, runs `npm run build` as a `ExecStartPre`, then `node server.js`. It runs in the directory you executed `npx bmwebui setup systemd` from. + +**Day-to-day commands:** + +```bash +sudo systemctl status bmwebui.service +sudo systemctl restart bmwebui.service +sudo journalctl -u bmwebui.service -f +``` + +### Docker + +The published Compose files (`docker-compose.prod.yml` and `docker-compose.prod-no-db.yml`) already declare `restart: unless-stopped`, so Docker handles restart-on-crash and restart-on-boot for you. Nothing extra is required. + +To restart manually after a config change: + +```bash +docker compose restart webui +``` + +### PM2 and other managers + +PM2, Forever, and similar managers all work with the WebUI — point them at `node server.js` in the install directory. They aren't covered in detail here. + +--- + +## Reverse proxy (HTTPS) + +For any non-Docker public install you'll want a reverse proxy in front of the WebUI to: + +- Terminate TLS so users get HTTPS. +- Add HTTP→HTTPS redirects. +- Optionally mount the WebUI on a sub-path (e.g. `https://example.com/banmanager`). + +The WebUI ships templates and helper commands for the three most common reverse proxies. Pick whichever you're already comfortable with — for greenfield installs, **Caddy** is the easiest because it manages HTTPS automatically. + +> **Don't forget `TRUST_PROXY=true`.** When the WebUI sits behind a reverse proxy, set `TRUST_PROXY=true` in your `.env` so it reads `X-Forwarded-For` and `X-Forwarded-Proto`. Without it the WebUI thinks every request is coming from `127.0.0.1`, so the "Your connection is not encrypted" warning on `/setup` won't appear even when an external user is connecting over plain HTTP. + +### Caddy (automatic HTTPS) + +```bash +npx bmwebui setup caddy +``` + +Caddy provisions and renews a Let's Encrypt certificate automatically — there's no separate `certbot` step. The helper: + +- Asks for your domain and (optional) sub-path. +- Writes a snippet to `/etc/caddy/Caddyfile.d/.caddy`. +- Validates the config and reloads Caddy. + +Make sure your main `/etc/caddy/Caddyfile` includes the snippet directory: + +```caddyfile +import Caddyfile.d/*.caddy +``` + +### Apache + +```bash +npx bmwebui setup apache +``` + +Apache is auto-detected on both Debian (`/etc/apache2`) and RHEL (`/etc/httpd`). The helper: + +- Writes a virtual host config to the right `sites-available` / `conf.d` directory. +- Enables `proxy`, `proxy_http`, `proxy_wstunnel`, `rewrite`, and `headers` modules. +- Reloads Apache. + +To add HTTPS: + +```bash +# Debian / Ubuntu +sudo apt install certbot python3-certbot-apache +sudo certbot --apache -d example.com + +# RHEL / Fedora +sudo dnf install certbot python3-certbot-apache +sudo certbot --apache -d example.com +``` + +`certbot` rewrites the file you just generated to add HTTPS and a HTTP→HTTPS redirect. + +### nginx + +```bash +npx bmwebui setup nginx +``` + +The helper: + +- Asks for your domain and (optional) sub-path. +- Writes a config to `/etc/nginx/sites-available/` and symlinks it into `sites-enabled`. +- Reloads nginx. + +To add HTTPS via Let's Encrypt: + +```bash +sudo apt install certbot python3-certbot-nginx +sudo certbot --nginx -d example.com +``` + +`certbot` rewrites the generated config to add HTTPS and a HTTP→HTTPS redirect. + +--- + +## Sub-directory installs (`BASE_PATH`) + +To mount the WebUI on a sub-path (e.g. `https://example.com/banmanager`), set `BASE_PATH` in your `.env`: + +```bash +BASE_PATH=/banmanager +``` + +Then re-build and restart so Next.js bakes the sub-path into the assets: + +```bash +npm run build +sudo systemctl restart bmwebui.service # or: docker compose restart webui +``` + +Finally, re-run the proxy helper (`npx bmwebui setup caddy|apache|nginx`) — it'll pick up the new `BASE_PATH` and generate a config that mounts the WebUI at that prefix. The proxy helpers will refuse to continue if `BASE_PATH` doesn't match the sub-path you enter, and remind you to re-build. + +--- + +## Health monitoring + +The WebUI exposes an unauthenticated `/health` endpoint suitable for uptime checks and load-balancer probes. It returns JSON like: + +```json +{ + "status": "ok", + "version": "x.y.z", + "migrations": "up-to-date", + "admin": "present" +} +``` + +`status` is one of: + +- `"ok"` — fully configured and serving traffic. HTTP 200. +- `"setup_required"` — server is in setup mode. HTTP 200. +- `"db_unreachable"` — database connection failed. HTTP 503 (so most uptime monitors will alert). diff --git a/content/docs/webui/install.mdx b/content/docs/webui/install.mdx deleted file mode 100644 index 569e0d23..00000000 --- a/content/docs/webui/install.mdx +++ /dev/null @@ -1,176 +0,0 @@ ---- -layout: 'docs' -title: 'Install' -navTitle: 'Install' -category: 'Web UI' -description: 'Install and configure the BanManager WebUI to aggregate and manage punishment data from your mobile or computer' ---- -A full guide for installing, configuring and running BanManager WebUI for use in production. - -## Prerequisites -The recommended installation requires the following stack: -- BanManager configured to use MySQL or MariaDB -- MySQL or MariaDB (this can be the same database used above but must be accessible) -- Git -- [Node.js](https://nodejs.org/) LTS -- NGINX or equivalent (for SSL) -- A server with at least 1GB memory -- A registered domain name - ---- - -## Initial Setup -There are two parts, the Minecraft plugin which enables web only features and the UI which renders the page and provides a GraphQL API. - -### BanManager-WebEnhancer -This is a required plugin which enables web only features. - -1. [Download](https://ci.frostcast.net/job/BanManager-WebEnhancer/) and add the jar to your compatible server. The [source code](https://github.com/BanManagement/BanManager-WebEnhancer) is also available. -1. Edit BanManager's [messages.yml](/docs/banmanager/configuration/messages-yml), and add a `[pin]` token to the `ban.player.disallowed` & `tempban.player.disallowed messages` - ```yml - ban: - player: - disallowed: '&6You have been banned from this server for &4[reason] \nUse [pin] to appeal' - tempban: - player: - disallowed: '&6You have been temporarily banned from this server for &4[reason] \n&6It expires in [expires] \nUse [pin] to appeal' - ``` -1. Restart the server or enable BanManager-WebEnhancer plugin and execute `/bmreload` - -## WebUI -Create a directory on your server for your installation. This can be a different server than your Minecraft server (as long it can connect to the MySQL database). We'll name it `banmanager` in this example but you can use whatever you like. - -```bash -mkdir /home/banmanager -cd /home/banmanager -``` - -### Download -```bash -git clone https://github.com/BanManagement/BanManager-WebUI.git -``` - -### Install -```bash -cd /home/banmanager/BanManager-WebUI -npm ci --production -``` - -Once dependencies have been downloaded and installed, run the setup command: -```bash -npm run setup -``` - -#### Setup Questions -During the installation, the CLI will ask a number of questions to configure the application. Press Enter to use the default value. If you make a mistake during the installation process, simply exit the setup (ctrl + c OR cmd + c) and run it again. - -The CLI will generate a `.env` file containing the necessary environment variables in order for the application to run. This will automatically be used on start up. If you do not wish to use this, simply remove the file and pass in the environment variables yourself when running the process. - -##### `Contact Email Address` -On setup, tokens are generated to enable push notifications. This is a requirement from vendors in order to contact you if this functionality is abused. This should be an email address that can receive mail. - -##### `Database Host` -This should be the host of the database used to setup web specific tables such as logins. This can be the same database used by the BanManager Minecraft plugin, but it does not have to be. The setup process will create the tables for you. - -##### `Database Port` -As above, this will default to 3306 - -##### `Database User` -As above. Ensure this user has permissions to create tables. - -##### `Database Password` -As above - -##### `Database Name` -As above - -##### `Add BanManager Server` -You will be prompted to specify details of your BanManager plugin database connection details. If tables are not found or the connection fails, you will be reprompted the question again. - -##### `playerPins table` - -This is the name of the table which contains login pins. By default this is set to bm_player_pins and is the value within your BanManager `config.yml` file. - -##### `playerReportLogs table` -This is the name of the table which contains report log data. By default this is set to bm_report_logs and is the value within your BanManager `config.yml` file. - -##### `serverLogs table` -This is the name of the table which contains report log data. By default this is set to bm_server_logs and is the value within your BanManager `config.yml` file. - -##### `Console UUID` -BanManager generates a UUID to use when punishing players by the console. This can be found in your [console.yml](/docs/banmanager/configuration/console-yml) file. This record must exist. - -##### `Server Name` -Like the legacy UI, you can name servers in order to differentiate between where punishments occurred. This is useful for multi-server setups. This can be whatever you like. - -##### `Your Email Address` -Set this to an address you wish to use to login with. This does not need to be the same email address as your Mojang account. - -##### `Your Password` -Set this to a value you wish to use to login with. This should **not be the same password as your Mojang account**. If you forget this password, you can login using a pin generated in-game via `/bmpin` command (requires BanManager-WebEnhancer). - -##### `Your Minecraft Player UUID` -This is required to setup your login and associate your data. If you're not sure what this is, use a lookup tool such as https://mcuuid.net/ to lookup your online UUID. - -#### Run -The following environment variables are required and should have been generated by the previous setup step. - -```bash -CONTACT_EMAIL -ENCRYPTION_KEY -SESSION_KEY -NOTIFICATION_VAPID_PUBLIC_KEY -NOTIFICATION_VAPID_PRIVATE_KEY -DB_HOST -DB_PORT -DB_USER -DB_PASSWORD -DB_NAME -``` - -If you are not using the .env file, you must pass these variables yourself in the next steps. - -Next run the systemd command below to run the UI as a service. This will ensure it runs in the background and automatically restarts. You may be prompted to provide a password for sudo access. This is expected and the commands that will be executed will be provided beforehand. -```bash -npx bmwebui setup systemd -``` - -If you do not have systemd, you can use an alternative such as [PM2](https://github.com/Unitech/pm2). Note that this is not covered by the installation guide. - -It is highly recommended to use a web server such as NGINX to provide HTTPS support and defend against a number of common web attacks. Certificates for HTTPS can be obtained freely via [Let's Encrypt](https://letsencrypt.org/). To help with this, another setup command can be used to configure NGINX via HTTP. - -First install NGINX if you haven't already: -```bash -sudo apt update && sudo apt install nginx -``` - -Next run the setup command: - -```bash -npx bmwebui setup nginx -``` - -#### NGINX Setup Questions - -##### Domain -This will be how you access the website. You are expected to have registered a domain name and configured the DNS to point to your server. Without this, the WebUI will not function as expected. - -##### Subdirectory -If you want to run the UI on an existing domain rather than a separate domain or subdomain, please provide the path here. A new environment variable of `BASE_PATH` will be added to your `.env` file. Please restart the UI (if via systemd above run `sudo systemctl restart bmwebui.service`) and re-run the `npx bmwebui setup nginx` command once completed. - -Once this is completed, the UI should be available over HTTP. Try it out! Next, we need to secure the site via HTTPS to prevent attackers eavesdropping on pins/passwords that are entered into the UI. - -#### Let's Encrypt Setup -First install CertBot. This is used to manage and rotate certificates. - -```bash -sudo apt update && sudo apt install certbot -``` - -Once installed, run the following command to automatically generate a certificate and update your NGINX configuration. Ensure to replace `example.com` with the domain you chose in the setup previously. - -```bash -sudo certbot --nginx -d example.com -``` - -That's it! Now head over to your UI domain and login. diff --git a/content/docs/webui/install/cli.mdx b/content/docs/webui/install/cli.mdx new file mode 100644 index 00000000..e937c9e9 --- /dev/null +++ b/content/docs/webui/install/cli.mdx @@ -0,0 +1,113 @@ +--- +layout: 'docs' +title: 'Install with the CLI' +navTitle: 'Install with the CLI' +navOrder: 13 +category: 'Web UI' +description: 'Install the BanManager WebUI from the terminal using the bmwebui setup wizard.' +--- +A terminal-only installer. The wizard auto-detects your BanManager database connection, table names, and console UUID from your `plugins/BanManager` folder, so you only answer the handful of questions it can't figure out on its own. Useful when you don't want to run a browser or expose `/setup`. + +Make sure you've worked through the shared [prerequisites](/docs/webui/install#prerequisites) and the [BanManager-WebEnhancer setup](/docs/webui/install#banmanager-webenhancer) before continuing. + +## Prerequisites + +- Shell access to the install host. +- [Node.js](https://nodejs.org/) LTS (v20 or v22). +- A reachable MySQL or MariaDB server with the database created and a user that can read/write it. +- Read access to your `plugins/BanManager` folder (optional — only used by auto-detect; you can fall back to manual entry if it's on a different host). + +## Install + +```bash +sudo mkdir -p /home/banmanager +cd /home/banmanager + +git clone https://github.com/BanManagement/BanManager-WebUI.git +cd BanManager-WebUI + +npm ci --omit=dev +npm run setup +``` + +`npm run setup` runs `bmwebui setup --writeFile .env` — every value the wizard collects is appended to a `.env` file alongside the app, and re-running the command picks up where you left off. + +--- + +## Walk through the wizard + +The wizard asks for everything in roughly five batches. Steps you've already completed are skipped automatically (`SETTING_NAME detected, skipping`). + +### 1. Server display name and contact email + +- **Server name** — used in the website footer (≤ 32 chars). +- **Contact email** — used to register with the push-notification vendors. Use a real address you check. + +### 2. Generated keys (no questions asked) + +The wizard generates `ENCRYPTION_KEY`, `SESSION_KEY`, and the `NOTIFICATION_VAPID_*` pair for you. They're written to `.env` immediately so they survive a restart. + +> **Don't change `ENCRYPTION_KEY` later.** It encrypts the BanManager database password stored in `bm_web_servers`. If you rotate it after install, the WebUI will no longer be able to talk to your BanManager database. + +### 3. WebUI database + +You're prompted for the database the WebUI itself will use (host, port, user, password, database name). The wizard verifies the connection and then runs all migrations against it. This database can be the same one as BanManager, or a separate one. + +### 4. BanManager server + +If a BanManager server is already configured (you're re-running setup), the wizard verifies the connection and skips ahead. Otherwise it offers to **auto-detect from your BanManager plugin folder** — point it at the directory containing `config.yml` and `console.yml` (defaults to `./plugins/BanManager`, override with `BM_CONFIG_PATH`) and it pre-fills: + +- The BanManager database connection (host, port, user, password, database). +- All the BanManager table names. +- The console player UUID. + +If auto-detect can't find the files (different host, restricted permissions), you'll be asked to enter each value by hand. You'll also be offered the option to "use the same database as the WebUI" if the BanManager and WebUI databases are colocated. + +The wizard verifies the connection, that all tables exist, and that the console UUID resolves to a row in the `bm_players` table before continuing. + +### 5. Admin user + +If an admin already exists, this step is skipped. Otherwise you're prompted for: + +- Your email (used to log in). +- A password (≥ 6 characters, asked twice). +- Your Minecraft player UUID (must already exist in `bm_players`, i.e. you've joined the server at least once). + +Look up your UUID at [mcuuid.net](https://mcuuid.net/) if you're not sure. **Don't reuse your Mojang password.** + +The user and admin role are inserted in a single database transaction so a failure between the two steps can't leave a half-created admin behind. + +--- + +## Resumability + +`npm run setup` is safe to re-run. The wizard reads the existing `.env`, treats any already-set value as done, and skips the corresponding question. So if you mistype a database password or the BanManager DB is unreachable, you can fix it (edit the `.env` directly or unset the variable) and re-run without starting from scratch. + +If you'd rather keep the values in a different file, run the underlying command directly: + +```bash +npx bmwebui setup --writeFile=/etc/bmwebui/.env +``` + +Without `--writeFile` the values are only echoed to stdout — useful for piping into a secrets manager during automated setups. + +--- + +## Build and start + +Once the wizard finishes, build the production assets and start the server: + +```bash +npm run build +npm start +``` + +The WebUI listens on `http://0.0.0.0:3000` by default. Sign in at `http://your-host:3000/login`. + +--- + +## What next? + +- [Verify the install](/docs/webui/install#verify-with-bmwebui-doctor) with `npx bmwebui doctor`. +- [Run in production](/docs/webui/deployment) — `systemd` and reverse-proxy templates with HTTPS. +- [Add more accounts](/docs/webui/install#add-more-accounts) with `npx bmwebui account create`. diff --git a/content/docs/webui/install/docker.mdx b/content/docs/webui/install/docker.mdx new file mode 100644 index 00000000..387bd6ec --- /dev/null +++ b/content/docs/webui/install/docker.mdx @@ -0,0 +1,156 @@ +--- +layout: 'docs' +title: 'Install with Docker' +navTitle: 'Install with Docker' +navOrder: 11 +category: 'Web UI' +description: 'Install the BanManager WebUI with Docker Compose using the official banmanagement/webui image.' +--- +The recommended way to run the WebUI in production. The container generates its own encryption keys, waits for the database, runs migrations, and persists state to a Docker volume — so you can be up and running in two commands. + +Make sure you've worked through the shared [prerequisites](/docs/webui/install#prerequisites) and the [BanManager-WebEnhancer setup](/docs/webui/install#banmanager-webenhancer) before continuing. + +## Prerequisites + +- Docker 20.10+ with the Compose plugin (`docker compose ...`). +- DNS for your domain pointing at this server (only required when you're ready to expose the WebUI publicly). + +## Pick a compose file + +Two official compose files are published in the [BanManager-WebUI repository](https://github.com/BanManagement/BanManager-WebUI): + +| File | Use when | +| --- | --- | +| [`docker-compose.prod.yml`](https://github.com/BanManagement/BanManager-WebUI/blob/master/docker-compose.prod.yml) | You want everything in one shot — runs MySQL alongside the WebUI in the same Compose project. | +| [`docker-compose.prod-no-db.yml`](https://github.com/BanManagement/BanManager-WebUI/blob/master/docker-compose.prod-no-db.yml) | You already have a MySQL or MariaDB server you want the WebUI to use. | + +### Bundled MySQL + +```bash +curl -O https://raw.githubusercontent.com/BanManagement/BanManager-WebUI/master/docker-compose.prod.yml + +cat > .env < .env < **Security.** The `/setup` page is open by default — whoever loads it first becomes the admin. If your install host is reachable from the internet, set `SETUP_TOKEN` in your `.env` file before bringing the stack up: +> ```bash +> SETUP_TOKEN=$(openssl rand -hex 24) +> ``` +> The setup screen will require it as the first step. Once an admin user exists the setup routes return 404 automatically. + +--- + +## Verify + +After setup completes, run the doctor to make sure everything is wired up correctly: + +```bash +docker compose exec webui npx bmwebui doctor +``` + +You should see `PASS` for every check (env file, environment variables, database connection, migrations, admin user, BanManager server, plugin tables, console player). + +--- + +## Persistent volumes + +The compose files declare four named volumes. Back these up to keep your install reproducible: + +| Volume | Contents | +| --- | --- | +| `webui_config` | The generated `.env` file (encryption keys, DB credentials). **Critical — don't lose this.** | +| `webui_uploads` | Uploaded report attachments. | +| `webui_image_cache` | Next.js image cache (regenerable). | +| `webui_opengraph_cache` | OpenGraph preview cache (regenerable). | + +The bundled-MySQL compose also has a `mysql_data` volume holding the WebUI database itself. + +--- + +## Updating + +Pull the latest image and restart in place: + +```bash +docker compose pull +docker compose up -d +``` + +The entrypoint runs any pending database migrations on startup, so updates are usually a one-step operation. If you want a manual confirmation, run `docker compose exec webui npx bmwebui doctor` after the update. + +--- + +## Restarting and operations + +Both compose files set `restart: unless-stopped` — Docker will restart the WebUI on host reboot or container crash without any extra setup. There's no `systemd` unit to install. + +For HTTPS in front of the container, see [Deployment](/docs/webui/deployment#reverse-proxy). When you put a reverse proxy in front of the container, set `TRUST_PROXY=true` in your `.env` so the WebUI sees the real client IP and HTTPS state. + +To follow the logs: + +```bash +docker compose logs -f webui +``` + +To shell into the running container: + +```bash +docker compose exec webui sh +``` + +--- + +## What next? + +- [Run in production](/docs/webui/deployment) — reverse proxy with HTTPS via Caddy / Apache / nginx. +- [Add more accounts](/docs/webui/install#add-more-accounts) with `npx bmwebui account create`. +- See the [environment variables reference](/docs/webui/install#environment-variables) for all available options. diff --git a/content/docs/webui/install/index.mdx b/content/docs/webui/install/index.mdx new file mode 100644 index 00000000..81b0c2f3 --- /dev/null +++ b/content/docs/webui/install/index.mdx @@ -0,0 +1,220 @@ +--- +layout: 'docs' +title: 'Install' +navTitle: 'Install' +navOrder: 10 +category: 'Web UI' +description: 'Install and configure the BanManager WebUI to aggregate and manage punishment data from your mobile or computer' +--- +The BanManager WebUI is a self-hosted web interface for managing your BanManager punishment data. It runs alongside your Minecraft server, talks to the same MySQL/MariaDB database, and adds appeals, reports, role-based permissions, and a single dashboard for one or more servers. + +This page walks through the prerequisites that apply to every install, then helps you pick the install method that suits you best. + +## Prerequisites + +The WebUI works on any host that can reach your BanManager database, including a separate server from your Minecraft host. + +- BanManager configured to use [MySQL 5+ or MariaDB 10+](/docs/banmanager/install#setup-shared-database-optional). The default H2 database is not supported. +- A server with at least 1GB of memory. +- A registered domain name (required for HTTPS). +- [Node.js](https://nodejs.org/) LTS (v20 or v22) — only required if you're not using Docker. + +--- + +## BanManager-WebEnhancer + +This Minecraft plugin enables web-only features (login pins, appeal links). It's required no matter which install method you choose below. + +1. [Download](https://ci.frostcast.net/job/BanManager-WebEnhancer/) the jar and add it to your server. The [source code](https://github.com/BanManagement/BanManager-WebEnhancer) is also available. +1. Edit BanManager's [messages.yml](/docs/banmanager/configuration/messages-yml), and add a `[pin]` token to the `ban.player.disallowed` and `tempban.player.disallowed` messages: + ```yml + ban: + player: + disallowed: '&6You have been banned from this server for &4[reason]&6. Your appeal pin is [pin]' + tempban: + player: + disallowed: '&6You have been temporarily banned from this server for &4[reason]\n&6It expires in [expires]. Your appeal pin is [pin]' + ``` +1. Restart your server, or enable the plugin and run `/bmreload`. + +--- + +## Pick your installation method + +The WebUI ships three install paths. They all produce the same end result — pick the one that suits how you like to run servers. + +### [Install with Docker](/docs/webui/install/docker) + +**Recommended.** One `docker compose up -d` and you're done. The container generates its own encryption keys, runs database migrations, and persists state to a volume. Open a browser to finish setup. There are two compose files: one bundles MySQL, one expects you to bring your own. + +### [Install with the web installer](/docs/webui/install/web) + +Clone the repo, run `node server.js`, and finish the install in a browser at `/setup`. Useful when you want the convenience of a guided UI without Docker, or when you can't keep a long-lived shell session open during install. + +### [Install with the CLI](/docs/webui/install/cli) + +`npm run setup` walks you through every step in your terminal. The wizard auto-detects your BanManager database connection, console UUID, and table names from your `plugins/BanManager` folder, so you only answer a handful of questions. + +--- + +## After install + +The same handful of follow-ups apply no matter which path you took. + +### Verify with `bmwebui doctor` + +Run a preflight check at any time. It validates your environment variables, database connection, migrations, admin user, BanManager server connection, console player, and plugin tables in one shot. + +```bash +npx bmwebui doctor +``` + +Useful flags: + +- `--url=http://127.0.0.1:3000/health` — also probe a running server's `/health` endpoint. +- `--strict` — exit non-zero on warnings (handy in CI). + +### Run in production + +When you're ready to go live, see [Deployment](/docs/webui/deployment) for `systemd`, Docker restart policy, and reverse-proxy templates (Caddy, Apache, nginx) with HTTPS via Let's Encrypt. + +### Add more accounts + +The install creates your first admin. To add additional users later: + +```bash +npx bmwebui account create +``` + +You'll be prompted for an email, password, Minecraft UUID, and role. + +### Health monitoring + +Every WebUI exposes an unauthenticated `/health` endpoint that returns JSON suitable for uptime checks and load-balancer probes: + +```json +{ + "status": "ok", + "version": "x.y.z", + "migrations": "up-to-date", + "admin": "present" +} +``` + +`status` is `"ok"`, `"setup_required"`, or `"db_unreachable"` (HTTP 503 in the latter case). + +--- + +## Environment variables + +The WebUI is configured via environment variables — usually written to a `.env` file alongside the app, or to `/app/config/.env` inside the Docker container. You rarely need to set these by hand: the install paths above each generate the required values for you. + +### Required + +| Variable | Purpose | +| --- | --- | +| `DB_HOST`, `DB_PORT`, `DB_USER`, `DB_NAME` | WebUI database connection. Can be the same database as BanManager, or a separate one. | +| `DB_PASSWORD` | WebUI database password. Optional for socket-auth or unauthenticated dev databases — required everywhere else. | +| `ENCRYPTION_KEY` | 64-character hex string used to encrypt stored BanManager database passwords. **Don't change this after install** (see below). | +| `SESSION_KEY` | 64-character hex string used to sign user sessions. | +| `CONTACT_EMAIL` | Contact address registered with the push-notification vendors. | +| `NOTIFICATION_VAPID_PUBLIC_KEY` / `NOTIFICATION_VAPID_PRIVATE_KEY` | VAPID keys for browser push notifications. | + +Generate hex keys with: + +```bash +node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" +``` + +### Operations + +| Variable | Default | Purpose | +| --- | --- | --- | +| `PORT` | `3000` | HTTP listen port. | +| `HOSTNAME` | (all) | Bind address. | +| `LOG_LEVEL` | `info` | Pino log level. The shipped `.env.example` and Docker Compose files set this to `info`; running `node server.js` directly with no `.env` will fall back to `debug`. | +| `NODE_ENV` | `production` | Should be `production` for live deployments. | +| `SERVER_FOOTER_NAME` | (empty) | Server name shown in the website footer. | +| `BASE_PATH` | (empty) | Sub-directory mount, e.g. `/banmanager`. Requires a re-build. | +| `TRUST_PROXY` | `false` | Set to `true` when behind nginx / Caddy / Apache so the WebUI reads `X-Forwarded-For` and `X-Forwarded-Proto`. | +| `SESSION_NAME` | `bm-webui-sess` | Session cookie name. | +| `DB_CONNECTION_LIMIT` | `5` | Maximum connections in the WebUI database pool. | + +### Uploads + +| Variable | Default | Purpose | +| --- | --- | --- | +| `UPLOAD_MAX_SIZE` | `10MB` | Maximum upload size. Accepts human-readable values (`5MB`, `1GB`, etc.). | +| `UPLOAD_PATH` | `./uploads/documents` | Where uploaded documents are stored. | +| `UPLOAD_MAX_DIMENSION` | `8192` | Maximum image dimension in pixels (defends against pixel bombs). | +| `DOCUMENT_CLEANUP_AGE_HOURS` | `24` | How long unattached documents live before being garbage-collected. | + +### Setup-only + +| Variable | Purpose | +| --- | --- | +| `SETUP_TOKEN` | Locks the `/setup` page behind a shared secret while you're installing. Strongly recommended on any host reachable from the internet. | +| `DOTENV_CONFIG_PATH` | Override the location of the `.env` file the server reads at startup. | + +--- + +## Security and operational notes + +### `SETUP_TOKEN` — protect the open installer + +The browser-based installer at `/setup` is **unauthenticated by default**: whoever loads the page first becomes the admin (the same model as WordPress and Ghost). On a loopback-only host that's harmless. On any host reachable from the internet, set a token before starting: + +```bash +SETUP_TOKEN=$(openssl rand -hex 24) +``` + +The setup screen will require it as the very first step. Once an admin user exists the setup routes return 404 automatically. + +### `TRUST_PROXY=true` behind a reverse proxy + +Without this, every request looks like it came from `127.0.0.1` and the wizard's "you're on a secure local connection" banner can be misleading. Set `TRUST_PROXY=true` so the WebUI reads `X-Forwarded-For` and `X-Forwarded-Proto`. + +### Don't change `ENCRYPTION_KEY` after install + +`ENCRYPTION_KEY` encrypts the BanManager database passwords stored in `bm_web_servers`. If you rotate it after the install, the WebUI can no longer decrypt those credentials and will fail to talk to your BanManager database. `npx bmwebui doctor` will report `Failed to decrypt the stored BanManager password` if this happens. + +If you've lost the original key, you'll need to delete the affected row from `bm_web_servers` and re-run `npx bmwebui setup` to re-create it with the new key. + +--- + +## Troubleshooting + +`npx bmwebui doctor` is the single best place to start — it diagnoses most install problems automatically. Some common errors and their fixes: + +### "Cannot connect to BanManager database" + +The WebUI host must be able to reach the BanManager database host. Check your firewall, and that the database user has been granted access from the WebUI host's IP: + +```sql +GRANT ALL PRIVILEGES ON dbname.* TO 'bmuser'@'webui-host-ip' IDENTIFIED BY 'password'; +FLUSH PRIVILEGES; +``` + +### "Console UUID could not be verified" + +The console UUID has to exist as a row in the `bm_players` table. BanManager inserts it automatically the first time the plugin starts after install — so make sure your Minecraft server has been started at least once with BanManager enabled before running the WebUI installer. + +### "Setup is already complete" returned from `/setup` + +An admin user already exists, so the install routes are disabled. Sign in instead, or use `npx bmwebui account create` to add another account. + +### "Failed to decrypt the stored BanManager password" + +`ENCRYPTION_KEY` was rotated after install — see the warning above. + +### "Migrations failed" or `migrations: pending` in `/health` + +Apply pending database migrations: + +```bash +npx bmwebui update +``` + +### Still stuck? + +[Join us on Discord](https://discord.gg/59bsgZB) or [open an issue](https://github.com/BanManagement/BanManager-WebUI/issues/new) — please include the output of `npx bmwebui doctor` so we can help quickly. diff --git a/content/docs/webui/install/web.mdx b/content/docs/webui/install/web.mdx new file mode 100644 index 00000000..6859802d --- /dev/null +++ b/content/docs/webui/install/web.mdx @@ -0,0 +1,124 @@ +--- +layout: 'docs' +title: 'Install with the web installer' +navTitle: 'Install with the web installer' +navOrder: 12 +category: 'Web UI' +description: 'Install the BanManager WebUI from source and finish setup in your browser at /setup.' +--- +A guided, browser-based installer for the WebUI. Start the server with no `.env` and it boots in setup mode — visit `/setup` to enter your database details, point it at your BanManager server, create the first admin, and you're done. + +Make sure you've worked through the shared [prerequisites](/docs/webui/install#prerequisites) and the [BanManager-WebEnhancer setup](/docs/webui/install#banmanager-webenhancer) before continuing. + +## Prerequisites + +- Shell access to the server during the initial start (you can disconnect once setup is done). +- [Node.js](https://nodejs.org/) LTS (v20 or v22). +- A reachable MySQL or MariaDB server (the installer can create the database for you if the user has permission). + +## Install + +Pick a directory for your installation — we'll use `/home/banmanager` in this example. + +```bash +sudo mkdir -p /home/banmanager +cd /home/banmanager + +git clone https://github.com/BanManagement/BanManager-WebUI.git +cd BanManager-WebUI + +npm ci --omit=dev +npm run build +``` + +> **Reachable from the internet?** Set a setup token before starting the server. See [security](#security) below. + +Start the server. With no `.env` file present, it'll boot in **setup mode** — only the `/setup`, `/health`, and static asset routes respond: + +```bash +node server.js +``` + +You should see something like: + +``` +warn: Server started in setup mode. Visit /setup to complete installation. +``` + +--- + +## Walk through the wizard + +Open `http://your-host:3000/setup` in a browser. The wizard will guide you through five steps. + +### 1. Setup token (only if `SETUP_TOKEN` is set) + +If you set a `SETUP_TOKEN` before starting the server, the wizard prompts for it as the first step. The token is checked with a constant-time comparison and the same value is required for every subsequent step. + +### 2. Database + +Enter the connection details for the database the WebUI itself will use (logins, roles, sessions, server registry). This can be the same database as your BanManager plugin or a separate one. + +If the database doesn't exist yet, tick **"Create database if missing"** and supply a privileged user (e.g. `root` and the root password). The installer will create the database, switch to your normal user, and run all migrations automatically. + +### 3. BanManager server + +Tell the WebUI where your BanManager plugin's database lives and which tables to read from. Three options: + +- **Paste your config** — paste the contents of `plugins/BanManager/config.yml` and `plugins/BanManager/console.yml`. The installer parses them and pre-fills the connection, table names, and console UUID. +- **Filesystem path** — point the installer at your `plugins/BanManager` folder if it lives on the same machine. +- **Manual entry** — type the connection details, table names, and console UUID by hand. + +The installer verifies it can reach the BanManager database, that all the configured tables exist, and that the console UUID resolves to a row in `bm_players` before letting you continue. + +### 4. Admin account + +Create your first admin user. You'll need: + +- An email address — used to log in. +- A password — at least 6 characters. **Don't reuse your Mojang password.** +- Your Minecraft player UUID — used to associate the account with your in-game player. Look it up at [mcuuid.net](https://mcuuid.net/) if you're not sure. + +### 5. Finalize + +The installer: + +- Writes a `.env` file alongside the app (or to `/app/config/.env` inside Docker) with your DB credentials, generated encryption keys, and VAPID keys. +- Runs all database migrations. +- Creates the BanManager server entry and your admin user in a single transaction (so a partial failure can't leave a half-created account behind). + +Inside Docker the container restarts itself automatically. On a regular host, stop the server with `Ctrl+C` and start it again — this time it'll come up in normal mode with the new configuration. + +```bash +node server.js +``` + +You can now sign in at `http://your-host:3000/login`. + +--- + +## Security + +The `/setup` page is **unauthenticated by default** — whoever loads it first becomes the admin (the same model as WordPress and Ghost). On a loopback-only host that's harmless. On any host reachable from the internet, gate it with a token before starting: + +```bash +SETUP_TOKEN=$(openssl rand -hex 24) node server.js +``` + +The setup screen will require it as the very first step. Share the token only with whoever is doing the install. Once an admin user exists the setup routes return 404 automatically. + +A few additional protections are always on: + +- **Rate limiting** — 10 setup-API requests per IP per minute. +- **Same-origin checks** — POSTs to `/api/setup/*` are rejected if the `Origin` or `Referer` doesn't match the request host (so a malicious page can't trick your browser into completing setup on your behalf). +- **Setup routes return 404 once an admin exists** — the installer can't be re-run to create a second "first" admin. + +If your install is sitting behind a reverse proxy, also set `TRUST_PROXY=true` in your `.env` so the WebUI reads `X-Forwarded-For` and `X-Forwarded-Proto` correctly. Without it the WebUI thinks every request is coming from `127.0.0.1`, so the "Your connection is not encrypted" warning won't appear even when an external user is connecting over plain HTTP. + +--- + +## What next? + +- [Verify the install](/docs/webui/install#verify-with-bmwebui-doctor) with `npx bmwebui doctor`. +- [Run in production](/docs/webui/deployment) — `systemd` and reverse-proxy templates with HTTPS. +- [Add more accounts](/docs/webui/install#add-more-accounts) with `npx bmwebui account create`. diff --git a/data/navigation.json b/data/navigation.json index 13ab6d57..bbd7320a 100644 --- a/data/navigation.json +++ b/data/navigation.json @@ -66,11 +66,12 @@ }, { "layout": "docs", - "title": "Install", - "navTitle": "Install", + "title": "Deployment", + "navTitle": "Deployment", + "navOrder": 14, "category": "Web UI", - "description": "Install and configure the BanManager WebUI to aggregate and manage punishment data from your mobile or computer", - "__resourcePath": "docs/webui/install.mdx" + "description": "Run the BanManager WebUI in production: keep it alive with systemd or Docker, and serve it over HTTPS with Caddy, Apache, or nginx.", + "__resourcePath": "docs/webui/deployment.mdx" }, { "layout": "docs", @@ -199,6 +200,42 @@ "category": "Migration Guides", "description": "Import bans and IP bans from Minecraft Java Edition's built-in banning system to BanManager.", "__resourcePath": "docs/banmanager/migrations/minecraft-java-edition.mdx" + }, + { + "layout": "docs", + "title": "Install with the CLI", + "navTitle": "Install with the CLI", + "navOrder": 13, + "category": "Web UI", + "description": "Install the BanManager WebUI from the terminal using the bmwebui setup wizard.", + "__resourcePath": "docs/webui/install/cli.mdx" + }, + { + "layout": "docs", + "title": "Install with Docker", + "navTitle": "Install with Docker", + "navOrder": 11, + "category": "Web UI", + "description": "Install the BanManager WebUI with Docker Compose using the official banmanagement/webui image.", + "__resourcePath": "docs/webui/install/docker.mdx" + }, + { + "layout": "docs", + "title": "Install", + "navTitle": "Install", + "navOrder": 10, + "category": "Web UI", + "description": "Install and configure the BanManager WebUI to aggregate and manage punishment data from your mobile or computer", + "__resourcePath": "docs/webui/install/index.mdx" + }, + { + "layout": "docs", + "title": "Install with the web installer", + "navTitle": "Install with the web installer", + "navOrder": 12, + "category": "Web UI", + "description": "Install the BanManager WebUI from source and finish setup in your browser at /setup.", + "__resourcePath": "docs/webui/install/web.mdx" } ], "docsNav": { @@ -319,9 +356,46 @@ "layout": "docs", "title": "Install", "navTitle": "Install", + "navOrder": 10, "category": "Web UI", "description": "Install and configure the BanManager WebUI to aggregate and manage punishment data from your mobile or computer", - "__resourcePath": "docs/webui/install.mdx" + "__resourcePath": "docs/webui/install/index.mdx" + }, + { + "layout": "docs", + "title": "Install with Docker", + "navTitle": "Install with Docker", + "navOrder": 11, + "category": "Web UI", + "description": "Install the BanManager WebUI with Docker Compose using the official banmanagement/webui image.", + "__resourcePath": "docs/webui/install/docker.mdx" + }, + { + "layout": "docs", + "title": "Install with the web installer", + "navTitle": "Install with the web installer", + "navOrder": 12, + "category": "Web UI", + "description": "Install the BanManager WebUI from source and finish setup in your browser at /setup.", + "__resourcePath": "docs/webui/install/web.mdx" + }, + { + "layout": "docs", + "title": "Install with the CLI", + "navTitle": "Install with the CLI", + "navOrder": 13, + "category": "Web UI", + "description": "Install the BanManager WebUI from the terminal using the bmwebui setup wizard.", + "__resourcePath": "docs/webui/install/cli.mdx" + }, + { + "layout": "docs", + "title": "Deployment", + "navTitle": "Deployment", + "navOrder": 14, + "category": "Web UI", + "description": "Run the BanManager WebUI in production: keep it alive with systemd or Docker, and serve it over HTTPS with Caddy, Apache, or nginx.", + "__resourcePath": "docs/webui/deployment.mdx" }, { "layout": "docs", diff --git a/scripts/generate-navigation.mjs b/scripts/generate-navigation.mjs index 4a7913c3..67dd7a6c 100644 --- a/scripts/generate-navigation.mjs +++ b/scripts/generate-navigation.mjs @@ -54,6 +54,25 @@ function generateNavigation () { navData[page.category].push(page) }) + // Sort within each category: pages with explicit navOrder first (ascending), + // then pages without navOrder in their original glob-discovery order. We use + // a stable sort with navTitle as a tiebreaker so the output is deterministic + // for pages that share a navOrder. + Object.keys(navData).forEach((category) => { + navData[category].sort((a, b) => { + const aHas = typeof a.navOrder === 'number' + const bHas = typeof b.navOrder === 'number' + + if (aHas && bHas) { + if (a.navOrder !== b.navOrder) return a.navOrder - b.navOrder + return a.navTitle.localeCompare(b.navTitle) + } + if (aHas) return -1 + if (bHas) return 1 + return 0 + }) + }) + // Sort by category order const docsNav = categoryOrder.reduce((r, k) => { if (navData[k]) {