unify config: single .env.example, default password mirvmon2026, docker in README

- .env.example moved to project root (used by both Docker and manual install)
- Migration 007: admin password = mirvmon2026 (bcrypt hash)
- docker-compose.yml reads ../.env from root
- deploy.sh generates DB passwords, shows default admin password
- README.md updated with Docker install section (Variant A) and manual (Variant B)
- Consistent default credentials everywhere: admin/mirvmon2026

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
mirivlad 2026-04-14 16:20:01 +08:00
parent 8938b61c78
commit 3ba8629146
6 changed files with 194 additions and 268 deletions

40
.env.example Normal file
View File

@ -0,0 +1,40 @@
# ==========================================
# MirvMon — Environment Configuration
# ==========================================
# Скопируйте: cp .env.example .env
# Этот файл используется и для Docker, и для ручной установки.
# ------------------------------------------
# Приложение
# ------------------------------------------
APP_PORT=8080
APP_TIMEZONE=Asia/Irkutsk
# ------------------------------------------
# База данных
# ------------------------------------------
# Для Docker: всё поднимается автоматически
# Для ручной: убедитесь что БД и пользователь созданы
DB_HOST=localhost
DB_PORT=3306
DB_NAME=monitoring_system
DB_USERNAME=mon_user
DB_PASSWORD=mon_password_123
DB_ROOT_PASSWORD=root_password_change_me
# ------------------------------------------
# Уведомления — Email (опционально)
# ------------------------------------------
# SMTP_HOST=smtp.gmail.com
# SMTP_PORT=587
# SMTP_USERNAME=your@email.com
# SMTP_PASSWORD=your_app_password
# SMTP_ENCRYPTION=tls
# SMTP_FROM_EMAIL=your@email.com
# ------------------------------------------
# Уведомления — Telegram (опционально)
# ------------------------------------------
# TELEGRAM_BOT_TOKEN=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
# TELEGRAM_CHAT_ID=-1001234567890
# TELEGRAM_PROXY=http://127.0.0.1:1081

350
README.md
View File

