diff --git a/FIX_PROMLEMS.md b/FIX_PROMLEMS.md new file mode 100644 index 0000000..1e11e0a --- /dev/null +++ b/FIX_PROMLEMS.md @@ -0,0 +1,92 @@ +# FIX_PROBLEMS.md + +## Текущий статус Prometheus + +### ✅ Что работает: +- Prometheus доступен по `https://188.68.223.37/prometheus/` +- Nginx проксирование настроено правильно +- Другие таргеты работают (Node Exporter, боты) +- Grafana работает по `https://188.68.223.37/grafana/` + +### ❌ Что не работает: + +#### 1. Самомониторинг Prometheus +- **Статус:** `"health":"down"` с ошибкой 404 +- **Проблема:** Prometheus не может получить доступ к своим метрикам по `/metrics` +- **Ошибка:** `"server returned HTTP status 404 Not Found"` +- **Причина:** Prometheus не экспортирует метрики по эндпоинту `/metrics` внутри контейнера + +#### 2. Редирект в Prometheus +- **Проблема:** Редирект с `https://188.68.223.37/prometheus/` на `https://188.68.223.37/prometheus/prometheus/query` +- **Причина:** Неправильная конфигурация Nginx proxy_pass +- **Статус:** ТРЕБУЕТ ИСПРАВЛЕНИЯ + +### 🔧 Быстрые исправления: + +#### Исправление редиректа Prometheus: +Проблема в конфигурации Nginx - нужно убрать слэш в `proxy_pass`: +```nginx +# Было: +proxy_pass http://prometheus_backend/; + +# Должно быть: +proxy_pass http://prometheus_backend; +``` + +#### Исправление самомониторинга: +Проблема в том, что Prometheus не экспортирует метрики. Возможные решения: +1. Убрать job 'prometheus' из конфигурации +2. Добавить параметры для экспорта метрик +3. Использовать другой подход для самомониторинга + +### 📋 Следующие шаги: +1. ✅ Исправить редирект Prometheus +2. ❌ Решить проблему с самомониторингом (пропущено) +3. ✅ Исправить главную страницу +4. ✅ Исправить Alertmanager +5. 🔄 Настроить безопасность +6. 🔄 Настроить Uptime Kuma + +--- + +## Этап 5: Настройка безопасности + +### План действий: +1. **Добавить базовую аутентификацию для Prometheus** + - Создать файл с логином/паролем + - Настроить Nginx для запроса аутентификации + - Проверить, что теперь требуется логин/пароль + +2. **Добавить базовую аутентификацию для Alertmanager** + - Создать файл с логином/паролем + - Настроить Nginx для запроса аутентификации + - Проверить, что теперь требуется логин/пароль + +3. **Перезагрузить Nginx** + - Применить новые настройки безопасности + +4. **Проверить, что теперь требуется логин/пароль** + - Убедиться, что Prometheus и Alertmanager защищены + +**Цель:** Сейчас Prometheus и Alertmanager доступны без аутентификации, что небезопасно. Нужно добавить базовую HTTP аутентификацию. + +--- + +## Этап 6: Настройка Uptime Kuma + +### План действий: +1. **Проверить статус Uptime Kuma** + - Убедиться, что контейнер запущен + - Проверить логи на наличие ошибок + +2. **Настроить мониторинг основных сервисов** + - Добавить мониторинг Grafana + - Добавить мониторинг Prometheus + - Добавить мониторинг Alertmanager + - Добавить мониторинг ботов + +3. **Проверить доступность `/status/`** + - Убедиться, что страница работает + - Проверить отображение статуса сервисов + +**Цель:** Uptime Kuma должен показывать статус всех сервисов и их доступность. diff --git a/docker-compose.yml b/docker-compose.yml index 9a700bb..5be7f32 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -39,7 +39,6 @@ services: - GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource - GF_SERVER_ROOT_URL=https://${SERVER_IP}/grafana/ - GF_SERVER_SERVE_FROM_SUB_PATH=true - - GF_SERVER_DOMAIN=${SERVER_IP} ports: - "3000:3000" volumes: @@ -111,7 +110,7 @@ services: environment: - SERVER_IP=${SERVER_IP} volumes: - - ./infra/nginx/nginx.conf:/etc/nginx/templates/nginx.conf.template:ro + - ./infra/nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./infra/nginx/conf.d:/etc/nginx/conf.d:ro - ./infra/nginx/ssl:/etc/nginx/ssl:ro - ./infra/nginx/.htpasswd:/etc/nginx/.htpasswd:ro @@ -255,4 +254,5 @@ networks: driver: bridge ipam: config: - - subnet: 192.168.100.0/24 + - subnet: 172.20.0.0/16 + gateway: 172.20.0.1 diff --git a/infra/alertmanager/alertmanager.yml b/infra/alertmanager/alertmanager.yml index 933c0ba..5776a80 100644 --- a/infra/alertmanager/alertmanager.yml +++ b/infra/alertmanager/alertmanager.yml @@ -94,92 +94,26 @@ receivers: - url: 'http://localhost:5001/' send_resolved: true - # Critical alerts - immediate notification via multiple channels + # Critical alerts - immediate notification via webhook - name: 'critical-alerts' - email_configs: - - to: 'admin@{{DOMAIN}}' - subject: '🚨 CRITICAL ALERT: {{ .GroupLabels.alertname }}' - body: | - {{ range .Alerts }} - Alert: {{ .Annotations.summary }} - Description: {{ .Annotations.description }} - Severity: {{ .Labels.severity }} - Service: {{ .Labels.service }} - Instance: {{ .Labels.instance }} - Time: {{ .StartsAt }} - {{ end }} - html: | -

🚨 Critical Alert

- - - - -
Alert:{{ .GroupLabels.alertname }}
Service:{{ .GroupLabels.service }}
Time:{{ .GroupLabels.time }}
-

Alerts:

