ops-panel — это веб-панель для безопасного добавления доменов через GitHub GitOps.
Текущий режим приложения: только GitOps.
Локального режима с прямой записью в domains.csv и запуском скриптов Traefik из панели нет.
- Принимает домен (Unicode/Punycode).
- Делает DNS-проверки (A/AAAA,
wwwдля доменов 2-го уровня, TTL, проверка дубликатов в GitOps CSV). - Создаёт PR в GitHub в
profiles/<profile>/domains.csv. - Показывает в UI статусы:
- проверки PR,
- итог PR,
- деплой (по
deploy.yml), - ссылку на deploy run и PR.
- После успешного деплоя показывает блок
Готовос информацией о выпуске SSL.
- Автообновление статуса PR/деплоя через JSON poll endpoint.
- Интервал опроса:
- ~5 сек пока PR/деплой в процессе,
- ~60 сек после завершения.
- Время отображается в удобном формате:
(GMT+3) 04.03.2026 19:23:17- таймзона берётся из
TZ.
Код в app/ переведен на слойную структуру: Action + Service + DTO.
app/index.php— фронт-контроллер.- Его задачи:
- инициализация сессии и security headers,
- сбор
configиз env, - создание
stateдля UI, - маршрутизация POST/GET действий в
Action, - рендер
views/panel.php.
Action-классы отвечают за сценарии HTTP-запросов:
AuthAction—login/logout.ProfileSelectAction— переключение целевого профиля.GithubPollAction— JSON endpoint?github_pr_poll=1.DomainSubmitAction— основной flow проверки домена и создания PR.
Action не содержит низкоуровневой инфраструктуры, а вызывает сервисы.
Сервисы инкапсулируют бизнес-логику:
AuthService- remember-me,
- rate-limit,
- авторизация/разлогин.
DnsValidationService- валидация домена,
- DNS/WHOIS проверки,
- формирование итогового результата проверки.
GitHubPrService- создание PR,
- refresh snapshot,
- поиск последнего PR по профилю,
- преобразование данных для poll/UI.
DTO фиксируют структуру данных между слоями:
ValidationResult— результат DNS/WHOIS проверки.AuthResult— результат auth-действия (нужен ли redirect).GithubPrSnapshot— типизированная обертка над snapshot PR/деплоя.
app/lib/*.php сохраняет инфраструктурные и совместимые функции:
target_dns.php— DNS/WHOIS/профили,auth.php— токены, rate-limit, audit log,github.php— GitHub API, PR/deploy state,ui_helpers.php— форматирование времени и экранирование.
Сервисы используют эти функции как низкоуровневый слой.
POST action=domain_submitприходит вindex.php.DomainSubmitAction:- проверяет CSRF/авторизацию,
- вызывает
DnsValidationService, - при успехе вызывает
GitHubPrService::createPullRequest, - пишет audit log,
- обновляет session snapshot.
stateсохраняется в flash (storePanelResultFlash) и выполняется PRG redirect.- После redirect UI берет flash и показывает сообщения/статусы.
- JS вызывает
GET /?github_pr_poll=1. GithubPollAction:- поднимает snapshot из сессии,
- при
force=1может искать последний PR по профилю, - обновляет snapshot через GitHub API,
- возвращает JSON (
snapshot,poll_interval,deploy_success).
app/assets/panel.jsобновляет блок статусов без перезагрузки страницы.
index.phpстал короче и предсказуемее.- Логика разделена по ответственности, проще менять и тестировать.
- Поведение UI и бизнес-правила сохранены без изменения UX.
Минимально обязательные:
PANEL_PASSWORDGITHUB_TOKENGITHUB_REPO
Основные:
TARGET_PROFILE_IDS=ru,fi,kzTARGET_PROFILE_DEFAULT=ruTARGET_PROFILE_<ID>_NAMETARGET_PROFILE_<ID>_FLAGTARGET_PROFILE_<ID>_IPTARGET_PROFILE_<ID>_ENABLED=1|0TARGET_PROFILES_JSON(опциональный полный override)AUDIT_LOG_PATH=/logs/domain-additions.logAUTH_MAX_ATTEMPTS=5AUTH_BLOCK_SECONDS=300AUTH_ATTEMPTS_PATH=/logs/login-attempts.jsonREMEMBER_COOKIE_NAME=panel_rememberREMEMBER_TOKENS_PATH=/logs/remember-tokens.jsonREMEMBER_TTL_SECONDS=2592000GITHUB_BASE_BRANCH=mainGITHUB_PROFILE_PATH_PREFIX=profilesPANEL_UID=1000PANEL_GID=1000TZ=Europe/Moscow
Полный актуальный шаблон: .env.example.
- Создать env:
cp .env.example .env- Запустить контейнеры:
docker compose up -d --buildВ docker-compose.yml уже зашиты labels для:
https://ops-panel.example.com- TLS
certresolver=letsEncrypt
В репозитории сейчас лежат:
.github/workflows/pr-validate.yml.github/workflows/pr-enable-auto-merge.yml.github/workflows/deploy.yml
Важно:
- Текущие workflow ограничены профилями
ru|fi|kz. - Если добавляете новые профили в панели (
TARGET_PROFILE_IDS), обновите regex/матрицу в workflow.
./logs:
nginx-access.lognginx-error.logphp-error.logdomain-additions.loglogin-attempts.jsonremember-tokens.json
- Индексация отключена (
X-Robots-Tag,meta robots,robots.txt). - CSRF для POST-действий.
- Ограничение попыток входа по IP (файл +
flock). - Серверный remember-me токен (без хранения пароля в браузере).
- В Nginx включен
Content-Security-Policy(CSP): разрешены только источникиselfдляscript-src,style-src,connect-src,font-src; изображения —selfиdata:.