@ -1,11 +1,15 @@
# 🖥️ mirvmon — Система мониторинга серверов # 🖥️ mirvmon — Система мониторинга серверов
> Лёгкая и функциональная система мониторинга для домашних и небольших серверных инфраструктур. > Лёгкая и функциональная система мониторинга для домашних и небольших серверных
инфраструктур.
[![PHP](https://img.shields.io/badge/PHP-8.3+-777BB4.svg)](https://php.net) [![PHP](https://img.shields.io/badge/PHP-8.3+-777BB4.svg)](https://php.net)
[![Slim](https://img.shields.io/badge/Slim-4.x-3399FF.svg)](https://www.slimframework.com) [![Slim](https://img.shields.io/badge/Slim-4.x-3399FF.svg)](https://www.slimfram
[![MariaDB](https://img.shields.io/badge/MariaDB-10.11-003545.svg)](https://mariadb.org) ework.com)
[![Chart.js](https://img.shields.io/badge/Chart.js-4.x-FF6384.svg)](https://www.chartjs.org) [![MariaDB](https://img.shields.io/badge/MariaDB-10.11-003545.svg)](https://mari
adb.org)
[![Chart.js](https://img.shields.io/badge/Chart.js-4.x-FF6384.svg)](https://www.
chartjs.org)
--- ---
@ -21,6 +25,112 @@
--- ---
## 🚀 Установка
### Вариант A: Docker (рекомендуется)
Самый быстрый способ — всё поднимается автоматически:
```bash
# 1. Клонируем
git clone https://git.mirv.top/mirivlad/mirvmon.git
cd mirvmon
# 2. Запускаем скрипт (сам поставит Docker, сгенерит пароли, поднимет)
cd docker && bash deploy.sh
# 3. Открываем браузер
# http://localhost:8080
# Логин: admin
# Пароль: mirvmon2026 (смените сразу!)
```
**Ручной Docker (без скрипта):**
```bash
git clone https://git.mirv.top/mirivlad/mirvmon.git
cd mirvmon
cp .env.example .env # меняем пароли
docker compose -f docker/docker-compose.yml up -d --build
```
**При обновлении:**
```bash
git pull
docker compose -f docker/docker-compose.yml up -d --build
```
> 📦 Код внутри Docker-образа (immutable). Данные БД в volume `db_data` — не теряются.
---
### Вариант B: Ручная установка
#### 1. Зависимости
```bash
apt install php8.3 php8.3-fpm php8.3-mysql php8.3-mbstring php8.3-curl nginx mariadb-server
composer install
```
#### 2. База данных
```bash
mysql -u root -p <<EOF
CREATE DATABASE monitoring_system CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'mon_user'@'localhost' IDENTIFIED BY 'mon_password_123';
GRANT ALL PRIVILEGES ON monitoring_system.* TO 'mon_user'@'localhost';
FLUSH PRIVILEGES;
EOF
# Загружаем схему
mysql -u mon_user -pmon_password_123 monitoring_system < docker/migrations/001_create_base_schema.sql
mysql -u mon_user -pmon_password_123 monitoring_system < docker/migrations/002_add_encrypted_token.sql
mysql -u mon_user -pmon_password_123 monitoring_system < docker/migrations/003_add_agent_configs.sql
mysql -u mon_user -pmon_password_123 monitoring_system < docker/migrations/004_add_global_notification_settings.sql
mysql -u mon_user -pmon_password_123 monitoring_system < docker/migrations/005_add_service_tables.sql
mysql -u mon_user -pmon_password_123 monitoring_system < docker/migrations/006_server_metrics_value_to_text.sql
mysql -u mon_user -pmon_password_123 monitoring_system < docker/migrations/007_seed_admin_user.sql
```
#### 3. Настройка .env
```bash
cp .env.example .env
# Отредактируйте DB_HOST, DB_PASSWORD и другие параметры
nano .env
```
#### 4. Nginx
```nginx
server {
listen 80;
server_name mon.mirv.top;
root /var/www/mon/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
}
```
#### 5. Вход в систему
`http://your-server/login`
- Логин: `admin`
- Пароль: `mirvmon2026` (смените сразу!)
---
## 🏗️ Архитектура ## 🏗️ Архитектура
``` ```
@ -38,235 +148,3 @@
│ disk, ps) │ │ system │ │ disk, ps) │ │ system │
└─────────────────────┘ └──────────────────┘ └─────────────────────┘ └──────────────────┘
``` ```
---
## 🚀 Быстрый старт
### 1. Клонирование
```bash
git clone https://git.mirv.top/mirivlad/mirvmon.git
cd mirvmon
```
### 2. Установка зависимостей
```bash
composer install
```
### 3. База данных
```bash
mysql -u root -p monitoring_system < monitoring_system_dump.sql
```
### 4. Настройка БД
Отредактируйте `config/DatabaseConfig.php`:
```php
private $host = 'localhost';
private $db_name = 'monitoring_system';
private $username = 'mon_user';
private $password = 'mon_password_123';
```
### 5. Веб-сервер (Nginx)
```nginx
server {
listen 80;
server_name mon.mirv.top;
root /var/www/mon/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
}
```
### 6. Вход в систему
Перейдите на `http://mon.mirv.top/login`. Пароль по умолчанию для тестовых данных: `admin123`.
---
## 🤖 Установка Python-агента
### Через скрипт установки (рекомендуется):
1. **Получите ссылку на скрипт:**
В веб-интерфейсе перейдите на страницу редактирования сервера и нажмите кнопку **«Скачать install.sh»**.
Или сгенерируйте ссылку вручную:
```bash
https://mon.mirv.top/agent/install.sh?token=ВАШ_ТОКЕН
```
2. **Запустите установку на сервере:**
```bash
curl -o install.sh "https://mon.mirv.top/agent/install.sh?token=ВАШ_ТОКЕН"
chmod +x install.sh
sudo bash install.sh
```
*Скрипт сам установит Python, зависимости, создаст конфиг и настроит systemd-сервис.*
3. **Проверьте статус:**
```bash
systemctl status server-monitor-agent
```
### Что собирает агент:
- **CPU** (`cpu_load`) — загрузка процессора (%)
- **RAM** (`ram_used`) — использование памяти (%) + топ-5 процессов
- **Диск** (`disk_used_root`, `disk_used_home`, ...) — по каждому реальному разделу (%) + общий объём (GB)
- **Сеть** (`net_in_enp4s0`, `net_out_enp4s0`) — % использования пропускной способности интерфейса
- **Сервисы** — статус всех systemd-юнитов (running/stopped)
---
## 📁 Структура проекта
```
/var/www/mon/
├── config/
│ └── DatabaseConfig.php # Настройки подключения к БД
├── public/
│ ├── index.php # Точка входа (Slim Framework)
│ ├── chartjs-plugin-zoom.min.js # Плагин зума для графиков
│ └── hammer.min.js # Зависимость zoom (CDN)
├── src/
│ ├── Controllers/
│ │ ├── DashboardController.php # Дашборд с карточками серверов
│ │ ├── ServerDetailController.php # Детали сервера + графики + пороги
│ │ ├── ServerController.php # CRUD серверов
│ │ ├── GroupController.php # CRUD групп
│ │ ├── AlertController.php # Управление алертами
│ │ ├── AdminController.php # Админ-панель
│ │ └── Api/
│ │ └── MetricsController.php # REST API для приёма метрик
│ ├── Models/
│ │ ├── Server.php # Модель сервера
│ │ ├── Group.php # Модель группы
│ │ └── Alert.php # Модель алерта
│ ├── Middlewares/
│ │ ├── AuthMiddleware.php # Проверка авторизации
│ │ ├── CsrfMiddleware.php # CSRF-защита
│ │ ├── SessionMiddleware.php # Работа с сессиями
│ │ └── FlashMiddleware.php # Flash-сообщения
│ └── Services/
│ └── NotificationService.php # Отправка уведомлений (Telegram/Email)
├── templates/
│ ├── layout.twig # Базовый layout (Bootstrap 5)
│ ├── dashboard.twig # Дашборд с карточками
│ ├── servers/detail.twig # Детали сервера: графики, пороги, сервисы
│ └── ...
├── composer.json
├── monitoring_system_dump.sql # Дамп структуры + примеры данных
└── schema.sql # Чистая схема БД
```
---
## 📊 Метрики и графики
### На странице сервера доступны:
| Метрика | Тип графика | Описание |
|---------|-------------|----------|
| **CPU Загрузка** | Line (синий) | Загрузка процессора во времени |
| **RAM Использование** | Line (фиолетовый) | Использование памяти + топ процессов в тултипе |
| **Сеть: enp4s0** | Line (2 линии: 🟢 In / 🔴 Out) | % использования пропускной способности |
| **Диски** | Doughnut (карточки по 3 в ряд) | Текущее заполнение каждого раздела с GB |
### Управление графиками:
- 🖱️ **Колёсико мыши** — зум
- ✋ **Перетаскивание** — панорамирование
- 🔍 **Кнопка «Сброс»** — возврат к исходному масштабу
- ⏱️ **Период:** 1ч / 6ч / 24ч / 7д / 30д
---
## 🔔 Алерты и уведомления
### Пороги метрик
Для каждой метрики настраиваются:
- ⚠️ **Предупреждение** (warning threshold)
- 🚨 **Критический** (critical threshold)
- ⏱️ **Длительность** (минуты до срабатывания)
### Алерты сервисов
- 🛑 **Остановка** — красное уведомление, создаётся алерт
- ✅ **Запуск** — зелёное уведомление, алерт закрывается
- Отслеживаются только сервисы, отмеченные галочкой во вкладке «Сервисы»
### Каналы уведомлений
- **Telegram** — через Bot API (с поддержкой прокси)
- **Email** — через SMTP или функцию `mail()`
---
## 🗄️ База данных
### Основные таблицы:
| Таблица | Описание |
|---------|----------|
| `servers` | Мониторимые серверы |
| `server_metrics` | Временные ряды метрик |
| `metric_names` | Справочник метрик |
| `metric_thresholds` | Пороги алертов для серверов |
| `alerts` | Активные и закрытые алерты |
| `service_status` | Текущие статусы сервисов |
| `service_alerts` | Алерты на остановку сервисов |
| `agent_configs` | Настройки агентов (интервал, список сервисов) |
| `agent_tokens` | Токены авторизации агентов |
| `server_groups` | Группы серверов |
| `users` | Пользователи системы |
| `global_notification_settings` | Глобальные настройки уведомлений |
---
## ⚙️ Конфигурация
### PHP-FPM
- PHP 8.3+
- Расширения: `pdo`, `pdo_mysql`, `json`, `curl`, `mbstring`
### Nginx
- PHP-FPM через Unix socket
- `try_files` для Slim routing
### Python Agent
- Python 3.8+
- `psutil >= 5.0`
- `requests >= 2.25`
- `systemd` (для сбора статусов сервисов)
---
## 🔒 Безопасность
- ✅ Все пароли хешируются через `password_hash()` (bcrypt)
- ✅ Токены агентов хранятся как SHA-256 хеши
- ✅ Подготовленные выражения (PDO) для всех SQL-запросов
- ✅ CSRF-токены для всех форм
- ✅ Сессионная аутентификация для веб-интерфейса
- ✅ Валидация и санитизация входных данных
---
## 📝 Лицензия
MIT
---
## 👤 Автор
Владимир (mirivlad) — [git.mirv.top](https://git.mirv.top/mirivlad/mirvmon)

View File

@ -1,7 +1,8 @@
# ========================================== # ==========================================
# MirvMon — Environment Configuration # MirvMon — Environment Configuration
# ========================================== # ==========================================
# Скопируйте этот файл в .env и заполните значения # Скопируйте: cp .env.example .env
# Этот файл используется и для Docker, и для ручной установки.
# ------------------------------------------ # ------------------------------------------
# Приложение # Приложение
@ -12,17 +13,15 @@ APP_TIMEZONE=Asia/Irkutsk
# ------------------------------------------ # ------------------------------------------
# База данных # База данных
# ------------------------------------------ # ------------------------------------------
# Для Docker: всё поднимается автоматически
# Для ручной: убедитесь что БД и пользователь созданы
DB_HOST=localhost
DB_PORT=3306
DB_NAME=monitoring_system DB_NAME=monitoring_system
DB_USERNAME=mon_user DB_USERNAME=mon_user
DB_PASSWORD=mon_password_123 DB_PASSWORD=mon_password_123
DB_ROOT_PASSWORD=root_password_change_me DB_ROOT_PASSWORD=root_password_change_me
# ------------------------------------------
# Пользователь веб-интерфейса (первый запуск)
# ------------------------------------------
ADMIN_USERNAME=admin
ADMIN_PASSWORD=admin_change_me
# ------------------------------------------ # ------------------------------------------
# Уведомления — Email (опционально) # Уведомления — Email (опционально)
# ------------------------------------------ # ------------------------------------------

View File

@ -1,6 +1,7 @@
#!/bin/bash #!/bin/bash
# deploy.sh — Быстрый разворот MirvMon на чистом сервере # deploy.sh — Быстрый разворот MirvMon на чистом сервере
# Использование: bash deploy.sh # Использование: cd docker/ && bash deploy.sh
# Все файлы .env лежат в корне проекта (../.env)
set -e set -e
@ -26,27 +27,32 @@ echo "✅ Compose: $($DOCKER_COMPOSE_CMD version 2>/dev/null || echo 'v1')"
echo "" echo ""
# ------------------------------------------ # ------------------------------------------
# 2. Создаём .env если нет # 2. Определяем пути
# ------------------------------------------ # ------------------------------------------
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
ENV_FILE="$PROJECT_DIR/.env"
ENV_EXAMPLE="$SCRIPT_DIR/.env.example"
if [ ! -f "$SCRIPT_DIR/.env" ]; then # ------------------------------------------
# 3. Создаём .env если нет
# ------------------------------------------
if [ ! -f "$ENV_FILE" ]; then
echo "📝 Creating .env from template..." echo "📝 Creating .env from template..."
cp "$SCRIPT_DIR/.env.example" "$SCRIPT_DIR/.env" cp "$ENV_EXAMPLE" "$ENV_FILE"
# Генерируем случайные пароли # Генерируем случайные пароли
ROOT_PASS=$(openssl rand -base64 16 | tr -dc 'a-zA-Z0-9' | head -c 20) ROOT_PASS=$(openssl rand -base64 16 | tr -dc 'a-zA-Z0-9' | head -c 20)
DB_PASS=$(openssl rand -base64 16 | tr -dc 'a-zA-Z0-9' | head -c 20) DB_PASS=$(openssl rand -base64 16 | tr -dc 'a-zA-Z0-9' | head -c 20)
ADMIN_PASS=$(openssl rand -base64 16 | tr -dc 'a-zA-Z0-9' | head -c 20) ADMIN_PASS=$(openssl rand -base64 16 | tr -dc 'a-zA-Z0-9' | head -c 20)
sed -i "s/DB_ROOT_PASSWORD=.*/DB_ROOT_PASSWORD=${ROOT_PASS}/" "$SCRIPT_DIR/.env" sed -i "s/DB_ROOT_PASSWORD=.*/DB_ROOT_PASSWORD=${ROOT_PASS}/" "$ENV_FILE"
sed -i "s/DB_PASSWORD=.*/DB_PASSWORD=${DB_PASS}/" "$SCRIPT_DIR/.env" sed -i "s/DB_PASSWORD=.*/DB_PASSWORD=${DB_PASS}/" "$ENV_FILE"
sed -i "s/ADMIN_PASSWORD=.*/ADMIN_PASSWORD=${ADMIN_PASS}/" "$SCRIPT_DIR/.env"
echo "🔐 Generated random passwords:" echo "🔐 Generated random passwords:"
echo " DB root: $ROOT_PASS" echo " DB root: $ROOT_PASS"
echo " DB user: $DB_PASS" echo " DB user: $DB_PASS"
echo " Admin web: $ADMIN_PASS" echo " Admin web: mirvmon2026 (по умолчанию, смени в настройках)"
echo "" echo ""
echo "⚠️ Save these! Change .env if you want custom passwords." echo "⚠️ Save these! Change .env if you want custom passwords."
else else
@ -55,25 +61,28 @@ fi
echo "" echo ""
# ------------------------------------------ # ------------------------------------------
# 3. Запускаем # 4. Запускаем из директории проекта
# ------------------------------------------ # ------------------------------------------
echo "📦 Building and starting services..." echo "📦 Building and starting services..."
$DOCKER_COMPOSE_CMD up -d --build cd "$PROJECT_DIR"
$DOCKER_COMPOSE_CMD -f docker/docker-compose.yml up -d --build
echo "" echo ""
echo "⏳ Waiting for migrations..." echo "⏳ Waiting for migrations..."
sleep 10 sleep 15
# Проверяем статус # Проверяем статус
$DOCKER_COMPOSE_CMD ps $DOCKER_COMPOSE_CMD -f docker/docker-compose.yml ps
APP_PORT=$(grep APP_PORT "$ENV_FILE" | head -1 | cut -d= -f2)
echo "" echo ""
echo "✅ MirvMon is running!" echo "✅ MirvMon is running!"
echo "" echo ""
echo "🌐 Web UI: http://localhost:$(grep APP_PORT .env | cut -d= -f2)" echo "🌐 Web UI: http://localhost:${APP_PORT:-8080}"
echo "👤 Login: admin" echo "👤 Login: admin"
echo "🔑 Password: $(grep ADMIN_PASSWORD .env | cut -d= -f2)" echo "🔑 Password: mirvmon2026"
echo "" echo ""
echo "📊 To check logs: $DOCKER_COMPOSE_CMD logs -f app" echo "📊 To check logs: $DOCKER_COMPOSE_CMD -f docker/docker-compose.yml logs -f app"
echo "🔧 To stop: $DOCKER_COMPOSE_CMD down" echo "🔧 To stop: $DOCKER_COMPOSE_CMD -f docker/docker-compose.yml down"
echo "" echo ""

View File

@ -5,7 +5,9 @@ services:
dockerfile: docker/Dockerfile dockerfile: docker/Dockerfile
restart: unless-stopped restart: unless-stopped
env_file: env_file:
- .env - ../.env
environment:
DB_HOST: db
depends_on: depends_on:
db: db:
condition: service_healthy condition: service_healthy
@ -18,7 +20,7 @@ services:
image: nginx:alpine image: nginx:alpine
restart: unless-stopped restart: unless-stopped
ports: ports:
- "${APP_PORT:-80}:80" - "${APP_PORT:-8080}:80"
volumes: volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on: depends_on:

View File

@ -1,10 +1,8 @@
-- 007: Создаём админа по умолчанию (если нет ни одного пользователя) -- 007: Создаём админа по умолчанию (если нет ни одного пользователя)
-- Пароль: mirvmon2026 (обязательно смените при первом входе!)
-- Пароль: admin (нужно сменить при первом входе!)
-- Хеш генерируется через password_hash('admin', PASSWORD_DEFAULT)
-- Это хеш от 'admin' — смените сразу после входа!
INSERT INTO users (username, password_hash, email, role) INSERT INTO users (username, password_hash, email, role)
SELECT 'admin', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'admin@localhost', 'admin' SELECT 'admin', '$2b$12$13ox46bUsmmrG2o0eEktEuUG90HI8hgC9cqnbOecx9J.NXXn5rTRW', 'admin@localhost', 'admin'
WHERE NOT EXISTS (SELECT 1 FROM users LIMIT 1); WHERE NOT EXISTS (SELECT 1 FROM users LIMIT 1);
-- Создаём настройки уведомлений для админа -- Создаём настройки уведомлений для админа