- webhook_configs: - url: 'http://localhost:5001/critical' send_resolved: true # Warning alerts - less urgent notification - name: 'warning-alerts' - email_configs: - - to: 'admin@{{DOMAIN}}' - subject: '⚠️ WARNING: {{ .GroupLabels.alertname }}' - body: | - {{ range .Alerts }} - Alert: {{ .Annotations.summary }} - Description: {{ .Annotations.description }} - Severity: {{ .Labels.severity }} - Service: {{ .Labels.service }} - Instance: {{ .Labels.instance }} - Time: {{ .StartsAt }} - {{ end }} webhook_configs: - url: 'http://localhost:5001/warning' send_resolved: true # Bot-specific alerts - name: 'bot-alerts' - email_configs: - - to: 'bot-admin@{{DOMAIN}}' - subject: '🤖 Bot Alert: {{ .GroupLabels.alertname }}' - body: | - Bot Alert: {{ .GroupLabels.alertname }} - Service: {{ .GroupLabels.service }} - - {{ range .Alerts }} - - {{ .Annotations.summary }} - {{ .Annotations.description }} - Instance: {{ .Labels.instance }} - Time: {{ .StartsAt }} - {{ end }} webhook_configs: - url: 'http://localhost:5001/bot' send_resolved: true # Infrastructure alerts - name: 'infrastructure-alerts' - email_configs: - - to: 'infra@{{DOMAIN}}' - subject: '🏗️ Infrastructure Alert: {{ .GroupLabels.alertname }}' - body: | - Infrastructure Alert: {{ .GroupLabels.alertname }} - Service: {{ .GroupLabels.service }} - - {{ range .Alerts }} - - {{ .Annotations.summary }} - {{ .Annotations.description }} - Instance: {{ .Labels.instance }} - Time: {{ .StartsAt }} - {{ end }} webhook_configs: - url: 'http://localhost:5001/infrastructure' send_resolved: true diff --git a/infra/ansible/playbook.yml b/infra/ansible/playbook.yml index df7ec7e..b73fb8e 100644 --- a/infra/ansible/playbook.yml +++ b/infra/ansible/playbook.yml @@ -19,7 +19,11 @@ grafana_admin_password: "{{ lookup('env', 'GRAFANA_ADMIN_PASSWORD') | default('admin') }}" tasks: - - name: Обновить SSH host key для избежания ошибок при переустановке + # ======================================== + # ЭТАП 1: ПОДГОТОВКА СИСТЕМЫ (ROOT) + # ======================================== + + - name: "[1/10] Обновить SSH host key для избежания ошибок при переустановке" known_hosts: path: ~/.ssh/known_hosts name: "{{ ansible_host }}" @@ -29,11 +33,11 @@ run_once: true ignore_errors: yes - - name: Обновить кэш пакетов + - name: "[1/10] Обновить кэш пакетов" apt: update_cache: yes - - name: Установить необходимые пакеты + - name: "[1/10] Установить необходимые пакеты" apt: name: - docker.io @@ -61,64 +65,77 @@ - python3-certbot-nginx state: present - - name: Установить Python библиотеки для Ansible + - name: "[1/10] Установить Python библиотеки для Ansible" pip: name: - passlib - bcrypt state: present - - name: Установить часовой пояс Europe/Moscow + - name: "[1/10] Установить часовой пояс Europe/Moscow" timezone: name: Europe/Moscow - - name: Проверить существование swap-файла + # ======================================== + # ЭТАП 2: НАСТРОЙКА СИСТЕМЫ (ROOT) + # ======================================== + + - name: "[2/10] Проверить существование swap-файла" stat: path: /swapfile register: swap_file_stat - - name: Создать swap-файл (2GB) + - name: "[2/10] Создать swap-файл (2GB)" command: fallocate -l 2G /swapfile when: not swap_file_stat.stat.exists - - name: Установить правильные права на swap-файл + - name: "[2/10] Установить правильные права на swap-файл" file: path: /swapfile mode: '0600' owner: root group: root - - name: Настроить swap-файл + - name: "[2/10] Настроить swap-файл" command: mkswap /swapfile when: not swap_file_stat.stat.exists - - name: Включить swap-файл + - name: "[2/10] Включить swap-файл" command: swapon /swapfile when: not swap_file_stat.stat.exists - - name: Настроить swappiness = 10 (временно) + - name: "[2/10] Настроить swappiness = 10 (временно)" sysctl: name: vm.swappiness value: '10' state: present reload: yes - - name: Настроить swappiness = 10 (постоянно) + - name: "[2/10] Настроить swappiness = 10 (постоянно)" lineinfile: path: /etc/sysctl.conf regexp: '^vm\.swappiness\s*=' line: 'vm.swappiness = 10' state: present - - name: Добавить swap-файл в /etc/fstab для автоматического монтирования + - name: "[2/10] Добавить swap-файл в /etc/fstab для автоматического монтирования" lineinfile: path: /etc/fstab line: '/swapfile none swap sw 0 0' state: present create: yes - # --- НАСТРОЙКА БЕЗОПАСНОСТИ ЯДРА --- - - name: Настроить параметры безопасности ядра + - name: "[2/10] Проверить статус swap" + command: swapon --show + register: swap_status + changed_when: false + + - name: "[2/10] Показать информацию о swap" + debug: + var: swap_status.stdout_lines + + # Настройка параметров безопасности ядра + - name: "[2/10] Настроить параметры безопасности ядра" sysctl: name: "{{ item.name }}" value: "{{ item.value }}" @@ -153,7 +170,7 @@ - { name: "kernel.threads-max", value: "4096" } - { name: "vm.max_map_count", value: "262144" } - - name: Сохранить параметры безопасности в /etc/sysctl.conf + - name: "[2/10] Сохранить параметры безопасности в /etc/sysctl.conf" lineinfile: path: /etc/sysctl.conf regexp: "^{{ item.name }}\\s*=" @@ -188,95 +205,385 @@ - { name: "kernel.threads-max", value: "4096" } - { name: "vm.max_map_count", value: "262144" } - - name: Проверить статус swap - command: swapon --show - register: swap_status - changed_when: false - - - name: Показать информацию о swap - debug: - var: swap_status.stdout_lines - - - name: Включить и запустить prometheus-node-exporter + # ======================================== + # ЭТАП 3: СИСТЕМНЫЕ СЕРВИСЫ (ROOT) + # ======================================== + + - name: "[3/10] Включить и запустить prometheus-node-exporter" systemd: name: prometheus-node-exporter enabled: yes state: started - - name: Проверить статус prometheus-node-exporter + - name: "[3/10] Проверить статус prometheus-node-exporter" command: systemctl status prometheus-node-exporter register: node_exporter_status changed_when: false - - name: Показать статус prometheus-node-exporter + - name: "[3/10] Показать статус prometheus-node-exporter" debug: var: node_exporter_status.stdout_lines - - name: Проверить, что node_exporter слушает на порту 9100 + - name: "[3/10] Проверить, что node_exporter слушает на порту 9100" command: netstat -tulpn | grep 9100 register: node_exporter_port changed_when: false - - name: Показать информацию о порте 9100 + - name: "[3/10] Показать информацию о порте 9100" debug: var: node_exporter_port.stdout_lines - - name: Обновить Docker Compose до последней версии + - name: "[3/10] Обновить Docker Compose до последней версии" get_url: url: "https://github.com/docker/compose/releases/latest/download/docker-compose-{{ ansible_system }}-{{ ansible_architecture }}" dest: /usr/local/bin/docker-compose mode: '0755' - become: yes - - name: Включить и запустить Docker + - name: "[3/10] Включить и запустить Docker" systemd: name: docker enabled: yes state: started - - name: Разрешить SSH (порт 22) перед включением UFW - ufw: - rule: allow - port: "22" - proto: tcp + # ======================================== + # ЭТАП 4: ПОЛЬЗОВАТЕЛЬ DEPLOY (ROOT) + # ======================================== + + - name: "[4/10] Проверить существование пользователя deploy" + getent: + database: passwd + key: "{{ deploy_user }}" + register: user_exists + failed_when: false - - name: Разрешить новый SSH порт (15722) перед включением UFW - ufw: - rule: allow - port: "15722" - proto: tcp + - name: "[4/10] Создать группу deploy с GID 1001" + group: + name: "{{ deploy_user }}" + gid: "{{ gid }}" + when: user_exists.ansible_facts.getent_passwd is not defined - - name: Настроить политику UFW по умолчанию - ufw: - policy: deny - direction: incoming + - name: "[4/10] Создать пользователя deploy с UID 1001 (если не существует)" + user: + name: "{{ deploy_user }}" + uid: "{{ uid }}" + group: "{{ gid }}" + shell: /bin/zsh + create_home: yes + system: no + groups: docker + append: yes + when: user_exists.ansible_facts.getent_passwd is not defined - - name: Включить UFW (файрвол) - ufw: - state: enabled + - name: "[4/10] Установить zsh как оболочку по умолчанию для существующего пользователя deploy" + user: + name: "{{ deploy_user }}" + shell: /bin/zsh + when: user_exists.ansible_facts.getent_passwd is defined - - name: Открыть порты для сервисов - ufw: - rule: allow - port: "{{ item }}" - proto: tcp + - name: "[4/10] Скопировать SSH ключ с локальной машины для пользователя deploy" + authorized_key: + user: "{{ deploy_user }}" + key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" + state: present + + - name: "[4/10] Настроить sudo для deploy (только Docker команды)" + lineinfile: + path: /etc/sudoers.d/deploy + line: "{{ deploy_user }} ALL=(ALL) NOPASSWD: /usr/bin/docker, /usr/bin/docker-compose, /usr/bin/make" + create: yes + mode: '0440' + validate: 'visudo -cf %s' + + - name: "[4/10] Удалить /home/prod, если требуется (чистое развертывание)" + file: + path: "{{ project_root }}" + state: absent + when: recreate_project | bool + + - name: "[4/10] Создать директорию проекта /home/prod" + file: + path: "{{ project_root }}" + state: directory + owner: "{{ deploy_user }}" + group: "{{ deploy_user }}" + mode: '0755' + + - name: "[4/10] Скопировать приватный SSH ключ для Git" + copy: + src: "~/.ssh/id_rsa" + dest: "/home/{{ deploy_user }}/.ssh/id_rsa" + owner: "{{ deploy_user }}" + group: "{{ deploy_user }}" + mode: '0600' + remote_src: no + + - name: "[4/10] Настроить SSH config для GitHub" + lineinfile: + path: "/home/{{ deploy_user }}/.ssh/config" + line: "Host github.com\n StrictHostKeyChecking no\n UserKnownHostsFile /dev/null" + create: yes + owner: "{{ deploy_user }}" + group: "{{ deploy_user }}" + mode: '0600' + + # ======================================== + # ЭТАП 5: КЛОНИРОВАНИЕ РЕПОЗИТОРИЕВ (DEPLOY) + # ======================================== + + - name: "[5/10] Клонировать основной репозиторий prod" + git: + repo: git@github.com:KerradKerridi/prod.git + dest: "{{ project_root }}" + update: yes + force: yes + become: yes + become_user: "{{ deploy_user }}" + + - name: "[5/10] Клонировать AnonBot" + git: + repo: git@github.com:KerradKerridi/AnonBot.git + dest: "{{ project_root }}/bots/AnonBot" + update: yes + force: yes + become: yes + become_user: "{{ deploy_user }}" + + - name: "[5/10] Клонировать telegram-helper-bot" + git: + repo: git@github.com:KerradKerridi/telegram-helper-bot.git + dest: "{{ project_root }}/bots/telegram-helper-bot" + version: dev-9 + update: yes + force: yes + become: yes + become_user: "{{ deploy_user }}" + + # ======================================== + # ЭТАП 6: КОПИРОВАНИЕ КОНФИГУРАЦИЙ (ROOT) + # ======================================== + + - name: "[6/10] Скопировать конфигурацию Alertmanager" + copy: + src: "{{ project_root }}/infra/alertmanager/alertmanager.yml" + dest: "{{ project_root }}/infra/alertmanager/alertmanager.yml" + owner: "{{ deploy_user }}" + group: "{{ deploy_user }}" + mode: '0644' + backup: yes + remote_src: yes + + - name: "[6/10] Скопировать правила алертов Prometheus" + copy: + src: "{{ project_root }}/infra/prometheus/alert_rules.yml" + dest: "{{ project_root }}/infra/prometheus/alert_rules.yml" + owner: "{{ deploy_user }}" + group: "{{ deploy_user }}" + mode: '0644' + backup: yes + remote_src: yes + + - name: "[6/10] Скопировать дашборды Grafana" + copy: + src: "{{ project_root }}/infra/grafana/dashboards/" + dest: "{{ project_root }}/infra/grafana/dashboards/" + owner: "{{ deploy_user }}" + group: "{{ deploy_user }}" + mode: '0644' + backup: yes + remote_src: yes + + - name: "[6/10] Скопировать скрипт настройки SSL" + copy: + src: "{{ project_root }}/scripts/setup-ssl.sh" + dest: /usr/local/bin/setup-ssl.sh + owner: root + group: root + mode: '0755' + backup: yes + remote_src: yes + + - name: "[6/10] Установить правильные права на дашборд Node Exporter Full" + file: + path: "{{ project_root }}/infra/grafana/provisioning/dashboards/node-exporter-full-dashboard.json" + owner: "{{ deploy_user }}" + group: "{{ deploy_user }}" + mode: '0644' + + # ======================================== + # ЭТАП 7: КОПИРОВАНИЕ ДАННЫХ СО СТАРОГО СЕРВЕРА (ROOT) + # ======================================== + + - name: "[7/10] Скопировать SSH ключ на старый сервер для копирования файлов" + authorized_key: + user: root + key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" + state: present + delegate_to: "{{ old_server }}" + + - name: "[7/10] Копировать .env для telegram-helper-bot со старого сервера" + fetch: + src: "/home/prod/bots/telegram-helper-bot/.env" + dest: "/tmp/telegram-helper-bot.env" + flat: yes + delegate_to: "{{ old_server }}" + + - name: "[7/10] Переместить .env для telegram-helper-bot на новое место" + copy: + src: "/tmp/telegram-helper-bot.env" + dest: "{{ project_root }}/bots/telegram-helper-bot/.env" + owner: "{{ deploy_user }}" + group: "{{ deploy_user }}" + mode: '0644' + + - name: "[7/10] Проверить размер БД для telegram-helper-bot" + stat: + path: "/home/prod/bots/telegram-helper-bot/database/tg-bot-database.db" + delegate_to: "{{ old_server }}" + register: db_size + + - name: "[7/10] Показать размер БД для telegram-helper-bot" + debug: + msg: "Размер БД: {{ (db_size.stat.size / 1024 / 1024) | round(2) }} MB" + + - name: "[7/10] Копировать БД для telegram-helper-bot" + fetch: + src: "/home/prod/bots/telegram-helper-bot/database/tg-bot-database.db" + dest: "/tmp/tg-bot-database.db" + flat: yes + delegate_to: "{{ old_server }}" + + - name: "[7/10] Переместить БД для telegram-helper-bot на новое место" + copy: + src: "/tmp/tg-bot-database.db" + dest: "{{ project_root }}/bots/telegram-helper-bot/database/tg-bot-database.db" + owner: "{{ deploy_user }}" + group: "{{ deploy_user }}" + mode: '0644' + + - name: "[7/10] Создать папку voice_users на новом сервере" + file: + path: "{{ project_root }}/bots/telegram-helper-bot/voice_users" + state: directory + owner: "{{ deploy_user }}" + group: "{{ deploy_user }}" + mode: '0755' + + - name: "[7/10] Создать временную папку для voice_users на локальной машине" + file: + path: "/tmp/voice_users_migration" + state: directory + mode: '0755' + delegate_to: localhost + become: no + + - name: "[7/10] Копировать voice_users со старого сервера на локальную машину" + command: > + rsync -avz --progress --stats --partial --verbose + root@77.223.98.129:/home/prod/bots/telegram-helper-bot/voice_users/ + /tmp/voice_users_migration/ + delegate_to: localhost + become: no + + - name: "[7/10] Копировать voice_users с локальной машины на новый сервер" + synchronize: + src: "/tmp/voice_users_migration/" + dest: "{{ project_root }}/bots/telegram-helper-bot/voice_users/" + mode: push + rsync_opts: "--progress --stats --partial --verbose" + + - name: "[7/10] Очистить временную папку на локальной машине" + file: + path: "/tmp/voice_users_migration" + state: absent + delegate_to: localhost + become: no + + - name: "[7/10] Копировать корневой .env файл" + fetch: + src: "/home/prod/.env" + dest: "/tmp/root.env" + flat: yes + delegate_to: "{{ old_server }}" + + - name: "[7/10] Переместить корневой .env файл на новое место" + copy: + src: "/tmp/root.env" + dest: "{{ project_root }}/.env" + owner: "{{ deploy_user }}" + group: "{{ deploy_user }}" + mode: '0644' + + - name: "[7/10] Копировать .env для AnonBot" + fetch: + src: "/home/prod/bots/AnonBot/.env" + dest: "/tmp/anonbot.env" + flat: yes + delegate_to: "{{ old_server }}" + + - name: "[7/10] Переместить .env для AnonBot на новое место" + copy: + src: "/tmp/anonbot.env" + dest: "{{ project_root }}/bots/AnonBot/.env" + owner: "{{ deploy_user }}" + group: "{{ deploy_user }}" + mode: '0644' + + - name: "[7/10] Проверить размер БД для AnonBot" + stat: + path: "/home/prod/bots/AnonBot/database/anon_qna.db" + delegate_to: "{{ old_server }}" + register: anon_db_size + + - name: "[7/10] Показать размер БД для AnonBot" + debug: + msg: "Размер БД AnonBot: {{ (anon_db_size.stat.size / 1024 / 1024) | round(2) }} MB" + + - name: "[7/10] Копировать БД для AnonBot" + fetch: + src: "/home/prod/bots/AnonBot/database/anon_qna.db" + dest: "/tmp/anon_qna.db" + flat: yes + delegate_to: "{{ old_server }}" + + - name: "[7/10] Переместить БД для AnonBot на новое место" + copy: + src: "/tmp/anon_qna.db" + dest: "{{ project_root }}/bots/AnonBot/database/anon_qna.db" + owner: "{{ deploy_user }}" + group: "{{ deploy_user }}" + mode: '0644' + + - name: "[7/10] Установить права на скопированные файлы" + file: + path: "{{ item }}" + owner: "{{ deploy_user }}" + group: "{{ deploy_user }}" + mode: '0644' loop: - - "8080" # Telegram Bot - - "8081" # AnonBot - - "9090" # Prometheus - - "3000" # Grafana - - "9100" # Node Exporter - - "80" # HTTP - - "443" # HTTPS + - "{{ project_root }}/bots/telegram-helper-bot/.env" + - "{{ project_root }}/bots/telegram-helper-bot/database/tg-bot-database.db" + - "{{ project_root }}/bots/AnonBot/.env" + - "{{ project_root }}/bots/AnonBot/database/anon_qna.db" - # --- НАСТРОЙКА NGINX --- - - name: Остановить nginx (если запущен) + - name: "[7/10] Исправить права доступа для voice_users (рекурсивно)" + file: + path: "{{ project_root }}/bots/telegram-helper-bot/voice_users" + owner: "{{ deploy_user }}" + group: "{{ deploy_user }}" + mode: '0755' + recurse: yes + + # ======================================== + # ЭТАП 8: NGINX КОНФИГУРАЦИЯ (ROOT) + # ======================================== + + - name: "[8/10] Остановить nginx (если запущен)" systemd: name: nginx state: stopped ignore_errors: yes - - name: Создать директории для nginx конфигураций + - name: "[8/10] Создать директории для nginx конфигураций" file: path: "{{ item }}" state: directory @@ -292,7 +599,7 @@ - "{{ project_root }}/infra/grafana/dashboards" - "{{ project_root }}/scripts" - - name: Сгенерировать самоподписанный SSL сертификат (fallback) + - name: "[8/10] Сгенерировать самоподписанный SSL сертификат (fallback)" command: > openssl req -x509 -newkey rsa:4096 -keyout {{ project_root }}/infra/nginx/ssl/key.pem -out {{ project_root }}/infra/nginx/ssl/cert.pem -days 365 -nodes @@ -301,7 +608,7 @@ creates: "{{ project_root }}/infra/nginx/ssl/cert.pem" when: not use_letsencrypt | default(false) - - name: Создать директории для Let's Encrypt + - name: "[8/10] Создать директории для Let's Encrypt" file: path: "{{ item }}" state: directory @@ -315,14 +622,14 @@ - /etc/letsencrypt/renewal when: use_letsencrypt | default(false) - - name: Настроить cron для автоматического обновления SSL сертификатов + - name: "[8/10] Настроить cron для автоматического обновления SSL сертификатов" cron: name: "SSL Certificate Renewal" job: "0 2 * * 1 /usr/local/bin/ssl-renewal.sh" user: root when: use_letsencrypt | default(false) - - name: Установить права на SSL сертификаты + - name: "[8/10] Установить права на SSL сертификаты" file: path: "{{ item }}" owner: root @@ -332,7 +639,7 @@ - "{{ project_root }}/infra/nginx/ssl/cert.pem" - "{{ project_root }}/infra/nginx/ssl/key.pem" - - name: Создать htpasswd файл для status page + - name: "[8/10] Создать htpasswd файл для status page" htpasswd: path: "{{ project_root }}/infra/nginx/.htpasswd" name: "admin" @@ -341,37 +648,59 @@ group: root mode: '0644' - - name: Скопировать основную конфигурацию nginx - copy: - src: "{{ project_root }}/infra/nginx/nginx.conf" + - name: "[8/10] Удалить старую конфигурацию nginx" + file: + path: /etc/nginx/nginx.conf + state: absent + + - name: "[8/10] Скопировать основную конфигурацию nginx" + template: + src: "/Users/andrejkatyhin/PycharmProjects/prod/infra/nginx/nginx.conf" dest: /etc/nginx/nginx.conf owner: root group: root mode: '0644' backup: yes - remote_src: yes + vars: + SERVER_IP: "{{ ansible_host }}" - - name: Скопировать конфигурации nginx для сервисов + - name: "[8/10] Скопировать конфигурации nginx для сервисов" copy: - src: "{{ project_root }}/infra/nginx/conf.d/" + src: "/Users/andrejkatyhin/PycharmProjects/prod/infra/nginx/conf.d/" dest: /etc/nginx/conf.d/ owner: root group: root mode: '0644' backup: yes - remote_src: yes - - name: Скопировать SSL сертификаты - copy: - src: "{{ project_root }}/infra/nginx/ssl/" - dest: /etc/nginx/ssl/ + - name: "[8/10] Создать директорию для SSL сертификатов" + file: + path: /etc/nginx/ssl + state: directory + owner: root + group: root + mode: '0755' + + - name: "[8/10] Сгенерировать самоподписанный SSL сертификат" + command: > + openssl req -x509 -nodes -days 365 -newkey rsa:2048 + -keyout /etc/nginx/ssl/privkey.pem + -out /etc/nginx/ssl/fullchain.pem + -subj "/C=RU/ST=Moscow/L=Moscow/O=Bot Infrastructure/OU=IT Department/CN={{ ansible_host }}" + args: + creates: /etc/nginx/ssl/fullchain.pem + + - name: "[8/10] Установить права на SSL сертификаты" + file: + path: "{{ item }}" owner: root group: root mode: '0600' - backup: yes - remote_src: yes + loop: + - /etc/nginx/ssl/privkey.pem + - /etc/nginx/ssl/fullchain.pem - - name: Скопировать htpasswd файл + - name: "[8/10] Скопировать htpasswd файл" copy: src: "{{ project_root }}/infra/nginx/.htpasswd" dest: /etc/nginx/.htpasswd @@ -381,108 +710,53 @@ backup: yes remote_src: yes - - name: Скопировать конфигурацию Alertmanager - copy: - src: "{{ project_root }}/infra/alertmanager/alertmanager.yml" - dest: "{{ project_root }}/infra/alertmanager/alertmanager.yml" - owner: "{{ deploy_user }}" - group: "{{ deploy_user }}" - mode: '0644' - backup: yes - remote_src: yes - - - name: Скопировать правила алертов Prometheus - copy: - src: "{{ project_root }}/infra/prometheus/alert_rules.yml" - dest: "{{ project_root }}/infra/prometheus/alert_rules.yml" - owner: "{{ deploy_user }}" - group: "{{ deploy_user }}" - mode: '0644' - backup: yes - remote_src: yes - - - name: Скопировать дашборды Grafana - copy: - src: "{{ project_root }}/infra/grafana/dashboards/" - dest: "{{ project_root }}/infra/grafana/dashboards/" - owner: "{{ deploy_user }}" - group: "{{ deploy_user }}" - mode: '0644' - backup: yes - remote_src: yes - - - name: Скопировать скрипт настройки SSL - copy: - src: "{{ project_root }}/scripts/setup-ssl.sh" - dest: /usr/local/bin/setup-ssl.sh - owner: root - group: root - mode: '0755' - backup: yes - remote_src: yes - - - name: Проверить конфигурацию nginx - command: nginx -t - register: nginx_config_test - changed_when: false - - - name: Показать результат проверки nginx - debug: - var: nginx_config_test.stdout_lines - - - name: Включить и запустить nginx + - name: "[8/10] Включить nginx (запустим позже после контейнеров)" systemd: name: nginx enabled: yes - state: started + state: stopped - - name: Проверить статус nginx - command: systemctl status nginx - register: nginx_status - changed_when: false - - name: Показать статус nginx - debug: - var: nginx_status.stdout_lines + # ======================================== + # ЭТАП 9: БЕЗОПАСНОСТЬ И ФАЙРВОЛ (ROOT) + # ======================================== + + - name: "[9/10] Разрешить SSH (порт 22) перед включением UFW" + ufw: + rule: allow + port: "22" + proto: tcp - - name: Проверить существование пользователя deploy - getent: - database: passwd - key: "{{ deploy_user }}" - register: user_exists - failed_when: false + - name: "[9/10] Разрешить новый SSH порт (15722) перед включением UFW" + ufw: + rule: allow + port: "15722" + proto: tcp - - name: Создать группу deploy с GID 1001 - group: - name: "{{ deploy_user }}" - gid: "{{ gid }}" - when: user_exists.ansible_facts.getent_passwd is not defined + - name: "[9/10] Настроить политику UFW по умолчанию" + ufw: + policy: deny + direction: incoming - - name: Создать пользователя deploy с UID 1001 (если не существует) - user: - name: "{{ deploy_user }}" - uid: "{{ uid }}" - group: "{{ gid }}" - shell: /bin/zsh - create_home: yes - system: no - groups: docker - append: yes - when: user_exists.ansible_facts.getent_passwd is not defined + - name: "[9/10] Включить UFW (файрвол)" + ufw: + state: enabled - - name: Установить zsh как оболочку по умолчанию для существующего пользователя deploy - user: - name: "{{ deploy_user }}" - shell: /bin/zsh - when: user_exists.ansible_facts.getent_passwd is defined + - name: "[9/10] Открыть порты для сервисов" + ufw: + rule: allow + port: "{{ item }}" + proto: tcp + loop: + - "8080" # Telegram Bot + - "8081" # AnonBot + - "9090" # Prometheus + - "3000" # Grafana + - "9100" # Node Exporter + - "80" # HTTP + - "443" # HTTPS - - name: Скопировать SSH ключ с локальной машины для пользователя deploy - authorized_key: - user: "{{ deploy_user }}" - key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" - state: present - - - name: Настроить безопасный SSH + - name: "[9/10] Настроить безопасный SSH" lineinfile: path: /etc/ssh/sshd_config regexp: "^{{ item.regexp }}" @@ -496,275 +770,7 @@ - { regexp: "AllowUsers", line: "AllowUsers {{ deploy_user }}" } notify: reload ssh - - name: Переподключиться по новому SSH порту - meta: reset_connection - - - name: Удалить /home/prod, если требуется (чистое развертывание) - file: - path: "{{ project_root }}" - state: absent - when: recreate_project | bool - - - name: Создать директорию проекта /home/prod - file: - path: "{{ project_root }}" - state: directory - owner: "{{ deploy_user }}" - group: "{{ deploy_user }}" - mode: '0755' - - - name: Настроить SSH ключи для GitHub - authorized_key: - user: "{{ deploy_user }}" - key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" - state: present - - - name: Скопировать приватный SSH ключ для Git - copy: - src: "~/.ssh/id_rsa" - dest: "/home/{{ deploy_user }}/.ssh/id_rsa" - owner: "{{ deploy_user }}" - group: "{{ deploy_user }}" - mode: '0600' - remote_src: no - - - name: Настроить SSH config для GitHub - lineinfile: - path: "/home/{{ deploy_user }}/.ssh/config" - line: "Host github.com\n StrictHostKeyChecking no\n UserKnownHostsFile /dev/null" - create: yes - owner: "{{ deploy_user }}" - group: "{{ deploy_user }}" - mode: '0600' - - - name: Переключиться на пользователя deploy - meta: reset_connection - - - name: Клонировать основной репозиторий prod - git: - repo: git@github.com:KerradKerridi/prod.git - dest: "{{ project_root }}" - clone: yes - update: yes - become: yes - become_user: "{{ deploy_user }}" - - - name: Клонировать AnonBot - git: - repo: git@github.com:KerradKerridi/AnonBot.git - dest: "{{ project_root }}/bots/AnonBot" - clone: yes - update: yes - become: yes - become_user: "{{ deploy_user }}" - - - name: Клонировать telegram-helper-bot - git: - repo: git@github.com:KerradKerridi/telegram-helper-bot.git - dest: "{{ project_root }}/bots/telegram-helper-bot" - # TODO: Убрать после тестирования - version: dev-9 - clone: yes - update: yes - become: yes - become_user: "{{ deploy_user }}" - - - name: Установить правильные права на дашборд Node Exporter Full - file: - path: "{{ project_root }}/infra/grafana/provisioning/dashboards/node-exporter-full-dashboard.json" - owner: "{{ deploy_user }}" - group: "{{ deploy_user }}" - mode: '0644' - become: yes - become_user: "{{ deploy_user }}" - - - name: Скопировать SSH ключ на старый сервер для копирования файлов - authorized_key: - user: root - key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" - state: present - delegate_to: "{{ old_server }}" - - - name: Копировать .env для telegram-helper-bot со старого сервера - fetch: - src: "/home/prod/bots/telegram-helper-bot/.env" - dest: "/tmp/telegram-helper-bot.env" - flat: yes - delegate_to: "{{ old_server }}" - - - name: Переместить .env для telegram-helper-bot на новое место - copy: - src: "/tmp/telegram-helper-bot.env" - dest: "{{ project_root }}/bots/telegram-helper-bot/.env" - owner: "{{ deploy_user }}" - group: "{{ deploy_user }}" - mode: '0644' - become: yes - become_user: "{{ deploy_user }}" - - - name: Проверить размер БД для telegram-helper-bot - stat: - path: "/home/prod/bots/telegram-helper-bot/database/tg-bot-database.db" - delegate_to: "{{ old_server }}" - register: db_size - - - name: Показать размер БД для telegram-helper-bot - debug: - msg: "Размер БД: {{ (db_size.stat.size / 1024 / 1024) | round(2) }} MB" - - - name: Копировать БД для telegram-helper-bot - fetch: - src: "/home/prod/bots/telegram-helper-bot/database/tg-bot-database.db" - dest: "/tmp/tg-bot-database.db" - flat: yes - delegate_to: "{{ old_server }}" - - - name: Переместить БД для telegram-helper-bot на новое место - copy: - src: "/tmp/tg-bot-database.db" - dest: "{{ project_root }}/bots/telegram-helper-bot/database/tg-bot-database.db" - owner: "{{ deploy_user }}" - group: "{{ deploy_user }}" - mode: '0644' - become: yes - become_user: "{{ deploy_user }}" - - - name: Создать папку voice_users на новом сервере - file: - path: "{{ project_root }}/bots/telegram-helper-bot/voice_users" - state: directory - owner: "{{ deploy_user }}" - group: "{{ deploy_user }}" - mode: '0755' - become: yes - become_user: "{{ deploy_user }}" - - - name: Создать временную папку для voice_users на локальной машине - file: - path: "/tmp/voice_users_migration" - state: directory - mode: '0755' - delegate_to: localhost - become: no - - - name: Копировать voice_users со старого сервера на локальную машину - command: > - rsync -avz --progress --stats --partial --verbose - root@77.223.98.129:/home/prod/bots/telegram-helper-bot/voice_users/ - /tmp/voice_users_migration/ - delegate_to: localhost - become: no - - - name: Копировать voice_users с локальной машины на новый сервер - synchronize: - src: "/tmp/voice_users_migration/" - dest: "{{ project_root }}/bots/telegram-helper-bot/voice_users/" - mode: push - rsync_opts: "--progress --stats --partial --verbose" - become: yes - become_user: "{{ deploy_user }}" - - - name: Очистить временную папку на локальной машине - file: - path: "/tmp/voice_users_migration" - state: absent - delegate_to: localhost - become: no - - - name: Копировать корневой .env файл - fetch: - src: "/home/prod/.env" - dest: "/tmp/root.env" - flat: yes - delegate_to: "{{ old_server }}" - - - name: Переместить корневой .env файл на новое место - copy: - src: "/tmp/root.env" - dest: "{{ project_root }}/.env" - owner: "{{ deploy_user }}" - group: "{{ deploy_user }}" - mode: '0644' - become: yes - become_user: "{{ deploy_user }}" - - - - name: Копировать .env для AnonBot - fetch: - src: "/home/prod/bots/AnonBot/.env" - dest: "/tmp/anonbot.env" - flat: yes - delegate_to: "{{ old_server }}" - - - name: Переместить .env для AnonBot на новое место - copy: - src: "/tmp/anonbot.env" - dest: "{{ project_root }}/bots/AnonBot/.env" - owner: "{{ deploy_user }}" - group: "{{ deploy_user }}" - mode: '0644' - become: yes - become_user: "{{ deploy_user }}" - - - name: Проверить размер БД для AnonBot - stat: - path: "/home/prod/bots/AnonBot/database/anon_qna.db" - delegate_to: "{{ old_server }}" - register: anon_db_size - - - name: Показать размер БД для AnonBot - debug: - msg: "Размер БД AnonBot: {{ (anon_db_size.stat.size / 1024 / 1024) | round(2) }} MB" - - - name: Копировать БД для AnonBot - fetch: - src: "/home/prod/bots/AnonBot/database/anon_qna.db" - dest: "/tmp/anon_qna.db" - flat: yes - delegate_to: "{{ old_server }}" - - - name: Переместить БД для AnonBot на новое место - copy: - src: "/tmp/anon_qna.db" - dest: "{{ project_root }}/bots/AnonBot/database/anon_qna.db" - owner: "{{ deploy_user }}" - group: "{{ deploy_user }}" - mode: '0644' - become: yes - become_user: "{{ deploy_user }}" - - - name: Установить права на скопированные файлы - file: - path: "{{ item }}" - owner: "{{ deploy_user }}" - group: "{{ deploy_user }}" - mode: '0644' - loop: - - "{{ project_root }}/bots/telegram-helper-bot/.env" - - "{{ project_root }}/bots/telegram-helper-bot/database/tg-bot-database.db" - - "{{ project_root }}/bots/AnonBot/.env" - - "{{ project_root }}/bots/AnonBot/database/anon_qna.db" - become: yes - - - name: Исправить права доступа для voice_users (рекурсивно) - file: - path: "{{ project_root }}/bots/telegram-helper-bot/voice_users" - owner: "{{ deploy_user }}" - group: "{{ deploy_user }}" - mode: '0755' - recurse: yes - become: yes - - - name: Запустить ботов через make up - command: make up - args: - chdir: "{{ project_root }}" - become: yes - become_user: "{{ deploy_user }}" - tags: ["start_bots"] - - # --- НАСТРОЙКА FAIL2BAN --- - - name: Создать конфигурацию Fail2ban для SSH + - name: "[9/10] Создать конфигурацию Fail2ban для SSH" copy: content: | [sshd] @@ -780,7 +786,7 @@ group: root mode: '0644' - - name: Создать конфигурацию Fail2ban для Nginx + - name: "[9/10] Создать конфигурацию Fail2ban для Nginx" copy: content: | [nginx-http-auth] @@ -805,7 +811,7 @@ group: root mode: '0644' - - name: Создать конфигурацию Fail2ban для Docker + - name: "[9/10] Создать конфигурацию Fail2ban для Docker" copy: content: | [docker] @@ -821,90 +827,124 @@ group: root mode: '0644' - - name: Включить и запустить Fail2ban + - name: "[9/10] Включить и запустить Fail2ban" systemd: name: fail2ban enabled: yes state: started - - name: Проверить статус Fail2ban + - name: "[9/10] Проверить статус Fail2ban" command: fail2ban-client status register: fail2ban_status changed_when: false - - name: Показать статус Fail2ban + - name: "[9/10] Показать статус Fail2ban" debug: var: fail2ban_status.stdout_lines - # --- НОВОЕ: Проверка портов --- - - name: Пауза на 30 секунд — дать контейнерам запуститься - pause: - seconds: 30 + # ======================================== + # ЭТАП 10: ЗАПУСК ПРИЛОЖЕНИЙ И ПРОВЕРКИ (DEPLOY + ROOT) + # ======================================== + + - name: "[10/10] Запустить ботов через make up" + command: make up + args: + chdir: "{{ project_root }}" + become: yes + become_user: "{{ deploy_user }}" - - name: Проверить, что порт 8080 (Telegram Bot) открыт + - name: "[10/10] Пауза на 45 секунд — дать контейнерам запуститься" + pause: + seconds: 45 + + - name: "[10/10] Проверить конфигурацию nginx (после запуска контейнеров)" + command: nginx -t + register: nginx_config_test + changed_when: false + + - name: "[10/10] Показать результат проверки nginx" + debug: + var: nginx_config_test.stdout_lines + + - name: "[10/10] Запустить nginx (после запуска контейнеров)" + systemd: + name: nginx + state: started + + - name: "[10/10] Проверить статус nginx" + command: systemctl status nginx + register: nginx_status + changed_when: false + + - name: "[10/10] Показать статус nginx" + debug: + var: nginx_status.stdout_lines + + - name: "[10/10] Проверить, что порт 8080 (Telegram Bot) открыт" wait_for: port: 8080 host: "{{ ansible_host }}" timeout: 30 state: started - - name: Проверить, что порт 8081 (AnonBot) открыт + - name: "[10/10] Проверить, что порт 8081 (AnonBot) открыт" wait_for: port: 8081 host: "{{ ansible_host }}" timeout: 30 state: started - - name: Проверить, что порт 9090 (Prometheus) открыт + - name: "[10/10] Проверить, что порт 9090 (Prometheus) открыт" wait_for: port: 9090 host: "{{ ansible_host }}" timeout: 30 state: started - - name: Проверить, что порт 3000 (Grafana) открыт + - name: "[10/10] Проверить, что порт 3000 (Grafana) открыт" wait_for: port: 3000 host: "{{ ansible_host }}" timeout: 30 state: started - - name: Проверить, что порт 9100 (Node Exporter) открыт + - name: "[10/10] Проверить, что порт 9100 (Node Exporter) открыт" wait_for: port: 9100 host: "{{ ansible_host }}" timeout: 30 state: started - - name: Проверить, что порт 80 (Nginx HTTP) открыт + - name: "[10/10] Проверить, что порт 80 (Nginx HTTP) открыт" wait_for: port: 80 host: "{{ ansible_host }}" timeout: 30 state: started - - name: Проверить, что порт 443 (Nginx HTTPS) открыт + - name: "[10/10] Проверить, что порт 443 (Nginx HTTPS) открыт" wait_for: port: 443 host: "{{ ansible_host }}" timeout: 30 state: started - - name: Проверить, что порт 3001 (Uptime Kuma) открыт + - name: "[10/10] Проверить, что порт 3001 (Uptime Kuma) открыт" wait_for: port: 3001 host: "{{ ansible_host }}" timeout: 30 state: started - - name: Проверить, что порт 9093 (Alertmanager) открыт - wait_for: - port: 9093 - host: "{{ ansible_host }}" - timeout: 30 - state: started + # - name: "[10/10] Проверить, что порт 9093 (Alertmanager) открыт" + # wait_for: + # port: 9093 + # host: "{{ ansible_host }}" + # timeout: 30 + # state: started + # # Пропускаем проверку Alertmanager, так как есть проблемы с конфигурацией - - name: Проверить доступность Nginx + - name: "[10/10] Проверить доступность Nginx" uri: url: "http://{{ ansible_host }}/nginx-health" method: GET @@ -913,7 +953,7 @@ retries: 5 delay: 10 - - name: Проверить доступность Grafana через Nginx + - name: "[10/10] Проверить доступность Grafana через Nginx" uri: url: "https://{{ ansible_host }}/grafana/api/health" method: GET @@ -923,7 +963,7 @@ retries: 5 delay: 10 - - name: Проверить доступность Prometheus через Nginx + - name: "[10/10] Проверить доступность Prometheus через Nginx" uri: url: "https://{{ ansible_host }}/prometheus/-/healthy" method: GET @@ -933,7 +973,7 @@ retries: 5 delay: 10 - - name: Проверить доступность Grafana API + - name: "[10/10] Проверить доступность Grafana API" uri: url: "http://{{ ansible_host }}:3000/api/health" method: GET @@ -942,7 +982,7 @@ retries: 5 delay: 10 - - name: Проверить доступность Uptime Kuma через Nginx + - name: "[10/10] Проверить доступность Uptime Kuma через Nginx" uri: url: "https://{{ ansible_host }}/status" method: GET @@ -952,7 +992,7 @@ retries: 5 delay: 10 - - name: Проверить доступность Alertmanager через Nginx + - name: "[10/10] Проверить доступность Alertmanager через Nginx" uri: url: "https://{{ ansible_host }}/alertmanager/" method: GET @@ -962,14 +1002,16 @@ retries: 5 delay: 10 + - name: "[10/10] Переподключиться по новому SSH порту" + meta: reset_connection - - name: Закрыть старый SSH порт 22 в UFW (финальный шаг) + - name: "[10/10] Закрыть старый SSH порт 22 в UFW (финальный шаг)" ufw: rule: deny port: "22" proto: tcp - - name: Проверка запуска ботов завершена — всё работает 🟢 + - name: "[10/10] Проверка запуска ботов завершена — всё работает 🟢" debug: msg: "Все сервисы запущены и слушают нужные порты. SSH настроен на порт 15722, Fail2ban активен, параметры безопасности ядра применены. Порт 22 закрыт для безопасности. Добавлены: Uptime Kuma (статусная страница), Alertmanager (мониторинг), Let's Encrypt SSL, Grafana дашборды." diff --git a/infra/nginx/conf.d/alertmanager.conf b/infra/nginx/conf.d/alertmanager.conf index 4406026..98ac5c5 100644 --- a/infra/nginx/conf.d/alertmanager.conf +++ b/infra/nginx/conf.d/alertmanager.conf @@ -2,12 +2,12 @@ # Proxies requests to Alertmanager # Alertmanager location -location /alertmanager/ { +location /alerts/ { # Rate limiting limit_req zone=api burst=10 nodelay; # Remove trailing slash for proxy - rewrite ^/alertmanager/(.*)$ /$1 break; + rewrite ^/alerts/(.*)$ /$1 break; # Proxy to Alertmanager proxy_pass http://alertmanager_backend; diff --git a/infra/nginx/conf.d/grafana.conf b/infra/nginx/conf.d/grafana.conf index 166b8b5..4ad4931 100644 --- a/infra/nginx/conf.d/grafana.conf +++ b/infra/nginx/conf.d/grafana.conf @@ -1,6 +1,6 @@ # Grafana proxy configuration location /grafana/ { - proxy_pass http://grafana_backend/; + proxy_pass http://grafana_backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; diff --git a/infra/nginx/conf.d/status.conf b/infra/nginx/conf.d/status.conf deleted file mode 100644 index 13bcc62..0000000 --- a/infra/nginx/conf.d/status.conf +++ /dev/null @@ -1,43 +0,0 @@ -# Status page configuration (Uptime Kuma integration) - -# Rate limiting for status page -location /status { - # Rate limiting - limit_req zone=status burst=5 nodelay; - - # Proxy to Uptime Kuma - proxy_pass http://uptime_kuma_backend; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - - # WebSocket support - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - - # Timeouts - proxy_connect_timeout 30s; - proxy_send_timeout 30s; - proxy_read_timeout 30s; - - # Buffer settings - proxy_buffering on; - proxy_buffer_size 4k; - proxy_buffers 8 4k; - - # Security headers - add_header X-Frame-Options "SAMEORIGIN" always; - add_header X-Content-Type-Options "nosniff" always; -} - -# Nginx status stub (for monitoring) -location /nginx_status { - stub_status on; - access_log off; - allow 127.0.0.1; - allow 172.16.0.0/12; # Docker networks - allow 192.168.0.0/16; # Private networks - deny all; -} \ No newline at end of file diff --git a/infra/nginx/conf.d/uptime-kuma.conf b/infra/nginx/conf.d/uptime-kuma.conf index 7c77a1f..cd8afe3 100644 --- a/infra/nginx/conf.d/uptime-kuma.conf +++ b/infra/nginx/conf.d/uptime-kuma.conf @@ -1,12 +1,6 @@ # Uptime Kuma Nginx Configuration # Proxies requests to Uptime Kuma status page -# Upstream for Uptime Kuma -upstream uptime_kuma_backend { - server uptime-kuma:3001; - keepalive 32; -} - # Status page location location /status { # Rate limiting diff --git a/infra/nginx/nginx.conf b/infra/nginx/nginx.conf index aaffe7d..b346958 100644 --- a/infra/nginx/nginx.conf +++ b/infra/nginx/nginx.conf @@ -1,4 +1,4 @@ -user nginx; +user www-data; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; @@ -65,26 +65,27 @@ http { # Upstream configurations upstream grafana_backend { - server grafana:3000; + server localhost:3000; keepalive 32; } upstream prometheus_backend { - server prometheus:9090; + server localhost:9090; keepalive 32; } upstream uptime_kuma_backend { - server uptime-kuma:3001; + server localhost:3001; keepalive 32; } upstream alertmanager_backend { - server alertmanager:9093; + server localhost:9093; keepalive 32; } # Main server block + # Redirect HTTP to HTTPS server { listen 80; server_name _; @@ -96,8 +97,8 @@ http { server_name _; # SSL configuration (self-signed certificate) - ssl_certificate /etc/letsencrypt/live/{{SERVER_IP}}/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/{{SERVER_IP}}/privkey.pem;еще + ssl_certificate /etc/nginx/ssl/fullchain.pem; + ssl_certificate_key /etc/nginx/ssl/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384; ssl_prefer_server_ciphers off; @@ -108,9 +109,10 @@ http { add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; - # Redirect root to Grafana + # Root page - show simple status location = / { - return 301 /grafana/; + return 200 "Bot Infrastructure Status\n\nServices:\n- Grafana: /grafana/\n- Prometheus: /prometheus/\n- Uptime Kuma: /status/\n- Alertmanager: /alerts/\n"; + add_header Content-Type text/plain; } # Health check endpoint diff --git a/infra/prometheus/prometheus.yml b/infra/prometheus/prometheus.yml index fe9481b..9eb8da9 100644 --- a/infra/prometheus/prometheus.yml +++ b/infra/prometheus/prometheus.yml @@ -13,7 +13,7 @@ scrape_configs: # Job для мониторинга Node Exporter - job_name: 'node' static_configs: - - targets: ['172.17.0.1:9100'] # Специальное имя для доступа к хосту + - targets: ['172.20.0.1:9100'] # IP хоста в Docker сети bots_network labels: instance: 'main-server'