РазделДорожная карта
Дорожная карта, матрица тестирования, CI
Этап 0 — каркас (выполнен 2026-09-05, проверен на Ubuntu 24.04)
- Репозиторий, сборка Go (
make build),nfpm.yaml, units, sysusers/tmpfiles,install.sh,mp setup. - OS Profile для Debian/Ubuntu и EL9/EL10 (+ generic для dev-машин); агент с
ApplyConfigSet,EnsureGroup,EnsureUnixUser,EnsureDirs,Service,Pkg; peer-cred на обоих сокетах. - SQLite-схема и миграции; auth (argon2id, сессии, Bearer-токены, CSRF-проверка); job-runner с локами; SSE.
- Установка nginx с nginx.org (
mp stack install nginx), шаблоны nginx/Apache/php-fpm с golden-тестами, CLI и TUI. - ACME (lego, HTTP-01 по webroot):
mp ssl issue/list/renew/rm, таблицаcertificates, автопродление, hot-swap сертификата панели (mp web tls). Проверено выпуском боевого сертификата Let's Encrypt на тестовом хосте. - Сборка SvelteKit-приложения (нужен Node; пока заглушка
web/build/index.html). - Репозиторий deb/rpm и подпись пакетов.
- Установка PHP (Sury/Remi) и Percona/MySQL 8.4 с
auth_socket— переносится в начало этапа 1. - VM-матрица: тестовая площадка на Proxmox с девятью машинами по всей матрице ОС,
make testbed-matrix(2026-09-09, см. docs/08-testbed.md). В CI пока не подключена — нужен self-hosted раннер с доступом к хосту.
Этап 1 — MVP (выполнен 2026-09-05, проверен на Ubuntu 24.04)
- PHP 5.6–8.5 через Sury/Remi (
mp php), несколько версий параллельно. - Сайты в режимах A (nginx → php-fpm), B (nginx → Apache → php-fpm) и proxy; per-site php_value; ACL; страница-заглушка; авто-сертификат.
- Apache 2.4 как компонент (Debian/Ubuntu). EL — не проверено.
- БД: Percona/MySQL 8.4 с
auth_socket, базы и пользователи, legacy-аутентификация для PHP < 7.4. phpMyAdmin — не сделан. - Cron, firewall (nftables) + fail2ban, бэкапы restic, метрики, логи,
mp doctor, DNS-01, TUI-паритет, Web UI (SvelteKit), ru. - Полная тест-матрица в CI на 9 ОС (нужен self-hosted раннер с VM).
Этап 2 — v1.0 (частично, 2026-09-05)
- Файловый менеджер через helper (
mp files, API/files), SFTP-chroot, unix-пароли. - Webhooks (HMAC), TOTP 2FA, API-токены, история конфигов (
confhistory), переопределение шаблонов,mp doctor. - Собственные сборки PHP, терминал в браузере, квоты, self-update, WHMCS-модуль, WebAuthn, SELinux confined-домен.
Автоматическое тестирование (2026-09-06)
- Фейковый агент
internal/agent/agenttest: unix-сокет, типизированные ответы, запись всех вызовов — покрывает job-и панели (сайты, пользователи, пресеты) без root и systemd. - Тесты пайплайна сайта: рендер nginx/пула, пресеты CMS и их PHP-значения, приоритет
php_iniнад пресетом, allow-list, отказы валидации, suspend, удаление, свои nginx-директивы с откатом, каскадное удаление пользователя. Покрытиеinternal/api9.5% → 21.2%, общее 23.3%. - Таймауты готовности вынесены в
Server.SetReadinessWaits: тесты не ждут nginx и сокет php-fpm (набор идёт ~2 с). -
make check(fmt + vet + lint + test),make test-race,make cover,make web-check,make help. -
golangci-lintv2.13.2 с.golangci.yml; намеренно игнорируемые ошибки помечены//nolint:errcheckс причиной, реальные находки (S1017, S1009, ineffassign, unconvert) исправлены. -
scripts/check-templates.sh: golden-конфиги проверяются настоящимиnginx -tиapachectl -t(в CI ставится nginx-core и apache2). -
e2e/(тегe2e): сценарий против живой панели — аккаунт, сайт с пресетом, PHP отвечает, запрет PHP в uploads работает, база, удаление; чистит за собой. Токен или логин/пароль через переменные окружения. - Токены по локальному сокету:
POST /tokensпринимаетuser, root без аккаунта получает токен единственного администратора (при нескольких — ошибка со списком), администратор видит и отзывает токены любого аккаунта;make e2e HOST=…берёт токен по ssh и отзывает его после прогона. - CI: параллельные джобы go / lint / templates / web, кэш модулей и pnpm,
-raceс покрытием в summary, сборка amd64 + arm64, e2e поworkflow_dispatch.
Управление расширениями PHP (2026-09-06)
-
GET|POST /php/versions/{v}/extensions,mp php ext list|enable|disable, переключатели в карточке ветки на странице PHP. Состояние читается изconf.dветки (phpquery отвечает из реестра Debian и продолжает показывать модуль послеphpdismod), список доступных — изmods-available. После переключения php-fpm ветки перезапускается. - Только на ветку целиком: php-fpm — один мастер на версию, пулы наследуют его расширения, отключить расширение для отдельного сайта нельзя. В интерфейсе это сказано прямо.
- Расширения, без которых типовой сайт не работает, помечены и требуют подтверждения; запретов нет — администратор и так root.
- Агенту добавлена операция
dir/listс белым списком каталогов (/etc/php/*/mods-available,*/conf.d,/etc/opt/remi/php*/php.d): без неё панель видит только загруженные модули, но не выключенные.
PHP 8.5 (2026-09-06)
- Установка 8.5 падала: панель просила
php8.5-opcache, которого в Sury нет — начиная с 8.5 opcache собран в ядро (php8.5 -mпоказывает Zend OPcache,opcache.enable => On). Отдельный пакет существует только с 7.0 по 8.4; правило и тест на обе границы — вinternal/osprofile/php.go.
Адаптация Web UI под телефоны и планшеты (2026-09-06)
- Каркас: боковое меню шириной 240px ниже
lgпревращается в выезжающую панель с затемнением и шапкой с кнопкой; выше — прежняя колонка. Переход по пункту закрывает меню, цели нажатия увеличены. - Таблицы: приём один на все девять страниц, потому что все используют класс
.tbl. Ниже 40rem строка становится карточкой, заголовки колонок уходят в подписи слева (data-labelна ячейках), таблица перестаёт быть таблицей (display: block) — иначе она считает ширину по содержимому и длинные значения уезжают за край. Ячейки без подписи — кнопки действий — держатся справа. - Мелочи: тост во всю ширину на телефоне, перенос длинного docroot, панель файлового менеджера в две строки, отступы страницы меньше на узком экране.
- Проверено на 375×812 и 768×1024 по всем страницам: горизонтального выхода за экран нет нигде, включая редактор Monaco и карточку сайта с вкладками.
Файловый менеджер в Web UI (2026-09-06)
-
FileManager.svelte: обзор домашнего каталога аккаунта, хлебные крошки, переход к каталогу сайта, создание папки и файла, загрузка перетаскиванием и выбором, скачивание, переименование, права, распаковка архивов, множественное выделение и удаление — всё поверх существующего/files-API, то есть от имени владельца через helper. - Редактор текстовых файлов: нумерация строк, Ctrl+S, Tab, защита от ухода с несохранёнными правками. Двоичные файлы (по расширению или нулевому байту) и файлы больше 1 МБ открываются только на скачивание. Без подсветки синтаксиса — она означала бы новую npm-зависимость.
- Страница
/files(с выбором аккаунта для администратора) и вкладка «Файлы» в карточке сайта, открывающаяся в его docroot. - Редактор — Monaco, то же ядро, что в VS Code (
web/static/monaco, MIT): подсветка php/html/css/js/ts/json/xml/ini/shell/sql/yaml/markdown/python/dockerfile, поиск и замена, мультикурсор, свёртка, палитра команд, тема следует за темой панели, высота — по содержимому. Сборка урезана с 24 МБ до 4,7: без языковых служб (IntelliSense-воркеры json/css/html/ts), переводов интерфейса и лишних режимов; бинарник вырос с 26 до 31 МБ. Грузится лениво, при сбое загрузки остаётся простое поле. Вендорится в репозиторий, а не тянется из npm или CDN: панель должна ставиться на сервер без интернета, а node-инструментов в репозитории нет. В CSP добавленfont-src data:— шрифт иконок вшит в CSS Monaco. - API: операция
touch(fsop touchсO_EXCL) — пустое тело PUT huma не принимает, а создание файла не должно затирать существующий;forceопустошает файл. Тестыinternal/cli/fsop_test.goна touch и на то, что «..» упирается в домашний каталог.
Обновление панели из релизов (2026-09-06)
-
internal/updater: релизы GitHub (или GitHub Enterprise черезapi), выбор по версии, а не по дате публикации; канал stable/beta; имена артефактов фиксированы (monopanel_<v>_<arch>.deb,monopanel-<v>.<arch>.rpm,monopanel-linux-<arch>,SHA256SUMS,SHA256SUMS.sig). - Подпись релиза ed25519:
scripts/release keygen|sign|verify, приватный ключ — секрет репозитория, публичный —update.public_keyвconfig.yaml(root-only, менять из панели нельзя). При заданном ключе неподписанный релиз не устанавливается; агент проверяет подпись повторно, а не доверяет хешу от API-процесса. - Установка вне панели: агент
POST /v1/panel/installзапускает transient-юнитmonopanel-update.service(StartTransientUnit), который переживает перезапуск API и агента;mp update-runставит пакет, перезапускает юниты, ждёт/healthс новой версией и откатывает прежний бинарник, если она не отвечает. Итог пишется в<data>/updates/state.jsonи попадает в audit после перезапуска. - API
GET|PUT /system/update,POST /system/update/check|apply(только администратор), задачаpanel.update, ежедневная проверка по расписанию иauto_apply; токен репозитория шифруется секрет-боксом. -
mp update,mp update check|apply|settings|trust; карточка «Обновление панели» в настройках Web UI ждёт перезапуск и перезагружает страницу; проверкаupdateвmp doctor. - Установка последней версии сама считается проверкой (2026-09-24): задача
panel.updateзапоминает найденный релиз, и послеmp update applyстатус больше не называет последним тот, что видела прошлая проверка. - Пакеты:
make packages(deb+rpm × amd64+arm64 + бинарники + SHA256SUMS),make release VERSION=…, workflowrelease.ymlпо тегуv*;preremoveбольше не выключает панель при обновлении,postinstallперезапускает юниты только на апгрейде.
Добавлено при миграции сайтов с FASTPANEL (2026-09-05)
- IP-allow-list на сайт (
sites.allow_from,mp site add|set --allow), ACME-проверка остаётся доступной. - Импорт готовых сертификатов (
POST /certificates/import,mp ssl import); Let's Encrypt-сертификаты продолжают продлеваться через ACME. - Доверенные прокси для
real_ip(mp stack real-ip --cloudflare,--from), файлhttp.d/10-real-ip.conf. - App-сервисы пользователей (
apps,mp app): systemd-юнит от имени пользователя,ProtectSystem=full,PrivateTmp. - HSTS в server-блоке и в static-локации при принудительном HTTPS.
- Web UI: allow-list в настройках сайта, импорт сертификатов, app-сервисы и cron в карточке пользователя, real-ip в настройках.
- Удаление пользователя (
DELETE /users/{login}?purge=, jobuser.delete,mp user rm): сайты → сертификаты → базы → app-сервисы → crontab → unix-аккаунт (агентuser/remove: убивает процессы uid,userdel [-r]только для home под www_root, uid ≥ 1000). - Редактирование nginx-директив сайта (
sites/<domain>.d/custom.conf,GET|PUT /sites/{domain}/nginx,mp site nginx):nginx -t, откат и текст ошибки в ответе; сгенерированный server-блок показывается read-only. - PHP-параметры сайта:
GET /sites/{domain}/php(эффективные значения + допустимые ключи), редактор переопределений во вкладке PHP; список ключей расширен (opcache.jit, session.cookie_*, max_file_uploads …). - Пресеты CMS (
sites.preset,templates/nginx/presets/*.conf.tmplкак{{ define "preset-…" }}в общем наборе шаблонов,presetIniвops_presets.go): WordPress, Joomla, 1С-Битрикс, OpenCart; выбор в форме создания и в настройках сайта,GET /sites/presets; проверены на nginx реальными запросами (ЧПУ, запреты, /api, urlrewrite, route). - Дизайн Web UI 0.4: токены светлой/тёмной темы (
prefers-color-scheme+data-themeиз localStorage, инициализация до первой отрисовки с хешем в CSP), анимации (переходы страниц, stagger строк, прогресс задач, skeleton), иконки, модальные подтверждения.
Почтовый сервер (2026-09-07)
-
mp mail install: postfix + dovecot + opendkim одной задачей — пакеты, пользовательvmail, конфигурация, сертификат, порты в firewall. Проверено на Ubuntu 24.04: submission с настоящим сертификатом, SASL через dovecot, LMTP-доставка, IMAP/POP3/ManageSieve, подпись DKIM, отклонение подмены отправителя. - Домены, ящики и алиасы (включая catch-all) в базе панели; postfix читает
hash:-карты, dovecot — passwd-файл с{BLF-CRYPT}иuserdb_quota_rule. Выключенный ящик исчезает из обеих карт: почта не принимается, войти нельзя, письма на диске остаются. - DKIM: ключ RSA 2048 генерируется панелью, приватный хранится зашифрованным в базе и файлом у opendkim;
mp mail domain dnsпоказывает MX/SPF/DKIM/DMARC/PTR и сверяет их с публичными резолверами (1.1.1.1, 8.8.8.8). - Сертификат почты — из того же хранилища, что у сайтов; при выпуске и продлении задача
cert.issueсама перезапускает postfix и dovecot. Пока сертификата нет, поднимается самоподписанный, и панель об этом предупреждает. - Занятый 25-й порт (на dev-хосте его держит приёмник mail-tester) не ломает установку: панель узнаёт чужой демон по баннеру, выключает приём снаружи и говорит об этом. После применения конфигурации порты проверяются на самом деле — юнит postfix рапортует «active» и когда мастер не поднялся.
- Вебпочта:
mp mail webmail <домен>ставит Roundcube 1.7.4 (архив с проверкой sha256) обычным сайтом панели — своя база, свой пул php-fpm, свой сертификат,installerудаляется. - Web UI
/mail: статус, порты, домены с DNS-подсказками, ящики, алиасы, установка вебпочты; CLImp mail; тесты на рендер конфигурации, карты, catch-all и уступку 25-го порта. - Вебпочта на порту:
--port 2096публикует Roundcube на имени и сертификате почтового сервера (свой серверный блок nginx вhttp.d, порт в firewall, слушает и на петле) — без отдельной записи в DNS и второго сертификата. - Домен-приёмник (
--lenient): строгие проверки HELO и отправителя перенесены в общий список с получателем, а картаcheck_recipient_accessобрывает его наOK. Так на dev-хосте postfix занял 25-й порт, а mail-tester забирает почту из служебного ящика по IMAP и берёт IP отправителя изReceived— проверено настоящим письмом с внешнего адреса и несуществующим доменом отправителя (отчёт тестера: «IP отправителя 83.97.77.254 (по заголовкам)»). - Страница почты грузилась 4,3 с: восемь портов опрашивались подряд и дважды, а на портах с обёрткой TLS проба ждала баннер, которого не бывает. Опрос разом, один раз на запрос → 0,02 с; Web UI забирает четыре списка параллельно и показывает скелет.
- dovecot 2.4 (Debian 13, Ubuntu 26.04) — другой синтаксис конфигурации; установка отказывается, пока шаблон не написан и не проверен.
- EL 9/10: пакеты есть (opendkim из EPEL), конфигурация не проверялась.
- Антиспам глубже postfix-проверок (rspamd), смена пароля ящика из Roundcube, автонастройка почтовых клиентов (autoconfig/autodiscover).
Перенос между панелями (2026-09-09)
- Прямой перенос MonoPanel → MonoPanel:
mp migrate grantна источнике,mp migrate plan(разбор с конфликтами, ничего не меняет) иmp migrate runна приёмнике. Схема — 07-migration.md. - Источник только читает: состояние, поток файлов (
tar) и поток дампа. Токен с областьюmigrate:user:<логин>пускает только на GET под/migrateи только для своего аккаунта; прочие области остаются пометками, чтобы не сломать выпущенные раньше токены. - Пароли переезжают хешами: argon2id панели, yescrypt из shadow (
chpasswd -e),SHOW CREATE USER ... AS '<хеш>'для MySQL,{BLF-CRYPT}для ящиков. Пользователи переезда не замечают, панель нигде не видит открытый текст. - Потоки идут насквозь через две новые операции агента (
/v1/stream/out,/v1/stream/in) и рекурсивныйchown: домашний каталог нигде не складывается на диск целиком. - Тест на две панели сразу: фикстура-источник и фикстура-приёмник, между ними настоящий HTTP — проверяются область токена, разбор, перенос аккаунта, сайта и cron, хеш пароля и оба потока tar. На живом сервере проверена отдающая половина: поток файлов, состояние с секретами и сертификатом.
- Досинхронизация (
resync) и завершение (finish) с заказом сертификатов после переключения DNS. - Адаптеры для чужих панелей (2026-09-12):
--from bitrixvmи--from fastpanelчитают старый сервер по ssh и отдают тот же бандл; проверены на площадке против bitrix-env 9 и FASTPANEL 1.11 (scripts/testbed/sources.sh). - Области
site:иserver:, пакет-файл, адаптерplain.
Два языка Web UI (2026-09-13)
- Весь Web UI переведён на английский; русский и английский лежат в словаре
web/src/lib/i18n/msgs/*.ts(фрагмент на страницу),t()/tn()берут текущий язык из стейта — переключение перерисовывает интерфейс без перезагрузки. - Язык по умолчанию — из языка браузера: русский для языков стран СНГ (ru, uk, be, kk, ky, uz, tg, tk, hy, az, ka, ro-MD…), английский для всех остальных; тот же список в
app.html, чтобы<html lang>был верным до старта приложения. - Переключатель «Авто / Русский / English» в настройках и на экране входа; выбор — в
localStorage.lang; даты и единицы (when(),bytes()) следуют языку. - Сообщения API, журналы задач и doctor — на английском (2026-09-25); заглушка нового сайта и страница приостановленного показываются на языке браузера посетителя, пресеты и каталог CMS интерфейс переводит сам.
- CLI и TUI пока только на русском; русские сообщения API для русского интерфейса — со словарём на стороне Go и языком у задачи.
Firewall: порядок правил и защита от самоблокировки (2026-09-14)
- Цепочка собирается по полкам: allow с источником → deny → всегда открытые порты и allow без источника. Раньше deny шёл первым, и «deny 8443 + allow 8443 с VPN» закрывал панель для всех, включая VPN.
- Guard: deny без источника на SSH или порт панели принимается только при наличии allow с источником; удаление последнего такого allow, а также deny или ban, накрывающие адрес запроса, отклоняются. Статус показывает закрытые порты и кому они открыты (
restricted, строка вmp firewall status, теги на странице).
Статика: сжатие и кэш (2026-09-15)
- Редактор открывался долго: http.FileServer отдавал вшитую статику без gzip, ETag и Cache-Control, и каждая перезагрузка страницы заново тянула 4,4 МБ Monaco шестью последовательными запросами. Теперь файл сжимается gzip один раз в память (Monaco 4,4 → 1,2 МБ), хешированные чанки (
_app/immutable/*,name-<hash>.js) кэшируются на год как immutable, остальное —no-cacheсо слабым ETag и 304. FileManager подгружает Monaco в idle сразу при открытии страницы файлов, а не по клику.
Документация API без чужого origin (2026-09-21)
- Страница
/api/v1/docsгрузила Stoplight Elements с unpkg.com, а для путей/api/панель не ставит CSP: сторонний скрипт работал на origin панели рядом с сессией администратора. Теперь Elements 9.0.15 вшит в бинарник (internal/api/elements, Apache-2.0), страница и её файлы отдаются самой панелью с CSPdefault-src 'none'; script-src 'self'без inline-скриптов и eval; тест пинит sha384 файлов к релизу npm и отсутствие чужих адресов на странице. - Документация, спецификация OpenAPI (
/openapi*) и JSON-схемы (/schemas/*) закрыты за авторизацией: сессия или API-токен любого аккаунта, токен переезда — 403, аноним — 401 (браузеру по ссылке на/docs— редирект на вход). Без входа остаются только/healthи/auth/login. -
/healthотдаёт версию панели только вошедшему (сессия, токен, локальный сокет); анониму —statusиtime. Экран входа версию больше не показывает.
Глобальные PHP-параметры (2026-09-23)
- У значений php.ini был источник «панель», который менялся только по одному сайту. Теперь слои: панель → глобально → пресет → сайт. Глобальный слой —
GET|PUT /php/settings(админ),mp php ini [set k=v|unset k], карточка «PHP-параметры для всех сайтов» на странице PHP; сохранение пересобирает пулы всех PHP-сайтов (site.applyна каждый). Вкладка PHP сайта показывает источник «глобально» и порядок слоёв.
Ротация логов сайтов (2026-09-24)
- Логи в
/var/www/<логин>/data/logsне ротировал никто: панель не писала конфигурацию logrotate, а конфиги дистрибутива этот путь не покрывают. Теперь/etc/logrotate.d/monopanel-sites— блок на аккаунт сsu <логин>(каталог клиентский, root в нём ничего не делает): раз в неделю или по 100 МБ, восемь копий, сжатие со второй,create 0660 <логин> <логин>. Все логи сайта — аккаунта с правами 0660: панель создаёт их до того, как их откроют nginx, Apache и php-fpm, а созданные ими раньше передаёт аккаунту — новым флагомmodeоперации агентаchown, через открытый файл (O_NOFOLLOW,fchown,fchmod). Иначе logrotate 3.18 на EL9 не справлялся: ротируя, он открывает лог, а сжимая — на запись. Файл переписывается при создании и удалении аккаунта (строка удаляемого уходит доuserdel, чтобы logrotate не встретил несуществующего пользователя) и при старте панели, перед записью проверяетсяlogrotate --debug. - Рабочие процессы nginx не могли переоткрыть логи сайтов после USR1 — ни после этой ротации, ни после ночной ротации самого nginx: в
data/logsне было прохода для группыmonopanel-web, и в журнал nginx каждую ночь падалоemerg … Permission denied, а запись продолжалась в старый файл.data/logsполучила ACLg:monopanel-web:xпри создании сайта иmp site fix, существующие аккаунты — при старте панели. Apache переоткрывает логи graceful-рестартом по USR1 через pid-файл:systemctlиз logrotate на EL упирается в SELinux. - slow-лог php-fpm на EL был пустым: трассировку php-fpm снимает через
ptraceрабочего процесса, а штатная политика молча запрещаетhttpd_tвозможностьsys_ptrace. Панель ставит свой модуль политикиmonopanel(CIL,semodule -i) сallow httpd_t self:capability sys_ptraceиself:process ptrace— вместе с подготовкой хоста под хостинг, а на уже подготовленных хостах при старте, без повторного relabel. - Проверено на Debian 13 (с Apache), Ubuntu 22.04 (logrotate 3.19), Rocky 9 (3.18) и AlmaLinux 10 в enforcing: после ротации nginx, Apache, PHP и php-fpm пишут в новые файлы, вторая ротация сжимает первую от имени аккаунта, в slow-логе на EL есть трассировки,
logrotate.serviceпроходит, отказов SELinux нет.
Valkey на аккаунт (2026-09-24)
-
mp stack install valkeyставит Valkey из дистрибутива (Debian 13, Ubuntu 24.04/26.04, EL9/EL10 AppStream, Debian 12 — из backports, если они подключены), а где его нет — Ubuntu 22.04, Debian 12 без backports — Redis (6.0 и 7.0) с тем же протоколом; общий экземпляр пакета (127.0.0.1:6379 без пароля для всех) останавливается и выключается. Сервер не удалить, пока на нём есть экземпляры. - У аккаунта два отдельных экземпляра:
cache(allkeys-lru,--save "") иsessions(volatile-lru, снимок раз в минуту). Каждый —monopanel-valkey-<login>-<purpose>.serviceот имени пользователя,Type=notify(перезапуск возвращается, когда снимок загружен и сокет принимает),MemoryMaxвдвое больше maxmemory с запасом, конфигурация целиком в аргументах (к/etc/monopanelу аккаунта доступа нет). Слушает только unix-сокет с правами 600 в каталоге 0700 (RuntimeDirectory=), снимки вStateDirectory=;mp valkey add|list|restart|rm,/users/{login}/valkey[/{purpose}], кнопка valkey на странице «Пользователи». Удаление аккаунта уносит его экземпляры, перенос между панелями переносит их настройки без данных. - PHP-сессии сайта в Valkey:
mp site set <домен> --sessions valkey|files, поле «PHP-сессии» в настройках сайта; пул получаетsession.save_handler = redisи путьunix://…/valkey.sockчерез php_admin_value. Нужны экземпляр sessions и расширение redis у ветки PHP сайта; пока сайт держит там сессии, экземпляр и расширение не удалить (409), сайт в режиме proxy сессий не держит. - SELinux (EL): сокеты —
redis_var_run_t, каталоги снимков —redis_var_lib_t, сам/var/lib/monopanel-valkeyостаётсяvar_lib_t: init_t не может добавлять записи в каталогredis_var_lib_t, иStateDirectory=падал с EACCES без единого AVC. Юнит безProtectKernelTunables=,ProtectKernelModules=иRestrictAddressFamilies=: для не-rootUser=они включают NoNewPrivileges, а политика EL9 под ним не пускает переход init_t → redis_t, и сервер оставался в init_t без права писать снимки. Живая проверка на Debian 13, Ubuntu 22.04, AlmaLinux 10 и Rocky 9 (enforcing): другой аккаунт и веб-сервер получают «Permission denied», PHP-сессия через php-fpm переживает перезапуск, AVC нет.
Этап 3 — v1.x
- Режим
proxyдля Node/Python/Docker-приложений. - Почта: postfix + dovecot + opendkim + Roundcube (Debian/Ubuntu).
- Перенос аккаунтов между панелями (MonoPanel → MonoPanel).
- Изолированные пулы с cgroup-лимитами, FTP, DNS (PowerDNS), WAF, reseller-роль, aarch64-сборка (кросс-компиляция готова:
make build-arm64), multi-server.
Матрица ОС
| ОС | Режимы | PHP (выборочно) | СУБД |
|---|---|---|---|
| Debian 12, 13 | A, B | 5.6, 7.4, 8.2, 8.5 | Percona 8.4, MySQL 8.4 |
| Ubuntu 22.04, 24.04, 26.04 | A, B | 7.4, 8.3, 8.5 | Percona 8.4 |
| AlmaLinux, Rocky Linux, Oracle Linux 9, 10 | A, B | 7.4, 8.4, 8.5 (+ 5.6 на EL9) | Percona 8.4, MySQL 8.4 |
Раннер: площадка на Proxmox — одиннадцать VM из cloud-образов с cloud-init и откатом к чистому снимку; запускается с рабочего места, не в CI. Контейнеров недостаточно для SELinux, nftables, квот и systemd-слайсов.
Сценарий make testbed-matrix: установка пакета → mp setup → nginx, PHP, СУБД → e2e (пользователь → сайт с пресетом → база → nginx и PHP отвечают → удаление) → mp doctor без ошибок. Перед релизом make testbed-full добавляет переносы между панелями, CMS на каждой машине и переезд с BitrixVM и FASTPANEL. Планируются: HTTPS через Pebble, бэкап → восстановление → suspend → purge.
Планируется периодический job (еженедельно): доступность пакетов в вендорских репозиториях по матрице и появление новых версий (PHP 8.6/9.0, nginx stable, Percona 8.4.x, релизы ОС).
Риски и как закрыты
| Риск | Митигация |
|---|---|
| Sury/Remi исчезнут или сломают совместимость | Этап 2: собственные сборки и репозиторий; OS Profile позволяет держать оба источника одновременно |
MySQL 9.x удалит mysql_native_password | Остаёмся на 8.4 LTS до 2032; для legacy PHP — только 8.4; переход на 9.x — ручная процедура |
| Новый релиз ОС без пакетов вендоров | Поддержка объявляется только после прохождения матрицы; еженедельная проверка |
| Ручные правки конфигов администратором | Include-каталоги, confhistory, mp doctor показывает дрейф, mp site apply перегенерирует сайт |
| Компрометация Web-слоя | api без привилегий; агент с allow-list; helper с setuid; секреты зашифрованы |
| Рост числа сайтов (сотни) | pm=ondemand, один master на версию, SQLite с WAL держит десятки тысяч сущностей; метрики — ролапы |