20 KiB
Локальная отладка 3dp-manager
⚠️ Внимание: Локальный стенд использует учётные данные
admin/adminтолько для разработки. Production-скрипты (install.sh,update.sh) автоматически генерируют безопасные пароли.
Порты локального стенда
| Сервис | Порт | Доступ |
|---|---|---|
| frontend | http://localhost:8080 |
✅ Доступен из браузера |
| backend API | http://backend:3100/api |
❌ Скрыт внутри Docker network |
| postgres | 5432/tcp |
❌ Скрыт внутри Docker network |
🔒 Безопасность: Backend и PostgreSQL не проброшены наружу — доступны только внутри Docker network.
Учётные данные (по умолчанию)
Локальный стенд (.env):
ADMIN_LOGIN: admin
ADMIN_PASSWORD: admin
POSTGRES_USER: admin
POSTGRES_PASSWORD: admin
POSTGRES_DB: 3dp_manager
JWT_SECRET: localDevSecretKey12345678901234567890
⚠️ Важно: Для локальной разработки используется
admin/admin. Production-скрипты автоматически генерируют случайные пароли при установке/обновлении.
Запуск/перезапуск
Полный запуск (с пересозданием volumes)
# Первый запуск или полная пересборка
docker compose -f docker-compose.local.yml --env-file .env up -d --build --force-recreate
# Если нужно очистить БД и пересоздать volumes
docker compose -f docker-compose.local.yml --env-file .env down -v
docker compose -f docker-compose.local.yml --env-file .env up -d --build
Частичный перезапуск
# Только frontend (без пересборки)
docker compose -f docker-compose.local.yml --env-file .env restart frontend
# Только backend (без пересборки)
docker compose -f docker-compose.local.yml --env-file .env restart backend
# Frontend с пересборкой
docker compose -f docker-compose.local.yml --env-file .env up -d --build --no-deps frontend
# Backend с пересборкой
docker compose -f docker-compose.local.yml --env-file .env up -d --build --no-deps backend
Статус контейнеров
docker compose -f docker-compose.local.yml --env-file .env ps
Просмотр логов
# Backend логи
docker compose -f docker-compose.local.yml --env-file .env logs -f backend
# Frontend логи
docker compose -f docker-compose.local.yml --env-file .env logs -f frontend
# Последние 50 строк
docker compose -f docker-compose.local.yml --env-file .env logs --tail 50 backend
Остановка
# Остановка без удаления volumes
docker compose -f docker-compose.local.yml --env-file .env down
# Полная очистка (включая volumes)
docker compose -f docker-compose.local.yml --env-file .env down -v
Быстрые проверки
# Проверка frontend (должен вернуть 200)
curl --noproxy "*" -s -o /dev/null -w "%{http_code}" http://localhost:8080
# Проверка backend API через frontend-proxy (должен вернуть 401 без токена)
curl --noproxy "*" -s -o /dev/null -w "%{http_code}" http://localhost:8080/api/settings
# Проверка login endpoint
curl --noproxy "*" -s -X POST http://localhost:8080/api/auth/login -H "Content-Type: application/json" -d '{"login":"admin","password":"admin"}'
Тесты и линтинг
Backend
cd server
npm run lint
npm run test
npm run test:cov
Frontend
cd client
npm run lint
npm run test
npm run test:cov
Что уже встроено
- Backend scanner (RealiTLScanner) собирается в
server/Dockerfileи кладется в контейнер backend. - Блок
Автопоиск SNI (backend scanner)показывается только если бинарник сканера доступен в контейнере. - Во время сканирования UI получает статус с backend (
/api/domains/scan/status) и показывает реальный countdown. - Если обновить страницу во время скана, UI подхватывает активный запуск по backend-статусу и продолжает отсчет.
- После завершения скана результат можно получить из backend (
/api/domains/scan/last-result) даже если исходный запрос был прерван (например, после F5). - Предварительный список сканера:
- ручная проверка ссылками,
- удаление позиций,
- очистка,
- экспорт в
.txt, - сохранение состояния после F5.
- Основной список:
- ссылки на домены,
- hover-подсветка строк,
- экспорт полного списка в
.txt.
Нормализация доменов (импорт и ручное добавление)
- Единые правила применяются и для загрузки файла, и для добавления по одному.
*.domain.comнормализуется вdomain.com.- Комментарии и мусор отбрасываются (
#,;,//, URL/пути/порты и т.п.). - Дубликаты убираются без учета регистра.
- Явно некорректные значения отклоняются.
Тестовый "больной" список
- Файл для проверки импорта:
checker/domains-import-fuzz.txt
Быстрые проверки
Invoke-WebRequest -UseBasicParsing http://localhost:8080
Invoke-WebRequest -UseBasicParsing http://localhost:8080/api/settings
Остановка
docker compose -f docker-compose.local.yml down
Перед PR
1. Проверка локального стенда
# Убедиться, что все контейнеры работают
docker compose -f docker-compose.local.yml --env-file .env.local ps
# Проверить логи на наличие ошибок
docker compose -f docker-compose.local.yml --env-file .env.local logs --tail 100 backend
docker compose -f docker-compose.local.yml --env-file .env.local logs --tail 100 frontend
# Быстрый тест API
curl --noproxy "*" -s -o /dev/null -w "%{http_code}" http://localhost:8080/api/settings
2. Прогнать тесты
# Backend тесты
cd server
npm run test
# Frontend тесты
cd client
npm run test
3. Прогнать линтинг
# Backend
cd server
npm run lint
# Frontend
cd client
npm run lint
4. Проверка изменений
git status --short
git diff --name-only
Проверяем, что в PR идут только целевые изменения фичи.
Тестирование на виртуальной машине (VMware)
VMWare имитирует чистый VPS — Ubuntu 24.04, без Docker, без 3dp-manager. VMware Network: NAT (интернет на VM, доступ из хоста по IP VM).
Подготовка VM
-
Узнать IP виртуалки:
hostname -I # или ip addr show | grep "inet " | grep -v 127.0.0.1 -
SSH с хост-машины (Windows):
ssh iqubik@192.168.186.128 -
Разрешить sudo без пароля (нужно для скриптов установки):
# На VM — ввести пароль один раз: echo 'iqubik ALL=(ALL) NOPASSWD:ALL' | sudo tee /etc/sudoers.d/iqubik-nopasswdПосле этого
sudoработает без запроса пароля — скрипты могут выполняться автоматически. -
Проверка:
sudo whoami # должно вывести: root
Custom-установка на VM (с нуля)
# Скачать скрипт (без кэширования) и запустить от root
curl -fsSL -H "Cache-Control: no-cache" -H "Pragma: no-cache" https://raw.githubusercontent.com/iqubik/3dp-manager/dp-custom/install-custom.sh -o /tmp/install-custom.sh && sudo bash /tmp/install-custom.sh
Что делает:
- Устанавливает Docker (если нет)
- Клонирует код из
dp-customв/opt/3dp-manager-src - Спрашивает домен (можно пропустить — будет IP без HTTPS)
- Выбор типа SSL:
1)Let's Encrypt автоматически (нужны открытые порты 80/443)2)Self-signed — самоподписанный (для тестов, VMWare)3)Свои сертификаты (указать пути к fullchain.pem / privkey.pem)4)Без SSL — HTTP
- Генерирует пароли, ставит Hysteria 2
- Собирает backend/frontend из исходников
dp-custom - Запускает контейнеры
После установки скрипт выведет ADMIN_LOGIN / ADMIN_PASSWORD — сохрани!
💡 Для VMWare без домена: выбери
2)Self-signed — сгенерируется самоподписанный сертификат на 365 дней. Браузер будет ругаться — «Принять риск» → продолжить.
Custom-обновление на VM
curl -fsSL -H "Cache-Control: no-cache" -H "Pragma: no-cache" https://raw.githubusercontent.com/iqubik/3dp-manager/dp-custom/update-custom.sh -o /tmp/update-custom.sh && sudo bash /tmp/update-custom.sh
⚠️ Важно: Заголовки
Cache-Control: no-cacheобязательны — GitHub CDN кэширует raw-файлы до 5 минут. Без них можно получить старую версию скрипта.
Что делает:
git fetch+git mergeпоследних коммитов изdp-custom- Пересобирает backend + frontend из обновлённых исходников
- Перезапускает контейнеры
Удаление с VM
# Удалить 3dp-manager (Hysteria 2 останется)
curl -fsSL -H "Cache-Control: no-cache" -H "Pragma: no-cache" https://raw.githubusercontent.com/iqubik/3dp-manager/dp-custom/delete-custom.sh -o /tmp/delete-custom.sh && sudo bash /tmp/delete-custom.sh
# Полное удаление (включая Hysteria 2)
curl -fsSL -H "Cache-Control: no-cache" -H "Pragma: no-cache" https://raw.githubusercontent.com/iqubik/3dp-manager/dp-custom/delete-custom.sh | bash -s -- -H
⚠️ Важно: Кэширование также влияет на
delete-custom.sh. БезCache-Control: no-cacheможно получить старую версию.
Диагностика на VM
# Статус контейнеров
sudo docker compose -f /opt/3dp-manager/docker-compose.yml ps
# Логи backend
sudo docker compose -f /opt/3dp-manager/docker-compose.yml logs --tail 50 backend
# Логи frontend
sudo docker compose -f /opt/3dp-manager/docker-compose.yml logs --tail 50 frontend
# Содержимое .env (пароли)
sudo cat /opt/3dp-manager/.env
# docker-compose.yml
sudo cat /opt/3dp-manager/docker-compose.yml
# Дисковое пространство
df -h
# Оперативная память
free -m
Полная проверка хвостов после удаления
ssh iqubik@192.168.186.128 "echo '=== Docker контейнеры ===' && sudo docker ps -a --filter 'name=3dp-' && echo '' && echo '=== Docker образы 3dp ===' && sudo docker images --format '{{.Repository}}:{{.Tag}}' | grep -i 3dp || echo 'пусто' && echo '' && echo '=== Директории ===' && ls -d /opt/3dp-manager /opt/3dp-manager-src 2>&1 || true && echo '' && echo '=== Systemd hysteria ===' && systemctl list-unit-files | grep hysteria || echo 'пусто' && echo '' && echo '=== Hysteria бинарник ===' && which hysteria 2>&1 || echo 'не найден' && echo '' && echo '=== Hysteria конфиг ===' && ls -la /etc/hysteria/ 2>&1 || echo 'нет' && echo '' && echo '=== Процессы ===' && ps aux | grep -E '3dp|hysteria|3x-ui' | grep -v grep || echo 'пусто' && echo '' && echo '=== UFW ===' && sudo ufw status numbered 2>/dev/null || echo 'ufw не активен' && echo '' && echo '=== SSL ===' && ls /etc/letsencrypt/live/ 2>/dev/null || echo 'пусто' && echo '' && echo '=== Cron ===' && sudo crontab -l 2>/dev/null || echo 'пусто' && echo '' && echo '=== Диск ===' && df -h /"
Ожидаемый результат после delete-custom.sh -H: всё «пусто» / «нет» / «не найден».
Снапшоты VMware
Перед экспериментами — делай снапшот чистой Ubuntu:
- VMware → VM → Snapshot → Take Snapshot (или
Ctrl+Shift+S) - Перед
install-custom.sh— снапшот "clean" - После успешной установки — снапшот "installed"
- Перед
update-custom.sh— снапшот "pre-update"
Откат к снапшоту
- VMware → VM → Snapshot → Revert to Snapshot
- VM возвращается в сохранённое состояние за секунды
Обновление production (кастомная ветка)
⚠️ Важно: Начиная с версии 2.0.3, скрипты обновления автоматически проверяют и заменяют учётные данные по умолчанию (
admin/admin) на безопасные. Новые пароли выводятся в лог при обновлении.
Для сервера, где bash <(curl ...) не работает из-за /dev/fd, используем пайп:
curl -fsSL https://raw.githubusercontent.com/iqubik/3dp-manager/dp-fix/update-custom.sh | bash -s -- -r https://github.com/iqubik/3dp-manager.git -b dp-fix
Что делает команда:
- подтягивает исходники из
iqubik/3dp-managerветкиdp-fixв/opt/3dp-manager-src, - собирает
backend/frontendиз этих исходников, - поднимает контейнеры через
docker-compose.custom.ymlповерх текущей установки в/opt/3dp-manager.
Проверка после обновления:
cd /opt/3dp-manager
docker compose -f docker-compose.yml -f docker-compose.custom.yml ps
docker compose -f docker-compose.yml -f docker-compose.custom.yml logs --tail 120 backend
docker compose -f docker-compose.yml -f docker-compose.custom.yml logs --tail 120 frontend
Ожидаемо и нормально в логах frontend:
can not modify /etc/nginx/conf.d/default.conf (read-only file system?)
Это штатно при :ro-монтировании nginx-конфига.
Полная custom-установка на VPS (dp-custom)
⚠️ Важно: Скрипт
install-custom.shавтоматически генерирует безопасные пароли при установке. Учётные данные выводятся в лог после установки — сохраните их!
Сценарий "с нуля или поверх существующей установки":
curl -fsSL https://raw.githubusercontent.com/iqubik/3dp-manager/dp-custom/install-custom.sh | bash -s -- -r https://github.com/iqubik/3dp-manager.git -b dp-custom
Только обновление custom-кода (без базовой установки):
curl -fsSL https://raw.githubusercontent.com/iqubik/3dp-manager/dp-custom/update-custom.sh | bash -s -- -r https://github.com/iqubik/3dp-manager.git -b dp-custom
Git workflow: dp-custom -> dp-fix -> автор
Роли веток:
dp-custom: рабочая ветка для всех локальных/продовых/вспомогательных правок (включаяupdate-custom.sh,debug.md,pub.md).dp-fix: чистая ветка для PR в репозиторий автора (только код, который должен попасть upstream).
Почему GitHub Desktop "не даёт":
- Он не всегда удобно поддерживает сценарий "перенос отдельных коммитов между ветками одного репо".
- Для этого используем terminal и
cherry-pick.
Базовый цикл работы:
# 1) Работаем в dp-custom
git checkout dp-custom
# ... правки ...
git add .
git commit -m "feat: ... / fix: ..."
git push origin dp-custom
Проверка прода из dp-custom:
curl -fsSL https://raw.githubusercontent.com/iqubik/3dp-manager/dp-custom/update-custom.sh | bash -s -- -r https://github.com/iqubik/3dp-manager.git -b dp-custom
Перенос только нужных коммитов в dp-fix:
# 2) Смотрим, что нового в dp-custom относительно dp-fix
git log --oneline dp-fix..dp-custom
# 3) Переходим в чистую ветку PR
git checkout dp-fix
# 4) Переносим только нужные коммиты
git cherry-pick <commit_sha_1> <commit_sha_2> ...
# 5) Пушим чистую ветку и обновляем PR автору
git push origin dp-fix
Если конфликт при cherry-pick:
git status
# исправить конфликтные файлы
git add <resolved_files>
git cherry-pick --continue
Если нужно отменить текущий перенос:
git cherry-pick --abort
Проверка перед push в dp-fix:
git status --short
git diff --name-only upstream/dp-fix..HEAD
Ожидаем в dp-fix только те файлы, которые должны уйти автору.
Файл .env.local
Файл .env.local в корне проекта содержит переменные окружения для локального стенда:
# Локальные учётные данные для разработки
POSTGRES_USER=admin
POSTGRES_PASSWORD=admin
POSTGRES_DB=3dp_manager
JWT_SECRET=localDevSecretKey12345678901234567890
ADMIN_LOGIN=admin
ADMIN_PASSWORD=admin
PORT=3100
ALLOWED_ORIGINS=http://localhost:8080,http://localhost
⚠️ Не коммитьте
.env.localв репозиторий! Файл должен быть добавлен в.gitignoreдля безопасности.
Изменение учётных данных
Если нужно изменить логин/пароль для локальной разработки:
- Отредактируйте
.env.local - Пересоздайте контейнеры с очисткой volumes:
docker compose -f docker-compose.local.yml --env-file .env.local down -v docker compose -f docker-compose.local.yml --env-file .env.local up -d --build