v1.3.0
What's New
-
CrowdSec integration - a new optional CrowdSec tab shows active decisions (bans, captchas, bypasses), recent alerts, and lets you unban an IP directly from the UI. Configure your LAPI URL and API key in Settings - System Monitoring - CrowdSec (no restart needed). Works with both a CrowdSec instance installed via the traefik-stack installer and an existing CrowdSec you connect to manually. Env vars
CROWDSEC_LAPI_URLandCROWDSEC_API_KEYare also supported as a fallback. -
Gatekeeper middleware wizard - the middleware wizard now includes a Gatekeeper preset under Forward Auth. Enter your Gatekeeper base URL and optional policy name - TM appends
/auth/verifyautomatically and pre-fills theX-Auth-UserandX-Auth-Emailresponse headers. See https://github.com/chr0nzz/gatekeeper. -
Route clone - each route card now has a clone icon. Clicking it opens the add modal pre-filled with the existing route's service URL, middlewares, and entrypoints so you can create a similar route without starting from scratch.
-
traefik-stack installer - the installer now optionally sets up CrowdSec as part of the stack (installs CrowdSec + auto-generates a bouncer API key) or connects to an existing CrowdSec instance by prompting for the LAPI URL and API key.
Fixes
-
#50 - Middleware chip ordering - selected middlewares in the route form now appear first in insertion order, each numbered (1. auth, 2. ratelimit, ...), with a visual divider separating them from available-but-unselected chips. Makes middleware ordering visible at a glance since Traefik processes them left to right.
-
#51 - Redirect-regex wizard YAML corruption - the replacement string field was mangling dollar-sign capture groups (
$1,$2, etc.) into${{1}}before writing to YAML, causing Traefik to reject the config. Field is now written verbatim. -
#52 - Wizard state bleeding between templates - switching from one middleware template to another (e.g. Rate Limit to IP Allowlist) was keeping the previous template's field values in the form. Fields now clear and checkboxes reset to defaults whenever the active wizard section changes.
-
#53 - All CDN dependencies bundled in the Docker image - the app previously required outbound internet access at runtime to load Tailwind CSS, Phosphor Icons, QRCode.js, Dagre, Monaco Editor, Monaco themes, and the Inter and JetBrains Mono fonts from various CDNs. All of these are now downloaded at Docker build time (no npm required - standalone Tailwind CLI binary + npm registry tarballs via curl) and served from
/static/vendor/. The container works fully offline afterdocker pull. Route Map app icons from selfhst/icons are the only remaining CDN call (those are per-service and depend on route names at runtime). -
Route Map entrypoint filter and Android edit crash - routes with a single entrypoint are sometimes stored as a plain YAML string instead of a list. This caused the Route Map's entrypoint filter to use substring matching instead of exact matching (e.g.
websecureincorrectly matchingwebsecure-ext), and crashed the Android edit form when it called.join()on a string. Fixed by normalisingentryPointsandmiddlewaresto always be arrays in the backend (_to_list()helper) and addingArray.isArray()guards in the Route Map frontend and mobile app. -
Navbar badge toggle broken after CDN switch - the Tailwind Play CDN injects its generated
<style>into the DOM after all<link>tags, so Tailwind utilities (including.hidden) always overrodeapp.cssclass selectors at equal specificity. The pre-builttailwind.csswas originally placed beforeapp.css, reversing that order and making.hiddenloseable to.nav-btn { display: inline-flex }. Fixed by loadingapp.cssfirst andtailwind.csslast, which also preserves responsive override behaviour (sm:flexcan still beathiddenwithin the same file). -
#54 - Modal closes when releasing mouse outside after text selection - all modal overlays (
appModal,mwModal, Settings, Route Map group/edit/popup) used aclickevent to detect backdrop clicks. A click fires at the mouseup location, so starting a text selection drag inside the modal and releasing the mouse on the backdrop incorrectly closed the modal. Fixed by tracking the mousedown target globally and only closing when both mousedown and mouseup land on the same backdrop element. -
Settings modal not scrolling on desktop - the settings modal panels were not scrollable on desktop. Root cause:
openSettingsModalwas callingelement.style.display = ''to show#settingsPanelWrapper, which removes the inline style and falls back to the CSS cascade. The only CSS rule providingdisplay:flexfor that element was inside a@media (max-width:640px)block (mobile only), so on desktop it becamedisplay:block. In block layout the inneroverflow-y:autopanels never triggered. Fixed by explicitly settingdisplay:flexin the JS instead. -
#56 - 401 when Traefik dashboard requires authentication - if the Traefik API is configured with
api.insecure: falseand basic auth, all TM API calls returned 401. AddedTRAEFIK_API_USERandTRAEFIK_API_PASSWORDenvironment variables (and matching Settings - Connection fields) to pass HTTP Basic Auth on every Traefik API request. The password is stored encrypted inmanager.yml. The Test Connection button in Settings tests with the currently-entered credentials. -
#57 - Go template syntax in dynamic config crashes the app - Traefik supports Go templating in dynamic config files (
{{ env "MY_VAR" }}). When TM loaded such a file withruamel.yaml, the double-brace syntax caused a YAML parse error that crashed the entire app on startup. Fixed by pre-processing config files as raw text before parsing:{{ ... }}expressions are replaced with the placeholder__TM_TEMPLATE__so the YAML structure loads cleanly. The Monaco editor reads raw files from disk so users still see their actual template syntax.