Auto-built release for commit db6d0f4.
2026-11-01 — monthly cut: db6d0f4da
stable moved from 51fd7fc25 to db6d0f4da: 302 changes.
Migrations 000309–000341 (33). Changing rows: 000311, 000317, 000318, 000332, 000335, 000340.
9755a6aedfix(mail): DMARC reports reach every domain; postmaster@ is the server admin's (#1940)35826ef14feat(php): per-domain log_errors, file_uploads and short_open_tag, pinned so they cannot leak between domains — GH #1701 (#1951)bfa676212feat(php): pin every per-domain PHP value on every PHP vhost, and show the value the pool really runs as the default — GH #1701 (#1969)393a37efafeat(domains): a tenant domain goes live only after its owner proves the name — GH #1816 (#1923)1b51eba08chore(db): drop the retired users.webmail_enabled column — GH #1817 (#1970)ad60c7788fix(malware): "Update signatures" refreshes the signature-base YARA pack, not the removed PMF unit (#1971)8d121ac67docs(ftp): isolated accounts re-mount on the first reconcile tick after a reboot; there is no boot unit (#1972)a05912544feat(php): per-domain open_basedir and allow_url_fopen, pinned on every PHP vhost — GH #1701 Slice 3 (#1974)654a15a30fix(php): app installs in a subfolder get the domain's PHP values — GH #1701 (#1975)29b19cebbfeat(php): PHP Settings shows each setting's state live and keeps unsaved changes safe — GH #1701 (#1976)f71a5eb91fix(ui): sticky elements in tenant pages stay in view while the page scrolls (#1977)0dc8eaf3dfix(backups): retention keeps or forgets whole backups, so no restore point is left partial — GH #1169 (#1978)e2d94d29ffix(backups): retention works on rotated and default Local destinations and alerts when all fail;backup retention verifyfinds unrestorable backups — GH #1169 (#1979)2057dd0d0fix(backups): retention keeps backups that lost only their manifest, and deletes rows with no snapshot left — GH #1169 (#1980)c7212ee34fix(backups): retention alerts when a schedule's destinations cannot be loaded (#1981)b30e288eafix(backups): retention deletes the rows of old failed and cancelled backups (#1982)071da216bfix(install): install systemd-timesyncd when it is missing, so the clock is synced (#1983)60c0f3b91fix(crowdsec): the firewall bouncer no longer stays silently down (#1984)cfdb7e1c6fix(backup): a timed-out restic command no longer leaves its lock behind (#1985)ae798731afix(backups): retention deletes the rows of backups whose manifest is gone — GH #1169 (#1986)0542d0314fix(cron): System jobs shows the last run of a disabled job, and a disabled job as not scheduled — GH #1686 (#1987)616e48126fix(update): switching to the stable channel never moves a box backwards (#1988)7feffc412fix(backups): the retention sweep runs after the panel self-update, not alongside it (#1989)623f697e8fix(php): a package that allows PHP exec functions really allows them, and picks disabled functions one by one — GH #1701 (#1990)1d50e7c8afeat(mail): the catch-all is set on the mail domain's Settings tab — GH #1916 (#1991)f3e633ba8chore: land the work stale branches still held — a serve wiring test and three blueprints (#1994)ef64db270feat(files): the File Manager sorts by Name, Size or Modified when you click a header — GH #1184 (#1995)1f45e3c60fix(backup): account-restore --apply=false really leaves the live system alone (#1996)71bcef49cfeat(mail): mail apps find calendars and contacts on their own, so the per-mailbox URL modal is gone — GH #1917 (#1998)012038bb6feat(dns): one zone list — the name opens its records, and DNSSEC lives in the row's ⋯ menu — GH #1918 (#2000)189db834efix(php): a function this PHP-FPM build does not have is no longer shown as Allowed — GH #1701 (#2002)ed392219ffeat(nginx): a Front controller rule sets where requests that match no file go — GH #1999 (#2005)15642a648fix(php): PHP Settings says when AppArmor lets exec functions start only the shell and cat — GH #2001 (#2006)fc5d78938fix(php): say when an allowed exec function can start any program because PHP's AppArmor profile is not enforcing — GH #2001 (#2007)45806c1e6fix(security): phpMyAdmin and Adminer can no longer start programs — their PHP pool disables the exec functions (#2008)89058a2f3chore(apps): new ITFlow installs get v26.10 — GH #1973 (#2009)cda7a8307fix(domains): deleting a domain on a server without mail finishes its teardown — GH #357 (#2010)807638655fix(php): a failed PHP-FPM reload or restart says why, instead of "%!w()" — GH #1820 (#2011)340b42ac8fix(limits): a pool or Python app that cannot start because the account is at its Max tasks limit says so — GH #1820 (#2012)c28a1ce95fix(python-apps): a first build no longer dies at the panel's 120s deadline — pip runs in the background — GH #357 (#2013)fa848b0d0ux(dns): DNS Zones no longer shows the "provisioned automatically" callout — GH #1919 (#2014)56cf38a80fix(dns): DNS records are managed only under DNS > Zones — GH #1920 (#2015)a596617fafix(services): restarting nginx from the panel no longer cuts off its own request — GH #1992 (#2016)c4a9b08f4fix(backups): restoring an account backup into an account made on this server keeps its domains — GH #1993 (#2018)0c1e7196bfix(security): restoring an uploaded backup can't write outside the target account or restore admin-level settings — GH #1993 (#2019)1d55a8bffGH #1993: uploaded account backups stay on the server, listed in Backups with a retention choice (#2020)d4f50d572GH #1993: a restore attaches mail, grants and apps to the account's own domain, mailbox or database of the same name (#2022)0938c607afix(update): re-render the AppSec config after the migrations, not before (#2024)700e1d728fix(backups): a restore reports an app install or cron job that is already there as skipped, not "Error 1062" — GH #1993 (#2027)d5dd5db1dfix(security): restoring an uploaded backup no longer imports the sign-in identity it carries — GH #1993 (#2026)6452c698efix(backups): a domain restored onto another server gets a new SSL certificate instead of staying on plain HTTP — GH #1993 (#2028)d49ccfcd7feat(backups): a restore from an uploaded backup shows its progress by step — GH #1993 (#2021)aad13631afix(ssl): tenants no longer see Renew and Retry buttons that always fail with 403 (#2030)f464bdf5bCreating an account that reuses an existing sign-in identity sets that identity's password (#2031)630a244cbfix(backups): a restore recreates each database user's MariaDB account, grants and password — GH #1993 (#2023)4cb0f6643GH #1993: a restore brings back the domains' custom DNS records (#2025)572cee827fix(security): restores and migrations re-own a tenant's files without following a link swapped in mid-walk (#2033)13904d8bbfix(backups): a restore from an uploaded backup follows no symlink outside a home or an app's data — GH #1993 (#2035)44cf076f3GH #1993: a restore into an existing account keeps its home directory's owner and mode, so its sites stay up (#2034)a1910b390feat(backups): a restore from an uploaded backup adds only what the account is missing, unless "Overwrite existing items with the backup" is checked — GH #1993 (#2036)2d5799d8efix(security): a restored domain's PHP limits reach its web server config only when the PHP settings page would accept them — GH #1993 (#2037)355b5b762fix(security): a PHP pool restored from an uploaded backup keeps to the limits of the PHP pool page and the account's package — GH #1993 (#2039)04bc4f22efix(security): an uploaded backup's database users get access only to a database that holds nothing but the backup's data — GH #1993 (#2040)bca3e4dccfeat(backups): with Overwrite on, a restore from an uploaded backup gives the account's existing mailboxes and database users the backup's settings — GH #1993 (#2042)ef762e730fix(security): a domain restored from an uploaded backup takes a PHP limit only when the account's package lets a tenant set it — GH #1993 (#2043)b18cc13deGH #1993: with Overwrite, a restore updates the account's own PHP pools (#2044)90058cb48fix(installer): a failed download is tried once more over IPv4 — GH #2041 (#2045)7201968fbGH #1993: with Overwrite, a restore updates the account's own domains (#2046)c09134876fix(mail): a mail domain's Forwarders and Shared Folders tabs list that domain only — GH #1997 (#2047)ee9ae6e19GH #1993: a restore recreates each PostgreSQL database user's role and grants (#2048)2967fe00cGH #1993: a backup job restored into a recreated account rebuilds its panel rows (#2049)fc6b75727GH #1993: a restore from an uploaded backup checks the backup against this server first (#2050)7ddb95a19GH #1993: restored PostgreSQL objects belong to the account's database user, not to postgres (#2051)0de6deb92test: the pdnsutil and certbot test stubs reuse one directory per user (#2052)86dc6b7c6GH #1993: a restore from an uploaded backup brings FTP passwords back into an account it created (#2053)287eb77b6GH #1993: a restore from an uploaded backup brings SSH keys back only into an account it created (#2054)101abcfdcfix(ftp): an account restored under the same username gets its FTP subaccounts on the next pass (#2055)5eb4bd0b8GH #1993: an account restore brings back each domain's nginx rules, redirects and web settings (#2057)11748d69aGH #1993: an account restore can bring the backup's SSL certificates back (#2060)3446c131dchore(docker-apps): n8n 2.42.2, zitadel 4.19.4, and fresh openemr and peertube digests (#2061)f4a82c47bGH #1956: Docker app Update never crosses a major the app can't take in place (Gitea 28, Nextcloud 35, Odoo 20) (#2062)925d799beGH #1993: a restore brings back a domain's PHP settings, mail settings and web domain aliases (#2063)069f565f5fix(mta-sts): deleting a domain removes its MTA-STS vhost, so nginx -t keeps passing (#2064)b3f3b9ad7fix(security): a box without CrowdSec no longer gets an agent call and a warning on every admin request (#2065)05a53bea4GH #2001: a failed AppArmor mode switch says why, and apparmor-utils gets installed (#2066)25c662737GH #2003: a tenant can flush its own Redis keys (panel-run, scoped to its prefix) (#2067)2b340336bjabali-cache 1.2.0: flushes bump a generation counter; jabali update syncs the bundled plugin (#2068)f7b043912WP cache: the panel cleans up old cache generations; disabling or deleting a site removes its Redis user (#2069)ca85d4cb1WP cache: a site's Redis user no longer gets SCAN (least privilege) (#2070)83cac19deGH #2001: jabali-sendmail gets its own AppArmor profile file; an update keeps each profile's mode (#2071)0b12ddea7GH #2056: the Modules card shows why a module install failed, and Mail waits for DNS (#2074)3e18489b9GH #2056: website mail can go out through a smarthost (#2075)d094b7726GH #2004: the update hands objects earlier restores left to postgres to the database's user (#2076)b69ff5f3fdocs: a mailbox's password is changed in the panel, not in webmail (GH #2072) (#2080)3eb1dbe8fMail: app passwords and API keys follow the panel's password change, disable and suspend (#2081)4939ccd7cMail: the spam filter thresholds are set in the panel, and an update keeps them (GH #2017) (#2083)1ddf4c5a9Mail: a mailbox can trust senders, so their mail stays out of Junk (GH #2017) (#2084)1f7c8be9fAgent tests no longer depend on the free disk space of the machine (#2085)eb9fb043cDisk usage matches df: blocks reserved for root are not counted as used (GH #2029) (#2086)ba855d772UserPHPPerformanceCard test: no toast can render after the test environment is gone (#2087)ab6619fabGH #2032: a tenant can use their own Cloudflare token for DNS-01 (#2088)44b690612GH #2032: users save their own Cloudflare token on the SSL page (#2090)f63af486cGH #1249: admin Dashboard takes the community-mix layout (Option 7) (#2092)632823b1aGH #2082: mail. gets its Let's Encrypt certificate when the site and DNS are elsewhere (#2094)3462ba9fbGH #2082: mail. keeps answering Let's Encrypt with webmail off (#2095)731e9a9d0GH #2082: mail apps keep autoconfig, calendars and contacts with webmail off (#2096)98ee194deGH #2093: jabali says it must run as root, and names each cron job's account (#2097)1bfd30b45GH #2093 follow-up: deleting or disabling a cron job stops its timer (#2098)f8dddcbb4GH #1993: a restore brings back every PHP pool of the account, and an account with no email (#2099)d38e9d45cDeleting an account no longer fails when its PHP pool is started again mid-delete (#2100)48b541c53GH #2101: the Modules card says when it couldn't read the settings (#2102)1bcd29be7docs: OPcache and JIT are set on the account's OPcache & JIT tab (GH #2091) (#2103)d5aca63d6GH #2058: Reset password also sets the SSH/SFTP password and the stored hash (#2104)bb315e035GH #2077: a destination test answers instead of the connection closing (#2105)a6aadc5fcGH #2079: AIDE rebuild works, checks and rebuilds run in the background, and big reports aren't read as clean (#2107)ca1c2c23eGH #2059: the Redis socket works from the SSH shell and cron jobs (#2108)d85d79c03GH #2056, #2101: turning DNS on no longer runsjabali updateand breaks PowerDNS (#2109)bd735ff96Rotated install logs are deleted after 8 weeks (#2110)2d628745cGH #2089: backup downloads are named for the account and time, and the list names the account and destination (#2111)8bf71c268GH #1993: a restore from an uploaded backup converts an admin's nginx directives to rules (#2112)4ac415c4fGH #2101: turning DNS on works when an earlier update masked PowerDNS (#2113)ee7f8fbf8GH #2077: a failed connection test keeps its reason behind Cloudflare (#2114)c382c464fErrors that say why keep their reason behind Cloudflare (GH #2077 follow-up) (#2115)3d0ef7efaAn agent failure keeps its message behind Cloudflare (GH #2077 follow-up) (#2116)829eb326bGH #2077: an SFTP-only account can be a backup destination (#2117)6cf080a33Backup key repair keeps a repository path one argument on the backup host (#2118)4f5ed1c51GH #2101: the Modules card follows an install to its end (#2119)38b3b5a41GH #2078: acknowledge an AppArmor profile kept in complain mode (#2121)a6f8a6833CLI: a declined confirmation fails instead of exiting 0 (#2123)f05b25d81GH #2122: Run now leaves a long job running instead of killing it (#2124)5fc0c9853Root cron jobs run, and Run now, the log and Last run reach them (#2125)20825883dDiscussion #1032: Nextcloud one-click PHP app (#2127)addd6fa7fOne-click installers: pass credentials on stdin (#2128)1e251239bAppArmor: tenant PHP gets no system D-Bus (#2129)2013ea77aPython apps: no system D-Bus (#2130)df5f979abOne-click installs refuse admin credentials the app would reject (#2132)cf569dd9apanel-ui tests: toasts unmount with the test; DNS-template wait (#2133)953a16886App snippets pass PHP to the domain's pool, not the default one (#2134)596efc187Deleting a PHP pool removes that pool on the host, not the default one (#2135)9ad8cf8ddServer Settings → Nginx reaches nginx on every panel start, not only on a save (#2136)8c40f7cf5"Show nginx version: off" reaches nginx when nginx.conf has it commented out (#2137)d31440e09A Moodle install's course files are the account's alone (#2138)3974bef45Existing Moodle installs: the web server's group loses its way into the course files (#2139)bb322d97ajabali appsec exclusion listsays which rows an app install manages (#2140)cb2bed281GH #2126: the panel hostname gets no per-domain certificate (#2141)3e0b0cc74GH #2131: secondary DNS servers (AXFR + NOTIFY), and NOTIFY that is actually sent (#2142)f9c37f252GH #2120: a tenant cron job's output shows on a volatile journal (#2143)aec341cb9Fix logo display for light and dark modes (#2106)93ffecf28GH #2120: a tenant cron job's last line shows when it has no newline (#2144)5b30d15c2Login: a session with no panel account offers to sign out (#2145)34a787f20Opt-in "Ask Jabali" AI support chat for the admin and client panels (#2146)c2bc8d4daUpdates page: cards stack in two columns, no hole under the shorter card (#2147)91a471878Support chat: load the one hosted Ask Jabali script tag (#2148)cfe03cbdeWP cache: stage the bundled plugin by file descriptor, inside the account's home (#2149)1b51e0088jabali settings set: support_chat_admin and support_chat_clients (#2150)3bce4e8dfdocs: fix four claims that contradict the code (#2151)3831057c2Docker-app domains get their Let's Encrypt certificate from the shared ACME root (#2153)e2e440445A docker-app domain's vhost and certificate go with its domain row (#2154)ba71ca39eRemove a Docker app vhost left without its domain row (#2155)3e90c4b22Docker apps: never give out a host port that is already in use (#2157)063f8469aDocker apps: status and domain stay right after a CLI start/stop or an edit (#2158)3cdfc3008Python Apps: add sic (GH #2156) (#2160)a7f151d07Docker apps: a refused domain edit keeps the app's domain; the CLI checks the name (GH #2158) (#2161)a1533c313Docker apps: a removed Docker app domain takes its mail with it (#2162)d79a84ac0Docker apps: a deleted app's recreated containers leave no anonymous volumes (#2163)df82ed080API tokens follow act-as; Redis access refuses admin accounts (GH #2159) (#2167)b37c15f86One panel clock: server timezone and admin date format for every time shown (GH #2164) (#2168)45bb8674cSign-in lands on the dashboard again, not a blank shell (#2169)7ade464ebTenants can list and delete their own Redis keys (GH #2165) (#2170)22b04e8cbPanel SSL: the public DNS check no longer reads /etc/hosts (GH #2166) (#2171)2956895bbPanel hostname change: /etc/hosts, config.toml and all three doors (#2172)1084a2fe7GH #2165: Redis keys per call is a hosting package setting (#2174)23cc21879GH #2166: with Let's Encrypt off, Panel SSL regenerates the self-signed cert (#2175)ac3aa612fGH #2166: Panel SSL tab in SSL Manager (#2176)63cbf323aGH #2166: the mail certificate follows the Let's Encrypt toggle (#2177)7094b76a6AppArmor flip-mature: the soak gate reads the audit log and counts complain-mode ALLOWED (#2178)c9904c151GH #2166: no mail certificate, and no Stalwart start, without the mail module (#2181)9bf0c9c65Installer: Docker, Docker apps and PostgreSQL install when chosen; mail needs DNS (#2183)3281958a4Fresh install: the panel's mail repair waits for the installer (#2185)3f30d18b1Fresh install: start the cache-doctor timer after the panel's first boot (#2186)510d752e8GH #2166: with Let's Encrypt off, Panel SSL shows the certificate in use (#2187)e860de823Docs: install.sh --uninstall exists; say what it removes and what it keeps (#2188)cf535c3ceNginx: switch to allow proxy_pass to local / private addresses (#2189)feec1052eDatabase users: one engine account, one panel row, in creates, imports and restores (#2201)dcb988815HestiaCP import: a PostgreSQL dump is not restored into MariaDB (#2202)770585630Bandwidth suspension leaves manual disables alone; docs for bandwidth limits and the CrowdSec blocklist (#2191)80c41429fDomain statistics: daily traffic and visitors by country (#2192)38e590dd7Bot blocking: per-domain "Block AI crawlers", a server-wide blocked user-agent list, admin rate limits (#2193)bbb70badaUsernames with "-": the account can be deleted, and has database users and phpMyAdmin/Adminer (#2197)0b5d00f3aDocker apps: baseline hardening for admin installs; icc off on the default bridge (#2195)ed11af263CrowdSec: optional FireHOL blocklists and the admin's own lists on top of the community list (#2194)c54ada336Docker apps: a generated password never starts with "-" (#2196)81c63fe5dDocker apps: 16 catalog apps that could never start now install healthy (#2199)e9e51a4a7Rocket.Chat: MongoDB 8.0, with a one-time copy of an older install's 6.0 database (#2203)9764b7f04Kratos: its MariaDB session runs in UTC (#2204)016396201Docker apps: a catalog entry can be retired; Bigcapital is (#2205)50a41cb09Extra blocklists: whole networks in the agent's own nftables table, plus IPsum level 3 and Spamhaus DROP for IPv6 (#2206)a121fcddcCI: secret scan of each PR's commits (gitleaks) (#2207)438d1974bCI: fail a PR that adds a vulnerable dependency (OSV-Scanner) (#2208)b103f56a6CI: static analysis with gosec and Semgrep, advisory (#2209)a706a649ePHP security releases reach the box, and FPM then runs the patched PHP (#2210)6709a5426AppArmor: every profile includes its /etc/apparmor.d/local file (#2211)dc495aa84nginx: refuse a Host header that names another host than the request line (#2213)7acf9bc97AppSec exclusions can name a CrowdSec rule (crowdsecurity/vpatch-…) (#2214)ad510d89fWAF exclusions by path never follow a ".." segment out of their prefix (#2215)9750ada24Vendor security updates install by themselves, and exposed services run them (#2216)6324fdad2Hotfix releases: stable servers get a fix as a prebuilt release (#2217)17aceeb5eSecurity advisories reach every server within the hour (#2218)6760caebeMerge stable 51fd7fc into main's history (#2219)1367a2c9aSecurity advisories apply themselves, even with self-update off (#2220)1242b55d6PHP errors go to a log file, not to nginx: no 502 on noisy pages (#2222)46f73d214Logs page: PHP Errors, a live view of a domain's PHP error log (#2223)ddb038f8bEgress: an app's loopback port opens only for the account that owns it (#2225)05b8a50d2Egress: only a Python app's own process answers on its port (#2226)252d6fc55ADR-0175: Node.js apps on the Application Manager (accepted) (#2227)5a97e4851Agent: an app command changes into its directory as the account (#2228)df2b574c1Agent: a Python app's build runs in the owner's slice (#2229)e87d8f994Docs: a Python app's build runs in the account's slice (#2230)e2620e5a8Python apps: the env file is the same on every apply, so an app with several variables doesn't restart every minute (#2231)a0132ed6fSSL: a domain waiting for proof of ownership says so, instead of offering a retry that can't help (#2233)35d7d468dUpdates: install only releases signed with the release key (ADR-0162) (#2234)1305de327Updates: Automatic Updates saves each switch when you change it (GH #2221) (#2235)a4a91a69dEgress: learning mode counts each new connection and lists it as allowed (GH #2224) (#2236)ae219af25Repair Center: Delete orphans deletes them and lists any site left (GH #2237) (#2239)faa070d4bUpdates: the development channel streams main without the release signature (GH #2240) (#2241)113801c60View as: the sidebar and the File Manager selection bar stay below the banner (GH #2243) (#2247)21b8d2661API docs: pick a section from a list, search every endpoint, and jump works in the admin panel (GH #2244) (#2249)34e4923d5Alerts: explanations fold to their title and stay as you left them (GH #2242) (#2248)2def5d2ceAlerts: the rest of the panel's explanations fold too (GH #2242) (#2250)b3343c452Alerts: an arrow at the end of the title folds and opens them (GH #2242) (#2252)672330205API docs: the Personal API Tokens page is one card laid out like Notifications > Events (GH #2244) (#2253)39a001441Backups: Cancel stops the backup, and a backup that failed stops showing as running (GH #2245) (#2254)62505cab2Backups: an SFTP destination that is down fails in 30s, stall bounds follow the agent's limits, clearer 401 for the wrong token (GH #2245) (#2255)dba7be0b9Backups: an SFTP destination stored as a bare URL gets the ssh timeouts too (GH #2245) (#2256)b783b3c26Backups: an account's own schedule opens in Schedules with its type and interval, and saving it keeps them (GH #2246) (#2257)b7a309301Backups: admins add an account's own schedule, admin schedules run hourly (GH #2246) (#2258)f763c95a4API tokens: pin admin backups out of the backups scope (GH #2245) (#2259)af72ba1a5Backups: every account schedule in the list says what it backs up, Full account too (GH #2246) (#2260)dc62527cbBackups: Cancel answers once the backup has stopped, tenants can cancel their own (GH #2245) (#2263)cda44c76aPages: Logs, Cron Jobs, Databases and Migrations are laid out like Security and Backups (GH #2251) (#2264)ff571a3f2Cache: the hourly check and the cache cleanup idle on a server with no cached WordPress site (GH #2261) (#2265)11c46a1b1Pages: PHP Settings keeps its tabs in one card; Disk Usage, Python Apps, Mail, Notifications and Cache get page headings (GH #2251) (#2268)f8d64391fRepair Center: Auto-Repair fixes docroot permissions, and a row it leaves says why (GH #2266) (#2269)5a24ed6cbPHP Defense: disabling a rule sticks, Recent incidents pages and counts right, shows the PHP version, and can be cleared (GH #2262) (#2270)7bdc3198eFirewall: a disabled firewall shows as disabled, so it can be enabled again from the page (GH #2271) (#2272)dd17d4f0aMail: a Can send as grant is kept only once the mail server takes it (GH #2267) (#2274)b48a6a7a3Free hostname: a claim retried from the same server gets its label back (#2275)79e96322eFree hostname: claim over IPv4, keep a claim on Back, check in once set up (#2278)72e62eaf5Mail: the send-as list reaches the mail server after any mailbox change (GH #2267) (#2279)eab3178c9PHP Defense: incidents from websites show the visitor's address, not 0.0.0.0 (GH #2262) (#2281)8a1360b6cFree hostname: preview URLs get a real certificate (#2280)51e842968SSL: a failed certbot run is reported as failed, not as the old certificate (#2282)6ffa1186aDrupal installer: Composer and drush run on the domain's PHP (#2283)17b2320fdComposer runs: users run Composer for a domain from the panel API (GH #2276) (#2284)7d06cd82cComposer runs: a Composer tab on each domain, the Composer package switch, and the ssh scope for tokens (GH #2276) (#2285)9bab34d72CrowdSec: count SSH login failures only from the SSH server itself (#2287)e4d13410eSSH sandbox: an admin can let PHP Defense blocks from shell and cron PHP reach Incidents (ADR-0177) (#2286)eb1894cdfGit deploy: connect a domain to a Git repository and list its branches through the API (GH #2277) (#2291)64e345dd1Outbound address checks refuse more non-public ranges (#2292)d6cc3c95fMigrations: the source host check refuses the same ranges as the panel's other outbound checks (#2293)e88d40058Git deploy: deploy a domain's branch into releases, with deploy commands and rollback (GH #2277) (#2294)aba73bf56Composer runs: a domain can name its project folder, shared by several domains (GH #2276) (#2295)f6f3d6f35Git deploy: a push to the domain's branch deploys it, through a signed webhook (GH #2277) (#2296)8e2ce2fbdPython apps: a deleted app's unit no longer keeps running on its port (GH #2289) (#2297)87104e89dPython apps: deleting a domain deletes its Python apps (GH #2289) (#2298)a1e1e7d0cBackups: the schedule drawer tests wait for the drawer's values (#2299)6ac1eba8eGit deploy: a Git tab on the domain's page (GH #2277) (#2301)b111cbfffDomains: changing a domain's owner deletes its Python apps (GH #2289) (#2302)e1f1f944dDomains: changing a domain's owner unlinks another account's Docker app (GH #2289) (#2304)4892cd960Backups: an account's schedules keep their times of day, like cron (GH #2300) (#2305)27d4c910bTranslations: Russian, Romanian and Portuguese strings from Weblate (#2306)29b395a05Cron: an account whose plan includes SSH can schedule its own shell scripts (GH #2290) (#2307)167d61242Backups: restore any domain's files and see every domain's DNS (GH #2303) (#2309)e9f41eef3Docs: no internal codes in the published pages; password-reset-confirm slug (#2308)420d20137Translations: Russian covers every string in the panel (#2310)e3b3fdac3Git deploy: a web directory the repository doesn't have is created (GH #2277) (#2312)e48333b0fTranslations: Russian strings pass Weblate's checks (#2313)24802add3Cron: the command help is a section you open, grouped by command type (GH #2290) (#2311)be4279f2ci18n: Russian, Ukrainian and Arabic counts use their own plural forms (#2314)1a90a037ai18n: Russian "from N IPs" in the AppSec card inflects with the count (#2316)98b35e5ecDocs: Directory Privacy pages use a dash where it was lost (#2315)d41b882abTests: the restore drawer test clicks a domain until antd takes it (#2317)5b66762cfPHP: session upload progress is off in every PHP pool (CVE-2026-115560) (#2321)ea4d121beDocs: Ubuntu 24.04 is a supported install target (#2322)335373a13Tests: the server_names_hash update test reads each function before matching (#2323)2e1e40822Timezones: the lists use current zone names, so India, Ukraine and 16 more can be saved (GH #2320) (#2324)ac170e9d4Mail: an update keeps a newer Stalwart instead of downgrading it (GH #2318) (#2325)be10d3064Backups: deleting or auto-removing an account's backup removes it from its own destination (#2326)bf0694a6fBackups: a schedule at the plan's limit removes its own oldest backup instead of stopping (GH #2300) (#2327)13846c712README: link the documentation, and list every CLI command (#2330)f43cb4a14AppSec: rule exclusions by name match paths the way rule-id exclusions do (#2332)5f2a7c48aFree hostname: the verification code mail carries a Date and a Message-ID (GH #2319) (#2333)1408badbcFree hostname: the verification code mail says who asked for it (GH #2319) (#2334)46076c5bcFree hostname: the verification code mail names no domain in its text (GH #2319) (#2335)565b1d1ddChangelog: one entry per move of stable, from the October cut on (#2336)8e92d7cb7Free hostname: the retired 6to4 relay block gets no hostname (#2337)ceb56962edeps: monthly dependency bumps, November 2026 (GH #2338) (#2340)58d5ed806deps: panel-ui on React 19 (GH #2338) (#2341)52b250eeaRoot terminal: connects on hosts in AppArmor enforce mode, and shows an error when it can't (#2343)6334cfc8adeps: Go 1.26.10 (GH #2338) (#2344)fd601a7b2chore(docker-apps): monthly catalog version bumps, November 2026 (#2345)db6d0f4dadeps: Bulwark webmail 1.19.1 (GH #2338) (#2346)
#2210 and #2211 are listed because #2219 joined the hotfix line to main's history. They shipped to stable in the Oct 21 hotfix, not in this cut.
Stable releases are signed from this cut on. Servers on 51fd7fc25 take this one without checking a signature, because their build predates the key. After it, every move of stable needs a signature.
What servers do on the first update with it:
- Migration 000332 turns security auto-apply on, on every server. Hourly signed advisory checks start, and servers apply listed fixes and run
jabali updateon their own. - Migration 000335 deletes duplicate PHP Defense incidents and keeps the first of each. A down migration does not bring them back.
- Migrations 000311, 000317, 000318 and 000340 fill new columns on existing rows: domains and aliases marked ownership
verified, packageswebsite_sends_email = 1, mailboxespassword_changed_at, composer runswork_dir. - Vendor security updates cover more sources, and nginx, pdns, pdns-recursor and webmail restart once wherever they still run a replaced library.
- PHP Defense is rebuilt once and every
jabali-fpm@reloads.session.upload_progressgoes off in every PHP pool. - Webmail downloads Bulwark 1.19.1 (60 MB), swaps it in and restarts once.
- AIDE tamper alerts may fire after the update.
- Servers whose wildcard renewal was failing without saying so start logging "acme shared certs: issue failed".
- Extra blocklists move to the agent's own nftables table. Old CrowdSec decisions from those lists expire within 48 hours.
- Rocket.Chat installs need an admin to press Update once.
The same entry is in CHANGELOG.md.