[{"content":"Вместо того чтобы форматировать флешку под каждый новый образ, Ventoy позволяет просто копировать ISO-файлы как обычные файлы. При загрузке вы получаете меню со всеми доступными образами.\nПреимущества:\n✅ Не нужно перезаписывать флешку для каждого образа ✅ Поддержка Windows, Linux, утилит - всё на одном носителе ✅ Обычные файлы доступны из любой ОС ✅ Гибкая настройка через JSON-конфиги 🗂 Правильная структура флешки [Первый раздел флешки - exFAT/NTFS] ├── /ventoy/ # ← Обязательно здесь! │ ├── ventoy.json # Главный конфиг │ ├── revi/ # Авто-установка Windows │ │ └── autounattend.xml │ └── theme/ # Кастомная тема │ └── distro/theme.txt │ ├── BACKUP/ # Рабочие файлы ├── LINUX/ # Образы Linux │ ├── Archlinux 2025.12.01.iso │ ├── Debian 13.2.0.iso │ └── NixOS 25.11.1734.iso ├── WINDOWS/ # Образы Windows │ ├── Windows 10 22H2.iso │ ├── Windows 10 Enterprise LTSC 2021.iso │ └── Windows 11 25H2.iso ├── ReviSetup/ # Скрипты пост-установки │ └── setup.cmd └── UTILS/ # Утилиты ├── gparted-live.iso └── memtest86+.iso ⚠️ Критично: /ventoy/ должна быть на первом разделе (том, где лежат ISO), не в корне!\n⚙️ Базовая конфигурация: ventoy.json Файл должен лежать в /ventoy/ventoy.json, кодировка UTF-8.\nМинимальный пример { \u0026#34;control\u0026#34;: [ { \u0026#34;VTOY_DEFAULT_MENU_MODE\u0026#34;: \u0026#34;1\u0026#34; }, { \u0026#34;VTOY_FILT_DOT_UNDERSCORE_FILE\u0026#34;: \u0026#34;1\u0026#34; } ], \u0026#34;theme\u0026#34;: { \u0026#34;file\u0026#34;: \u0026#34;/ventoy/theme/distro/theme.txt\u0026#34;, \u0026#34;gfxmode\u0026#34;: \u0026#34;1920x1080\u0026#34;, \u0026#34;resolution_fit\u0026#34;: \u0026#34;1\u0026#34; } } Параметр Описание VTOY_DEFAULT_MENU_MODE Режим меню по умолчанию VTOY_FILT_DOT_UNDERSCORE_FILE Скрывать файлы, начинающиеся с . и _ theme.file Путь к файлу темы GRUB gfxmode Разрешение меню resolution_fit Авто-подгонка под экран 🎨 Кастомизация: темы для меню Где взять темы distro-grub-themes - коллекция готовых тем для Ventoy Gnome-look.org - темы с тегом ventoy Своя тема - создайте по документации Ventoy Установка темы # Склонируйте тему cd /mnt/ventoy/ventoy/theme git clone https://github.com/AdisonCavani/distro-grub-themes.git distro # Или скачайте с Gnome-look wget https://www.gnome-look.org/.../theme.tar.gz tar xzf theme.tar.gz В ventoy.json укажите путь:\n{ \u0026#34;theme\u0026#34;: { \u0026#34;file\u0026#34;: \u0026#34;/ventoy/theme/distro/theme.txt\u0026#34;, \u0026#34;resolution_fit\u0026#34;: \u0026#34;1\u0026#34; } } 🪟 Авто-установка Windows Структура для автоустановки /ventoy/ └── revi/ └── autounattend.xml # Ответы для Windows Setup /ReviSetup/ └── setup.cmd # Пост-установка Пример ventoy.json для автоустановки { \u0026#34;auto_install\u0026#34;: [ { \u0026#34;parent\u0026#34;: \u0026#34;/WINDOWS\u0026#34;, \u0026#34;template\u0026#34;: [\u0026#34;/ventoy/revi/autounattend.xml\u0026#34;], \u0026#34;autosel\u0026#34;: 1 } ] } Параметр Значение parent Папка с образами Windows template Путь к autounattend.xml autosel Авто-выбор шаблона Что делает autounattend.xml Пропускает создание аккаунта Microsoft Отключает телеметрию Применяет настройки приватности Запускает setup.cmd после установки 💡 Готовые конфиги: meetrevision/ventoy-conf\n🛠 Пост-установка: setup.cmd Скрипт применяется автоматически после установки Windows.\nПример действий :: Отключение обновлений драйверов reg add \u0026#34;HKLM\\Software\\Policies\\Microsoft\\Windows\\DriverSearching\u0026#34; /v \u0026#34;SearchOrderConfig\u0026#34; /t REG_DWORD /d 0 /f :: Пауза обновлений до 2038 reg add \u0026#34;HKLM\\SOFTWARE\\Microsoft\\WindowsUpdate\\UX\\Settings\u0026#34; /v \u0026#34;PauseUpdatesExpiryTime\u0026#34; /t REG_SZ /d \u0026#34;2038-01-19T03:14:07Z\u0026#34; /f :: Отключение телеметрии reg add \u0026#34;HKLM\\Software\\Policies\\Microsoft\\Windows\\DataCollection\u0026#34; /v \u0026#34;AllowTelemetry\u0026#34; /t REG_DWORD /d 0 /f :: Запрет автоустановки Teams reg add \u0026#34;HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows\\Windows Chat\u0026#34; /v \u0026#34;ChatIcon\u0026#34; /t REG_DWORD /d 2 /f 🗂 Чеклист создания флешки Установил Ventoy через Ventoy2Disk.sh / .exe Создал /ventoy/ на первом разделе Положил ventoy.json в /ventoy/ (UTF-8) Скопировал образы в логические папки (LINUX/, WINDOWS/) (Опционально) Установил тему меню (Опционально) Настроил авто-установку Windows Проверил синтаксис JSON через json.cn Протестировал загрузку 🔧 Полезные команды # Проверка синтаксиса ventoy.json cat /ventoy/ventoy.json | jq . # В меню Ventoy: F5 - показать содержимое ventoy.json # Пересоздать раздел Ventoy (данные будут удалены!) sudo ./Ventoy2Disk.sh -i /dev/sdX 📚 Дополнительные возможности Ventoy поддерживает множество плагинов и расширений:\nPersistence - сохранение данных между перезагрузками Live-систем Memdisk - загрузка образов в RAM Auto install - автоматизация установки ОС Custom menu - свои пункты меню Injection - внедрение драйверов/файлов в образы 🔗 Документация: ventoy.net\n⚠️ Частые проблемы Симптом Решение ventoy.json не применяется Проверить путь: строго /ventoy/ventoy.json Тема не загружается Проверить кодировку (UTF-8) и путь в конфиге Автоустановка не работает Убедиться, что parent указывает на правильную папку Ошибка парсинга JSON Проверить синтаксис через онлайн-валидатор 🔐 Безопасность ✅ exFAT - доступ из любой ОС (но без шифрования) 🔐 Для конфиденциальных файлов: VeraCrypt-контейнер ✅ autounattend.xml и setup.cmd - текстовые файлы, не содержат паролей 🗂 Ссылки 🚀 Официальный сайт Ventoy 🎨 Коллекция тем 🎨 Темы на Gnome-look 🪟 Автоустановка Windows 📘 Документация плагинов ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/linux/ventoy-multiboot/","summary":"\u003cp\u003eВместо того чтобы форматировать флешку под каждый новый образ, \u003cstrong\u003eVentoy\u003c/strong\u003e позволяет просто копировать ISO-файлы как обычные файлы. При загрузке вы получаете меню со всеми доступными образами.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eПреимущества\u003c/strong\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e✅ Не нужно перезаписывать флешку для каждого образа\u003c/li\u003e\n\u003cli\u003e✅ Поддержка Windows, Linux, утилит - всё на одном носителе\u003c/li\u003e\n\u003cli\u003e✅ Обычные файлы доступны из любой ОС\u003c/li\u003e\n\u003cli\u003e✅ Гибкая настройка через JSON-конфиги\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch2 id=\"-правильная-структура-флешки\"\u003e🗂 Правильная структура флешки\u003c/h2\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e[Первый раздел флешки - exFAT/NTFS]\n├── /ventoy/                    # ← Обязательно здесь!\n│   ├── ventoy.json            # Главный конфиг\n│   ├── revi/                  # Авто-установка Windows\n│   │   └── autounattend.xml\n│   └── theme/                 # Кастомная тема\n│       └── distro/theme.txt\n│\n├── BACKUP/                    # Рабочие файлы\n├── LINUX/                     # Образы Linux\n│   ├── Archlinux 2025.12.01.iso\n│   ├── Debian 13.2.0.iso\n│   └── NixOS 25.11.1734.iso\n├── WINDOWS/                   # Образы Windows\n│   ├── Windows 10 22H2.iso\n│   ├── Windows 10 Enterprise LTSC 2021.iso\n│   └── Windows 11 25H2.iso\n├── ReviSetup/                 # Скрипты пост-установки\n│   └── setup.cmd\n└── UTILS/                     # Утилиты\n    ├── gparted-live.iso\n    └── memtest86+.iso\n\u003c/code\u003e\u003c/pre\u003e\u003cblockquote\u003e\n\u003cp\u003e⚠️ \u003cstrong\u003eКритично\u003c/strong\u003e: \u003ccode\u003e/ventoy/\u003c/code\u003e должна быть на \u003cstrong\u003eпервом разделе\u003c/strong\u003e (том, где лежат ISO), не в корне!\u003c/p\u003e","title":"Ventoy: Многозагрузочная флешка с правильной структурой"},{"content":" 📌 Это третья часть цикла. Часть 1: Теория, Часть 2: Практика.\n🔗 Что будем интегрировать Компонент Назначение Сложность ONEmesh MQTT Мост между локальной сетью и глобальной картой + уведомления в Telegram 🟢 Низкая Home Assistant Сенсоры нод, device_tracker, автоматизации на сообщения из сети 🟡 Средняя Уведомления Алерты о новых нодах, потере связи, упоминаниях в чате 🟢 Низкая 💡 Все примеры проверены на: HA 2026.4.2 (Docker) + Orange Pi 3B + встроенный MQTT-брокер.\n🌐 Шаг 1: Настройка MQTT в Meshtastic для ONEmesh Параметры подключения Параметр Значение Примечание MQTT Address mqtt.onemesh.ru Сервер сообщества Username onemesh По умолчанию Password onecat Общий для всех Root topic msh/RU/XXX XXX = код города (список) TLS enabled Yes Если не работает - попробуйте No JSON enabled Yes Обязательно для Home Assistant Uplink / Downlink Yes / No Для мониторинга достаточно только uplink ⚠️ Важно: в прошивке 2.5+ появилась поддержка нового формата ключей шифрования (PKI). Если используете шифрование - убедитесь, что ключи синхронизированы между нодами.\nКак проверить работу Включите JSON enabled в настройках MQTT Подключитесь к брокеру через mosquitto_sub или MQTT Explorer: mosquitto_sub -h mqtt.onemesh.ru -u onemesh -P onecat \\ -t \u0026#39;msh/RU/MOW/json/#\u0026#39; -v Вы увидите сообщения вида: { \u0026#34;id\u0026#34;: 452664778, \u0026#34;from\u0026#34;: 2130636288, \u0026#34;payload\u0026#34;: { \u0026#34;text\u0026#34;: \u0026#34;Привет из локальной сети!\u0026#34;, \u0026#34;battery_level\u0026#34;: 87, \u0026#34;voltage\u0026#34;: 4.12 }, \u0026#34;type\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;timestamp\u0026#34;: 1714234567 } 📬 Шаг 2: Уведомления в Telegram через ONEmesh Bot ONEmesh автоматически пересылает сообщения из вашей городской темы в приватный чат с ботом.\nПримеры уведомлений [26.04.2026 20:52] ONEmesh Bot: LF | qwrt (https://map.onemesh.ru/?node_id=483535916) QWRT Pocket 20, cтaндapт. a вoт для дoмaшнeй нoды aнтeннa тpиaдa SNR 4.75 RSSI -92 HopLimit 3 - данные от 44b4 (https://map.onemesh.ru/?node_id=49169588) Поле Что означает Зачем нужно SNR Signal-to-Noise Ratio Качество сигнала: чем выше, тем лучше RSSI Received Signal Strength Мощность сигнала: ближе к 0 = лучше HopLimit Оставшееся число прыжков Показывает, насколько далеко ушло сообщение Как настроить Найдите бота @ONEmeshBot в Telegram Отправьте /start - бот покажет инструкции Убедитесь, что ваша нода отправляет данные в MQTT с правильным root topic Готово: уведомления будут приходить автоматически 💡 Совет: если уведомления не приходят - проверьте, что OK to MQTT включено в настройках канала и нода имеет интернет-соединение.\n🏠 Шаг 3: Интеграция с Home Assistant Предварительные требования Встроенный MQTT-брокер в HA (Settings → Devices \u0026amp; Services → MQTT) Meshtastic-нода с включённым JSON enabled в MQTT Доступ к configuration.yaml и возможность создавать mqtt.yaml Шаг 3.1: Подключение MQTT в HA # configuration.yaml mqtt: !include mqtt.yaml # mqtt.yaml broker: core-mosquitto # или адрес вашего брокера port: 1883 username: homeassistant password: !secret mqtt_password # Если используете внешний брокер (например, ONEmesh): # broker: mqtt.onemesh.ru # port: 8883 # username: onemesh # password: onecat # certificate: /config/certs/ca.crt # для TLS Шаг 3.2: Создание сенсоров для ноды # mqtt.yaml - продолжение sensor: # Батарея ноды - name: \u0026#34;Meshtastic Node Battery\u0026#34; unique_id: \u0026#34;meshtastic_node_battery\u0026#34; state_topic: \u0026#34;msh/RU/MOW/json/LongFast/!abcd1234\u0026#34; value_template: \u0026gt;- {% if value_json.from == 2130636288 and value_json.payload.battery_level is defined %} {{ value_json.payload.battery_level | int }} {% else %} {{ this.state }} {% endif %} unit_of_measurement: \u0026#34;%\u0026#34; device_class: battery # Напряжение - name: \u0026#34;Meshtastic Node Voltage\u0026#34; unique_id: \u0026#34;meshtastic_node_voltage\u0026#34; state_topic: \u0026#34;msh/RU/MOW/json/LongFast/!abcd1234\u0026#34; value_template: \u0026gt;- {% if value_json.from == 2130636288 and value_json.payload.voltage is defined %} {{ value_json.payload.voltage | float | round(2) }} {% else %} {{ this.state }} {% endif %} unit_of_measurement: \u0026#34;V\u0026#34; device_class: voltage # Канал утилизации (загрузка эфира) - name: \u0026#34;Meshtastic Channel Utilization\u0026#34; unique_id: \u0026#34;meshtastic_chutil\u0026#34; state_topic: \u0026#34;msh/RU/MOW/json/LongFast/!abcd1234\u0026#34; value_template: \u0026gt;- {% if value_json.from == 2130636288 and value_json.payload.channel_utilization is defined %} {{ value_json.payload.channel_utilization | float | round(1) }} {% else %} {{ this.state }} {% endif %} unit_of_measurement: \u0026#34;%\u0026#34; 🔑 Важно: замените 2130636288 на десятичный from вашей ноды (найдите в MQTT Explorer или через meshtastic --info).\nШаг 3.3: Отслеживание местоположения (device_tracker) # automations.yaml - alias: \u0026#34;Meshtastic: Update node location\u0026#34; trigger: platform: mqtt topic: \u0026#34;msh/RU/MOW/json/LongFast/!abcd1234\u0026#34; value_template: \u0026gt;- {% if value_json.from == 2130636288 and value_json.payload.latitude_i is defined and value_json.payload.longitude_i is defined %}on{% endif %} action: service: device_tracker.see data: dev_id: \u0026#34;meshtastic_node_1\u0026#34; gps: - \u0026#34;{{ (trigger.payload_json.payload.latitude_i | int * 1e-7) }}\u0026#34; - \u0026#34;{{ (trigger.payload_json.payload.longitude_i | int * 1e-7) }}\u0026#34; battery: \u0026#34;{{ states(\u0026#39;sensor.meshtastic_node_battery\u0026#39;) | default(0) }}\u0026#34; 💡 Meshtastic хранит координаты в формате integer * 1e7, поэтому умножаем на 1e-7 для получения реальных значений.\nШаг 3.4: Уведомления о сообщениях из сети # automations.yaml - alias: \u0026#34;Meshtastic: Notify on mention\u0026#34; trigger: platform: mqtt topic: \u0026#34;msh/RU/MOW/json/LongFast/!abcd1234\u0026#34; value_template: \u0026gt;- {% if value_json.type == \u0026#34;text\u0026#34; and value_json.payload.text is defined and \u0026#34;ponf\u0026#34; in value_json.payload.text.lower() %}on{% endif %} action: service: notify.mobile_app_your_phone data: title: \u0026#34;📡 Meshtastic\u0026#34; message: \u0026#34;Упоминание: {{ trigger.payload_json.payload.text }}\u0026#34; data: priority: high 🔐 Безопасность: шифрование и ключи Что изменилось в прошивке 2.5+ Версия Тип ключей Особенности \u0026lt; 2.5 Единый PSK для канала Простая настройка, но уязвимо при компрометации ≥ 2.5 PKI + shared secret Отдельные ключи для шифрования и аутентификации Как настроить шифрование В приложении Meshtastic: Channel → Primary → PSK Включите шифрование Скопируйте ключ (он же AQ== для базового канала) В настройках MQTT: Encryption enabled → Yes Убедитесь, что все ноды в сети используют одинаковый ключ ⚠️ Критично: если ключи не совпадают - сообщения будут приходить, но не расшифровываться. Проверяйте через MQTT Explorer.\nГде хранить ключи ✅ В secrets.yaml Home Assistant (не коммитить в Git!) ✅ В менеджере паролей (Bitwarden, KeePassXC) ❌ Не в публичных репозиториях, не в логах, не в скриншотах ⚠️ Частые проблемы Симптом Причина Решение Сенсоры не обновляются Неверный from в value_template Найдите десятичный ID ноды через meshtastic --info Нет сообщений в Telegram Неправильный root topic Проверьте код города: msh/RU/MOW, msh/RU/SPB и т.д. Шифрование не работает Ключи не совпадают Скопируйте PSK точно, без пробелов, в обе ноды device_tracker не двигается Координаты в неверном формате Умножайте latitude_i/longitude_i на 1e-7 HA не подключается к брокеру Неверные учётные данные Проверьте username/password и порт (1883/8883) Ссылки 📡 Meshtastic MQTT Docs 🏠 HA Meshtastic Integration 🗺️ ONEmesh Map 🔐 Meshtastic Security Guide ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/mesh/integrations/","summary":"\u003cblockquote\u003e\n\u003cp\u003e📌 \u003cstrong\u003eЭто третья часть цикла\u003c/strong\u003e. \u003ca href=\"https://potatoenergy.gitverse.site/potatoenergy-site/blog/mesh/intro/\"\u003eЧасть 1: Теория\u003c/a\u003e, \u003ca href=\"https://potatoenergy.gitverse.site/potatoenergy-site/blog/mesh/practice/\"\u003eЧасть 2: Практика\u003c/a\u003e.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003chr\u003e\n\u003ch2 id=\"-что-будем-интегрировать\"\u003e🔗 Что будем интегрировать\u003c/h2\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eКомпонент\u003c/th\u003e\n          \u003cth\u003eНазначение\u003c/th\u003e\n          \u003cth\u003eСложность\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003eONEmesh MQTT\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eМост между локальной сетью и глобальной картой + уведомления в Telegram\u003c/td\u003e\n          \u003ctd\u003e🟢 Низкая\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003eHome Assistant\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eСенсоры нод, device_tracker, автоматизации на сообщения из сети\u003c/td\u003e\n          \u003ctd\u003e🟡 Средняя\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003eУведомления\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eАлерты о новых нодах, потере связи, упоминаниях в чате\u003c/td\u003e\n          \u003ctd\u003e🟢 Низкая\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cblockquote\u003e\n\u003cp\u003e💡 Все примеры проверены на: HA 2026.4.2 (Docker) + Orange Pi 3B + встроенный MQTT-брокер.\u003c/p\u003e","title":"Heltec V4: Интеграции. Home Assistant, Telegram, мониторинг. Часть 3"},{"content":"Home Assistant в Docker не видит Bluetooth-устройства, даже если на хосте всё работает.\nПричины:\n❌ Контейнер не имеет прямого доступа к /dev/hci0 ❌ BlueZ внутри контейнера конфликтует с демоном на хосте ❌ Пассивное сканирование BLE требует флага --experimental в BlueZ Решение: не запускать Bluetooth-стек внутри контейнера, а пробросить D-Bus с хоста.\n✅ Настройка Docker Compose Минимальная конфигурация services: home-assistant: container_name: home-assistant image: ghcr.io/home-assistant/home-assistant:stable volumes: - config:/config - /run/dbus:/run/dbus:ro # ← Критично для Bluetooth cap_add: - NET_ADMIN - NET_RAW - SYS_ADMIN restart: unless-stopped networks: - traefik - prometheus volumes: config: driver: local networks: traefik: external: true name: traefik prometheus: external: true name: prometheus ⚠️ Не добавляйте devices: - /dev/hci0:/dev/hci0 - это не нужно при пробросе D-Bus и может вызвать конфликт.\n🔧 Настройка BlueZ на хосте Включение экспериментального режима (для пассивного сканирования) Home Assistant использует пассивное сканирование BLE, которое требует запуска bluetoothd с флагом --experimental.\n# 1. Создайте оверлей для systemd sudo systemctl edit bluetooth # 2. Вставьте: [Service] ExecStart= ExecStart=/usr/lib/bluetooth/bluetoothd --experimental # 3. Примените и перезапустите sudo systemctl daemon-reload sudo systemctl restart bluetooth # 4. Проверьте, что флаг применён ps aux | grep bluetoothd # Ожидаемо: /usr/lib/bluetooth/bluetoothd --experimental 💡 Почему это нужно: пассивное сканирование не отправляет активные запросы, что экономит батарею устройств. Но эта функция в BlueZ помечена как «экспериментальная».\n🔗 Сопряжение устройств (на хосте!) Управляйте Bluetooth только на хосте, не внутри контейнера.\n# 1. Включите адаптер sudo bluetoothctl power on # 2. Запустите сканирование sudo bluetoothctl scan on # 3. Когда устройство появится (например, Meshtastic_XXXX): sudo bluetoothctl pair AA:BB:CC:DD:EE:FF sudo bluetoothctl trust AA:BB:CC:DD:EE:FF sudo bluetoothctl connect AA:BB:CC:DD:EE:FF ✅ После сопряжения на хосте, Home Assistant увидит устройство через проброшенный D-Bus.\n⚙️ Интеграция в Home Assistant Установка интеграции Установите Meshtastic через HACS (или другую нужную интеграцию) Перезапустите HA: docker compose restart home-assistant Настройки → Интеграции → Добавить интеграцию → [Название] Устройство должно появиться в списке обнаруженных (по имени или адресу) Если устройство не обнаруживается # Проверьте на хосте: - Устройство спарено? `bluetoothctl paired-devices` - Адаптер не заблокирован? `rfkill list` - BlueZ запущен с --experimental? `ps aux | grep bluetoothd` # В Home Assistant: - Перезагрузите интеграцию: Настройки → Система → Перезагрузить - Проверьте логи: Настройки → Система → Логи → поиск \u0026#34;bluetooth\u0026#34; ⚠️ Частые проблемы Симптом Причина Решение Unable to open mgmt_socket в контейнере Конфликт демонов Не запускайте bluetoothctl внутри контейнера Устройство не появляется в скане Не включено сопряжение на устройстве В приложении устройства: включить режим сопряжения Error.Busy при включении питания hciattach держит устройство Убрать флаг -n в сервисе инициализации Пассивное сканирование не работает BlueZ без --experimental Добавить флаг в ExecStart и перезапустить Ссылки 🏠 Home Assistant Bluetooth Docs 📘 BlueZ Experimental Features 🐙 Meshtastic HA Integration 🐳 Docker Bind Mounts ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/home-assistant/bluetooth-docker/","summary":"\u003cp\u003eHome Assistant в Docker не видит Bluetooth-устройства, даже если на хосте всё работает.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eПричины\u003c/strong\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e❌ Контейнер не имеет прямого доступа к \u003ccode\u003e/dev/hci0\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e❌ BlueZ внутри контейнера конфликтует с демоном на хосте\u003c/li\u003e\n\u003cli\u003e❌ Пассивное сканирование BLE требует флага \u003ccode\u003e--experimental\u003c/code\u003e в BlueZ\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eРешение\u003c/strong\u003e: не запускать Bluetooth-стек внутри контейнера, а пробросить D-Bus с хоста.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"-настройка-docker-compose\"\u003e✅ Настройка Docker Compose\u003c/h2\u003e\n\u003ch3 id=\"минимальная-конфигурация\"\u003eМинимальная конфигурация\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-yaml\" data-lang=\"yaml\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003eservices\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003ehome-assistant\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"nt\"\u003econtainer_name\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"l\"\u003ehome-assistant\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"nt\"\u003eimage\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"l\"\u003eghcr.io/home-assistant/home-assistant:stable\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"nt\"\u003evolumes\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e- \u003cspan class=\"l\"\u003econfig:/config\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e- \u003cspan class=\"l\"\u003e/run/dbus:/run/dbus:ro\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c\"\u003e# ← Критично для Bluetooth\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"nt\"\u003ecap_add\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e- \u003cspan class=\"l\"\u003eNET_ADMIN\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e- \u003cspan class=\"l\"\u003eNET_RAW\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e- \u003cspan class=\"l\"\u003eSYS_ADMIN\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"nt\"\u003erestart\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"l\"\u003eunless-stopped\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"nt\"\u003enetworks\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e- \u003cspan class=\"l\"\u003etraefik\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e- \u003cspan class=\"l\"\u003eprometheus\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003evolumes\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003econfig\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"nt\"\u003edriver\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"l\"\u003elocal\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003enetworks\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003etraefik\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"nt\"\u003eexternal\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"nt\"\u003ename\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"l\"\u003etraefik\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"nt\"\u003eprometheus\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"nt\"\u003eexternal\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"nt\"\u003ename\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"l\"\u003eprometheus\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cblockquote\u003e\n\u003cp\u003e⚠️ \u003cstrong\u003eНе добавляйте \u003ccode\u003edevices: - /dev/hci0:/dev/hci0\u003c/code\u003e\u003c/strong\u003e - это не нужно при пробросе D-Bus и может вызвать конфликт.\u003c/p\u003e","title":"Home Assistant + Docker: Bluetooth для обнаружения устройств"},{"content":"На Orange Pi 3B встроенный Bluetooth-чип Spreadtrum UWE5622 подключён через UART (/dev/ttyBT0). В отличие от USB-адаптеров, он требует:\nЗагрузки прошивки и калибровочных данных перед инициализацией Запуска hciattach_opi с правильными флагами Корректного порядка запуска: сначала инициализация чипа, потом демон BlueZ Симптомы:\nbluetoothctl scan on → No default controller available btmgmt info → Index list with 0 items hciconfig -a показывает hci0, но bluetoothctl его не видит Ошибка org.bluez.Error.Busy при попытке включить питание Причина: сервис orangepi3b-sprd-bluetooth.service запускает hciattach_opi с флагом -n (no-detach), который удерживает устройство, не давая BlueZ зарегистрировать контроллер.\n✅ Решение: два шага Шаг 1: Установите недостающие утилиты sudo apt update sudo apt install -y rfkill bluez rfkill нужен для разблокировки адаптера, bluez - сам стек Bluetooth.\nШаг 2: Исправьте сервис инициализации Вариант А: Быстрый фикс (вручную) # 1. Остановите всё sudo systemctl stop orangepi3b-sprd-bluetooth sudo systemctl stop bluetooth sudo killall -9 hciattach_opi 2\u0026gt;/dev/null sleep 2 # 2. Загрузите драйверы и разблокируйте адаптер sudo modprobe -a sprdbt_tty sprdwl_ng sudo rfkill unblock all # 3. Запустите инициализацию БЕЗ флага -n (hciattach отцепится сам) sudo /usr/bin/hciattach_opi -s 1500000 /dev/ttyBT0 sprd # ← Процесс завершится через 2-3 секунды, если чип ответил # 4. Запустите BlueZ - он подхватит готовый hci0 sudo systemctl start bluetooth sleep 2 # 5. Проверка btmgmt info # Ожидаемо: Index list with 1 item, hci0: Primary controller sudo bluetoothctl power on sudo bluetoothctl scan on # Ожидаемо: Changing power on succeeded, устройство появится в скане Вариант Б: Постоянный фикс (через systemd) # 1. Откройте сервис для редактирования sudo systemctl edit orangepi3b-sprd-bluetooth # 2. Переопределите ExecStart (уберите -n): [Service] ExecStart= ExecStart=/usr/bin/hciattach_opi -s 1500000 /dev/ttyBT0 sprd # 3. Примените и перезапустите sudo systemctl daemon-reload sudo systemctl restart orangepi3b-sprd-bluetooth sudo systemctl restart bluetooth # 4. Проверка btmgmt info sudo bluetoothctl power on sudo bluetoothctl scan on 💡 Почему -n ломает: флаг no-detach заставляет hciattach оставаться в фоне и удерживать UART. BlueZ не может зарегистрировать контроллер, потому что устройство уже занято.\n🔧 Если не работает: диагностика # Проверить, видит ли ядро чип dmesg | grep -iE \u0026#34;ttyBT|sprd|uwe5622\u0026#34; # Проверить, загружены ли драйверы lsmod | grep -iE \u0026#34;sprd|bt\u0026#34; # Проверить блокировки rfkill list # Если Soft blocked: yes → sudo rfkill unblock bluetooth # Проверить, запущен ли bluetoothd с нужными флагами ps aux | grep bluetoothd # Для пассивного сканирования (нужно для HA) требуется: --experimental # Проверить права на устройство ls -l /dev/hci0 /dev/ttyBT0 # Должно быть: root:bluetooth, права 660 🐳 Для Docker: проброс в контейнер Если вы запускаете Home Assistant или другое приложение в Docker:\nservices: home-assistant: volumes: - /run/dbus:/run/dbus:ro # ← Обязательно для доступа к Bluetooth # Не запускайте bluetoothctl внутри контейнера! # Управляйте сопряжением на хосте, приложение подхватит через D-Bus ⚠️ Не используйте network_mode: host только ради Bluetooth - это ломает сетевую изоляцию. Проброса /run/dbus достаточно.\nСсылки 🍊 Orange Pi 3B Wiki 📘 BlueZ Documentation 🔧 hciattach Source 🐙 Meshtastic Docs ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/linux/orangepi/orangepi3b-bluetooth/","summary":"\u003cp\u003eНа Orange Pi 3B встроенный Bluetooth-чип \u003cstrong\u003eSpreadtrum UWE5622\u003c/strong\u003e подключён через UART (\u003ccode\u003e/dev/ttyBT0\u003c/code\u003e). В отличие от USB-адаптеров, он требует:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eЗагрузки прошивки и калибровочных данных перед инициализацией\u003c/li\u003e\n\u003cli\u003eЗапуска \u003ccode\u003ehciattach_opi\u003c/code\u003e с правильными флагами\u003c/li\u003e\n\u003cli\u003eКорректного порядка запуска: сначала инициализация чипа, потом демон BlueZ\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eСимптомы\u003c/strong\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003ebluetoothctl scan on\u003c/code\u003e → \u003ccode\u003eNo default controller available\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ebtmgmt info\u003c/code\u003e → \u003ccode\u003eIndex list with 0 items\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ehciconfig -a\u003c/code\u003e показывает \u003ccode\u003ehci0\u003c/code\u003e, но \u003ccode\u003ebluetoothctl\u003c/code\u003e его не видит\u003c/li\u003e\n\u003cli\u003eОшибка \u003ccode\u003eorg.bluez.Error.Busy\u003c/code\u003e при попытке включить питание\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eПричина\u003c/strong\u003e: сервис \u003ccode\u003eorangepi3b-sprd-bluetooth.service\u003c/code\u003e запускает \u003ccode\u003ehciattach_opi\u003c/code\u003e с флагом \u003ccode\u003e-n\u003c/code\u003e (no-detach), который удерживает устройство, не давая BlueZ зарегистрировать контроллер.\u003c/p\u003e","title":"Orange Pi 3B: Включаем Bluetooth (Spreadtrum UWE5622)"},{"content":"Домашняя зона (zone.home) - основа для:\n✅ Детекции присутствия (автоматизации «пришёл/ушёл») ✅ Расчёта времени восхода/заката (освещение, шторы) ✅ Прогноза погоды (привязка к координатам) ✅ Геозон для устройств и пользователей Неточные координаты = ложные срабатывания, неверный прогноз, сбои автоматизаций.\n🎯 Проблема стандартного мастера При первой настройке Home Assistant предлагает выбрать локацию на карте. Но:\n❌ Нет ручного ввода координат в мастере ❌ Автоопределение по IP часто даёт погрешность 1–10 км ❌ Высота над уровнем моря не запрашивается Решение: настроить точные координаты после установки, через UI или YAML.\n🔧 Способ 1: Через UI (после установки) Шаг 1: Получить точные координаты Используйте устройство с GPS (телефон с приложением Home Assistant):\nУстановите официальное приложение Дайте разрешение на точное местоположение Включите датчик device_tracker.\u0026lt;device\u0026gt; в настройках приложения Откройте Developer Tools → States в веб-интерфейсе Найдите сущность device_tracker.\u0026lt;your_device\u0026gt; Скопируйте атрибуты: latitude, longitude, altitude Шаг 2: Обновить домашнюю зону Settings → Areas, labels \u0026amp; zones → Zones Откройте home Вставьте координаты в поля Latitude / Longitude Сохраните Шаг 3: Задать высоту Settings → System → General Заполните Elevation above sea level (в метрах) Сохраните 💡 Радиус зоны: по умолчанию 100 м. Увеличьте до 200–500 м, если дом в частном секторе или есть погрешность GPS.\n⚙️ Способ 2: Через YAML (для продвинутых) Добавьте в configuration.yaml:\nhomeassistant: name: Home latitude: 55.7558 # ← пример, замените на свои longitude: 37.6173 # ← пример, замените на свои elevation: 156 # высота в метрах radius: 200 # радиус зоны в метрах unit_system: metric time_zone: \u0026#34;Europe/Moscow\u0026#34; country: \u0026#34;RU\u0026#34; currency: \u0026#34;RUB\u0026#34; Важно:\nПосле изменения configuration.yaml выполните Check Configuration и Restart Если координаты заданы в YAML, поля в UI станут недоступны для редактирования 🔄 Альтернатива: действие homeassistant.set_location Для динамического обновления (например, из автоматизации):\nautomation: - alias: \u0026#34;Update home location\u0026#34; trigger: platform: time_pattern minutes: \u0026#34;/30\u0026#34; # каждые 30 минут action: - action: homeassistant.set_location data: latitude: \u0026#34;{{ states(\u0026#39;sensor.gps_latitude\u0026#39;) }}\u0026#34; longitude: \u0026#34;{{ states(\u0026#39;sensor.gps_longitude\u0026#39;) }}\u0026#34; elevation: \u0026#34;{{ states(\u0026#39;sensor.gps_altitude\u0026#39;) }}\u0026#34; ⚠️ Используйте с осторожностью: частое обновление локации может нарушить работу автоматизаций присутствия.\n⚠️ Частые проблемы # \u0026#34;Away\u0026#34; не меняется на \u0026#34;Home\u0026#34; при возвращении → Проверьте радиус зоны: увеличьте до 300–500 м → Убедитесь, что `device_tracker` обновляется (интервал, мин. расстояние) # Неверное время восхода/заката → Проверьте `elevation` и `time_zone` в настройках → Перезагрузите интеграцию `sun` # Координаты не сохраняются в UI → Возможно, они заданы в `configuration.yaml` - редактируйте только там Ссылки 🏠 Home Assistant Location Docs 📍 Zone Configuration 📱 Companion App Location Tracking 🗺️ Get Coordinates (OpenStreetMap) ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/home-assistant/location-config/","summary":"\u003cp\u003eДомашняя зона (\u003ccode\u003ezone.home\u003c/code\u003e) - основа для:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e✅ Детекции присутствия (автоматизации «пришёл/ушёл»)\u003c/li\u003e\n\u003cli\u003e✅ Расчёта времени восхода/заката (освещение, шторы)\u003c/li\u003e\n\u003cli\u003e✅ Прогноза погоды (привязка к координатам)\u003c/li\u003e\n\u003cli\u003e✅ Геозон для устройств и пользователей\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eНеточные координаты = ложные срабатывания, неверный прогноз, сбои автоматизаций.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"-проблема-стандартного-мастера\"\u003e🎯 Проблема стандартного мастера\u003c/h2\u003e\n\u003cp\u003eПри первой настройке Home Assistant предлагает выбрать локацию на карте. Но:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e❌ Нет ручного ввода координат в мастере\u003c/li\u003e\n\u003cli\u003e❌ Автоопределение по IP часто даёт погрешность 1–10 км\u003c/li\u003e\n\u003cli\u003e❌ Высота над уровнем моря не запрашивается\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eРешение\u003c/strong\u003e: настроить точные координаты после установки, через UI или YAML.\u003c/p\u003e","title":"Home Assistant: Точная настройка домашней локации"},{"content":" 📌 Это вторая часть цикла. Часть 1: Теория объясняет, зачем это нужно.\n📦 Распаковка и подготовка Комплектация Heltec V4 Компонент Назначение Плата ~60×30 мм ESP32-S3R2 + SX1262, OLED 128×64, USB-C Антенна (IPEX) Подключается к разъёму ANT - обязательно! Кабель USB-C Питание + прошивка + отладка Пины (опционально) Для подключения внешних датчиков/антенн ⚠️ Важно: без подключённой антенны радиомодуль может выйти из строя. Всегда подключайте антенну перед подачей питания.\nХарактеристики Heltec V4 Компонент Описание MCU ESP32-S3R2 (WiFi + Bluetooth) LoRa Transceiver Semtech SX1262 Частоты 863–870 МГц (EU), 902–928 МГц (US) Дисплей 0.96\u0026quot; OLED 128×64 Мощность До +28±1 dBm (High Power option) Питание USB-C + оптимизированное управление LiPo Разъёмы USB-C, U.FL/IPEX для LoRa, 1.25-8Pin GNSS, 1.25-2Pin Solar Форм-фактор Совместим с V3/V3.1 по пинам ⚡ Прошивка: веб-флешер Официальный флешер: https://flasher.meshtastic.org\nТребования Требование Почему Chromium-браузер (Chrome, Edge, Brave) Web Serial API работает только в них Доступ к COM-портам В Linux - права пользователя на dialout Отключённая батарея На время прошивки - только питание по USB 🐧 Linux: права на последовательный порт Если при подключении видите:\n[09:52:42.841] Serial: serial_io_handler.cc:157 Failed to open serial port: FILE_ERROR_ACCESS_DENIED Решение:\n# Добавить пользователя в группу dialout sudo usermod -a -G dialout $USER # Применить изменения (выйти и зайти снова, или) newgrp dialout # Проверить доступ ls -l /dev/ttyUSB* # или /dev/ttyACM* 🔧 Процесс прошивки Отключите батарею и USB от платы Откройте веб-флешер, выберите: Device: Heltec V4 Firmware: 2.7.21 (или новее стабильный/бета) Вариант: Full erase and install Нажмите Erase Flash and Install Зажмите кнопку PRG на плате Не отпуская PRG, подключите USB-кабель Наблюдайте: краткая красная вспышка → в выпадающем списке порта появится USB JTAG Отпустите PRG, выберите USB JTAG, нажмите Connect Дождитесь окончания прошивки (терминал покажет прогресс) После сообщения Leaving... нажмите кнопку RST (сброс) 💡 Если флешер не видит порт - попробуйте другой кабель (не все кабели поддерживают данные), другой порт USB, или перезапустите браузер.\n🔌 Первое подключение: три способа После прошивки плата перезагрузится и запустит Meshtastic.\nВарианты подключения к ноде Интерфейс Как подключиться Когда использовать Bluetooth Приложение Meshtastic (Android/iOS) → поиск устройств Переносная нода, одно активное подключение Wi-Fi Нода создаёт AP → подключитесь к вашей сети → IP отображается на экране Стационарная нода, несколько устройств одновременно USB/COM Подключение через терминал (PuTTY, screen) Домашняя нода, отладка, прямой доступ ⚠️ Bluetooth: только одно активное подключение.\nWi-Fi: можно подключить несколько устройств одновременно (удобно для стационарных нод).\nUSB: надёжно для настройки и отладки, не требует беспроводного подключения.\nНастройка через приложение на смартфоне (рекомендуется) Установите Meshtastic (Android) или iOS-версию Запустите, дайте разрешения на локацию и Bluetooth Перейдите на вкладку «Устройства» (иконка роутера) → выберите тип подключения (Bluetooth, Wi-Fi или COM-порт), в зависимости от режима ноды (по умолчанию - Bluetooth) → нажмите 🔍 Сканирование или + Добавить Подтвердите сопряжение Альтернативные варианты настройки На экране ноды отобразится IP-адрес (обычно 192.168.1.x) Подключитесь к Wi-Fi сети ноды (пароль отображается на экране) Откройте в браузере http://\u0026lt;IP_адрес_ноды\u0026gt; Через веб-интерфейс можно просматривать данные (например, JSON-сообщения), но настройка ноды не выполняется здесь. Для конфигурации используйте: Приложение Meshtastic Приложение MeshApp CLI через Python (meshtastic), подключаясь по USB, BLE или Wi-Fi 💡 IP-адрес: нода получает адрес от вашего роутера (не 192.168.4.1!). Точный адрес отображается на OLED-экране устройства.\n👤 Настройка пользователя (User) Основные параметры Параметр Значение Примечание Long Name [PE] ponfertato Полное имя ноды, видно всем в сети (до 20 символов, можно кириллицу) Short Name ponf Короткий идентификатор в сообщениях (строго 4 символа, латиница) Role CLIENT или CLIENT_MUTE Для городов с \u0026gt;200 нод - CLIENT_MUTE (безопасный режим без ретрансляции чужих пакетов) Is Licensed (HAM) Нет Если Да - отключите шифрование в MQTT (требования регулятора) 💡 ShortName: ровно 4 символа! Это отображается в заголовках сообщений. Примеры: ponf, KST1, MOW2.\nДополнительные флаги (опционально) Параметр Значение Зачем Show on map Да Разрешить отображение на публичных картах (управляется через MQTT) Ignore location requests Нет Отвечать на запросы координат от других нод Продвинутые настройки пользователя Параметр Значение Примечание Public Key (автогенерация) Не менять вручную; используется для шифрования Private Key (хранить в секрете) Экспортировать и сохранить при первой настройке Admin Key (пусто) Заполнять только при удалённом управлении нодой Managed Mode Нет Не включать без настроенного Remote Admin 🌐 Настройка MQTT для ONEmesh (RU) ONEmesh - карта устройств Meshtastic в России. Подключение к их MQTT-серверу позволяет вашей ноде отображаться на карте и обмениваться данными с другими участниками.\n🔐 Что передаётся через MQTT: текстовые сообщения, метрики устройства (батарея, сигнал), местоположение (если включено). Данные попадают на карту и в региональные чаты Telegram согласно настройкам города.\nОсновные параметры Параметр Значение Примечание MQTT Address mqtt.onemesh.ru Сервер сообщества (домен, не IP) Port 8883 (TLS) / 1883 (без TLS) Порт выбирается автоматически при включении TLS Username onemesh По умолчанию; onemeshz / onemeshd - для downlink Password onecat Общий для всех участников проекта Encryption enabled Да Шифрование трафика в MQTT; требует PSK: AQ== в канале JSON enabled Нет Не нужно для карты, создаёт лишнюю нагрузку TLS enabled Да Шифрование соединения; если ошибки - попробуйте Нет + порт 1883 Root topic msh/RU/KST KST = код города Кострома (список кодов) Proxy to client Да (Bluetooth) / Нет (Wi-Fi) При прямом Wi-Fi прокси не нужен Map reports Да Разрешить отправку отчётов для отображения на карте I agree Да Подтверждение правил передачи геоданных Precision 729 m Точность координат на публичной карте (~15 бит) Map report interval 3600 s (1 час) Минимальный интервал отправки отчётов 💡 Совет: если кнопка «Сохранить» неактивна - заполняйте настройки поэтапно: сначала базовые (адрес, логин, пароль), потом карту, потом дополнительные опции.\nРежимы имён пользователя Username Downlink Когда использовать onemesh ❌ Отключён Большинству пользователей - безопасный режим, только uplink onemeshz ✅ Zero-hop Если нужно получать данные из интернета, но не ретранслировать их по радио (политика нулевого хопа) onemeshd ✅ Полный Только для интеграций, соединения сегментов сети; не рекомендуется для обычных нод - создаёт нагрузку на эфир ⚠️ Использование onemeshd с включённым Downlink может перегрузить локальную сеть пакетами из интернета. Используйте осознанно и только при понимании последствий.\nПродвинутые параметры MQTT Параметр Значение Примечание Connection Retry Interval 30 сек Как часто пытаться переподключиться при обрыве Keepalive Interval 60 сек Интервал проверки живости соединения QoS Level 0 Quality of Service: 0 = fire-and-forget (оптимально для Meshtastic) Retain Messages Нет Не сохранять последние сообщения на брокере Topic Filter msh/RU/KST/# Подписка на подтопики (для интеграций) Частые проблемы с MQTT Симптом Возможная причина Решение Connection refused Неверный логин/пароль или порт Проверить onemesh/onecat, порт 8883 с TLS TLS handshake failed Проблема с сертификатами или временем Проверить синхронизацию времени (NTP), временно отключить TLS для теста No messages on map Неверный Root topic или PSK Убедиться: msh/RU/KST, канал с PSK: AQ== MQTT disconnected Нестабильный интернет на ноде/телефоне Проверить соединение, увеличить Map report interval Message not appearing Downlink отключён на сервере для onemesh Использовать onemeshz если нужен downlink 📡 Настройка LoRa и каналов Раздел LoRa Параметр Значение Зачем Region Russia Автоматически задаёт частоту 433 МГц, мощность ≤20 dBm и корневую тему MQTT Modem Preset LongFast Баланс дальности и скорости для городских условий Frequency Slot 2 Публичный интервал для RU868 (избегать конфликтов) Transmit Power 20 dBm Максимальная разрешённая мощность для любительской связи в РФ Boosted RX Gain Вкл Улучшает приём слабых сигналов (критично для городской застройки) Hop Limit 5 Максимальное число прыжков; достаточно для города, не перегружает эфир Ignore MQTT Нет Принимать пакеты, пришедшие через интернет (от соседей с MQTT) OK to MQTT Да ⚠️ Критично: разрешает соседям ретранслировать ваши данные на карту OneMesh Продвинутые параметры LoRa Параметр Значение Примечание Bandwidth 250 kHz Ширина канала; не менять при использовании пресетов Spreading Factor 11 Фактор расширения; выше = дальше, но медленнее Coding Rate 5 (4/5) Коррекция ошибок; баланс надёжности/скорости Frequency Offset 0.0 Hz Коррекция частоты кристалла; менять только при калибровке Override Duty Cycle Нет Не переопределять ограничения по времени в эфире SX126x RX Boosted Gain Вкл Аппаратное усиление приёма на SX1262 Каналы (Channels) - детально Настройте основной канал (Primary, индекс 0):\nПараметр Значение Примечание Role Primary Только один канал может быть первичным; через него идёт телеметрия устройства Name LongFast Точно так: публичная сеть фильтрует пакеты по этому имени PSK AQ== Базовый ключ шифрования для OneMesh (128 бит); обязателен при включённом шифровании в MQTT Uplink enabled Да Отправлять данные с этого канала на MQTT-сервер Downlink enabled Нет Не получать данные из MQTT (если не используете onemeshz/onemeshd) Position enabled Да Передавать координаты через этот канал Precise location Нет Скрывать точные координаты от других нод в канале Precision 182 m Точность позиции, передаваемой в канале (~17 бит) Muted Нет Не заглушать канал (иначе сообщения не будут видны) Вторичный канал (опционально, индекс 1) Параметр Значение Примечание Role Secondary Дополнительный канал для приватных групп или ботов Name [PE] Backup Любое имя \u0026lt;12 байт (латиница) PSK (сгенерировать свой) Приватный ключ для своей группы Uplink / Downlink Нет Не отправлять в публичный MQTT Position Нет Не передавать координаты в приватный канал Precision 45 m Максимальная точность для приватного использования ✅ Важно: хотя бы один канал должен иметь PSK: AQ== или быть без шифрования, чтобы сервер OneMesh принял пакеты.\n💡 Вторичные каналы создаются через + в приложении. Они не мешают основному трафику и полезны для приватного общения.\nУправление каналами: советы Порядок каналов: Primary должен быть первым (индекс 0) - через него идёт системная телеметрия. Имена каналов: используйте латиницу, без пробелов и спецсимволов. PSK длины: поддерживаются 0 (нет шифрования), 8, 128, 256 бит. OneMesh требует AQ== (8 бит). Экспорт/импорт: настройки каналов можно экспортировать в JSON для быстрого развёртывания на других нодах. 📍 Местоположение (Position) Фиксированные координаты (для стационарных нод) Параметр Значение Рекомендация Fixed position Включено Для нод без GPS-модуля Latitude 57.742 Широта Костромы, без лишних нулей (вводить как 57.742, не 57.742000) Longitude 40.978 Долгота Костромы, аналогично Altitude 100 Высота над уровнем моря (примерно, в метрах) 💡 Координаты хранятся как integer × 1e7. В приложении вводите с 6 знаками после запятой.\nПакет позиции - интервалы и точность Параметр Значение Зачем Position broadcast interval 7200 s (2 часа) Баланс между актуальностью на карте и нагрузкой на эфир Smart position Нет Фиксированный интервал надёжнее для стационарной ноды Smart position min distance 100 m Мин. расстояние для отправки при включённой умной рассылке Smart position min interval 300 s Мин. интервал для умной рассылки Position flags ALTITUDE + TIMESTAMP Передавать только высоту и метку времени (меньше трафика) Provide location to network Да Разрешить передачу координат в сеть (управляется через OK to MQTT) Продвинутые настройки позиции Параметр Значение Примечание GPS Enabled Нет Отключить, если нет модуля; экономит питание GPS Update Interval 60 сек Как часто опрашивать GPS (если включён) GPS Attempt Time 0 Не ограничивать время поиска спутников RX/TX/Enable GPIO 0 Пины для внешнего GPS-модуля (по умолчанию) Broadcast Smart Minimum Distance 100 м Мин. смещение для триггера умной рассылки Broadcast Smart Minimum Interval 300 сек Мин. время между умными рассылками 🔐 Для повышения приватности: уменьшите Precision в канале (182 m) и Map precision (729 m), либо задайте фиксированные координаты в стороне от реального местоположения.\n⚙️ Дополнительные модули Информация об окружении (Neighbor Info) Параметр Значение Примечание Enabled Да Для отображения слоя «Соседи» на карте OneMesh Update interval 14400 s (4 часа) Минимальный интервал, не сокращать - лишняя нагрузка на эфир Transmit over LoRa Нет Не передавать данные о соседях по радио (только через MQTT) 🗺️ На карте появятся слои «Кто слышал это устройство» и «Кого слышало это устройство» - полезно для анализа покрытия.\nУстройство (Device) - роль и ретрансляция Параметр Значение Когда использовать Role CLIENT_MUTE В городах с \u0026gt;200 нод - безопасный режим без ретрансляции чужих пакетов CLIENT Если сеть маленькая или у вас хорошая антенна/расположение - можно помогать сети Rebroadcast mode CORE_PORTNUMS_ONLY Ретранслировать только базовые типы пакетов (позиция, текст) - оптимально для города ALL Ретранслировать всё - только для тестов или очень маленьких сетей Node info broadcast interval 43200 s (12 часов) Как часто рассылать информацию о себе; 12 ч - достаточно для мониторинга Double tap as button Нет Защита от случайных срабатываний Disable triple click Да Защита от ложных маяков (beacon) LED heartbeat disabled Нет Визуальный контроль работы (мигание светодиода) Продвинутые настройки устройства Параметр Значение Примечание Button GPIO 0 Пин кнопки (по умолчанию) Buzzer GPIO 0 Пин бузера (по умолчанию) Buzzer Mode ALL_ENABLED Режим бузера: DISABLED, ALERTS_ONLY, ALL_ENABLED TZDEF GMT-3 Часовой пояс для локального времени Is Managed Нет Управляемый режим (только для админ-нод) Serial Enabled Нет Последовательная консоль (для отладки) Debug Log API Нет Вывод отладочных логов (не для продакшена) Часовой пояс Параметр Значение Примечание Timezone GMT+3 (Москва) Для корректного отображения времени в логах и метках Use phone timezone Кнопка Нажать, чтобы подставить часовой пояс из настроек телефона Питание (Power) - для стабильности Параметр Значение Примечание Power Saving Mode Нет Стационарная нода с питанием от USB On Battery Shutdown After 0 сек Не выключать при потере питания (если есть ИБП) ADC Multiplier Override 1.0 Калибровка напряжения батареи Wait Bluetooth Secs 0 При прямом WiFi не ждать BLE-подключения Min Wake Secs 30 Мин. время активности после получения пакета INA219 Address 0 Адрес монитора питания (автоопределение) Дисплей (Display) - оптимизация OLED Параметр Значение Примечание Screen Timeout 60 сек Тайм-аут OLED для экономии GPS Format UNUSED Формат координат на экране (не используется при фиксированной позиции) Auto Screen Carousel 0 Отключить автопереключение окон Compass North Top Да Фиксировать север сверху на компасе Flip Screen Нет Не переворачивать экран (по ориентации корпуса) Units METRIC Метрическая система (°C, м, км/ч) OLED Type OLED_AUTO Автоопределение контроллера дисплея Display Mode DEFAULT Стандартный режим отображения Heading Bold Да Жирный заголовок для лучшей читаемости Wake on Tap or Motion Нет Отключить пробуждение по движению (нет акселерометра на V4) Bluetooth - при отключённом WiFi Параметр Значение Примечание Enabled Нет При включённом WiFi Bluetooth отключается автоматически на ESP32 Pairing Mode FIXED_PIN Если нужно включить - использовать фиксированный PIN Fixed PIN 123456 → смените! Обязательно измените на случайный 6-значный код Сеть (Network) - WiFi для стационарной ноды Параметр Значение Примечание WiFi Enabled Да Прямое подключение к роутеру SSID / PSK \u0026lt;ваши данные\u0026gt; Только 2.4 GHz сети Enable Local UDP Broadcast Нет Не требуется для OneMesh NTP Server pool.ntp.org Надёжнее, чем meshtastic.pool.ntp.org Address Mode DHCP Автополучение IP IPv6 Enabled Нет Не используется в текущей конфигурации ⚠️ При включённом WiFi Bluetooth автоматически отключается на архитектуре ESP32.\n🧩 Настройки модулей (продолжение) Телеметрия (Telemetry) Параметр Значение Примечание Send Device Telemetry Да Включить для мониторинга статуса ноды Device Metrics Interval 900 сек (15 мин) Как часто отправлять метрики устройства Power Metrics Enabled Да Критично для мониторинга питания Power Metrics Interval 300 сек (5 мин) Как часто отправлять данные о питании Environment Metrics Enabled Нет Если нет датчиков BME280/BME680 Air Quality Enabled Нет Только для BME680 Display Metrics on Screen Да Показывать метрики на OLED Display Fahrenheit Нет Метрическая система (°C) Шаблонные сообщения (Canned Messages) Параметр Значение Примечание Enabled Да Удобно для быстрых ответов Messages Тест связи,На связи,73!,Координаты получены Через запятую, без пробелов после Send Bell Нет Не отправлять звуковой сигнал с сообщениями Rotary Encoder Нет Если не подключён энкодер Отключённые модули (рекомендация для OneMesh) Модуль Состояние Почему COM-порт Нет Не используется консоль External Notification Нет Без внешних пьезо/LED-модулей Store \u0026amp; Forward Нет Только для REPEATER/ROUTER Range Test Нет Создаёт избыточный трафик Audio Нет Не поддерживается на Heltec V4 Remote Hardware Нет Не используется Ambient Lighting Нет Экономия энергии Detection Sensor Нет Без внешних GPIO-датчиков Paxcounter Нет Избыточный трафик для OneMesh Status Message Нет Не требуется для стационарной ноды 🔑 Критичные флаги и порядок применения Имя канала: Primary должен называться строго LongFast. PSK: AQ== в основном канале обязателен для фильтрации OneMesh. OK to MQTT: Вкл - без этого соседи не смогут ретранслировать ваши пакеты на сервер. Порядок сохранения (обход багов UI): LoRa → Region → сохранить Каналы → имя + PSK + Uplink/Downlink → сохранить MQTT → базовые параметры → сохранить MQTT → Отчёты по карте → сохранить отдельно Местоположение / Устройство / Питание → сохранить Перезагрузить ноду Проверка: В приложении: MQTT → статус Подключено На карте: нода появляется в течение 1–3 часов В чате LongFast: видны сообщения от соседей 🔧 Оптимизация процесса прошивки Для Heltec V4 (обход бага загрузчика) Из-за особенности загрузчика Heltec V4, стандартный порядок не всегда работает. Оптимальный процесс:\nОтключите батарею и USB от платы Откройте веб-флешер Выберите device: Heltec V4, firmware: 2.7.21 Нажмите Erase Flash and Install Зажмите кнопку PRG на плате Не отпуская PRG, подключите USB-кабель Наблюдайте: краткая красная вспышка → в списке портов появится USB JTAG Отпустите PRG, выберите USB JTAG, нажмите Connect Дождитесь окончания прошивки После Leaving... нажмите кнопку RST (сброс) 💡 Примечание: этот процесс описан в meshtastic/firmware#8543\n📤 Первые сообщения между двумя нодами Подготовка Прошейте обе платы по инструкции выше На каждой настройте: Один и тот же регион (Russia) Один и тот же канал с одинаковым PSK (AQ==) Position enabled: Yes (для теста) Разместите ноды на расстоянии 10–50 м (для первого теста) Тест На первой ноде в приложении: Messages → + → введите текст → Send На второй ноде: должно появиться входящее сообщение Проверьте вкладку Map - если включён MQTT, обе ноды появятся на карте в течение часа Диагностика, если не работает Симптом Проверка Решение Нет сообщений Проверьте, что каналы имеют одинаковый PSK Скопируйте ключ точно, без пробелов Нода не видна на карте Проверьте MQTT enabled, Map reports, интернет на телефоне/ноде Перезапустите ноду (RST), подождите 1–2 цикла отчёта Ошибка подключения к MQTT Проверьте TLS enabled, корневую тему Попробуйте отключить TLS; убедитесь, что Root topic = msh/RU/XXX Нет соединения по радио Проверьте антенну, регион, Hop limit Подключите антенну, установите Region: Russia, Hop limit: 5 🆘 Помощь и сообщество 🗺️ Карта ONEmesh - визуализация сети 💬 Группа в Telegram - вопросы, помощь, координация по городам 📘 Официальная документация Meshtastic 🐙 Репозиторий прошивок 🔧 Heltec V4 Specs ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/mesh/practice/","summary":"\u003cblockquote\u003e\n\u003cp\u003e📌 \u003cstrong\u003eЭто вторая часть цикла\u003c/strong\u003e. \u003ca href=\"https://potatoenergy.gitverse.site/potatoenergy-site/blog/mesh/intro/\"\u003eЧасть 1: Теория\u003c/a\u003e объясняет, зачем это нужно.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003chr\u003e\n\u003ch2 id=\"-распаковка-и-подготовка\"\u003e📦 Распаковка и подготовка\u003c/h2\u003e\n\u003ch3 id=\"комплектация-heltec-v4\"\u003eКомплектация Heltec V4\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eКомпонент\u003c/th\u003e\n          \u003cth\u003eНазначение\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eПлата ~60×30 мм\u003c/td\u003e\n          \u003ctd\u003eESP32-S3R2 + SX1262, OLED 128×64, USB-C\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eАнтенна (IPEX)\u003c/td\u003e\n          \u003ctd\u003eПодключается к разъёму \u003ccode\u003eANT\u003c/code\u003e - \u003cstrong\u003eобязательно!\u003c/strong\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eКабель USB-C\u003c/td\u003e\n          \u003ctd\u003eПитание + прошивка + отладка\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eПины (опционально)\u003c/td\u003e\n          \u003ctd\u003eДля подключения внешних датчиков/антенн\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cblockquote\u003e\n\u003cp\u003e⚠️ \u003cstrong\u003eВажно\u003c/strong\u003e: без подключённой антенны радиомодуль может выйти из строя. Всегда подключайте антенну перед подачей питания.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch3 id=\"характеристики-heltec-v4\"\u003eХарактеристики Heltec V4\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eКомпонент\u003c/th\u003e\n          \u003cth\u003eОписание\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003eMCU\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eESP32-S3R2 (WiFi + Bluetooth)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003eLoRa Transceiver\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eSemtech SX1262\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003eЧастоты\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003e863–870 МГц (EU), 902–928 МГц (US)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003eДисплей\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003e0.96\u0026quot; OLED 128×64\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003eМощность\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eДо +28±1 dBm (High Power option)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003eПитание\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eUSB-C + оптимизированное управление LiPo\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003eРазъёмы\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eUSB-C, U.FL/IPEX для LoRa, 1.25-8Pin GNSS, 1.25-2Pin Solar\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003eФорм-фактор\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eСовместим с V3/V3.1 по пинам\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003chr\u003e\n\u003ch2 id=\"-прошивка-веб-флешер\"\u003e⚡ Прошивка: веб-флешер\u003c/h2\u003e\n\u003cp\u003eОфициальный флешер: \u003ca href=\"https://flasher.meshtastic.org\"\u003ehttps://flasher.meshtastic.org\u003c/a\u003e\u003c/p\u003e","title":"Heltec V4: Практика. Прошивка, настройка, первые сообщения. Часть 2"},{"content":"PostgreSQL не поддерживает in-place upgrade между мажорными версиями (15 → 17, 17 → 18). Данные нужно переносить логически: через дамп и восстановление.\nПочему это важно:\n✅ Новые версии = исправления безопасности, оптимизации, новые функции ✅ Поддержка актуальных клиентов (Nextcloud, Mastodon, Authelia требуют свежие версии) ✅ Предсказуемость: один и тот же процесс для любого проекта Сложность в Docker:\n❌ Нельзя просто поменять тег образа - формат данных несовместим ❌ pg_upgrade требует одновременного доступа к старым и новым бинарникам - ломает изоляцию контейнеров ✅ Решение: pg_dumpall → новый контейнер → psql \u0026lt; dump 📋 Предварительные требования Перед началом убедись, что:\nЕсть доступ к терминалу с правами на docker и docker compose Свободно ~2× размера базы на диске (для дампа + архива) Знаешь имя контейнера БД (nextcloud-postgres) и пользователя (nextcloud) Есть файл docker-compose.yml с описанием сервиса postgres Приложение (Nextcloud/Mastodon) остановлено или переведено в режим обслуживания 💡 Если не уверен - сделай полный бэкап тома перед началом: tar czf backup-volume.tar.gz /var/lib/docker/volumes/...\nШаг 1: Логический бэкап # Создаём дамп всех баз, ролей и глобальных настроек docker exec nextcloud-postgres pg_dumpall -U nextcloud \u0026gt; pg_dumpall_$(date +%F).sql # Проверяем размер и целостность ls -lh pg_dumpall_*.sql tail -10 pg_dumpall_*.sql # должен заканчиваться \u0026#34;;\u0026#34; ⚠️ Если пользователь не имеет прав суперпользователя, используй -U postgres.\nШаг 2: Физический архив тома (страховка) # Останавливаем БД docker compose stop postgres # Находим имя тома docker volume ls | grep nextcloud_database # Архивируем сырые данные sudo tar czf postgres-volume-$(date +%F).tar.gz \\ -C /var/lib/docker/volumes/nextcloud_database/_data . Шаг 3: Удаление старого контейнера и тома docker compose down postgres docker volume rm nextcloud_database Шаг 4: Обновление docker-compose.yml Выбери один из вариантов в зависимости от целевой версии.\n✅ Вариант А: PostgreSQL 15 / 16 / 17 (без изменений путей) services: postgres: image: postgres:17-alpine # или 15, 16 volumes: - database:/var/lib/postgresql/data ✅ Вариант Б: PostgreSQL 18+ (новый стандарт) services: postgres: image: postgres:18-alpine volumes: - database:/var/lib/postgresql # ← монтируем родительскую директорию # Контейнер сам создаст /var/lib/postgresql/18/docker внутри тома 🔧 Вариант В: PostgreSQL 18+ с обратной совместимостью services: postgres: image: postgres:18-alpine volumes: - database:/var/lib/postgresql/data environment: PGDATA: /var/lib/postgresql/data # ← принудительно старый путь 💡 Рекомендация: используй Вариант Б. Он соответствует стандарту Debian/Alpine и упрощает будущие pg_upgrade --link.\nШаг 5: Запуск новой БД docker compose up -d postgres sleep 20 # ждём initdb docker exec nextcloud-postgres pg_isready -U nextcloud -d nextcloud # Ожидаемо: \u0026#34;accepting connections\u0026#34; Шаг 6: Восстановление данных docker exec -i nextcloud-postgres psql -U nextcloud \u0026lt; pg_dumpall_*.sql 🟡 Нормальные ошибки в логах:\nERROR: role \u0026#34;nextcloud\u0026#34; already exists ERROR: database \u0026#34;nextcloud\u0026#34; already exists Новый контейнер уже создал роль/БД из stack.env. psql игнорирует дубли и корректно заливает таблицы. Просто продолжай.\nШаг 7: Финальная проверка # Версия docker exec nextcloud-postgres psql -U nextcloud -c \u0026#34;SELECT version();\u0026#34; # Путь данных docker exec nextcloud-postgres psql -U nextcloud -c \u0026#34;SHOW data_directory;\u0026#34; # ≤17: /var/lib/postgresql/data # ≥18: /var/lib/postgresql/18/docker # Таблицы docker exec nextcloud-postgres psql -U nextcloud -d nextcloud -c \u0026#34;\\dt\u0026#34; 🔄 Откат (если что-то пошло не так) docker compose down # Возвращаем старый образ и путь (пример для 17) sed -i \u0026#39;s/postgres:18/postgres:17/\u0026#39; docker-compose.yml sed -i \u0026#39;s|/var/lib/postgresql$|/var/lib/postgresql/data|\u0026#39; docker-compose.yml # Восстанавливаем том sudo rm -rf /var/lib/docker/volumes/nextcloud_database/_data/* sudo tar xzf postgres-volume-*.tar.gz -C /var/lib/docker/volumes/nextcloud_database/_data/ docker compose up -d postgres ⚠️ FAQ # \u0026#34;Что будет, если запустить 18 с volumes:/var/lib/postgresql/data?\u0026#34; → Контейнер не найдёт данные по новому пути, выполнит initdb и создаст пустую БД. Старые файлы останутся в томе нетронутыми. # \u0026#34;Как проверить путь после запуска?\u0026#34; → SHOW data_directory; внутри psql. # \u0026#34;А можно использовать pg_upgrade вместо дампа?\u0026#34; → В Docker это требует одновременного маунта старых/новых бинарников, что ломает изоляцию. Dump/restore надёжнее для контейнерных сред. # \u0026#34;Обновится ли 18→19 так же?\u0026#34; → Да. При каждом мажорном апгрейде меняется поддиректория (18/docker → 19/docker). Один том `/var/lib/postgresql` будет содержать все версии параллельно. Ссылки 🐘 PGDATA Change Discussion 🐳 Official PostgreSQL Docker Image 🗄️ pg_dumpall Reference 🔄 Nextcloud PostgreSQL Guide ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/docker/postgres-upgrade/","summary":"\u003cp\u003ePostgreSQL не поддерживает in-place upgrade между мажорными версиями (15 → 17, 17 → 18). Данные нужно переносить логически: через дамп и восстановление.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eПочему это важно\u003c/strong\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e✅ Новые версии = исправления безопасности, оптимизации, новые функции\u003c/li\u003e\n\u003cli\u003e✅ Поддержка актуальных клиентов (Nextcloud, Mastodon, Authelia требуют свежие версии)\u003c/li\u003e\n\u003cli\u003e✅ Предсказуемость: один и тот же процесс для любого проекта\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eСложность в Docker\u003c/strong\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e❌ Нельзя просто поменять тег образа - формат данных несовместим\u003c/li\u003e\n\u003cli\u003e❌ \u003ccode\u003epg_upgrade\u003c/code\u003e требует одновременного доступа к старым и новым бинарникам - ломает изоляцию контейнеров\u003c/li\u003e\n\u003cli\u003e✅ Решение: \u003ccode\u003epg_dumpall\u003c/code\u003e → новый контейнер → \u003ccode\u003epsql \u0026lt; dump\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch2 id=\"-предварительные-требования\"\u003e📋 Предварительные требования\u003c/h2\u003e\n\u003cp\u003eПеред началом убедись, что:\u003c/p\u003e","title":"PostgreSQL в Docker: Миграция между версиями без потери данных"},{"content":"При запуске приложений через Flatpak (Discord, OBS, Firefox и др.) вы можете увидеть предупреждение:\nПредупреждение: Во время загрузки http://ciscobinary.openh264.org/libopenh264-2.5.1-linux64.7.so.bz2: Server returned status 403 Или в логах:\nFailed to load OpenH264 library: openh264 cannot be opened Симптомы:\n❌ Видео в звонках не работает или показывает чёрный экран ❌ Запись экрана в OBS падает с ошибкой кодирования ❌ Веб-камера в браузере не передаёт видео Причина: сервер Cisco (ciscobinary.openh264.org) блокирует автоматическую загрузку библиотеки libopenh264 по политическим/лицензионным причинам. Статус 403 = «доступ запрещён».\n✅ Решение: заменить OpenH264 на ffmpeg-full Вместо проблемного кодека установим полнофункциональный ffmpeg-full из репозитория Flathub. Он включает все необходимые кодеки, включая H.264, и не зависит от внешних загрузок.\nШаг 1: Установить ffmpeg-full flatpak install org.freedesktop.Platform.ffmpeg-full При запросе версии выберите актуальную (обычно 24.08 или выше):\nКакой вы хотите использовать (0 - отмена)? [0-6]: 3 Шаг 2: Заблокировать загрузку OpenH264 flatpak mask org.freedesktop.Platform.openh264 Что это делает:\ninstall - добавляет полнофункциональный FFmpeg с поддержкой H.264 mask - запрещает Flatpak пытаться загрузить проблемный openh264 Шаг 3: Перезапустить приложение # Для пользовательских приложений flatpak kill org.discordapp.Discord # замените на ваш app-id flatpak run org.discordapp.Discord # Или просто перезагрузите систему 🔍 Проверка результата # Проверить, что ffmpeg-full установлен flatpak list | grep ffmpeg-full # Убедиться, что openh264 замаскирован flatpak mask --list | grep openh264 # Проверить логи приложения (опционально) flatpak run --command=sh org.discordapp.Discord -c \u0026#34;journalctl --user -n 50\u0026#34; Если предупреждений про 403 или openh264 нет - решение сработало.\n⚙️ Для продвинутых: установка в user-space (без sudo) Если вы используете Flatpak в режиме пользователя (--user), команды немного отличаются:\n# Установка в user-space flatpak install --user org.freedesktop.Platform.ffmpeg-full # Маскировка в user-space flatpak mask --user org.freedesktop.Platform.openh264 Проверка:\nflatpak list --user | grep ffmpeg-full flatpak mask --user --list | grep openh264 🔄 Если не помогло: дополнительные шаги 1. Обновить метаданные репозитория flatpak update --appstream flatpak update 2. Пересобрать кэш рантаймов # Очистить кэш (безопасно, файлы переустановятся при необходимости) flatpak repair 3. Проверить, какое приложение использует кодек # Узнать app-id приложения flatpak list | grep -i discord # Запустить с отладкой flatpak run --command=sh org.discordapp.Discord -c \u0026#34;env | grep -i h264\u0026#34; 4. Альтернатива: использовать системный FFmpeg Если Flatpak-версия не подходит, можно разрешить приложению доступ к системным библиотекам:\n# Разрешить доступ к /usr/lib (требует осторожности) flatpak override --user --filesystem=/usr/lib org.discordapp.Discord ⚠️ Это снижает изоляцию контейнера - используйте только если уверены.\n📊 Сравнение решений Метод Плюсы Минусы Для кого ffmpeg-full + mask ✅ Работает сразу, не требует sudo, обновляется через Flatpak ❌ Увеличивает размер установки (~100 МБ) Большинство пользователей Системный FFmpeg ✅ Использует уже установленные библиотеки ❌ Требует настройки прав, снижает изоляцию Продвинутые пользователи Ручная загрузка openh264 ✅ Минимальный размер ❌ Нестабильно, требует повторной загрузки при обновлениях Не рекомендуется ⚠️ Частые вопросы # «А не сломает ли это другие приложения?» → Нет. Маскировка применяется только к `openh264`, а `ffmpeg-full` обратно совместим. # «Почему не починить сервер Cisco?» → Это лицензионная политика. Мы не можем её изменить, но можем обойти. # «А если я хочу использовать именно openh264?» → Попробуйте скачать библиотеку вручную и положить в `~/.var/app/*/cache/openh264/`, но это нестабильно. # «Обновится ли ffmpeg-full автоматически?» → Да, при `flatpak update`. Маскировка сохранится. Ссылки 🐧 Flatpak Documentation 🎬 FFmpeg in Flathub 🚫 OpenH264 License Info 🛠 Flatpak Mask Command ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/linux/flatpak-openh264/","summary":"\u003cp\u003eПри запуске приложений через Flatpak (Discord, OBS, Firefox и др.) вы можете увидеть предупреждение:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eПредупреждение: Во время загрузки\n  http://ciscobinary.openh264.org/libopenh264-2.5.1-linux64.7.so.bz2:\n  Server returned status 403\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eИли в логах:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eFailed to load OpenH264 library: openh264 cannot be opened\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e\u003cstrong\u003eСимптомы\u003c/strong\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e❌ Видео в звонках не работает или показывает чёрный экран\u003c/li\u003e\n\u003cli\u003e❌ Запись экрана в OBS падает с ошибкой кодирования\u003c/li\u003e\n\u003cli\u003e❌ Веб-камера в браузере не передаёт видео\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eПричина\u003c/strong\u003e: сервер Cisco (\u003ccode\u003eciscobinary.openh264.org\u003c/code\u003e) блокирует автоматическую загрузку библиотеки \u003ccode\u003elibopenh264\u003c/code\u003e по политическим/лицензионным причинам. Статус \u003ccode\u003e403\u003c/code\u003e = «доступ запрещён».\u003c/p\u003e","title":"Flatpak: Ошибка 403 при загрузке OpenH264 - быстрое решение"},{"content":"🎮 Зачем это нужно Запуск игр через Steam на Linux - это часто «танцы с бубном»: разные движки требуют разных флагов, под AMD и NVIDIA нужны разные переменные окружения, а инструменты вроде Gamescope и MangoHud нужно вручную встраивать в команду запуска.\nРешение: steamscope.sh - скрипт-обёртка, который:\n✅ Автоматически определяет видеокарту (AMD/NVIDIA) и применяет нужные оптимизации ✅ Поддерживает флаги под движки: Source, Unreal, Unity ✅ Интегрирует Gamescope, Gamemode, MangoHud, FSR одной командой ✅ Работает как %command% в настройках запуска Steam ✅ Не ломает стандартный запуск - всё опционально 💡 Скрипт не заменяет Proton или Steam - он делает их работу предсказуемой и настраиваемой.\n📦 Установка Шаг 1: Скачать скрипт # Создать директорию (если нет) mkdir -p ~/.steam/steam/ # Скачать скрипт curl -o ~/.steam/steam/steamscope.sh \\ https://gist.githubusercontent.com/ponfertato/85fc964664423eae1ac0a7ee91d53db6/raw/steamscope.sh # Сделать исполняемым chmod +x ~/.steam/steam/steamscope.sh Шаг 2: Настроить игру в Steam Правой кнопкой по игре → Свойства В поле Параметры запуска добавить: ~/.steam/steam/steamscope.sh %command% (Опционально) Добавить флаги: ~/.steam/steam/steamscope.sh --gamemode --mangohud --engine=source %command% Готово. При запуске игры скрипт автоматически подхватит настройки.\n⚙️ Параметры запуска (категории) 🚀 Производительность Флаг Описание Для кого --gamemode Включает gamemoderun для приоритета процессов Все, особенно на слабых системах --fsr Включает FSR-апскейлинг через VKD3D (AMD) / DXVK (NVIDIA) AMD GPU, низкий нативный FPS --dxvk Принудительно использует DXVK вместо D9VK Игры с DirectX 9/10/11 👁 Мониторинг Флаг Описание Пример вывода --mangohud Показывает оверлей с FPS, загрузкой CPU/GPU, температурами FPS: 87 │ CPU: 45% │ GPU: 72°C 🖥 Режим работы Флаг Описание Зачем --gamescope Запускает игру в изолированной сессии Wayland через Gamescope Стабильный FPS, адаптивная синхронизация, масштабирование --resolution=1280x720 Задает разрешение для Gamescope (по умолчанию - нативное) Тестирование, снижение нагрузки 🎯 Движки Флаг Поддерживаемые движки Примеры игр --engine=source Source 1/2 CS2, TF2, Garry\u0026rsquo;s Mod, Left 4 Dead 2 --engine=unreal Unreal Engine 3/4/5 Risk of Rain 2, Deep Rock Galactic, Satisfactory --engine=unity Unity 7 Days to Die, Valheim, Among Us Что добавляет каждый движок:\nSource: -high -threads N +mat_vsync 0 +fps_max 0 +exec autoexec.cfg Unreal: -dx12 -nomansky -notexturestreaming -nomovie Unity: -screen-width W -screen-height H -nolog -batchmode 🔧 Как это работает (под капотом) Автоматическое определение железа # Скрипт проверяет видеокарту через lspci GPU_INFO=$(lspci -k 2\u0026gt;/dev/null | awk \u0026#39;/VGA|3D/,/Kernel driver/ {if (/Kernel driver in use/) print $NF}\u0026#39; | tail -1) # Для AMD: [[ \u0026#34;$GPU_INFO\u0026#34; == *\u0026#34;amdgpu\u0026#34;* ]] \u0026amp;\u0026amp; USE_AMD=true # → Добавляет: RADV_PERFTEST=aco, AMD_DEBUG=nodcc # Для NVIDIA: [[ \u0026#34;$GPU_INFO\u0026#34; == *\u0026#34;nvidia\u0026#34;* ]] \u0026amp;\u0026amp; USE_NVIDIA=true # → Добавляет: PROTON_ENABLE_NVAPI=1, __NV_PRIME_RENDER_OFFLOAD=1 Сборка финальной команды Скрипт строит команду «слоями»:\n[gamemoderun] → [mangohud] → [gamescope -- ...] → [ИГРА + флаги движка] Каждый слой добавляется только если соответствующий флаг передан.\nОбработка %command% Steam передаёт команду запуска как %command%. Скрипт:\nНаходит место после исполняемого файла (но не внутри proton, steam-runtime и т.п.) Вставляет флаги движка после исполняемого файла, но до аргументов игры Это гарантирует, что флаги попадут именно в игру, а не в лаунчер 🎯 Примеры для популярных игр Counter-Strike 2 (Source Engine, AMD) ~/.steam/steam/steamscope.sh \\ --engine=source \\ --gamemode \\ --mangohud \\ --fsr \\ --gamescope \\ %command% Что получит игра:\nПриоритет процессов через gamemoderun Оверлей MangoHud с метриками Апскейлинг FSR через VKD3D (для повышения FPS) Запуск в Gamescope с адаптивной синхронизацией Оптимизированные флаги Source: -high -threads 8 +fps_max 0 Deep Rock Galactic (Unreal Engine, NVIDIA) ~/.steam/steam/steamscope.sh \\ --engine=unreal \\ --gamemode \\ --dxvk \\ --mangohud \\ %command% Особенности:\n--dxvk включает DXVK для лучшей совместимости с Vulkan на NVIDIA Флаги Unreal отключают тяжёлые эффекты: -nomansky -notexturestreaming UE5_ALLOW_LINUX_DEBUGGING=1 для стабильности на Linux 7 Days to Die (Unity, кросс-платформа) ~/.steam/steam/steamscope.sh \\ --engine=unity \\ --gamemode \\ --fsr \\ --resolution=1280x720 \\ %command% Зачем:\n--resolution снижает нагрузку для плавного геймплея --fsr компенсирует потерю детализации апскейлингом Флаги Unity отключают логирование: -nolog -batchmode 🛠 Советы по настройке Начинай с минимума # Только игра (базовый запуск) ~/.steam/steam/steamscope.sh %command% # + мониторинг ~/.steam/steam/steamscope.sh --mangohud %command% # + оптимизация ~/.steam/steam/steamscope.sh --gamemode --mangohud %command% Добавляй параметры по одному - так проще найти причину проблем.\nЕсли игра падает Отключи --gamescope - самый частый источник конфликтов Отключи --gamemode - может конфликтовать с системными настройками Проверь логи: journalctl -f | grep -i steam Разрешение и масштабирование По умолчанию скрипт берёт нативное разрешение через xrandr Для принудительного изменения: --resolution=1280x720 В сочетании с --gamescope и --fsr даёт гибкое управление качеством/производительностью Локализация Скрипт устанавливает:\nexport LANG=\u0026#34;ru_RU.UTF-8\u0026#34; export LC_ALL=\u0026#34;ru_RU.UTF-8\u0026#34; Если игра требует английскую локаль - переопредели в параметрах запуска:\nLANG=en_US.UTF-8 ~/.steam/steam/steamscope.sh %command% ⚠️ Частые проблемы # \u0026#34;gamescope: command not found\u0026#34; → Установить: # Arch: sudo pacman -S gamescope # Debian/Ubuntu: sudo apt install gamescope # Fedora: sudo dnf install gamescope # \u0026#34;gamemoderun: command not found\u0026#34; → Установить: # Все дистрибутивы: sudo apt install gamemode или аналог # Игра игнорирует флаги движка → Убедиться, что %command% стоит в конце строки → Проверить, что игра действительно на нужном движке (не все «названия» совпадают с реальностью) # Нет оверлея MangoHud → Проверить, что mangohud установлен и в PATH → Для некоторых игр требуется: export MANGOHUD_DLSYM=1 (скрипт делает это автоматически) # Низкий FPS после включения --fsr → FSR - это апскейлинг, а не магия: он повышает FPS за счёт качества → Попробуй снизить --resolution вместе с --fsr # Скрипт не определяет видеокарту → Убедиться, что установлен pciutils: sudo apt install pciutils → Проверить вывод: lspci -k | grep -A2 -i vga 🔐 Безопасность и приватность Скрипт не собирает данные, не отправляет ничего в сеть и работает полностью локально.\nЧто он делает:\nЧитает lspci для определения GPU (только для оптимизаций) Устанавливает переменные окружения для процесса игры Не модифицирует файлы игры или системы Рекомендации:\nСкачивай скрипт только с официального gist Проверяй хэш при обновлении (опционально) Не передавай скрипт с чувствительными данными в аргументах 🗂 Чеклист перед использованием Установил зависимости: gamemode, mangohud, gamescope (по желанию) Скачал скрипт в ~/.steam/steam/steamscope.sh и сделал исполняемым Протестировал запуск одной игры с минимальными флагами Проверил, что %command% стоит в конце строки параметров запуска Ознакомился с локальной регуляторикой по использованию оверлеев в играх (если важно) Ссылки 🎮 Официальный Gist со скриптом 🐧 ProtonDB - совместимость игр 🖥 Gamescope на GitHub ⚡ Gamemode на GitHub 👁 MangoHud на GitHub 🎯 FSR в VKD3D-Proton ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/linux/steamscope/","summary":"\u003ch2 id=\"-зачем-это-нужно\"\u003e🎮 Зачем это нужно\u003c/h2\u003e\n\u003cp\u003eЗапуск игр через Steam на Linux - это часто «танцы с бубном»: разные движки требуют разных флагов, под AMD и NVIDIA нужны разные переменные окружения, а инструменты вроде Gamescope и MangoHud нужно вручную встраивать в команду запуска.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eРешение\u003c/strong\u003e: \u003ccode\u003esteamscope.sh\u003c/code\u003e - скрипт-обёртка, который:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e✅ Автоматически определяет видеокарту (AMD/NVIDIA) и применяет нужные оптимизации\u003c/li\u003e\n\u003cli\u003e✅ Поддерживает флаги под движки: Source, Unreal, Unity\u003c/li\u003e\n\u003cli\u003e✅ Интегрирует Gamescope, Gamemode, MangoHud, FSR одной командой\u003c/li\u003e\n\u003cli\u003e✅ Работает как \u003ccode\u003e%command%\u003c/code\u003e в настройках запуска Steam\u003c/li\u003e\n\u003cli\u003e✅ Не ломает стандартный запуск - всё опционально\u003c/li\u003e\n\u003c/ul\u003e\n\u003cblockquote\u003e\n\u003cp\u003e💡 Скрипт не заменяет Proton или Steam - он делает их работу предсказуемой и настраиваемой.\u003c/p\u003e","title":"steamscope.sh: Универсальный лаунчер для Steam на Linux"},{"content":"Представь: ты в походе, на даче, в районе с плохой связью - или просто хочешь общаться без операторов, облаков и слежки.\nРешение: децентрализованная сеть на базе LoRa - радиосвязь с низким энергопотреблением и дальностью до нескольких километров.\n💡 Это не замена интернету. Это «интернет для экстренных случаев, приватности и экспериментов».\nДля кого эта серия:\n✅ Для друзей и родственников, которые хотят понять «а зачем мне это» ✅ Для новичков в радио/электронике (не нужно паять!) ✅ Для тех, кто ценит приватность и независимость от инфраструктуры 📡 Что такое LoRa и mesh-сети (простыми словами) LoRa (Long Range) Параметр Значение Дальность 1–10 км в городе, до 50+ км на прямой видимости Потребление ~100 мА при передаче, ~10 мА в ожидании Скорость 0.3–50 кбит/с (только текст, координаты, небольшие данные) Частота 433 МГц (РФ), 868 МГц (ЕС), 915 МГц (США) Простая аналогия:\n🥔 LoRa - как пересылка записок через цепочку друзей. Медленно, но далеко и без интернета.\nMesh-сеть (ячеистая) Устройства (ноды) передают сообщения друг другу, как эстафету:\n[Ты] → [Нода А] → [Нода Б] → [Друг] ↑ ↑ [Нода В] → [Нода Г] Преимущества:\n✅ Не нужна вышка - сеть строится из устройств пользователей ✅ Отказоустойчивость: если одна нода отключилась, сообщение пойдёт другим путём ✅ Масштабируемость: чем больше участников, тем лучше покрытие 🔧 Почему именно Heltec V4? HELTEC® LoRa 32 V4 - плата на базе ESP32-S3R2 + SX1262.\nХарактеристики Компонент Описание ESP32-S3R2 240 МГц, WiFi + Bluetooth, 8 МБ Flash, 8 МБ PSRAM SX1262 LoRa-трансивер (433/863-870/902-928 МГц), до +28±1 дБм мощности Дисплей 0.96\u0026quot; OLED 128×64 (для отображения сообщений, статуса) Питание 3.7В LiPo (через JST), USB-C для зарядки/прошивки Корпус Компактный (~60×30 мм), готов к установке в карман/рюкзак Почему это круто Всё в одном: не нужно паять, соединять модули - плата готова к работе Два радио в одном: LoRa для дальней связи + WiFi/Bluetooth для настройки Дисплей: видишь сообщения, уровень сигнала, заряд батареи - без подключения к телефону Сообщество: поддержка Meshtastic, PlatformIO, Arduino - много готовых решений Цена: ~$25–30 за полноценную ноду 💡 Для старта достаточно двух плат: одна тебе, одна другу. Уже можно обмениваться сообщениями без интернета.\n🗣️ Meshtastic: просто, работает, для всех Meshtastic - open-source проект, который превращает платы типа Heltec V4 в узлы децентрализованной сети для обмена текстовыми сообщениями и координатами.\nЧто умеет ✅ Текстовые чаты (личные и групповые) ✅ Передача координат (GPS-трекинг, если подключить модуль) ✅ Многопрыжковая маршрутизация (multi-hop) ✅ Шифрование (опционально, на уровне приложения) ✅ Кроссплатформенные клиенты: Android, iOS, Web, Desktop Почему начать с него Критерий Почему подходит новичкам Настройка Прошивка через браузер, без компиляции кода Интерфейс Мобильное приложение как в мессенджере Документация Подробные гайды, активное сообщество Безопасность Рекомендации по настройке на русском Законность Соответствие регуляторам РФ при правильной настройке Ограничения (честно) Минус Как с этим жить Только текст и координаты Не для видео/аудио, но для «я в порядке» - идеально Низкая скорость Сообщения идут несколько секунд - это нормально для дальности Зависит от количества нод Чем больше участников, тем лучше сеть - приглашай друзей! 🔐 Reticulum: для тех, кто хочет больше Reticulum - более продвинутая платформа для децентрализованных сетей.\nВ чём отличие от Meshtastic Meshtastic Reticulum Простота, фокус на чат Гибкость, фокус на протокол Готовое приложение Библиотека для разработки своих приложений Только текст/координаты Текст, файлы, VoIP, интеграция с TCP/IP Сообщество «для всех» Сообщество «для разработчиков и энтузиастов» Зачем упоминать сейчас Перспектива: если захочешь не просто чатиться, а передавать файлы, поднимать локальные сервисы Интеграция: Reticulum может работать поверх других каналов (LoRa, WiFi, интернет) - единая сеть из разнородных узлов Приватность: сквозное шифрование, анонимные идентификаторы, устойчивая архитектура 💡 Не пугайся: для старта хватит Meshtastic. Reticulum - это «следующий уровень», к которому можно вернуться позже.\n⚖️ Законность в РФ (важно!) Использование радиочастот регулируется. Вот что нужно знать:\nРазрешённые параметры для 868 МГц (РФ) Параметр Значение Частота 868,7–869,2 МГц Мощность До 25 мВт (≤14 дБм) без регистрации Модуляция LoRa (разрешена) Назначение Любительская связь, эксперименты Как соблюсти правила Используй готовые прошивки (Meshtastic) с региональными настройками (автоматически выставляют мощность) Не усиливай сигнал внешними усилителями без разрешения Не передавай коммерческий трафик - только личные/экспериментальные данные Ознакомься с гайдом: Регуляторика для Meshtastic в РФ ⚠️ Это не юридическая консультация. При сомнениях - проконсультируйся со специалистом.\n🔒 Безопасность: что можно, а что не стоит Рекомендации по безопасности:\n✅ Что делать Включить шифрование канала (pre-shared key) Использовать никнеймы вместо реальных имён Не передавать чувствительные данные (пароли, адреса) в открытом виде Регулярно обновлять прошивку ❌ Чего избегать Не использовать дефолтные ключи шифрования из примеров Не передавать координаты дома/работы в публичные каналы Не полагаться на анонимность как на 100% защиту 💡 Шифрование в Meshtastic - это защита от случайного перехвата, не от целевой атаки спецслужб.\n🎯 Сценарии использования (для вдохновения) Для семьи / друзей Сценарий Как это работает Связь на даче Нода дома + нода в машине = чат без сотовой связи Поход / рыбалка Группа из 3–5 нод = сеть на несколько км без интернета Экстренная связь При отключении сотовой сети - резервный канал для «я в порядке» Для умного дома Сценарий Интеграция Датчики в саду Нода с датчиком влажности → шлёт данные на базовую ноду → Home Assistant Уведомления Событие в HA → сообщение в локальную сеть → ты видишь на дисплее ноды в кармане Резервный канал При потере интернета - критичные уведомления идут через LoRa Для сообщества Сценарий Идея Районная сеть 10–20 участников = покрытие всего района, чат, обмен координатами Event-связь Фестиваль, велопрогулка: временная сеть без нагрузки на сотовые вышки Образование Мастер-класс для друзей: «собери свою ноду за 15 минут» Ссылки 📡 Meshtastic Official 🔐 Безопасность в Meshtastic (RU) ⚖️ Регуляторика для РФ (RU) 🌐 Reticulum Network 🛒 Heltec V4 на AliExpress (пример, проверяй актуальность) 📘 MeshWorks Introduction (RU) ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/mesh/intro/","summary":"\u003cp\u003eПредставь: ты в походе, на даче, в районе с плохой связью - или просто хочешь общаться без операторов, облаков и слежки.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eРешение\u003c/strong\u003e: децентрализованная сеть на базе LoRa - радиосвязь с низким энергопотреблением и дальностью до нескольких километров.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e💡 Это не замена интернету. Это «интернет для экстренных случаев, приватности и экспериментов».\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e\u003cstrong\u003eДля кого эта серия\u003c/strong\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e✅ Для друзей и родственников, которые хотят понять «а зачем мне это»\u003c/li\u003e\n\u003cli\u003e✅ Для новичков в радио/электронике (не нужно паять!)\u003c/li\u003e\n\u003cli\u003e✅ Для тех, кто ценит приватность и независимость от инфраструктуры\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch2 id=\"-что-такое-lora-и-mesh-сети-простыми-словами\"\u003e📡 Что такое LoRa и mesh-сети (простыми словами)\u003c/h2\u003e\n\u003ch3 id=\"lora-long-range\"\u003eLoRa (Long Range)\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eПараметр\u003c/th\u003e\n          \u003cth\u003eЗначение\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eДальность\u003c/td\u003e\n          \u003ctd\u003e1–10 км в городе, до 50+ км на прямой видимости\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eПотребление\u003c/td\u003e\n          \u003ctd\u003e~100 мА при передаче, ~10 мА в ожидании\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eСкорость\u003c/td\u003e\n          \u003ctd\u003e0.3–50 кбит/с (только текст, координаты, небольшие данные)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eЧастота\u003c/td\u003e\n          \u003ctd\u003e433 МГц (РФ), 868 МГц (ЕС), 915 МГц (США)\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e\u003cstrong\u003eПростая аналогия\u003c/strong\u003e:\u003c/p\u003e","title":"Heltec V4: Своя сеть без интернета. Часть 1: Зачем это нужно?"},{"content":"Проблема После перехода на HyperOS (POCO, Xiaomi) ссылки из приложений (Telegram, WhatsApp и др.) открываются не в основном аккаунте Chrome, а в клонированном - даже если в настройках системы выбран основной браузер.\nСимптомы:\nКлик по ссылке → открывается Chrome второго пространства В настройках «Приложения по умолчанию» выбран основной Chrome Сброс настроек не помогает Причина: HyperOS приоритизирует клонированные приложения при обработке интентов, игнорируя выбор пользователя.\n💡 Проблема воспроизводится на MIUI 14 / HyperOS 1.0+ с включённой функцией «Клонирование приложений» / «Второе пространство».\n❌ Почему простые решения не работают Удаление через ADB (временное) adb shell pm uninstall -k --user 999 com.android.chrome Проблема: после перезагрузки системы Chrome во втором пространстве тихо переустанавливается. user 999 - это ID клонированного профиля, но HyperOS восстанавливает системные приложения при старте.\nОтключение «Клонирования приложений» Минус: удаляет все клонированные приложения и их данные. Не подходит, если нужны другие дубликаты (мессенджеры, банки).\n✅ Решения (по предпочтению) Решение 1: Shizuku + AppManager (рекомендуется) Позволяет удалить Chrome из второго пространства без root, с сохранением остальных клонированных приложений.\nШаг 1: Установить Shizuku Скачать Shizuku с F-Droid Запустить приложение → «Запустить через беспроводную отладку» Включить беспроводную отладку в «Для разработчиков»: Настройки → О телефоне → 7 раз тапнуть по «Версии ОС» Настройки → Дополнительные → Для разработчиков → ✅ Беспроводная отладка Следовать инструкциям в Shizuku для сопряжения Шаг 2: Установить AppManager Скачать AppManager с F-Droid Открыть приложение → предоставить доступ через Shizuku (автоматически) Шаг 3: Удалить Chrome из второго пространства Найти com.android.chrome (Google Chrome) Открыть карточку приложения → ⋮ → Удалить для пользователя Подтвердить удаление Результат: Chrome удалён только из второго пространства, основной аккаунт не затронут.\nШаг 4: Проверить # Через ADB (опционально) adb shell pm list packages --user 999 | grep chrome # Должно быть пусто Решение 2: Сменить браузер по умолчанию Если не хочется настраивать Shizuku:\nУстановить альтернативный браузер: Chrome Beta, Firefox, Brave Экспортировать закладки из основного Chrome (синхронизация с аккаунтом) Очистить данные основного Chrome (опционально) Назначить новый браузер по умолчанию: Настройки → Приложения → Приложения по умолчанию → Браузер Проверить открытие ссылок Плюс: не требует root, Shizuku или ADB\nМинус: нужно привыкнуть к новому браузеру\nРешение 3: ADB-скрипт с автозапуском (для продвинутых) Если Shizuku не работает, можно автоматизировать ADB-команды:\n#!/bin/bash # remove-chrome-clone.sh adb wait-for-device adb shell pm uninstall -k --user 999 com.android.chrome echo \u0026#34;Chrome удалён из второго пространства\u0026#34; Автозапуск через Termux + ADB:\nУстановить Termux Установить ADB Keyboard или использовать adb tcpip Запустить скрипт при загрузке через ~/.termux/boot/ Ограничение: после перезагрузки телефона нужно запускать скрипт вручную (или настраивать автозапуск через Tasker).\n🔍 Диагностика # Проверить, установлен ли Chrome во втором пространстве adb shell pm list packages --user 999 | grep chrome # Проверить браузер по умолчанию adb shell dumpsys package preferred | grep browser # Посмотреть обработчики интентов для ссылок adb shell dumpsys activity preferred-activities | grep -A5 \u0026#34;http\u0026#34; ⚠️ Частые проблемы # Shizuku не запускается → Включить беспроводную отладку и сопряжение заново → Перезапустить Shizuku после обновления системы # AppManager не видит пользователя 999 → Предоставить права через Shizuku: Настройки → Приложения → AppManager → Разрешения → Перезапустить AppManager # Chrome переустанавливается после ребута → Это особенность HyperOS. Решение: добавить скрипт в автозагрузку (Termux + Tasker) → Или использовать Shizuku + AppManager с повторным удалением при загрузке (требует рут) # Ссылки всё равно открываются в клоне → Очистить настройки по умолчанию: Настройки → Приложения → Управление приложениями → ⋮ → Сбросить настройки → Перезапустить телефон Ссылки 🔧 Shizuku на F-Droid 📱 AppManager на F-Droid 🤖 Termux на F-Droid 📘 Android Package Manager Docs ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/android/hyperos/chrome-dual-fix/","summary":"\u003ch2 id=\"проблема\"\u003eПроблема\u003c/h2\u003e\n\u003cp\u003eПосле перехода на HyperOS (POCO, Xiaomi) ссылки из приложений (Telegram, WhatsApp и др.) открываются не в основном аккаунте Chrome, а в клонированном - даже если в настройках системы выбран основной браузер.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eСимптомы\u003c/strong\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eКлик по ссылке → открывается Chrome второго пространства\u003c/li\u003e\n\u003cli\u003eВ настройках «Приложения по умолчанию» выбран основной Chrome\u003c/li\u003e\n\u003cli\u003eСброс настроек не помогает\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eПричина\u003c/strong\u003e: HyperOS приоритизирует клонированные приложения при обработке интентов, игнорируя выбор пользователя.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e💡 Проблема воспроизводится на MIUI 14 / HyperOS 1.0+ с включённой функцией «Клонирование приложений» / «Второе пространство».\u003c/p\u003e","title":"HyperOS: Удаление Chrome из второго пространства"},{"content":"Obtainium - менеджер обновлений для Android, который скачивает приложения напрямую из репозиториев разработчиков (GitHub, GitLab, Codeberg, F-Droid), минуя сторонние каталоги.\nЗачем нужен:\nПолучать обновления быстрее, чем в Google Play / F-Droid Избегать трекеров и рекламы из сторонних магазинов Контролировать, какие версии устанавливаются (stable, beta, pre-release) Автоматизировать обновления без ручного подтверждения 💡 Obtainium не хранит приложения - только указывает, где их скачать. Вы всегда знаете источник.\n📦 Установка Скачать F-Droid (рекомендуется) GitHub Releases Настройка при первом запуске Открыть Obtainium → разрешить «Установка из неизвестных источников» (только для Obtainium) Настройки → Метод установки → выбрать Shizuku (если настроен) или Системный установщик Настройки → Проверка обновлений → задать интервал (рекомендуется: 6–24 часа) Опционально:\n✅ Показывать уведомления о новых версиях ✅ Автозагрузка обновлений (требует стабильного интернета) ✅ Автоустановка (требует Shizuku) 🔍 Добавление приложений Способ 1: По ссылке на репозиторий Источник: GitHub URL: https://github.com/RikkaApps/Shizuku Фильтр: Releases → Stable only Формат: APK (универсальный) или arm64-v8a (для производительности) Шаги:\nВ Obtainium: «+» → «Добавить приложение» Вставить ссылку на репозиторий Нажать «Проверить» - Obtainium покажет доступные версии Настроить фильтры (теги, пре-релизы, архитектура) Сохранить Способ 2: Из каталога Obtainium имеет встроенный каталог популярных приложений:\nМеню → «Каталог» → выбрать приложение → «Добавить» Фильтры применяются автоматически Способ 3: Импорт списка // backup.json - экспорт настроек { \u0026#34;apps\u0026#34;: [ { \u0026#34;sourceId\u0026#34;: \u0026#34;github\u0026#34;, \u0026#34;url\u0026#34;: \u0026#34;https://github.com/user/repo\u0026#34;, \u0026#34;includePrereleases\u0026#34;: false, \u0026#34;filterReleaseTitlesByRegEx\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;filterReleaseNotesByRegEx\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;versionExtractionRegEx\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;apkFilterRegEx\u0026#34;: \u0026#34;arm64-v8a\u0026#34;, \u0026#34;invertAPKFilter\u0026#34;: false } ] } Импорт: Настройки → «Резервное копирование» → «Восстановить»\n⚙️ Продвинутые настройки Фильтры версий Параметр Пример Описание Стабильные только ✅ Игнорировать beta, alpha, rc Регулярное выражение (заголовок) ^v[0-9.]+$ Принимать только версии вида v1.2.3 Регулярное выражение (описание) (?i)android Искать ключевые слова в заметках к релизу Фильтры APK Параметр Пример Зачем Фильтр по имени arm64-v8a Скачивать только для 64-битных устройств Инвертировать фильтр ✅ Исключить определённые архитектуры Минимальный размер 1000000 (1 МБ) Отсеять пустые/повреждённые файлы Уведомления и автообновление Настройки → Уведомления: ✅ Показывать при новой версии ✅ Звук / Вибрация (опционально) Настройки → Автообновление: ✅ Включить (требует Shizuku для установки без подтверждения) ⏰ Интервал: 6 часов 🌙 Только при зарядке и WiFi (рекомендуется) 🔗 Интеграция с Shizuku Зачем Shizuku для Obtainium Без Shizuku С Shizuku Ручное подтверждение установки Полностью автоматическая установка Не работает со split-APK Поддержка всех форматов Требует «Неизвестные источники» Установка через системный Package Manager Настройка Убедиться, что Shizuku запущен (статус «Работает») В Obtainium: Настройки → Метод установки → Shizuku Предоставить доступ при первом запуске установки Протестировать: обновить любое приложение Проверить логи (если что-то не работает):\nadb logcat | grep -i obtainium adb logcat | grep -i shizuku 📊 Сравнение с альтернативами Менеджер Источники Автоустановка Split-APK Приватность Obtainium GitHub, GitLab, Codeberg, F-Droid, прямые ссылки ✅ (с Shizuku) ✅ 🔒 Высокая F-Droid Только F-Droid репозитории ❌ ❌ 🔒 Высокая Aurora Store Google Play (анонимно) ❌ ✅ 🔐 Средняя APKUpdater GitHub, F-Droid, APKMirror ❌ ⚠️ Частично 🔐 Средняя Google Play Только Play Store ✅ ✅ 🔓 Низкая Когда выбирать Obtainium:\nВы доверяете разработчикам напрямую Хотите обновления быстрее официальных каталогов Нужна поддержка split-APK и гибкие фильтры Важна приватность и контроль над источниками ⚠️ Частые проблемы # «Не удалось получить информацию о версии» → Проверить доступ к интернету → Убедиться, что репозиторий публичный (или добавить токен в настройках) → Попробовать «Проверить вручную» в карточке приложения # «Установка отменена пользователем» → Без Shizuku: это нормально - нужно подтвердить установку вручную → С Shizuku: проверить, запущен ли сервис и предоставлены ли права # «Неподдерживаемый формат APK» → Включить в настройках: «Поддерживать split-APK» → Обновить Obtainium до последней версии → Использовать SAI как резервный установщик # «Приложение не обновляется, хотя версия новее» → Проверить фильтры: возможно, новая версия помечена как pre-release → Очистить кэш приложения: Настройки → Приложения → Obtainium → Хранилище → Очистить кэш 🛡 Безопасность Как Obtainium обеспечивает безопасность Механизм Описание Прямая загрузка Никаких прокси - файл скачивается напрямую с сервера разработчика Проверка подписи При обновлении сравнивается подпись нового APK с установленным Открытый исходный код Код Obtainium доступен для аудита на GitHub Нет телеметрии Приложение не собирает данные об использовании Рекомендации по безопасности Добавлять только доверенные репозитории (официальные аккаунты разработчиков) Включить «Проверять подпись при обновлении» в настройках Использовать Shizuku только с доверенными приложениями Регулярно обновлять сам Obtainium Ссылки 📦 Obtainium на F-Droid 🐙 Obtainium на GitHub 🔧 Shizuku на F-Droid 📘 Obtainium Wiki 🔍 Как писать регулярные выражения ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/android/obtainium-guide/","summary":"\u003cp\u003eObtainium - менеджер обновлений для Android, который скачивает приложения \u003cstrong\u003eнапрямую из репозиториев разработчиков\u003c/strong\u003e (GitHub, GitLab, Codeberg, F-Droid), минуя сторонние каталоги.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eЗачем нужен\u003c/strong\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eПолучать обновления быстрее, чем в Google Play / F-Droid\u003c/li\u003e\n\u003cli\u003eИзбегать трекеров и рекламы из сторонних магазинов\u003c/li\u003e\n\u003cli\u003eКонтролировать, какие версии устанавливаются (stable, beta, pre-release)\u003c/li\u003e\n\u003cli\u003eАвтоматизировать обновления без ручного подтверждения\u003c/li\u003e\n\u003c/ul\u003e\n\u003cblockquote\u003e\n\u003cp\u003e💡 Obtainium не хранит приложения - только указывает, где их скачать. Вы всегда знаете источник.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003chr\u003e\n\u003ch2 id=\"-установка\"\u003e📦 Установка\u003c/h2\u003e\n\u003ch3 id=\"скачать\"\u003eСкачать\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://f-droid.org/packages/dev.imranr.obtainium.fdroid/\"\u003eF-Droid (рекомендуется)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/ImranR98/Obtainium/releases\"\u003eGitHub Releases\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"настройка-при-первом-запуске\"\u003eНастройка при первом запуске\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003eОткрыть Obtainium → разрешить «Установка из неизвестных источников» (только для Obtainium)\u003c/li\u003e\n\u003cli\u003eНастройки → \u003cstrong\u003eМетод установки\u003c/strong\u003e → выбрать \u003cstrong\u003eShizuku\u003c/strong\u003e (если настроен) или \u003cstrong\u003eСистемный установщик\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003eНастройки → \u003cstrong\u003eПроверка обновлений\u003c/strong\u003e → задать интервал (рекомендуется: 6–24 часа)\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eОпционально\u003c/strong\u003e:\u003c/p\u003e","title":"Obtainium: Обновления приложений из первоисточников"},{"content":"Shizuku - сервис, который даёт приложениям доступ к системным API Android без root-прав. Работает через ADB (Android Debug Bridge), используя привилегии shell.\nЗачем нужен:\nУстанавливать приложения без подтверждения (Obtainium, SAI) Замораживать/размораживать приложения (Ice Box, Hail) Управлять разрешениями (AppOps, Permission Pilot) Менять настройки системы (DarQ, Naptime) Удалять системные приложения (Canta, AppManager) 💡 Shizuku не даёт полный root - только ограниченный доступ к системным функциям. Безопаснее, чем рут, но мощнее, чем обычное приложение.\n📦 Установка и запуск Шаг 1: Скачать Shizuku F-Droid (рекомендуется) GitHub Releases Шаг 2: Включить режим разработчика Настройки → О телефоне → 7 раз тапнуть по «Версии MIUI» / «Номер сборки» Вернуться в настройки → Дополнительные → Для разработчиков Шаг 3: Включить беспроводную отладку В «Для разработчиков» → ✅ Беспроводная отладка Нажать «Сопряжение по коду» → запомнить код и порт В Shizuku: «Запустить» → «Сопряжение» → ввести код и порт После сопряжения: «Запустить» → сервис запустится Проверить статус:\nСтатус: Работает Версия: 13.x.x ⚠️ После перезагрузки телефона Shizuku нужно запускать заново (процесс не сохраняется).\n🔧 Пример 1: Obtainium + Shizuku Obtainium - менеджер обновлений приложений напрямую из источников (GitHub, GitLab, F-Droid).\nЗачем Shizuku для Obtainium Без Shizuku С Shizuku Ручное подтверждение установки Автоматическая установка Не работает со split-APK Поддержка всех форматов Требует «Неизвестные источники» Установка через системный PM Настройка Установить Obtainium с F-Droid Открыть Obtainium → Настройки → Метод установки Выбрать Shizuku (автоматически определится, если сервис запущен) Добавить приложения для отслеживания: Ввести URL репозитория: https://github.com/user/repo Или выбрать из каталога При обновлении: Obtainium скачает → установит через Shizuku → без подтверждения Пример добавления приложения:\nИсточник: GitHub URL: https://github.com/RikkaApps/Shizuku Фильтр: Releases (stable) Формат: APK 🔧 Пример 2: SAI + Shizuku SAI (Split APKs Installer) - установщик split-APK, XAPK, APKS (форматы, которые не ставятся стандартным установщиком).\nЗачем Shizuku для SAI Без Shizuku С Shizuku Ручное подтверждение для каждого APK Пакетная установка без подтверждения Не работает с некоторыми форматами Поддержка всех split-форматов Ошибки при установке Надёжная установка через системный PM Настройка Установить SAI с F-Droid Открыть SAI → Настройки → Метод установки Выбрать Shizuku (или «Session API + Shizuku» для максимальной совместимости) Установить приложение: Нажать «Установить APK» → выбрать файл .xapk, .apks, .apk SAI распакует → установит через Shizuku → готово Поддерживаемые форматы:\n.apk - обычный пакет .xapk - APK + OBB-данные .apks / .apk-m - split-APK (несколько файлов для разных архитектур) 🔄 Автозапуск Shizuku (опционально) После перезагрузки Shizuku останавливается. Варианты автозапуска:\nВариант 1: Tasker + ADB (без root) # Скрипт для Tasker: start-shizuku.sh adb shell sh /sdcard/Android/data/moe.shizuku.privileged.api/start.sh Настройка:\nУстановить Tasker Создать задачу → «Run Shell» → команда выше Триггер: «Device Boot» Вариант 2: KernelSU / Magisk (с root) Если есть рут - установить Shizuku как системное приложение:\nadb push shizuku.apk /data/local/tmp/ adb shell su -c \u0026#34;pm install /data/local/tmp/shizuku.apk\u0026#34; adb shell su -c \u0026#34;sh /sdcard/Android/data/moe.shizuku.privileged.api/start.sh\u0026#34; Плюс: Shizuku запускается автоматически при загрузке.\n🔍 Диагностика # Проверить, запущен ли Shizuku adb shell sh /sdcard/Android/data/moe.shizuku.privileged.api/start.sh --check # Посмотреть логи Shizuku adb logcat | grep -i shizuku # Проверить доступ приложения к Shizuku adb shell dumpsys package moe.shizuku.privileged.api | grep -A5 \u0026#34;Granted permissions\u0026#34; ⚠️ Частые проблемы # Shizuku не запускается → Перезапустить беспроводную отладку: выключить → включить → Перезагрузить телефон и запустить заново → Проверить, не блокирует ли антивирус/оптимизатор # Obtainium/SAI не видят Shizuku → Убедиться, что сервис запущен (статус «Работает» в приложении) → Перезапустить Shizuku и целевое приложение → Проверить разрешения: Настройки → Приложения → [App] → Разрешения # Ошибка установки «Package parser error» → Файл повреждён - перекачать → Неподдерживаемый формат - проверить версию SAI → Недостаточно места - очистить кэш # Shizuku отключается сам → Настройки → Батарея → [Shizuku] → ✅ Без ограничений → Настройки → Приложения → [Shizuku] → ✅ Автозапуск 🛡 Безопасность Что может делать приложение с доступом к Shizuku Действие Риск Установить/удалить приложение Средний (требует подтверждения пользователя в Obtainium/SAI) Изменить разрешения Средний (только для своего пакета или с явного согласия) Прочитать логи Низкий (только свои логи) Получить доступ к файлам Низкий (только с явного разрешения) Как минимизировать риски Устанавливать Shizuku только с F-Droid или GitHub Предоставлять доступ к Shizuku только доверенным приложениям (Obtainium, SAI, AppManager) Останавливать Shizuku, когда не используется Не включать беспроводную отладку в публичных сетях Ссылки 🔧 Shizuku на F-Droid 📦 Obtainium на F-Droid 📱 SAI на F-Droid 📘 Shizuku Documentation 🔐 Android ADB Docs ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/android/shizuku-guide/","summary":"\u003cp\u003eShizuku - сервис, который даёт приложениям доступ к системным API Android \u003cstrong\u003eбез root-прав\u003c/strong\u003e. Работает через ADB (Android Debug Bridge), используя привилегии \u003ccode\u003eshell\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eЗачем нужен\u003c/strong\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eУстанавливать приложения без подтверждения (Obtainium, SAI)\u003c/li\u003e\n\u003cli\u003eЗамораживать/размораживать приложения (Ice Box, Hail)\u003c/li\u003e\n\u003cli\u003eУправлять разрешениями (AppOps, Permission Pilot)\u003c/li\u003e\n\u003cli\u003eМенять настройки системы (DarQ, Naptime)\u003c/li\u003e\n\u003cli\u003eУдалять системные приложения (Canta, AppManager)\u003c/li\u003e\n\u003c/ul\u003e\n\u003cblockquote\u003e\n\u003cp\u003e💡 Shizuku не даёт полный root - только ограниченный доступ к системным функциям. Безопаснее, чем рут, но мощнее, чем обычное приложение.\u003c/p\u003e","title":"Shizuku: Системные возможности Android без root"},{"content":"Иногда на NixOS нужно запустить программу, которая есть только для Ubuntu/Debian или распространяется в виде .deb/.iso. Distrobox позволяет запустить её в контейнере, но с интеграцией в систему хоста - как нативное приложение.\n💡 Метод работает на любом дистрибутиве с установленным Nix.\n📦 Создание контейнера # Создать контейнер с пробросом нужных директорий nix shell nixpkgs#distrobox --command distrobox create \\ --image ubuntu:20.04 \\ --name \u0026lt;container-name\u0026gt; \\ --volume \u0026#34;\u0026lt;volume_pts\u0026gt;:/dev/pts\u0026#34; \\ --volume \u0026#34;\u0026lt;volume_journal\u0026gt;:/var/log/journal\u0026#34; \\ --home \u0026#34;$HOME/\u0026lt;container-name\u0026gt;-home\u0026#34; Параметры:\n--image - базовый образ (ubuntu:20.04, debian:11, etc.) --volume - проброс директорий (аудио, логи) --home - отдельная домашняя директория внутри контейнера --name - имя контейнера (используется в других командах) Войти в контейнер:\nnix shell nixpkgs#distrobox --command distrobox enter \u0026lt;container-name\u0026gt; 🔧 Установка программы внутри контейнера # Внутри контейнера (после distrobox enter) sudo sh -c \u0026#39; # Очистка старых конфигов rm -rf /etc/apt/sources.list.d/\u0026lt;vendor\u0026gt;.list* umount /mnt/\u0026lt;vendor\u0026gt; 2\u0026gt;/dev/null || true # Скачивание и монтирование образа wget -O /tmp/\u0026lt;vendor\u0026gt;.iso \u0026#34;https://\u0026lt;url\u0026gt;/\u0026lt;vendor\u0026gt;.iso\u0026#34; mkdir -p /mnt/\u0026lt;vendor\u0026gt; mount -o loop,ro -t iso9660 /tmp/\u0026lt;vendor\u0026gt;.iso /mnt/\u0026lt;vendor\u0026gt; # Установка из локального репозитория echo \u0026#34;deb [trusted=yes] file:/mnt/\u0026lt;vendor\u0026gt;/repo ./\u0026#34; \u0026gt; /etc/apt/sources.list.d/\u0026lt;vendor\u0026gt;.list apt update apt install -y \u0026lt;package-name\u0026gt;-full # Уборка umount /mnt/\u0026lt;vendor\u0026gt; rm -f /etc/apt/sources.list.d/\u0026lt;vendor\u0026gt;.list /tmp/\u0026lt;vendor\u0026gt;.iso \u0026#39; Заменить плейсхолдеры:\nПлейсхолдер Описание \u0026lt;vendor\u0026gt; Имя вендора (например, nausoftphone) \u0026lt;package-name\u0026gt; Имя пакета в репозитории \u0026lt;url\u0026gt; Ссылка на установочный образ Проверить:\n\u0026lt;package-name\u0026gt; --version 🖥 Ярлык для запуска (.desktop) # ~/.local/share/applications/\u0026lt;app\u0026gt;-distrobox.desktop [Desktop Entry] Version=1.0 Type=Application Name=\u0026lt;App Name\u0026gt; (Distrobox) Comment=Run \u0026lt;App Name\u0026gt; inside Distrobox container Exec=konsole --hold -e bash -c \u0026#39;nix shell nixpkgs#distrobox --command distrobox enter --name \u0026lt;container-name\u0026gt; -- \u0026lt;app-command\u0026gt;\u0026#39; Icon=\u0026lt;icon-name\u0026gt; Terminal=false Categories=Network;AudioVideo; Keywords=\u0026lt;app\u0026gt;;distrobox;container; Применить:\nupdate-desktop-database ~/.local/share/applications/ Теперь приложение доступно в меню, лаунчерах и поиске.\n🔄 Обновление программы # Войти в контейнер nix shell nixpkgs#distrobox --command distrobox enter \u0026lt;container-name\u0026gt; # Обновить пакет sudo apt update \u0026amp;\u0026amp; sudo apt install --only-upgrade \u0026lt;package-name\u0026gt;-full 🗑 Полное удаление (контейнер + volumes) # 1. Удалить контейнер distrobox rm \u0026lt;container-name\u0026gt; # 2. Удалить привязанные volumes (если создавались отдельно) # Для Podman: podman volume rm \u0026lt;volume_pts\u0026gt; \u0026lt;volume_journal\u0026gt; # Для Docker: docker volume rm \u0026lt;volume_pts\u0026gt; \u0026lt;volume_journal\u0026gt; # 3. Удалить домашнюю директорию контейнера (если использовалась) rm -rf \u0026#34;$HOME/\u0026lt;container-name\u0026gt;-home\u0026#34; # 4. Удалить ярлык rm -f ~/.local/share/applications/\u0026lt;app\u0026gt;-distrobox.desktop update-desktop-database ~/.local/share/applications/ ⚠️ Удаление volumes необратимо - убедитесь, что внутри нет нужных данных.\nПроверить, что всё удалено:\n# Контейнеры distrobox list | grep \u0026lt;container-name\u0026gt; # Volumes (Podman) podman volume ls | grep \u0026lt;volume_pts\u0026gt; # Volumes (Docker) docker volume ls | grep \u0026lt;volume_pts\u0026gt; ⚙️ Оптимизация запуска Скрыть терминал (для готовых решений) # Заменить Exec на: Exec=sh -c \u0026#39;nix shell nixpkgs#distrobox --command distrobox enter --name \u0026lt;container-name\u0026gt; -- \u0026lt;app-command\u0026gt;\u0026#39; \u0026gt;\u0026gt; ~/.cache/\u0026lt;app\u0026gt;.log 2\u0026gt;\u0026amp;1 \u0026amp; Проброс аудио (если не работает) # Добавить при создании контейнера: --volume \u0026#34;$XDG_RUNTIME_DIR/pulse:/run/user/1000/pulse\u0026#34; # Или для PipeWire: --volume \u0026#34;$XDG_RUNTIME_DIR/pipewire-0:/run/user/1000/pipewire-0\u0026#34; ⚠️ Частые проблемы # Ярлык не появляется → Проверить синтаксис: desktop-file-validate ~/.local/share/applications/\u0026lt;app\u0026gt;-distrobox.desktop → Обновить кэш: update-desktop-database ~/.local/share/applications/ # Контейнер не запускается после обновления Nix → Пересоздать: distrobox rm \u0026lt;name\u0026gt; \u0026amp;\u0026amp; создать заново → Данные в --home сохранятся, если не удалять директорию вручную # Нет доступа к аудио/устройствам → Проверить проброс volumes при создании контейнера → Убедиться, что пользователь в нужных группах (audio, input) # Volume не удаляется (\u0026#34;in use\u0026#34;) → Убедиться, что контейнер остановлен: distrobox list → Остановить принудительно: podman stop \u0026lt;container-name\u0026gt; || docker stop \u0026lt;container-name\u0026gt; Ссылки 🐧 Distrobox Docs 🦊 NixOS Wiki: Distrobox 🖥 Desktop Entry Spec ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/linux/nix/distrobox-apps/","summary":"\u003cp\u003eИногда на NixOS нужно запустить программу, которая есть только для Ubuntu/Debian или распространяется в виде \u003ccode\u003e.deb\u003c/code\u003e/\u003ccode\u003e.iso\u003c/code\u003e. Distrobox позволяет запустить её в контейнере, но с интеграцией в систему хоста - как нативное приложение.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e💡 Метод работает на любом дистрибутиве с установленным Nix.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003chr\u003e\n\u003ch2 id=\"-создание-контейнера\"\u003e📦 Создание контейнера\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Создать контейнер с пробросом нужных директорий\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enix shell nixpkgs#distrobox --command distrobox create \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --image ubuntu:20.04 \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --name \u0026lt;container-name\u0026gt; \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --volume \u003cspan class=\"s2\"\u003e\u0026#34;\u0026lt;volume_pts\u0026gt;:/dev/pts\u0026#34;\u003c/span\u003e \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --volume \u003cspan class=\"s2\"\u003e\u0026#34;\u0026lt;volume_journal\u0026gt;:/var/log/journal\u0026#34;\u003c/span\u003e \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --home \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$HOME\u003c/span\u003e\u003cspan class=\"s2\"\u003e/\u0026lt;container-name\u0026gt;-home\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003cstrong\u003eПараметры\u003c/strong\u003e:\u003c/p\u003e","title":"NixOS: Запуск «чужих» программ через Distrobox"},{"content":"Docker Desktop на Windows использует WSL2 с динамическими VHDX-файлами. Они растут, когда добавляются образы/контейнеры, но не сжимаются автоматически при удалении. Результат: диск C: заполняется, хотя docker system df показывает свободное место.\n💡 Решение: ручная оптимизация VHDX через PowerShell + утилита Docker.\n📦 Скрипт очистки Создание файла # Файл: $HOME\\Scripts\\docker-clear-wsl.ps1 $script = @\u0026#39; $LOCAL = \u0026#34;$env:LOCALAPPDATA\\Docker\\wsl\u0026#34; $VHD1 = Join-Path $LOCAL \u0026#34;disk\\docker_data.vhdx\u0026#34; $VHD2 = Join-Path $LOCAL \u0026#34;main\\ext4.vhdx\u0026#34; # 1. Очистка Docker docker system prune -f # 2. Возврат места через официальный инструмент docker run --rm --privileged --pid=host docker/desktop-reclaim-space docker rmi docker/desktop-reclaim-space -f # 3. Остановка Docker Desktop Get-Process -Name \u0026#34;Docker Desktop\u0026#34;,\u0026#34;com.docker.backend\u0026#34;,\u0026#34;com.docker.build\u0026#34; ` -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue # 4. Выключение WSL wsl --shutdown # 5. Оптимизация VHDX-файлов (сжатие) if (Test-Path $VHD1) { Optimize-VHD -Path $VHD1 -Mode Full } if (Test-Path $VHD2) { Optimize-VHD -Path $VHD2 -Mode Full } # 6. Запуск Docker Desktop Start-Sleep -Seconds 2 Start-Process -FilePath \u0026#34;$env:ProgramFiles\\Docker\\Docker\\Docker Desktop.exe\u0026#34; ` -ErrorAction SilentlyContinue \u0026#39;@ $script | Out-File -FilePath \u0026#34;$HOME\\Scripts\\docker-clear-wsl.ps1\u0026#34; -Encoding UTF8 Запуск # От имени Администратора (требуется для Optimize-VHD) powershell.exe -ExecutionPolicy Bypass -File \u0026#34;$HOME\\Scripts\\docker-clear-wsl.ps1\u0026#34; 🔍 Как это работает Шаг Команда Что делает 1 docker system prune -f Удаляет остановленные контейнеры, неиспользуемые образы, кэш 2 docker/desktop-reclaim-space Официальный инструмент Docker для возврата места в WSL2 3 Stop-Process Корректно останавливает Docker Desktop (иначе VHDX заблокирован) 4 wsl --shutdown Полностью выключает WSL, освобождая файлы для оптимизации 5 Optimize-VHD -Mode Full Сжимает VHDX-файлы, возвращая место на хосте 6 Start-Process Запускает Docker Desktop обратно Почему именно так:\nБез остановки процессов Optimize-VHD не сработает (файл занят) docker/desktop-reclaim-space работает внутри WSL, удаляя «призрачные» данные Mode Full - максимальное сжатие (медленнее, но эффективнее) ⚙️ Автоматизация Через Планировщик заданий (GUI) Открой Task Scheduler → Create Basic Task Trigger: Weekly (например, воскресенье, 03:00) Action: Start a program Program: powershell.exe Arguments: -ExecutionPolicy Bypass -File \u0026quot;C:\\Users\\ponfertato\\Scripts\\docker-clear-wsl.ps1\u0026quot; Settings: ✅ Run with highest privileges Через PowerShell (скриптом) # Создать задачу от имени Администратора $action = New-ScheduledTaskAction -Execute \u0026#34;powershell.exe\u0026#34; ` -Argument \u0026#34;-ExecutionPolicy Bypass -File `\u0026#34;$HOME\\Scripts\\docker-clear-wsl.ps1`\u0026#34;\u0026#34; $trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Sunday -At 3am $principal = New-ScheduledTaskPrincipal -UserId \u0026#34;SYSTEM\u0026#34; -RunLevel Highest Register-ScheduledTask -TaskName \u0026#34;Docker WSL Cleanup\u0026#34; ` -Action $action -Trigger $trigger -Principal $principal Проверка и запуск вручную # Запустить задачу Start-ScheduledTask -TaskName \u0026#34;Docker WSL Cleanup\u0026#34; # Проверить статус Get-ScheduledTask -TaskName \u0026#34;Docker WSL Cleanup\u0026#34; | Get-ScheduledTaskInfo # Просмотреть историю Get-WinEvent -FilterHashtable @{LogName=\u0026#39;Microsoft-Windows-TaskScheduler/Operational\u0026#39;; TaskName=\u0026#39;Docker WSL Cleanup\u0026#39;} -MaxEvents 10 📊 Мониторинг результата До и после # Размер VHDX до очистки Get-ChildItem \u0026#34;$env:LOCALAPPDATA\\Docker\\wsl\\disk\\docker_data.vhdx\u0026#34; | Select Name, @{N=\u0026#34;SizeGB\u0026#34;;E={[math]::Round($_.Length/1GB,2)}} # После очистки - сравнить значение Статистика Docker # Общая статистика docker system df # Детализация docker system df -v Ожидаемый результат:\ndocker system df покажет меньше данных Размер .vhdx на диске уменьшится (иногда в 2-5 раз) ⚠️ Безопасность и нюансы Требования Требование Почему важно Запуск от Администратора Optimize-VHD требует повышенных прав Закрытые приложения, использующие WSL Иначе wsl --shutdown не выполнится Резервная копия критичных данных На случай сбоя (маловероятно, но возможно) Если что-то пошло не так # Docker не запускается после очистки → Запусти вручную: \u0026#34;$env:ProgramFiles\\Docker\\Docker\\Docker Desktop.exe\u0026#34; → Проверь логи: Get-Content \u0026#34;$env:LOCALAPPDATA\\Docker\\log.txt\u0026#34; -Tail 50 # VHDX не сжался → Убедись, что Docker и WSL полностью остановлены: wsl --list --verbose → Попробуй вручную: Optimize-VHD -Path \u0026#34;C:\\path\\to\\docker_data.vhdx\u0026#34; -Mode Full # Ошибка \u0026#34;Access denied\u0026#34; → Запусти PowerShell от имени Администратора → Проверь антивирус: может блокировать доступ к VHDX Исключение из очистки (опционально) Если нужно сохранить определённые образы:\n# Перед prune пометить образы docker tag my-important-image my-important-image:keep docker system prune -f --filter \u0026#34;label!=keep\u0026#34; 🗂 Чеклист перед запуском Закрыл все приложения, использующие Docker/WSL Запустил PowerShell от имени Администратора Проверил свободное место на C: (нужно ~10% от размера VHDX для сжатия) Убедился, что критичные данные сохранены или помечены Протестировал на одном VHDX перед полной очисткой Ссылки 🐳 Docker Desktop WSL2 Backend 🔧 Optimize-VHD Docs 🗑️ docker system prune 🔄 Reclaim disk space in WSL2 ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/docker/wsl-cleanup/","summary":"\u003cp\u003eDocker Desktop на Windows использует WSL2 с динамическими VHDX-файлами. Они \u003cstrong\u003eрастут\u003c/strong\u003e, когда добавляются образы/контейнеры, но \u003cstrong\u003eне сжимаются автоматически\u003c/strong\u003e при удалении. Результат: диск \u003ccode\u003eC:\u003c/code\u003e заполняется, хотя \u003ccode\u003edocker system df\u003c/code\u003e показывает свободное место.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e💡 Решение: ручная оптимизация VHDX через PowerShell + утилита Docker.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003chr\u003e\n\u003ch2 id=\"-скрипт-очистки\"\u003e📦 Скрипт очистки\u003c/h2\u003e\n\u003ch3 id=\"создание-файла\"\u003eСоздание файла\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-powershell\" data-lang=\"powershell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e# Файл: $HOME\\Scripts\\docker-clear-wsl.ps1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$script\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u003c/span\u003e \u003cspan class=\"sh\"\u003e@\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003e$LOCAL = \u0026#34;$env:LOCALAPPDATA\\Docker\\wsl\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003e$VHD1 = Join-Path $LOCAL \u0026#34;disk\\docker_data.vhdx\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003e$VHD2 = Join-Path $LOCAL \u0026#34;main\\ext4.vhdx\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003e# 1. Очистка Docker\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003edocker system prune -f\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003e# 2. Возврат места через официальный инструмент\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003edocker run --rm --privileged --pid=host docker/desktop-reclaim-space\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003edocker rmi docker/desktop-reclaim-space -f\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003e# 3. Остановка Docker Desktop\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003eGet-Process -Name \u0026#34;Docker Desktop\u0026#34;,\u0026#34;com.docker.backend\u0026#34;,\u0026#34;com.docker.build\u0026#34; `\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003e  -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003e# 4. Выключение WSL\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003ewsl --shutdown\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003e# 5. Оптимизация VHDX-файлов (сжатие)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003eif (Test-Path $VHD1) { Optimize-VHD -Path $VHD1 -Mode Full }\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003eif (Test-Path $VHD2) { Optimize-VHD -Path $VHD2 -Mode Full }\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003e# 6. Запуск Docker Desktop\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003eStart-Sleep -Seconds 2\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003eStart-Process -FilePath \u0026#34;$env:ProgramFiles\\Docker\\Docker\\Docker Desktop.exe\u0026#34; `\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003e  -ErrorAction SilentlyContinue\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"sh\"\u003e\u0026#39;@\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$script\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"nb\"\u003eOut-File\u003c/span\u003e \u003cspan class=\"n\"\u003e-FilePath\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$HOME\u003c/span\u003e\u003cspan class=\"s2\"\u003e\\Scripts\\docker-clear-wsl.ps1\u0026#34;\u003c/span\u003e \u003cspan class=\"n\"\u003e-Encoding\u003c/span\u003e \u003cspan class=\"n\"\u003eUTF8\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"запуск\"\u003eЗапуск\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-powershell\" data-lang=\"powershell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e# От имени Администратора (требуется для Optimize-VHD)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003epowershell\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"py\"\u003eexe\u003c/span\u003e \u003cspan class=\"n\"\u003e-ExecutionPolicy\u003c/span\u003e \u003cspan class=\"n\"\u003eBypass\u003c/span\u003e \u003cspan class=\"o\"\u003e-File\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$HOME\u003c/span\u003e\u003cspan class=\"s2\"\u003e\\Scripts\\docker-clear-wsl.ps1\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"-как-это-работает\"\u003e🔍 Как это работает\u003c/h2\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eШаг\u003c/th\u003e\n          \u003cth\u003eКоманда\u003c/th\u003e\n          \u003cth\u003eЧто делает\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e1\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003edocker system prune -f\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eУдаляет остановленные контейнеры, неиспользуемые образы, кэш\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e2\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003edocker/desktop-reclaim-space\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eОфициальный инструмент Docker для возврата места в WSL2\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e3\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003eStop-Process\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eКорректно останавливает Docker Desktop (иначе VHDX заблокирован)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e4\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003ewsl --shutdown\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eПолностью выключает WSL, освобождая файлы для оптимизации\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e5\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003eOptimize-VHD -Mode Full\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eСжимает VHDX-файлы, возвращая место на хосте\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e6\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003eStart-Process\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eЗапускает Docker Desktop обратно\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e\u003cstrong\u003eПочему именно так\u003c/strong\u003e:\u003c/p\u003e","title":"Docker WSL: Очистка и оптимизация дисков"},{"content":"В долгосрочных проектах накапливаются устаревшие задачи: баги для старых версий, фичи, которые уже не актуальны, тестовые тикеты. Ручное удаление - долго и скучно. Этот скрипт автоматически находит и удаляет (или помечает) старые задачи по заданным меткам.\n💡 Скрипт использует dry-run по умолчанию - сначала покажет, что будет удалено, без реального удаления.\n📦 Скрипт: delete-issues.sh Полный код #!/bin/bash # Удаление старых GitHub Issues по меткам и дате # Использование: ./delete-issues.sh [--execute] set -euo pipefail # === НАСТРОЙКИ === REPO=\u0026#34;owner/repo\u0026#34; # Репозиторий в формате owner/repo LABELS=\u0026#39;label1,label2,label3\u0026#39; # Метки для фильтрации (через запятую) CUTOFF=\u0026#34;2025-12-31T23:59:59Z\u0026#34; # Удалять задачи, созданные ДО этой даты DRY_RUN=true # true = только показать, false = реально удалить # Парсинг аргументов if [[ \u0026#34;${1:-}\u0026#34; == \u0026#34;--execute\u0026#34; ]]; then DRY_RUN=false echo \u0026#34;⚠️ Режим: РЕАЛЬНОЕ УДАЛЕНИЕ\u0026#34; else echo \u0026#34;ℹ️ Режим: DRY RUN (ничего не будет удалено)\u0026#34; fi echo \u0026#34;🔍 Поиск задач в $REPO с метками: $LABELS, созданных до $CUTOFF\u0026#34; echo \u0026#34;---\u0026#34; # Получение и фильтрация задач gh issue list --repo \u0026#34;$REPO\u0026#34; --state all --limit 1000 \\ --json number,title,createdAt,labels,url | \\ jq -r --arg labels \u0026#34;$LABELS\u0026#34; --arg cutoff \u0026#34;$CUTOFF\u0026#34; \u0026#39; ($labels | split(\u0026#34;,\u0026#34;)) as $label_array | .[] | select(.createdAt \u0026lt; $cutoff) | select(.labels | map(.name) | any(. as $l | $label_array | index($l))) | \u0026#34;\\(.number)|\\(.title)|\\(.url)\u0026#34; \u0026#39; | \\ while IFS=\u0026#39;|\u0026#39; read -r number title url; do if [[ \u0026#34;$DRY_RUN\u0026#34; == \u0026#34;true\u0026#34; ]]; then echo \u0026#34;[DRY RUN] ##$number - $title\u0026#34; echo \u0026#34; $url\u0026#34; else echo \u0026#34;🗑 Удаление ##$number - $title\u0026#34; gh issue delete \u0026#34;$REPO\u0026#34; \u0026#34;$number\u0026#34; --yes sleep 1 # Небольшая пауза, чтобы не превысить rate limit fi done echo \u0026#34;---\u0026#34; echo \u0026#34;✅ Готово\u0026#34; Установка зависимостей # GitHub CLI # Windows (winget): winget install GitHub.cli # Linux (Ubuntu/Debian): sudo apt install gh # macOS (Homebrew): brew install gh # Авторизация gh auth login # jq (JSON-процессор) # Windows (winget): winget install jq.jq # Linux: sudo apt install jq # macOS: brew install jq Запуск # Сделать скрипт исполняемым chmod +x delete-issues.sh # DRY RUN (безопасный режим - только показать) ./delete-issues.sh # РЕАЛЬНОЕ УДАЛЕНИЕ (добавить флаг --execute) ./delete-issues.sh --execute 🔍 Как это работает Пошаговый разбор Шаг Команда Что делает 1 gh issue list --json ... Получает задачи в формате JSON с полями: номер, заголовок, дата, метки, ссылка 2 jq -r ... Фильтрует: дата \u0026lt; cutoff И есть хотя бы одна из указанных меток 3 while read ... Обрабатывает каждую найденную задачу 4 gh issue delete Удаляет задачу (только если DRY_RUN=false) Логика jq-фильтра ($labels | split(\u0026#34;,\u0026#34;)) as $label_array | # Разбиваем строку меток в массив .[] | # Для каждой задачи select(.createdAt \u0026lt; $cutoff) | # Только если создана до cutoff select( .labels | map(.name) | # Получаем список имён меток any(. as $l | $label_array | index($l)) # Есть ли совпадение с нашими метками ) | \u0026#34;\\(.number)|\\(.title)|\\(.url)\u0026#34; # Форматируем вывод Почему так:\nsplit(\u0026quot;,\u0026quot;) - позволяет задавать метки одной строкой any(...) - проверяет наличие любой из указанных меток (логическое ИЛИ) Формат вывода через | - надёжный способ передать заголовок с пробелами ⚙️ Адаптация под свои задачи Пример 1: Удалить старые баги REPO=\u0026#34;myorg/myproject\u0026#34; LABELS=\u0026#39;bug,critical\u0026#39; CUTOFF=\u0026#34;2024-01-01T00:00:00Z\u0026#34; # Удалить баги до 2024 года Пример 2: Архивировать, а не удалять Замените блок удаления на закрытие:\n# Вместо gh issue delete: echo \u0026#34;🔒 Закрытие ##$number - $title\u0026#34; gh issue edit \u0026#34;$REPO\u0026#34; \u0026#34;$number\u0026#34; --state closed Пример 3: Экспорт перед удалением (резервная копия) # Добавить перед удалением: echo \u0026#34;💾 Экспорт ##$number\u0026#34; gh issue view \u0026#34;$REPO\u0026#34; \u0026#34;$number\u0026#34; --json title,body,comments \u0026gt;\u0026gt; backup-issues.jsonl 🛡 Безопасность Обязательные проверки перед запуском # 1. Проверить, что выбранные задачи - действительно те, что нужно ./delete-issues.sh | grep -c \u0026#34;\\[DRY RUN\\]\u0026#34; # Посчитать количество # 2. Убедиться, что в списке нет важных задач ./delete-issues.sh | grep -i \u0026#34;critical\\|important\u0026#34; # 3. Проверить права доступа gh api /repos/$REPO | jq \u0026#39;.permissions.admin\u0026#39; # Должно быть true Rate limits GitHub API Тип Лимит Как не превысить Авторизованный 5000 запросов/час sleep 1 между удалениями Без авторизации 60 запросов/час Всегда использовать gh auth login Проверить остаток лимита:\ngh api rate_limit | jq \u0026#39;.resources.core\u0026#39; 📊 Альтернативы и расширения Только показать статистику (без удаления) gh issue list --repo \u0026#34;$REPO\u0026#34; --state all --limit 1000 \\ --json createdAt,labels | \\ jq -r --arg labels \u0026#34;$LABELS\u0026#34; --arg cutoff \u0026#34;$CUTOFF\u0026#34; \u0026#39; ($labels|split(\u0026#34;,\u0026#34;)) as $label_array | [.[] | select(.createdAt \u0026lt; $cutoff) | select(.labels | map(.name) | any(. as $l | $label_array | index($l)))] | length \u0026#39; Удаление по автору + меткам select(.author.login == \u0026#34;bot-user\u0026#34;) | select(.labels | map(.name) | any(. as $l | $label_array | index($l))) Экспорт в CSV перед удалением # Добавить в jq-вывод: \u0026#34;\\(.number),\\\u0026#34;\\(.title)\\\u0026#34;,\\(.createdAt),\\(.url)\u0026#34; ⚠️ Частые проблемы # \u0026#34;gh: command not found\u0026#34; → Установить GitHub CLI: https://cli.github.com # \u0026#34;jq: error: syntax error\u0026#34; → Проверить кавычки в команде: использовать одинарные для jq, двойные для bash # \u0026#34;HTTP 404: Not Found\u0026#34; → Проверить имя репозитория: должно быть owner/repo → Убедиться, что у токена есть права на чтение issues # \u0026#34;rate limit exceeded\u0026#34; → Подождать сброса лимита или добавить задержку: sleep 2 # Удалил не то! → Всегда запускать сначала без --execute → Делать бэкап: gh issue list --json ... \u0026gt; backup.json 🗂 Чеклист перед запуском Установил gh и jq, выполнил gh auth login Проверил права на репозиторий: gh api /repos/owner/repo Протестировал в dry-run режиме, проверил список задач Убедился, что в списке нет критичных задач При необходимости - сделал экспорт: gh issue list --json ... \u0026gt; backup.json Только после этого - запуск с --execute Ссылки 🐙 GitHub CLI Docs 🔍 gh issue list 🗑️ gh issue delete 🧰 jq Manual 🔐 GitHub API Rate Limits ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/git/delete-issues/","summary":"\u003cp\u003eВ долгосрочных проектах накапливаются устаревшие задачи: баги для старых версий, фичи, которые уже не актуальны, тестовые тикеты. Ручное удаление - долго и скучно. Этот скрипт автоматически находит и удаляет (или помечает) старые задачи по заданным меткам.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e💡 Скрипт использует \u003cstrong\u003edry-run по умолчанию\u003c/strong\u003e - сначала покажет, что будет удалено, без реального удаления.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003chr\u003e\n\u003ch2 id=\"-скрипт-delete-issuessh\"\u003e📦 Скрипт: delete-issues.sh\u003c/h2\u003e\n\u003ch3 id=\"полный-код\"\u003eПолный код\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#!/bin/bash\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Удаление старых GitHub Issues по меткам и дате\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Использование: ./delete-issues.sh [--execute]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eset\u003c/span\u003e -euo pipefail\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# === НАСТРОЙКИ ===\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003eREPO\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;owner/repo\u0026#34;\u003c/span\u003e                          \u003cspan class=\"c1\"\u003e# Репозиторий в формате owner/repo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003eLABELS\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;label1,label2,label3\u0026#39;\u003c/span\u003e              \u003cspan class=\"c1\"\u003e# Метки для фильтрации (через запятую)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003eCUTOFF\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;2025-12-31T23:59:59Z\u0026#34;\u003c/span\u003e             \u003cspan class=\"c1\"\u003e# Удалять задачи, созданные ДО этой даты\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003eDRY_RUN\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nb\"\u003etrue\u003c/span\u003e                               \u003cspan class=\"c1\"\u003e# true = только показать, false = реально удалить\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Парсинг аргументов\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"o\"\u003e[[\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nv\"\u003e1\u003c/span\u003e\u003cspan class=\"k\"\u003e:-\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;--execute\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e]]\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003ethen\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nv\"\u003eDRY_RUN\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;⚠️  Режим: РЕАЛЬНОЕ УДАЛЕНИЕ\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;ℹ️  Режим: DRY RUN (ничего не будет удалено)\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efi\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;🔍 Поиск задач в \u003c/span\u003e\u003cspan class=\"nv\"\u003e$REPO\u003c/span\u003e\u003cspan class=\"s2\"\u003e с метками: \u003c/span\u003e\u003cspan class=\"nv\"\u003e$LABELS\u003c/span\u003e\u003cspan class=\"s2\"\u003e, созданных до \u003c/span\u003e\u003cspan class=\"nv\"\u003e$CUTOFF\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;---\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Получение и фильтрация задач\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egh issue list --repo \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$REPO\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e --state all --limit \u003cspan class=\"m\"\u003e1000\u003c/span\u003e \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --json number,title,createdAt,labels,url \u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  jq -r --arg labels \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$LABELS\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e --arg cutoff \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$CUTOFF\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e    ($labels | split(\u0026#34;,\u0026#34;)) as $label_array |\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e    .[] |\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e    select(.createdAt \u0026lt; $cutoff) |\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e    select(.labels | map(.name) | any(. as $l | $label_array | index($l))) |\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e    \u0026#34;\\(.number)|\\(.title)|\\(.url)\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e  \u0026#39;\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"nv\"\u003eIFS\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;|\u0026#39;\u003c/span\u003e \u003cspan class=\"nb\"\u003eread\u003c/span\u003e -r number title url\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003edo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"o\"\u003e[[\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$DRY_RUN\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;true\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e]]\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003ethen\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;[DRY RUN] ##\u003c/span\u003e\u003cspan class=\"nv\"\u003e$number\u003c/span\u003e\u003cspan class=\"s2\"\u003e - \u003c/span\u003e\u003cspan class=\"nv\"\u003e$title\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;          \u003c/span\u003e\u003cspan class=\"nv\"\u003e$url\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;🗑  Удаление ##\u003c/span\u003e\u003cspan class=\"nv\"\u003e$number\u003c/span\u003e\u003cspan class=\"s2\"\u003e - \u003c/span\u003e\u003cspan class=\"nv\"\u003e$title\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      gh issue delete \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$REPO\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$number\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e --yes\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      sleep \u003cspan class=\"m\"\u003e1\u003c/span\u003e  \u003cspan class=\"c1\"\u003e# Небольшая пауза, чтобы не превысить rate limit\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003efi\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"k\"\u003edone\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;---\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;✅ Готово\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"установка-зависимостей\"\u003eУстановка зависимостей\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# GitHub CLI\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Windows (winget):\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ewinget install GitHub.cli\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Linux (Ubuntu/Debian):\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo apt install gh\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# macOS (Homebrew):\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ebrew install gh\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Авторизация\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egh auth login\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# jq (JSON-процессор)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Windows (winget):\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ewinget install jq.jq\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Linux:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo apt install jq\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# macOS:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ebrew install jq\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"запуск\"\u003eЗапуск\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Сделать скрипт исполняемым\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod +x delete-issues.sh\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# DRY RUN (безопасный режим - только показать)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e./delete-issues.sh\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# РЕАЛЬНОЕ УДАЛЕНИЕ (добавить флаг --execute)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e./delete-issues.sh --execute\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"-как-это-работает\"\u003e🔍 Как это работает\u003c/h2\u003e\n\u003ch3 id=\"пошаговый-разбор\"\u003eПошаговый разбор\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eШаг\u003c/th\u003e\n          \u003cth\u003eКоманда\u003c/th\u003e\n          \u003cth\u003eЧто делает\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e1\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003egh issue list --json ...\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eПолучает задачи в формате JSON с полями: номер, заголовок, дата, метки, ссылка\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e2\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003ejq -r ...\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eФильтрует: дата \u0026lt; cutoff И есть хотя бы одна из указанных меток\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e3\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003ewhile read ...\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eОбрабатывает каждую найденную задачу\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e4\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003egh issue delete\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eУдаляет задачу (только если \u003ccode\u003eDRY_RUN=false\u003c/code\u003e)\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"логика-jq-фильтра\"\u003eЛогика jq-фильтра\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode class=\"language-jq\" data-lang=\"jq\"\u003e($labels | split(\u0026#34;,\u0026#34;)) as $label_array |  # Разбиваем строку меток в массив\n.[] |                                      # Для каждой задачи\nselect(.createdAt \u0026lt; $cutoff) |            # Только если создана до cutoff\nselect(\n  .labels | map(.name) |                  # Получаем список имён меток\n  any(. as $l | $label_array | index($l)) # Есть ли совпадение с нашими метками\n) |\n\u0026#34;\\(.number)|\\(.title)|\\(.url)\u0026#34;            # Форматируем вывод\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e\u003cstrong\u003eПочему так\u003c/strong\u003e:\u003c/p\u003e","title":"GitHub CLI: Массовое удаление старых задач"},{"content":"Для домашних серверов и тестовых сред актуальна задача экономии ресурсов: ночью или в нерабочее время контейнеры можно останавливать, а систему - выключать. Это руководство описывает безопасный метод с сохранением состояния и автоматическим восстановлением.\n💡 Метод подходит для OrangePI, Raspberry Pi, старых ПК и любых систем, где важна экономия энергии.\n📦 Скрипт остановки контейнеров и выключения Создание скрипта # Файл: /usr/local/bin/stop_containers_and_shutdown.sh cat \u0026gt; /usr/local/bin/stop_containers_and_shutdown.sh \u0026lt;\u0026lt; \u0026#39;EOF\u0026#39; #!/bin/bash # # Скрипт сохраняет ID запущенных контейнеров, # останавливает их и инициирует завершение работы системы. # CONTAINERS_FILE=\u0026#34;/etc/active_containers.txt\u0026#34; echo \u0026#34;=== $(date \u0026#39;+%Y-%m-%d %H:%M:%S\u0026#39;) ===\u0026#34; echo \u0026#34;Запуск скрипта остановки контейнеров и выключения системы\u0026#34; # Получаем список запущенных контейнеров (по ID) RUNNING_CONTAINERS=$(docker ps -q) if [ -n \u0026#34;${RUNNING_CONTAINERS}\u0026#34; ]; then echo \u0026#34;Сохранение списка запущенных контейнеров в ${CONTAINERS_FILE}\u0026#34; echo \u0026#34;${RUNNING_CONTAINERS}\u0026#34; \u0026gt; \u0026#34;${CONTAINERS_FILE}\u0026#34; docker stop ${RUNNING_CONTAINERS} echo \u0026#34;Контейнеры остановлены.\u0026#34; else echo \u0026#34;Нет запущенных контейнеров.\u0026#34; [ -f \u0026#34;${CONTAINERS_FILE}\u0026#34; ] \u0026amp;\u0026amp; rm -f \u0026#34;${CONTAINERS_FILE}\u0026#34; fi sleep 10 echo \u0026#34;Завершение работы системы.\u0026#34; /sbin/shutdown -h now EOF Сделать исполняемым chmod +x /usr/local/bin/stop_containers_and_shutdown.sh Как работает Шаг Описание docker ps -q Получает ID всех запущенных контейнеров \u0026gt; /etc/active_containers.txt Сохраняет список для восстановления docker stop Корректно останавливает контейнеры (SIGTERM) sleep 10 Даёт время на завершение операций shutdown -h now Выключает систему Почему так:\nСохранение ID позволяет восстановить те же самые контейнеры docker stop даёт контейнерам время на корректное завершение sleep 10 гарантирует, что все данные записаны на диск 🚀 Скрипт запуска контейнеров Создание скрипта # Файл: /usr/local/bin/start_containers.sh cat \u0026gt; /usr/local/bin/start_containers.sh \u0026lt;\u0026lt; \u0026#39;EOF\u0026#39; #!/bin/bash # # Скрипт считывает список контейнеров из файла, # запускает их и затем удаляет файл. # CONTAINERS_FILE=\u0026#34;/etc/active_containers.txt\u0026#34; echo \u0026#34;=== $(date \u0026#39;+%Y-%m-%d %H:%M:%S\u0026#39;) ===\u0026#34; echo \u0026#34;Запуск скрипта старта контейнеров\u0026#34; if [ ! -f \u0026#34;${CONTAINERS_FILE}\u0026#34; ]; then echo \u0026#34;Файл ${CONTAINERS_FILE} не найден. Запуск не требуется.\u0026#34; exit 0 fi CONTAINERS=$(cat \u0026#34;${CONTAINERS_FILE}\u0026#34;) if [ -n \u0026#34;${CONTAINERS}\u0026#34; ]; then echo \u0026#34;Найден список контейнеров: ${CONTAINERS}\u0026#34; for cid in ${CONTAINERS}; do docker start \u0026#34;${cid}\u0026#34; if [ $? -eq 0 ]; then echo \u0026#34;Контейнер ${cid} запущен.\u0026#34; else echo \u0026#34;Ошибка при запуске контейнера ${cid}.\u0026#34; fi done else echo \u0026#34;Файл пуст. Контейнеры запускать не требуется.\u0026#34; fi rm -f \u0026#34;${CONTAINERS_FILE}\u0026#34; echo \u0026#34;Файл ${CONTAINERS_FILE} удалён.\u0026#34; EOF Сделать исполняемым chmod +x /usr/local/bin/start_containers.sh Как работает Шаг Описание Проверка файла Если нет - контейнеры не были остановлены скриптом docker start Запускает контейнеры по сохранённым ID rm -f Удаляет файл после успешного запуска Почему удаление файла:\nОдноразовый маркер - контейнеры не запустятся повторно случайно После перезагрузки без скрипта - система работает в обычном режиме ⏰ Настройка расписания (cron) Остановка (ночью) # crontab -e (от root) # Остановка в 00:00 ежедневно 0 0 * * * /usr/local/bin/stop_containers_and_shutdown.sh \u0026gt;\u0026gt; /var/log/docker-shutdown.log 2\u0026gt;\u0026amp;1 Запуск (утром) # crontab -e (от root) # Запуск в 08:00 ежедневно 0 8 * * * /usr/local/bin/start_containers.sh \u0026gt;\u0026gt; /var/log/docker-startup.log 2\u0026gt;\u0026amp;1 Важные замечания Параметр Описание \u0026gt;\u0026gt; /var/log/... Логирование для отладки 2\u0026gt;\u0026amp;1 Перенаправление ошибок в тот же лог От root Требуется для docker и shutdown Проверка cron:\n# Убедиться, что cron запущен systemctl status cron # Просмотреть логи tail -f /var/log/docker-shutdown.log tail -f /var/log/docker-startup.log 🔧 Альтернатива: systemd timer (современный метод) Таймер на остановку # /etc/systemd/system/docker-shutdown.timer [Unit] Description=Daily Docker shutdown timer [Timer] OnCalendar=*-*-* 00:00:00 Persistent=true [Install] WantedBy=timers.target Сервис на остановку # /etc/systemd/system/docker-shutdown.service [Unit] Description=Stop Docker containers and shutdown After=docker.service [Service] Type=oneshot ExecStart=/usr/local/bin/stop_containers_and_shutdown.sh Активация systemctl daemon-reload systemctl enable docker-shutdown.timer systemctl start docker-shutdown.timer # Проверить статус systemctl list-timers | grep docker-shutdown Преимущества systemd timer:\nТочное время запуска (не зависит от загрузки cron) Встроенное логирование через journalctl Persistent=true - выполнит пропущенный запуск после простоя 🛡 Безопасность и надёжность Исключение критичных контейнеров Если некоторые контейнеры должны работать постоянно:\n# Модификация скрипта остановки RUNNING_CONTAINERS=$(docker ps -q --filter \u0026#34;label=shutdown=false\u0026#34;) # В docker-compose.yml добавить метку services: critical-service: image: ... labels: - \u0026#34;shutdown=false\u0026#34; Проверка перед выключением # Добавить в скрипт остановки ACTIVE_CONNECTIONS=$(netstat -an | grep ESTABLISHED | wc -l) if [ \u0026#34;$ACTIVE_CONNECTIONS\u0026#34; -gt 10 ]; then echo \u0026#34;Обнаружены активные соединения. Отмена выключения.\u0026#34; exit 1 fi Резервное питание (UPS) # Интеграция с NUT (Network UPS Tools) # /etc/nut/upsmon.conf MONITOR ups@localhost 1 admin password slave SHUTDOWNCMD \u0026#34;/usr/local/bin/stop_containers_and_shutdown.sh\u0026#34; 📊 Мониторинг и отладка Проверка логов # Логи скриптов tail -50 /var/log/docker-shutdown.log tail -50 /var/log/docker-startup.log # Логи systemd (если используется) journalctl -u docker-shutdown.service -n 50 journalctl -u docker-startup.service -n 50 Проверка состояния # Какие контейнеры запущены docker ps --format \u0026#34;table {{.Names}}\\t{{.Status}}\u0026#34; # Статус таймеров systemctl list-timers | grep docker # Файл состояния (если существует) cat /etc/active_containers.txt 2\u0026gt;/dev/null || echo \u0026#34;Файл отсутствует\u0026#34; ⚠️ Частые проблемы # Скрипт не выполняется по cron → Проверить права: ls -la /usr/local/bin/*.sh → Проверить cron: grep CRON /var/log/syslog → Убедиться, что cron запущен: systemctl status cron # Контейнеры не запускаются → Проверить Docker: systemctl status docker → Проверить логи: docker logs \u0026lt;container_id\u0026gt; → Убедиться, что файл существует: cat /etc/active_containers.txt # Система не выключается → Проверить, что shutdown доступен: which shutdown → Проверить права: скрипт должен быть от root → Посмотреть логи: journalctl -b -1 (предыдущая загрузка) # Файл не удаляется после запуска → Проверить права на файл: ls -la /etc/active_containers.txt → Удалить вручную: rm -f /etc/active_containers.txt 🗂 Чеклист перед внедрением Протестировал скрипты вручную перед настройкой cron Проверил логирование: /var/log/docker-*.log Убедился, что критичные сервисы исключены (если нужно) Проверил, что данные контейнеров на persistent volumes Настроил уведомления об остановке/запуске (опционально) Создал резервную копию конфигов Ссылки 🐳 Docker Start/Stop Docs ⏰ Cron Documentation 🔧 Systemd Timer Docs 🛡 NUT - UPS Management ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/docker/scheduled-shutdown/","summary":"\u003cp\u003eДля домашних серверов и тестовых сред актуальна задача экономии ресурсов: ночью или в нерабочее время контейнеры можно останавливать, а систему - выключать. Это руководство описывает безопасный метод с сохранением состояния и автоматическим восстановлением.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e💡 Метод подходит для OrangePI, Raspberry Pi, старых ПК и любых систем, где важна экономия энергии.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003chr\u003e\n\u003ch2 id=\"-скрипт-остановки-контейнеров-и-выключения\"\u003e📦 Скрипт остановки контейнеров и выключения\u003c/h2\u003e\n\u003ch3 id=\"создание-скрипта\"\u003eСоздание скрипта\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Файл: /usr/local/bin/stop_containers_and_shutdown.sh\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecat \u0026gt; /usr/local/bin/stop_containers_and_shutdown.sh \u003cspan class=\"s\"\u003e\u0026lt;\u0026lt; \u0026#39;EOF\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e#!/bin/bash\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e#\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e# Скрипт сохраняет ID запущенных контейнеров,\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e# останавливает их и инициирует завершение работы системы.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e#\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003eCONTAINERS_FILE=\u0026#34;/etc/active_containers.txt\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003eecho \u0026#34;=== $(date \u0026#39;+%Y-%m-%d %H:%M:%S\u0026#39;) ===\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003eecho \u0026#34;Запуск скрипта остановки контейнеров и выключения системы\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e# Получаем список запущенных контейнеров (по ID)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003eRUNNING_CONTAINERS=$(docker ps -q)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003eif [ -n \u0026#34;${RUNNING_CONTAINERS}\u0026#34; ]; then\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e    echo \u0026#34;Сохранение списка запущенных контейнеров в ${CONTAINERS_FILE}\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e    echo \u0026#34;${RUNNING_CONTAINERS}\u0026#34; \u0026gt; \u0026#34;${CONTAINERS_FILE}\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e    docker stop ${RUNNING_CONTAINERS}\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e    echo \u0026#34;Контейнеры остановлены.\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003eelse\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e    echo \u0026#34;Нет запущенных контейнеров.\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e    [ -f \u0026#34;${CONTAINERS_FILE}\u0026#34; ] \u0026amp;\u0026amp; rm -f \u0026#34;${CONTAINERS_FILE}\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003efi\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003esleep 10\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003eecho \u0026#34;Завершение работы системы.\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e/sbin/shutdown -h now\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003eEOF\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"сделать-исполняемым\"\u003eСделать исполняемым\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod +x /usr/local/bin/stop_containers_and_shutdown.sh\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"как-работает\"\u003eКак работает\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eШаг\u003c/th\u003e\n          \u003cth\u003eОписание\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003edocker ps -q\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eПолучает ID всех запущенных контейнеров\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003e\u0026gt; /etc/active_containers.txt\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eСохраняет список для восстановления\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003edocker stop\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eКорректно останавливает контейнеры (SIGTERM)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003esleep 10\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eДаёт время на завершение операций\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003eshutdown -h now\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eВыключает систему\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e\u003cstrong\u003eПочему так\u003c/strong\u003e:\u003c/p\u003e","title":"Docker: Автоматическое выключение по расписанию"},{"content":"Docker Volumes хранят данные независимо от контейнеров, но требуют отдельного подхода к резервному копированию. Это руководство описывает универсальные методы работы с volumes на примере популярных сервисов.\n💡 Заменяйте имена volumes на свои. Методы работают с любыми контейнерами.\n📦 Бэкап volumes Через docker-volume-backup (рекомендуется) docker run --rm \\ -v portainer_data:/backup/portainer_data \\ -v postgres_data:/backup/postgres_data \\ -v redis_data:/backup/redis_data \\ -v /opt/docker/backup:/archive \\ --entrypoint backup \\ offen/docker-volume-backup:v2 Параметры:\nПараметр Описание -v \u0026lt;volume\u0026gt;:/backup/\u0026lt;name\u0026gt; Маппинг volume в директорию бэкапа -v /opt/docker/backup:/archive Куда сохранять архив на хосте --entrypoint backup Запускает режим бэкапа --rm Удаляет контейнер после завершения Почему этот метод:\n✅ Один контейнер - все volumes ✅ Автоматическое сжатие в tar.gz ✅ Не требует остановки сервисов (для большинства сценариев) ✅ Подходит для автоматизации по cron Альтернатива: через tar напрямую # Бэкап одного volume docker run --rm \\ -v postgres_data:/volume:ro \\ -v /opt/docker/backup:/backup \\ alpine tar czf /backup/postgres-$(date +%F).tar.gz -C /volume . Особенности:\n:ro - read-only, защита от модификации во время бэкапа Прямое создание архива без промежуточных скриптов Подходит для разовых операций 🔄 Восстановление из бэкапа Шаг 1: Распаковать архив tar -C /tmp -xvf backup-*.tar.gz Шаг 2: Копирование данных в volumes # Portainer docker run -d --name tmp-portainer -v portainer_data:/restore alpine docker cp /tmp/backup/portainer_data tmp-portainer:/restore docker stop tmp-portainer \u0026amp;\u0026amp; docker rm tmp-portainer # PostgreSQL docker run -d --name tmp-postgres -v postgres_data:/restore alpine docker cp /tmp/backup/postgres_data tmp-postgres:/restore docker stop tmp-postgres \u0026amp;\u0026amp; docker rm tmp-postgres # Redis docker run -d --name tmp-redis -v redis_data:/restore alpine docker cp /tmp/backup/redis_data tmp-redis:/restore docker stop tmp-redis \u0026amp;\u0026amp; docker rm tmp-redis Почему через временные контейнеры:\nПрямой доступ к volumes из хоста сложен (путь в /var/lib/docker/volumes/) docker cp сохраняет права и атрибуты файлов Контейнеры удаляются после копирования - чисто и безопасно ⚠️ Рекомендация # Остановить сервисы перед восстановлением docker compose stop postgres redis portainer # Выполнить восстановление # Запустить сервисы docker compose start 🔀 Миграция volumes Копирование в новый volume docker volume create new_volume \u0026amp;\u0026amp; \\ docker run --rm -it \\ -v old_volume:/from \\ -v new_volume:/to \\ alpine ash -c \u0026#39;cd /from \u0026amp;\u0026amp; cp -av . /to\u0026#39; Разбор:\ndocker volume create - создаёт целевой volume -v old_volume:/from - монтирует источник -v new_volume:/to - монтирует приёмник cp -av - копирует с сохранением прав (-a) и прогрессом (-v) Когда использовать:\nПереименование volume Перенос на другой драйвер хранения Очистка от временных файлов (копируем только нужное) Миграция на другой хост # Исходный хост: создать архив docker run --rm \\ -v postgres_data:/data \\ -v /backup:/archive \\ alpine tar czf /archive/postgres.tar.gz -C /data . # Скопировать на новый хост scp /backup/postgres.tar.gz user@newhost:/backup/ # Новый хост: восстановить docker volume create postgres_data docker run --rm \\ -v postgres_data:/data \\ -v /backup:/archive \\ alpine tar xzf /archive/postgres.tar.gz -C /data Преимущества:\nПереносит все данные и права Не зависит от версий Docker Работает через любую сеть (SCP, rsync, HTTPS) 🛠 Автоматизация Через cron на хосте # /etc/crontabs/root - ежедневный бэкап в 03:00 0 3 * * * docker run --rm -v postgres_data:/backup/data -v /opt/backup:/archive --entrypoint backup offen/docker-volume-backup:v2 Через Docker Compose version: \u0026#34;3.8\u0026#34; services: backup: image: offen/docker-volume-backup:v2 container_name: volume-backup environment: BACKUP_CRON_EXPRESSION: \u0026#34;0 3 * * *\u0026#34; BACKUP_RETENTION_DAYS: \u0026#34;7\u0026#34; volumes: - postgres_data:/backup/postgres_data - redis_data:/backup/redis_data - /opt/backup:/archive entrypoint: [\u0026#34;/bin/sh\u0026#34;, \u0026#34;-c\u0026#34;, \u0026#34;backup\u0026#34;] Возможности:\nВстроенная ротация бэкапов Логирование внутри контейнера Поддержка S3-совместимых хранилищ 📊 Проверка целостности # После бэкапа: проверить архив tar -tzf backup-*.tar.gz | head -20 sha256sum backup-*.tar.gz \u0026gt; backup.sha256 # После восстановления: проверить данные docker system df -v | grep postgres_data docker logs postgres --tail 50 ⚠️ Частые проблемы # \u0026#34;volume not found\u0026#34; → docker volume ls | grep \u0026lt;name\u0026gt; → docker volume inspect \u0026lt;name\u0026gt; # \u0026#34;permission denied\u0026#34; → Запускать от root или с sudo → Проверить права: ls -la /opt/docker/backup/ # Бэкап слишком большой → Исключить кэш: tar --exclude=\u0026#39;cache/*\u0026#39; ... → Настроить ротацию: BACKUP_RETENTION_DAYS=7 # Восстановление не работает → Остановить сервис: docker stop \u0026lt;container\u0026gt; → Проверить, что volume не используется: docker ps --filter volume=\u0026lt;name\u0026gt; 🗂 Чеклист Перед бэкапом Проверил место: df -h /opt/docker/backup Остановил БД и критичные сервисы Протестировал на одном volume Перед восстановлением Остановил целевые контейнеры Проверил архив: tar -tzf backup.tar.gz Подготовил план отката Ссылки 🐳 Docker Volumes Docs 🔄 offen/docker-volume-backup 📦 Docker Compose Production ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/docker/volumes-management/","summary":"\u003cp\u003eDocker Volumes хранят данные независимо от контейнеров, но требуют отдельного подхода к резервному копированию. Это руководство описывает универсальные методы работы с volumes на примере популярных сервисов.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e💡 Заменяйте имена volumes на свои. Методы работают с любыми контейнерами.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003chr\u003e\n\u003ch2 id=\"-бэкап-volumes\"\u003e📦 Бэкап volumes\u003c/h2\u003e\n\u003ch3 id=\"через-docker-volume-backup-рекомендуется\"\u003eЧерез docker-volume-backup (рекомендуется)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edocker run --rm \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  -v portainer_data:/backup/portainer_data \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  -v postgres_data:/backup/postgres_data \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  -v redis_data:/backup/redis_data \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  -v /opt/docker/backup:/archive \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --entrypoint backup \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  offen/docker-volume-backup:v2\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003cstrong\u003eПараметры\u003c/strong\u003e:\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eПараметр\u003c/th\u003e\n          \u003cth\u003eОписание\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003e-v \u0026lt;volume\u0026gt;:/backup/\u0026lt;name\u0026gt;\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eМаппинг volume в директорию бэкапа\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003e-v /opt/docker/backup:/archive\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eКуда сохранять архив на хосте\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003e--entrypoint backup\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eЗапускает режим бэкапа\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003e--rm\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eУдаляет контейнер после завершения\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e\u003cstrong\u003eПочему этот метод\u003c/strong\u003e:\u003c/p\u003e","title":"Docker Volumes: Бэкап и миграция"},{"content":"Подмодуль - это ссылка на другой Git-репозиторий внутри вашего проекта. Удобно, когда нужно использовать внешнюю библиотеку или общий код, но держать его в отдельном репозитории.\n💡 Подмодуль хранит не код, а ссылку на конкретный коммит внешнего репозитория.\nДобавить подмодуль # Добавить репозиторий как подмодуль в указанную папку git submodule add \u0026lt;URL\u0026gt; \u0026lt;путь/куда/положить\u0026gt; # Пример git submodule add https://github.com/luizdepra/hugo-coder.git themes/hugo-coder # Зафиксировать изменения git commit -m \u0026#34;Add submodule: themes/hugo-coder\u0026#34; git push После этого в проекте появятся:\nФайл .gitmodules - конфигурация подмодулей Папка с подмодулем - как ссылка на внешний репозиторий Клонировать проект с подмодулями # Вариант 1: сразу с подмодулями git clone --recursive \u0026lt;URL\u0026gt; # Вариант 2: если уже склонировали без подмодулей git submodule update --init --recursive Обновить подмодуль # Зайти в подмодуль и подтянуть изменения cd themes/hugo-coder git pull origin main # Вернуться в корень и зафиксировать новый коммит подмодуля cd ../.. git add themes/hugo-coder git commit -m \u0026#34;Update submodule: hugo-coder\u0026#34; git push Или одной командой из корня:\n# Обновить все подмодули до последних коммитов удалённых веток git submodule update --init --recursive --remote # Зафиксировать изменения ссылок git add . git commit -m \u0026#34;Update all submodules\u0026#34; git push ⚠️ --remote тянет последние коммиты из удалённых репозиториев. Без него - только те коммиты, что уже зафиксированы в .gitmodules.\nУдалить подмодуль # 1. Деинициализировать подмодуль git submodule deinit -f themes/hugo-coder # 2. Удалить из индекса и рабочей директории git rm -f themes/hugo-coder # 3. Удалить служебные данные (опционально, но рекомендуется) rm -rf .git/modules/themes/hugo-coder # 4. Зафиксировать изменения git commit -m \u0026#34;Remove submodule: themes/hugo-coder\u0026#34; git push Полезные команды # Показать статус всех подмодулей git submodule status # Показать, какие коммиты ждут обновления git submodule foreach \u0026#39;git log -1 --oneline\u0026#39; # Синхронизировать URL подмодулей (если изменился remote) git submodule sync --recursive # Выполнить команду во всех подмодулях git submodule foreach \u0026#39;git fetch\u0026#39; Частые проблемы # Подмодуль пустой после clone → git submodule update --init --recursive # Ошибка \u0026#34;fatal: not a git repository\u0026#34; внутри подмодуля → Удалите папку подмодуля и выполните: git submodule update --init # Конфликт версий подмодуля при мердже → Выберите нужную версию коммита: git add themes/hugo-coder git commit -m \u0026#34;Resolve submodule conflict\u0026#34; Ссылки 📘 Официальная книга Git: Подмодули 🐙 Документация git-submodule ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/git/submodules/","summary":"\u003cp\u003eПодмодуль - это ссылка на другой Git-репозиторий внутри вашего проекта. Удобно, когда нужно использовать внешнюю библиотеку или общий код, но держать его в отдельном репозитории.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e💡 Подмодуль хранит не код, а \u003cstrong\u003eссылку на конкретный коммит\u003c/strong\u003e внешнего репозитория.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003chr\u003e\n\u003ch2 id=\"добавить-подмодуль\"\u003eДобавить подмодуль\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Добавить репозиторий как подмодуль в указанную папку\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit submodule add \u0026lt;URL\u0026gt; \u0026lt;путь/куда/положить\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Пример\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit submodule add https://github.com/luizdepra/hugo-coder.git themes/hugo-coder\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Зафиксировать изменения\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit commit -m \u003cspan class=\"s2\"\u003e\u0026#34;Add submodule: themes/hugo-coder\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit push\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eПосле этого в проекте появятся:\u003c/p\u003e","title":"Git Submodules: Шпаргалка"},{"content":"Git - система контроля версий. Сохраняет историю изменений кода, позволяет работать в команде и откатывать ошибки.\n💡 Установил один раз - пользуешься годами.\nУстановка Windows Способ 1: Официальный установщик (рекомендуется)\nСкачай с git-scm.com Запусти установщик, оставляй настройки по умолчанию Важно: на шаге \u0026ldquo;Adjusting your PATH\u0026rdquo; выбери Git from the command line and also from 3rd-party software Способ 2: Через Winget (PowerShell)\nwinget install Git.Git Способ 3: Через Chocolatey\nchoco install git -y Linux Ubuntu / Debian\nsudo apt update sudo apt install git -y Fedora / RHEL\nsudo dnf install git -y Arch / Manjaro\nsudo pacman -S git Проверка установки (все системы)\ngit --version # Ожидаемый вывод: git version 2.x.x Базовая настройка # Имя и почта (будут в каждом коммите) git config --global user.name \u0026#34;Kirill Ponfertato\u0026#34; git config --global user.email \u0026#34;kirill@potatoenergy.ru\u0026#34; # Редактор по умолчанию (выбери один) git config --global core.editor \u0026#34;code --wait\u0026#34; # VS Code git config --global core.editor \u0026#34;nano\u0026#34; # Nano git config --global core.editor \u0026#34;vim\u0026#34; # Vim # Имя ветки по умолчанию git config --global init.defaultBranch main # Цветной вывод git config --global color.ui auto # Авто-CRLF для Windows (перевод строк) git config --global core.autocrlf true # Windows git config --global core.autocrlf input # Linux/macOS # Просмотр всех настроек git config --global --list SSH-ключи (для GitHub / GitLab) # Создать ключ (нажми Enter на все вопросы) ssh-keygen -t ed25519 -C \u0026#34;kirill@potatoenergy.ru\u0026#34; # Если ed25519 не поддерживается: ssh-keygen -t rsa -b 4096 -C \u0026#34;kirill@potatoenergy.ru\u0026#34; # Запустить SSH-агент и добавить ключ eval \u0026#34;$(ssh-agent -s)\u0026#34; ssh-add ~/.ssh/id_ed25519 # Показать публичный ключ (скопировать содержимое) cat ~/.ssh/id_ed25519.pub # Windows (PowerShell): Get-Content ~/.ssh/id_ed25519.pub # Добавить ключ в: # • GitHub: Settings → SSH and GPG keys → New SSH key # • GitLab: User Settings → SSH Keys Проверка подключения\n# GitHub ssh -T git@github.com # Ожидаемо: \u0026#34;Hi ponfertato! You\u0026#39;ve successfully authenticated\u0026#34; # GitLab ssh -T git@gitlab.com Первые шаги # Создать новый репозиторий mkdir my-project \u0026amp;\u0026amp; cd my-project git init # Клонировать существующий git clone \u0026lt;URL\u0026gt; git clone \u0026lt;URL\u0026gt; my-folder # в папку с именем git clone --depth 1 \u0026lt;URL\u0026gt; # только последний коммит # Проверить статус git status # Добавить файлы и сделать коммит git add . git commit -m \u0026#34;Initial commit\u0026#34; # Подключить удалённый репозиторий git remote add origin git@github.com:ponfertato/my-project.git git push -u origin main Полезные алиасы (опционально) # Добавить в ~/.gitconfig или выполнить команды: git config --global alias.co checkout git config --global alias.br branch git config --global alias.ci commit git config --global alias.st \u0026#34;status -s\u0026#34; git config --global alias.lg \u0026#34;log --oneline --graph --all\u0026#34; # Использование: git st # вместо git status -s git lg # красивый лог git co -b feature # создать и переключиться на ветку Если что-то не так # Git не найден после установки → Перезапусти терминал / компьютер # Ошибка \u0026#34;Permission denied (publickey)\u0026#34; → Проверь, что публичный ключ добавлен в профиль GitHub/GitLab → Проверь: ssh -T git@github.com # Конфликт переводов строк (CRLF/LF) → Настрой core.autocrlf под свою ОС (см. выше) # Сбросить все настройки к дефолтным git config --global --unset-all user.name git config --global --unset-all user.email # Или удалить файл: ~/.gitconfig Ссылки 🌐 Официальный сайт 📘 Книга Pro Git (бесплатно) 🎮 Интерактивный тренажёр 🔑 Генератор .gitignore ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/git/install/","summary":"\u003cp\u003eGit - система контроля версий. Сохраняет историю изменений кода, позволяет работать в команде и откатывать ошибки.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e💡 Установил один раз - пользуешься годами.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003chr\u003e\n\u003ch2 id=\"установка\"\u003eУстановка\u003c/h2\u003e\n\u003ch3 id=\"windows\"\u003eWindows\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003eСпособ 1: Официальный установщик (рекомендуется)\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eСкачай с \u003ca href=\"https://git-scm.com/download/win\"\u003egit-scm.com\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eЗапусти установщик, оставляй настройки по умолчанию\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eВажно\u003c/strong\u003e: на шаге \u0026ldquo;Adjusting your PATH\u0026rdquo; выбери \u003ccode\u003eGit from the command line and also from 3rd-party software\u003c/code\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eСпособ 2: Через Winget (PowerShell)\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-powershell\" data-lang=\"powershell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ewinget\u003c/span\u003e \u003cspan class=\"n\"\u003einstall\u003c/span\u003e \u003cspan class=\"n\"\u003eGit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"py\"\u003eGit\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003cstrong\u003eСпособ 3: Через Chocolatey\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-powershell\" data-lang=\"powershell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003echoco\u003c/span\u003e \u003cspan class=\"n\"\u003einstall\u003c/span\u003e \u003cspan class=\"n\"\u003egit\u003c/span\u003e \u003cspan class=\"n\"\u003e-y\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"linux\"\u003eLinux\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003eUbuntu / Debian\u003c/strong\u003e\u003c/p\u003e","title":"Git: Установка и настройка"},{"content":"GPT4Free (g4f) - бесплатный инструмент, который даёт доступ к мощным нейросетям: GPT-4/5, Claude, Gemini, DeepSeek. Работает через обратную инженерию публичных интерфейсов.\n⚠️ Важно: Только для обучения и тестов. Может нарушать правила некоторых сервисов.\nУстановка за 2 минуты Что нужно Компьютер с интернетом Python 3.10+ (поставьте галочку \u0026ldquo;Add to PATH\u0026rdquo; при установке) Команда установки pip install -U g4f[all] Готово. Библиотека установлена.\nЗапуск Вариант 1: Веб-интерфейс (как чат в браузере) python -m g4f.cli gui --port 8080 Откройте в браузере: http://localhost:8080/chat/\nВариант 2: Режим разработчика (локальный API) python -m g4f --port 1337 Теперь можно подключать любые приложения, поддерживающие OpenAI API.\nПервый скрипт: 5 строк кода Создайте файл test.py:\nfrom g4f.client import Client client = Client() response = client.chat.completions.create( model=\u0026#34;gpt-4o-mini\u0026#34;, messages=[{\u0026#34;role\u0026#34;: \u0026#34;user\u0026#34;, \u0026#34;content\u0026#34;: \u0026#34;Почему картофель - это состояние души?\u0026#34;}] ) print(response.choices[0].message.content) Запустите:\npython test.py Генерация изображений from g4f.client import Client client = Client() img = client.images.generate( model=\u0026#34;flux\u0026#34;, prompt=\u0026#34;Киберпанк-картофель в неоновом городе\u0026#34;, response_format=\u0026#34;url\u0026#34; ) print(f\u0026#34;Готово: {img.data[0].url}\u0026#34;) Какие модели работают (март 2026) Модель Статус Для чего gpt-4o-mini ✅ Стабильно Быстрые ответы, чат gpt-4o ✅ Стабильно Сложные задачи deepseek-v3 ✅ Стабильно Код, логика, математика gemini-2.5-pro ⚠️ Иногда Мультимодальные задачи llama-3.3-70b ✅ Стабильно Открытая альтернатива gpt-5 🔶 Эксперимент Может не работать 💡 Список меняется. Актуальный - через веб-интерфейс или команду:\nGET http://localhost:8080/backend-api/models\nПодключить к любому OpenAI-совместимому приложению После запуска python -m g4f --port 1337:\nfrom openai import OpenAI client = OpenAI( base_url=\u0026#34;http://localhost:1337/v1\u0026#34;, api_key=\u0026#34;не-важно-что-здесь\u0026#34; # можно любое значение ) response = client.chat.completions.create( model=\u0026#34;gpt-4o-mini\u0026#34;, messages=[{\u0026#34;role\u0026#34;: \u0026#34;user\u0026#34;, \u0026#34;content\u0026#34;: \u0026#34;Расскажи анекдот про картофель\u0026#34;}] ) print(response.choices[0].message.content) Работает с LibreChat, Flowise, AnythingLLM и другими.\nЕсли что-то не работает # Обновите библиотеку pip install -U g4f # Ошибка при установке на Windows pip install --upgrade pip setuptools wheel # Нейросеть не отвечает # → Попробуйте другую модель # → Включите VPN # → Подождите 10-30 секунд (некоторые провайдеры медленные) # Используете Docker? Добавьте памяти браузеру: docker run -p 8080:8080 --shm-size=\u0026#34;2g\u0026#34; hlohaus789/g4f:latest Docker (для серверов и продвинутых) docker run -p 8080:8080 --shm-size=\u0026#34;2g\u0026#34; hlohaus789/g4f:latest Веб-интерфейс: http://localhost:8080 API: http://localhost:8080/v1 Ссылки 🐍 Официальный репозиторий 📦 Docker-образ 🌐 Документация 💬 Telegram-канал ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/gpt/gpt4free/","summary":"\u003cp\u003eGPT4Free (g4f) - бесплатный инструмент, который даёт доступ к мощным нейросетям: GPT-4/5, Claude, Gemini, DeepSeek. Работает через обратную инженерию публичных интерфейсов.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e⚠️ \u003cstrong\u003eВажно\u003c/strong\u003e: Только для обучения и тестов. Может нарушать правила некоторых сервисов.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003chr\u003e\n\u003ch2 id=\"установка-за-2-минуты\"\u003eУстановка за 2 минуты\u003c/h2\u003e\n\u003ch3 id=\"что-нужно\"\u003eЧто нужно\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eКомпьютер с интернетом\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://python.org\"\u003ePython 3.10+\u003c/a\u003e (поставьте галочку \u0026ldquo;Add to PATH\u0026rdquo; при установке)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"команда-установки\"\u003eКоманда установки\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003epip install -U g4f\u003cspan class=\"o\"\u003e[\u003c/span\u003eall\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eГотово. Библиотека установлена.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"запуск\"\u003eЗапуск\u003c/h2\u003e\n\u003ch3 id=\"вариант-1-веб-интерфейс-как-чат-в-браузере\"\u003eВариант 1: Веб-интерфейс (как чат в браузере)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003epython -m g4f.cli gui --port \u003cspan class=\"m\"\u003e8080\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eОткройте в браузере: \u003ccode\u003ehttp://localhost:8080/chat/\u003c/code\u003e\u003c/p\u003e","title":"GPT4Free в 2026: Полный гайд по бесплатному доступу к GPT-5, DeepSeek и Gemini"},{"content":"OpenSSH - инструмент для безопасного удалённого доступа по протоколу SSH. Шифрует весь трафик, поддерживает аутентификацию по ключам, работает на Windows, Linux, macOS.\n💡 После настройки ты сможешь подключаться к своему Windows-ПК как к обычному Linux-серверу: ssh user@192.168.1.100\nТребования ОС: Windows 10 (1809+), Windows 11, Windows Server 2019/2022 Права: Администратор Сеть: Доступ к порту 22 (локально или извне) Установка (3 способа) Способ 1: PowerShell (рекомендуется) # Запусти от имени Администратора # Установить OpenSSH сервер Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 # Проверить установку Get-WindowsCapability -Online | Where-Object Name -like \u0026#39;OpenSSH*\u0026#39; Способ 2: DISM (альтернатива) dism /Online /Add-Capability /CapabilityName:OpenSSH.Server~~~~0.0.1.0 Способ 3: Через настройки (GUI) Настройки → Приложения → Дополнительные компоненты «Добавить компонент» → найди «OpenSSH Server» → Установить Настройка службы # Запустить от имени Администратора # Включить автозапуск sshd Set-Service -Name sshd -StartupType Automatic # Запустить службу Start-Service sshd # Проверить статус Get-Service sshd # Убедиться, что порт 22 слушается netstat -ano | findstr :22 Брандмауэр # Проверить правило для OpenSSH Get-NetFirewallRule -Name *OpenSSH-Server* | Select Name, Enabled # Если правила нет - создать New-NetFirewallRule -Name sshd ` -DisplayName \u0026#39;OpenSSH Server\u0026#39; ` -Enabled True ` -Direction Inbound ` -Protocol TCP ` -LocalPort 22 ` -Action Allow ` -Profile Any Проверка подключения # С этого же ПК ssh localhost # С другого устройства в сети ssh \u0026lt;твой_пользователь\u0026gt;@\u0026lt;IP_адрес_Windows\u0026gt; # Пример: ssh kirill@192.168.1.100 💡 Первый вход запросит подтверждение отпечатка ключа - введи yes.\nАутентификация по ключам (рекомендуется) На клиенте (где подключаешься) # Создать пару ключей (если нет) ssh-keygen -t ed25519 -C \u0026#34;kirill@potatoenergy.ru\u0026#34; # Скопировать публичный ключ на сервер # Для Windows-сервера - вручную: type $env:USERPROFILE\\.ssh\\id_ed25519.pub # Скопируй вывод На сервере (Windows) # Создать папку .ssh в профиле пользователя mkdir $env:USERPROFILE\\.ssh -Force # Создать/отредактировать authorized_keys notepad $env:USERPROFILE\\.ssh\\authorized_keys # Вставить публичный ключ (одной строкой), сохранить # Задать правильные права (ОБЯЗАТЕЛЬНО) $acl = Get-Acl $env:USERPROFILE\\.ssh\\authorized_keys $acl.SetAccessRuleProtection($true, $false) $rule = New-Object System.Security.AccessControl.FileSystemAccessRule( $env:USERNAME, \u0026#34;Read\u0026#34;, \u0026#34;Allow\u0026#34;) $acl.AddAccessRule($rule) Set-Acl $env:USERPROFILE\\.ssh\\authorized_keys $acl Отключить вход по паролю (опционально, для безопасности) # Отредактировать конфиг notepad C:\\ProgramData\\ssh\\sshd_config # Найти и изменить строки: # PasswordAuthentication no # PubkeyAuthentication yes # Перезапустить службу Restart-Service sshd Конфигурация: полезные настройки Файл: C:\\ProgramData\\ssh\\sshd_config\n# Только определённые пользователи AllowUsers kirill admin # Сменить порт (если 22 занят) Port 2222 # Запретить root-логин PermitRootLogin no # Таймаут неактивности ClientAliveInterval 300 ClientAliveCountMax 2 # Логирование LogLevel VERBOSE После правок:\nRestart-Service sshd Частые проблемы # Служба не запускается → Проверь логи: Get-WinEvent -LogName \u0026#34;OpenSSH/Operational\u0026#34; -MaxEvents 10 # Порт 22 не слушается → Проверь брандмауэр: Get-NetFirewallRule -Name sshd → Проверь, что служба запущена: Get-Service sshd # \u0026#34;Permission denied (publickey,password)\u0026#34; → Проверь права на authorized_keys (должен читать только владелец) → Убедись, что публичный ключ вставлен одной строкой, без переносов # Подключение есть, но нет прав на файлы → Проверь права пользователя на папки в Windows → Попробуй запустить терминал от имени администратора на клиенте Ссылки 🌐 Официальный репозиторий Win32-OpenSSH 📘 Документация Microsoft 🔑 Генератор конфигов sshd ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/windows/openssh/","summary":"\u003cp\u003eOpenSSH - инструмент для безопасного удалённого доступа по протоколу SSH. Шифрует весь трафик, поддерживает аутентификацию по ключам, работает на Windows, Linux, macOS.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e💡 После настройки ты сможешь подключаться к своему Windows-ПК как к обычному Linux-серверу: \u003ccode\u003essh user@192.168.1.100\u003c/code\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003chr\u003e\n\u003ch2 id=\"требования\"\u003eТребования\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eОС\u003c/strong\u003e: Windows 10 (1809+), Windows 11, Windows Server 2019/2022\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eПрава\u003c/strong\u003e: Администратор\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eСеть\u003c/strong\u003e: Доступ к порту 22 (локально или извне)\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch2 id=\"установка-3-способа\"\u003eУстановка (3 способа)\u003c/h2\u003e\n\u003ch3 id=\"способ-1-powershell-рекомендуется\"\u003eСпособ 1: PowerShell (рекомендуется)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-powershell\" data-lang=\"powershell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e# Запусти от имени Администратора\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e# Установить OpenSSH сервер\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eAdd-WindowsCapability\u003c/span\u003e \u003cspan class=\"n\"\u003e-Online\u003c/span\u003e \u003cspan class=\"n\"\u003e-Name\u003c/span\u003e \u003cspan class=\"n\"\u003eOpenSSH\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eServer\u003c/span\u003e\u003cspan class=\"p\"\u003e~~~~\u003c/span\u003e\u003cspan class=\"mf\"\u003e0.0\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"py\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"py\"\u003e0\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e# Проверить установку\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eGet-WindowsCapability\u003c/span\u003e \u003cspan class=\"n\"\u003e-Online\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"nb\"\u003eWhere-Object\u003c/span\u003e \u003cspan class=\"n\"\u003eName\u003c/span\u003e \u003cspan class=\"o\"\u003e-like\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;OpenSSH*\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"способ-2-dism-альтернатива\"\u003eСпособ 2: DISM (альтернатива)\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-powershell\" data-lang=\"powershell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003edism\u003c/span\u003e \u003cspan class=\"p\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003eOnline\u003c/span\u003e \u003cspan class=\"p\"\u003e/\u003c/span\u003e\u003cspan class=\"nb\"\u003eAdd-Capability\u003c/span\u003e \u003cspan class=\"p\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003eCapabilityName\u003c/span\u003e\u003cspan class=\"err\"\u003e:\u003c/span\u003e\u003cspan class=\"n\"\u003eOpenSSH\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eServer\u003c/span\u003e\u003cspan class=\"p\"\u003e~~~~\u003c/span\u003e\u003cspan class=\"mf\"\u003e0.0\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"py\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"py\"\u003e0\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"способ-3-через-настройки-gui\"\u003eСпособ 3: Через настройки (GUI)\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003eНастройки → Приложения → Дополнительные компоненты\u003c/li\u003e\n\u003cli\u003e«Добавить компонент» → найди «OpenSSH Server» → Установить\u003c/li\u003e\n\u003c/ol\u003e\n\u003chr\u003e\n\u003ch2 id=\"настройка-службы\"\u003eНастройка службы\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-powershell\" data-lang=\"powershell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e# Запустить от имени Администратора\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e# Включить автозапуск sshd\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eSet-Service\u003c/span\u003e \u003cspan class=\"n\"\u003e-Name\u003c/span\u003e \u003cspan class=\"n\"\u003esshd\u003c/span\u003e \u003cspan class=\"n\"\u003e-StartupType\u003c/span\u003e \u003cspan class=\"n\"\u003eAutomatic\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e# Запустить службу\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eStart-Service\u003c/span\u003e \u003cspan class=\"n\"\u003esshd\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e# Проверить статус\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eGet-Service\u003c/span\u003e \u003cspan class=\"n\"\u003esshd\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e# Убедиться, что порт 22 слушается\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003enetstat\u003c/span\u003e \u003cspan class=\"n\"\u003e-ano\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"n\"\u003efindstr\u003c/span\u003e \u003cspan class=\"err\"\u003e:\u003c/span\u003e\u003cspan class=\"mf\"\u003e22\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"брандмауэр\"\u003eБрандмауэр\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-powershell\" data-lang=\"powershell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e# Проверить правило для OpenSSH\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eGet-NetFirewallRule\u003c/span\u003e \u003cspan class=\"n\"\u003e-Name\u003c/span\u003e \u003cspan class=\"p\"\u003e*\u003c/span\u003e\u003cspan class=\"nb\"\u003eOpenSSH-Server\u003c/span\u003e\u003cspan class=\"p\"\u003e*\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"nb\"\u003eSelect \u003c/span\u003e\u003cspan class=\"n\"\u003eName\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eEnabled\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e# Если правила нет - создать\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eNew-NetFirewallRule\u003c/span\u003e \u003cspan class=\"n\"\u003e-Name\u003c/span\u003e \u003cspan class=\"n\"\u003esshd\u003c/span\u003e \u003cspan class=\"p\"\u003e`\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"n\"\u003e-DisplayName\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;OpenSSH Server\u0026#39;\u003c/span\u003e \u003cspan class=\"p\"\u003e`\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"n\"\u003e-Enabled\u003c/span\u003e \u003cspan class=\"n\"\u003eTrue\u003c/span\u003e \u003cspan class=\"p\"\u003e`\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"n\"\u003e-Direction\u003c/span\u003e \u003cspan class=\"n\"\u003eInbound\u003c/span\u003e \u003cspan class=\"p\"\u003e`\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"n\"\u003e-Protocol\u003c/span\u003e \u003cspan class=\"n\"\u003eTCP\u003c/span\u003e \u003cspan class=\"p\"\u003e`\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"n\"\u003e-LocalPort\u003c/span\u003e \u003cspan class=\"mf\"\u003e22\u003c/span\u003e \u003cspan class=\"p\"\u003e`\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"n\"\u003e-Action\u003c/span\u003e \u003cspan class=\"n\"\u003eAllow\u003c/span\u003e \u003cspan class=\"p\"\u003e`\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"n\"\u003e-Profile\u003c/span\u003e \u003cspan class=\"n\"\u003eAny\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"проверка-подключения\"\u003eПроверка подключения\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-powershell\" data-lang=\"powershell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e# С этого же ПК\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003essh\u003c/span\u003e \u003cspan class=\"n\"\u003elocalhost\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e# С другого устройства в сети\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003essh\u003c/span\u003e \u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eтвой_пользователь\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;@\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eIP_адрес_Windows\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e# Пример:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003essh\u003c/span\u003e \u003cspan class=\"n\"\u003ekirill\u003c/span\u003e\u003cspan class=\"nv\"\u003e@192\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"py\"\u003e168\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"py\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"py\"\u003e100\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cblockquote\u003e\n\u003cp\u003e💡 Первый вход запросит подтверждение отпечатка ключа - введи \u003ccode\u003eyes\u003c/code\u003e.\u003c/p\u003e","title":"OpenSSH на Windows: Установка сервера"},{"content":"Эта статья - практическое руководство по настройке OpenWRT для продвинутого домашнего использования. Мы разберём конфигурации, которые делают роутер умнее: фильтрация трафика на уровне DNS, безопасный удалённый доступ через WireGuard, мониторинг метрик и автоматические уведомления.\n💡 Все чувствительные данные заменены на \u0026lt;...\u0026gt;. Подставляйте свои значения.\n📦 Установка пакетов opkg update # Мониторинг: prometheus exporter + модули opkg install \\ prometheus-node-exporter-lua \\ prometheus-node-exporter-lua-nat_traffic \\ prometheus-node-exporter-lua-netstat \\ prometheus-node-exporter-lua-openwrt \\ prometheus-node-exporter-lua-wifi \\ prometheus-node-exporter-lua-wifi_stations # WireGuard: ядро + утилиты + LuCI opkg install \\ kmod-wireguard \\ wireguard-tools \\ luci-proto-wireguard # DNS over HTTPS opkg install https-dns-proxy # Утилиты для отладки opkg install curl jq tmux htop Зачем:\nprometheus-node-exporter-lua-* - лёгкие модули для сбора метрик без нагрузки на роутер kmod-wireguard - ядро в kernel-space, работает быстрее пользовательских реализаций https-dns-proxy - шифрует DNS-запросы, предотвращает утечки и цензуру 📢 Уведомления о событиях При загрузке системы (/etc/rc.local) sleep 10 \u0026amp;\u0026amp; \\ curl -s --max-time 10 -X POST \u0026#34;https://api.telegram.org/bot\u0026lt;TOKEN\u0026gt;/sendMessage\u0026#34; \\ -d chat_id=\u0026lt;CHAT_ID\u0026gt; \\ -d \u0026#34;text=✅ Router: online\u0026#34; \u0026gt;/dev/null 2\u0026gt;\u0026amp;1 \u0026amp;\u0026amp; \\ curl -s --max-time 10 -H \u0026#34;Content-Type: application/json\u0026#34; -X POST \\ -d \u0026#39;{\u0026#34;content\u0026#34;:\u0026#34;✅ Router: online\u0026#34;}\u0026#39; \\ \u0026#34;https://discord.com/api/webhooks/\u0026lt;WEBHOOK_ID\u0026gt;/\u0026lt;WEBHOOK_TOKEN\u0026gt;\u0026#34; \u0026gt;/dev/null 2\u0026gt;\u0026amp;1 \u0026amp;\u0026amp; \\ exit 0 Зачем:\nsleep 10 - даёт время поднять сеть перед отправкой --max-time 10 - не блокирует загрузку, если сеть недоступна Два канала (Telegram + Discord) - резервирование уведомлений Плановый перезапуск (воскресенье, 03:00) # /etc/crontabs/root 0 3 * * 0 /usr/bin/curl -s --max-time 10 -X POST \u0026#34;https://api.telegram.org/bot\u0026lt;TOKEN\u0026gt;/sendMessage\u0026#34; -d chat_id=\u0026lt;CHAT_ID\u0026gt; -d \u0026#34;text=🔄 Reboot scheduled\u0026#34; \u0026gt;/dev/null 2\u0026gt;\u0026amp;1 \u0026amp;\u0026amp; sleep 10 \u0026amp;\u0026amp; /sbin/reboot Зачем:\nЕженедельный ребут очищает утечки памяти в долгосрочной работе Ночное время минимизирует влияние на пользователей Уведомление «до» помогает отличить плановый ребут от сбоя 🌐 DNS: умная маршрутизация и фильтрация dnsmasq - локальный резолвер # /etc/config/dhcp config dnsmasq option cachesize \u0026#39;1000\u0026#39; # Кэш на 1000 записей - баланс памяти/скорости option local \u0026#39;/lan/\u0026#39; # Локальные домены .lan не уходят в интернет option domain \u0026#39;lan\u0026#39; # Домен по умолчанию для локальной сети # Маршрутизация: конкретные домены → конкретные DNS list server \u0026#39;/api.github.com/8.8.8.8\u0026#39; # GitHub через публичный DNS list server \u0026#39;/youtube.com/8.8.8.8\u0026#39; # YouTube через публичный DNS # Блокировка: трекеры и «умные» функции list server \u0026#39;/mask.icloud.com/0.0.0.0\u0026#39; # Блокировка Private Relay list server \u0026#39;/use-application-dns.net/0.0.0.0\u0026#39; # Запрет обхода локального DNS # Основной трафик → DoH-прокси (локально) list server \u0026#39;127.0.0.1#5053\u0026#39; list server \u0026#39;127.0.0.1#5054\u0026#39; Особенности:\nРазные upstream\u0026rsquo;ы для разных доменов - гибкость и отказоустойчивость Блокировка на уровне 0.0.0.0 - трекеры не резолвятся вообще Локальный DoH-прокси - шифрование без зависимости от провайдера https-dns-proxy - DNS over HTTPS # /etc/config/https-dns-proxy config https-dns-proxy option resolver_url \u0026#39;https://\u0026lt;DOH_PROVIDER\u0026gt;/dns-query\u0026#39; option listen_port \u0026#39;5053\u0026#39; option bootstrap_dns \u0026#39;\u0026lt;RESOLVER_IP\u0026gt;\u0026#39; # IP для резолвинга самого DoH-эндпоинта config https-dns-proxy option resolver_url \u0026#39;https://\u0026lt;BACKUP_DOH\u0026gt;/dns-query\u0026#39; option listen_port \u0026#39;5054\u0026#39; option bootstrap_dns \u0026#39;\u0026lt;BACKUP_IP\u0026gt;\u0026#39; Зачем два экземпляра:\nРезервирование: если один провайдер недоступен, работает второй Разные bootstrap_dns - независимость от одного резолвера Порты 5053/5054 - легко различать в логах и метриках 🔥 Firewall: политика «запретить всё, разрешить нужное» Базовые настройки config defaults option input \u0026#39;REJECT\u0026#39; # Блокируем входящие по умолчанию option forward \u0026#39;REJECT\u0026#39; # Блокируем форвардинг по умолчанию option output \u0026#39;ACCEPT\u0026#39; # Исходящие - разрешены option synflood_protect \u0026#39;1\u0026#39; # Защита от SYN-flood option drop_invalid \u0026#39;1\u0026#39; # Отбрасываем некорректные пакеты Почему так:\nМинимальная поверхность атаки: открыто только то, что явно разрешено drop_invalid - защита от сканирования и аномального трафика Зоны и правила # LAN - доверяем config zone option name \u0026#39;lan\u0026#39; list network \u0026#39;lan\u0026#39; option input \u0026#39;ACCEPT\u0026#39; option forward \u0026#39;ACCEPT\u0026#39; option output \u0026#39;ACCEPT\u0026#39; # WAN - не доверяем config zone option name \u0026#39;wan\u0026#39; list network \u0026#39;wan\u0026#39; \u0026#39;wan6\u0026#39; option input \u0026#39;REJECT\u0026#39; option forward \u0026#39;REJECT\u0026#39; option output \u0026#39;ACCEPT\u0026#39; option masq \u0026#39;1\u0026#39; # NAT для исходящих # WireGuard - как «вторая локалка» config zone option name \u0026#39;wg\u0026#39; list network \u0026#39;wg0\u0026#39; option input \u0026#39;ACCEPT\u0026#39; option forward \u0026#39;ACCEPT\u0026#39; option output \u0026#39;ACCEPT\u0026#39; option masq \u0026#39;1\u0026#39; Особенность зоны wg:\nWireGuard-клиенты получают доступ к LAN как «свои» При этом трафик из WG в WAN идёт через тот же NAT, что и из LAN Проброс портов (шаблоны) # WireGuard: входящий UDP 51820 → сервер в сети config redirect option name \u0026#39;wg\u0026#39; option src \u0026#39;wan\u0026#39; option proto \u0026#39;udp\u0026#39; option src_dport \u0026#39;51820\u0026#39; option dest_ip \u0026#39;\u0026lt;WG_SERVER_LAN_IP\u0026gt;\u0026#39; option dest_port \u0026#39;51820\u0026#39; option target \u0026#39;DNAT\u0026#39; # Игровой сервер: произвольный порт → внутренний хост config redirect option name \u0026#39;game-server\u0026#39; option src \u0026#39;wan\u0026#39; option proto \u0026#39;tcp\u0026#39; option src_dport \u0026#39;\u0026lt;EXTERNAL_PORT\u0026gt;\u0026#39; option dest_ip \u0026#39;\u0026lt;INTERNAL_IP\u0026gt;\u0026#39; option dest_port \u0026#39;\u0026lt;INTERNAL_PORT\u0026gt;\u0026#39; option target \u0026#39;DNAT\u0026#39; Важно:\noption proto поддерживает список: list proto 'tcp' + list proto 'udp' Для диапазонов портов: option src_dport '8443-8448' Блокировка QUIC (опционально) config rule option name \u0026#39;Block-UDP-80\u0026#39; option proto \u0026#39;udp\u0026#39; option dest_port \u0026#39;80\u0026#39; option target \u0026#39;REJECT\u0026#39; config rule option name \u0026#39;Block-UDP-443\u0026#39; option proto \u0026#39;udp\u0026#39; option dest_port \u0026#39;443\u0026#39; option target \u0026#39;REJECT\u0026#39; Зачем блокировать QUIC:\nHTTP/3 over QUIC (UDP 443) часто обходит DNS-фильтрацию Блокировка заставляет клиентов падать на TCP, где фильтрация работает Не влияет на большинство сайтов - они поддерживают fallback 📡 Сеть: PPPoE, WireGuard, статика Интерфейсы # PPPoE - основной канал (приоритет выше обычного wan) config interface \u0026#39;kmtn\u0026#39; option proto \u0026#39;pppoe\u0026#39; option device \u0026#39;eth0.2\u0026#39; option username \u0026#39;\u0026lt;PPPOE_LOGIN\u0026gt;\u0026#39; option password \u0026#39;\u0026lt;PPPOE_PASSWORD\u0026gt;\u0026#39; option metric \u0026#39;0\u0026#39; # Меньше = выше приоритет # WireGuard - туннель config interface \u0026#39;wg0\u0026#39; option proto \u0026#39;wireguard\u0026#39; option private_key \u0026#39;\u0026lt;WG_PRIVATE_KEY\u0026gt;\u0026#39; option listen_port \u0026#39;51820\u0026#39; list addresses \u0026#39;\u0026lt;WG_SUBNET\u0026gt;/24\u0026#39; config wireguard_wg0 option public_key \u0026#39;\u0026lt;PEER_PUBLIC_KEY\u0026gt;\u0026#39; option preshared_key \u0026#39;\u0026lt;PRESHARED_KEY\u0026gt;\u0026#39; # Дополнительный слой шифрования option endpoint_host \u0026#39;\u0026lt;YOUR_DOMAIN_OR_IP\u0026gt;\u0026#39; option endpoint_port \u0026#39;51820\u0026#39; option persistent_keepalive \u0026#39;25\u0026#39; # Поддержание соединения за NAT option route_allowed_ips \u0026#39;1\u0026#39; # Автоматическая маршрутизация list allowed_ips \u0026#39;\u0026lt;PEER_IP\u0026gt;/32\u0026#39; Особенности WireGuard-конфига:\npreshared_key - защита от будущих квантовых атак (дополнительный симметричный ключ) persistent_keepalive - критично, если роутер за натом провайдера route_allowed_ips '1' - не нужно вручную прописывать маршруты Статические DHCP-аренды config host option name \u0026#39;potatoServer\u0026#39; option mac \u0026#39;\u0026lt;MAC_ADDRESS\u0026gt;\u0026#39; option ip \u0026#39;192.168.1.\u0026lt;STATIC_IP\u0026gt;\u0026#39; option leasetime \u0026#39;infinite\u0026#39; Зачем:\nСервера и важные устройства всегда по одному адресу Упрощает правила фаервола и мониторинг leasetime 'infinite' - аренда не истекает, даже если устройство офлайн 📊 Мониторинг: prometheus-node-exporter Конфигурация # /etc/config/prometheus-node-exporter-lua config prometheus-node-exporter-lua \u0026#39;main\u0026#39; option listen_interface \u0026#39;lan\u0026#39; # Слушаем только локальную сеть - безопасность option listen_port \u0026#39;9101\u0026#39; Доступ к метрикам http://192.168.1.1:9101/metrics Что собирают модули Модуль Что измеряет Зачем нужно nat_traffic NAT-сессии, байты в/из Понимать нагрузку на трансляцию netstat Активные соединения, состояния Выявлять аномалии и утечки openwrt Версия, аптайм, пакеты Инвентаризация и алертинг wifi Сигнал, канал, загрузка эфира Оптимизация беспроводной сети wifi_stations Клиенты, RSSI, скорость на каждого Диагностика проблемных устройств Примеры PromQL-запросов для Grafana # Загрузка CPU в % 100 - (avg by (instance) (irate(node_cpu_seconds_total{mode=\u0026#34;idle\u0026#34;}[5m])) * 100) # Трафик на WAN (бит/с) irate(node_network_receive_bytes_total{device=\u0026#34;eth0.2\u0026#34;}[5m]) * 8 # Количество клиентов WiFi count(node_wifi_station_info) # NAT-сессии в реальном времени node_nat_traffic_sessions Почему prometheus-node-exporter-lua:\nНаписан на Lua - минимальное потребление ресурсов Интегрируется в OpenWRT-систему метрик Не требует отдельного бинарника или Python 📶 WiFi: две сети для разных задач # 5 ГГц - скорость config wifi-iface \u0026#39;default_radio0\u0026#39; option device \u0026#39;radio0\u0026#39; option network \u0026#39;lan\u0026#39; option mode \u0026#39;ap\u0026#39; option ssid \u0026#39;\u0026lt;SSID_5GHZ\u0026gt;\u0026#39; option encryption \u0026#39;psk2\u0026#39; option key \u0026#39;\u0026lt;WIFI_PASSWORD\u0026gt;\u0026#39; option band \u0026#39;5g\u0026#39; option htmode \u0026#39;VHT80\u0026#39; # 2.4 ГГц - дальность и совместимость config wifi-iface \u0026#39;default_radio1\u0026#39; option device \u0026#39;radio1\u0026#39; option network \u0026#39;lan\u0026#39; option mode \u0026#39;ap\u0026#39; option ssid \u0026#39;\u0026lt;SSID_2GHZ\u0026gt;\u0026#39; option encryption \u0026#39;psk2\u0026#39; option key \u0026#39;\u0026lt;WIFI_PASSWORD\u0026gt;\u0026#39; option band \u0026#39;2g\u0026#39; option htmode \u0026#39;HT40\u0026#39; Зачем разные SSID:\nIoT-устройства часто не поддерживают 5 ГГц - подключаются к 2.4 Ручной выбор: где нужна скорость - 5 ГГц, где важна дальность - 2.4 Разные htmode: VHT80 для 5 ГГц (широкий канал), HT40 для 2.4 (стабильность) 🔧 Полезные команды для администрирования # Статус WireGuard (пиры, трафик, last handshake) wg show # Перезапуск служб /etc/init.d/network restart /etc/init.d/firewall restart /etc/init.d/https-dns-proxy restart # Логи: ошибки и предупреждения logread | grep -iE \u0026#39;error|warn|fail\u0026#39; # Последние сообщения ядра dmesg | tail -50 # Проверка занятых портов netstat -tulpn # Тест DNS через конкретный порт nslookup google.com 127.0.0.1#5053 # Проверка правил фаервола в реальном времени iptables -L -n -v | grep -E \u0026#39;REJECT|ACCEPT\u0026#39; ⚠️ Диагностика: если что-то не работает # Нет доступа к веб-интерфейсу → Проверь правило для порта 80/443 в зоне \u0026#39;lan\u0026#39; → Попробуй по SSH: ssh root@192.168.1.1 # WireGuard не поднимается → Проверь ключи: без пробелов, переносов, в одной строке → Убедись, что порт 51820 свободен: netstat -ulpn | grep 51820 → Проверь маршрут: `ip route | grep wg0` # DNS не резолвит → Статус прокси: `/etc/init.d/https-dns-proxy status` → Bootstrap должен быть IP, не домен: `option bootstrap_dns \u0026#39;8.8.8.8\u0026#39;` → Тест: `nslookup google.com 127.0.0.1#5053` # Метрики не собираются → Слушает ли порт 9101: `netstat -tulpn | grep 9101` → Существует ли интерфейс \u0026#39;lan\u0026#39;: `ifconfig | grep br-lan` → Проверь фаервол: разрешён ли входящий на 9101 из \u0026#39;lan\u0026#39; Ссылки 🌐 OpenWRT Documentation 🔐 WireGuard Quick Start 🛡 DNS-over-HTTPS Providers 📊 prometheus-node-exporter-lua 🧰 OpenWRT Package Search ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/openwrt/setup/","summary":"\u003cp\u003eЭта статья - практическое руководство по настройке OpenWRT для продвинутого домашнего использования. Мы разберём конфигурации, которые делают роутер умнее: фильтрация трафика на уровне DNS, безопасный удалённый доступ через WireGuard, мониторинг метрик и автоматические уведомления.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e💡 Все чувствительные данные заменены на \u003ccode\u003e\u0026lt;...\u0026gt;\u003c/code\u003e. Подставляйте свои значения.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003chr\u003e\n\u003ch2 id=\"-установка-пакетов\"\u003e📦 Установка пакетов\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopkg update\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Мониторинг: prometheus exporter + модули\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopkg install \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  prometheus-node-exporter-lua \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  prometheus-node-exporter-lua-nat_traffic \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  prometheus-node-exporter-lua-netstat \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  prometheus-node-exporter-lua-openwrt \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  prometheus-node-exporter-lua-wifi \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  prometheus-node-exporter-lua-wifi_stations\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# WireGuard: ядро + утилиты + LuCI\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopkg install \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  kmod-wireguard \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  wireguard-tools \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  luci-proto-wireguard\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# DNS over HTTPS\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopkg install https-dns-proxy\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Утилиты для отладки\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopkg install curl jq tmux htop\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003cstrong\u003eЗачем\u003c/strong\u003e:\u003c/p\u003e","title":"OpenWRT: Продвинутая настройка роутера"},{"content":"OrangePI и другие ARM-одноплатники часто используют eMMC или SD-карты с ограниченным ресурсом записи. Со временем накопитель заполняется, деградирует или выходит из строя. Эта статья описывает метод восстановления данных и миграции на внешний носитель (USB SSD/HDD) через chroot-окружение.\n💡 Метод универсален: подходит для OrangePI, Raspberry Pi, NanoPi и других ARM-систем.\n📦 Подготовка Что потребуется Компонент Требования USB-накопитель SSD/HDD, объём ≥ данных на eMMC Live-образ Любой Linux с поддержкой ARM (опционально) Доступ root или sudo, физический доступ к плате Сеть Ethernet или WiFi (для удалённого доступа) Проверка подключённых накопителей # Показать все MMC-устройства (eMMC, SD-карта) ls /dev/mmc* # Показать все блочные устройства lsblk # Показать разделы и точки монтирования df -h Ожидаемый вывод:\n/dev/mmcblk0 - встроенная eMMC или SD-карта /dev/sda, /dev/sdb - подключённые USB-накопители 🔧 Монтирование разделов Шаг 1: Смонтировать корневую систему eMMC # Создать точку монтирования mkdir -p /mnt # Смонтировать корневой раздел (обычно mmcblk0p1 или p2) mount /dev/mmcblk0p2 /mnt Зачем:\nПрямой доступ к файловой системе для диагностики Возможность загрузиться с USB, но работать с данными eMMC Шаг 2: Подключить внешний накопитель # Создать точку для USB mkdir -p /mnt/usb # Смонтировать USB-раздел mount /dev/sda1 /mnt/usb Почему USB:\neMMC имеет ограниченный цикл записи (≈10K циклов) USB SSD надёжнее для долгосрочного хранения Легче заменить при деградации Шаг 3: Проверить доступность # Убедиться, что разделы смонтированы df -h /mnt df -h /mnt/usb # Проверить права доступа ls -la /mnt/ ls -la /mnt/usb/ 🚀 Работа через chroot Вход в chroot-окружение # Сменить корень на смонтированную систему chroot /mnt /bin/bash Что даёт chroot:\nРабота внутри оригинальной системы, а не с live-образа Доступ к установленным пакетам, конфигам, сервисам Возможность запускать команды от имени целевой системы Проверка внутри chroot # Убедиться, что мы в нужной системе hostname cat /etc/os-release # Проверить монтирования внутри chroot df -h ⚠️ Если нужны /proc, /sys, /dev - смонтировать до chroot:\nmount -t proc proc /mnt/proc mount -t sysfs sys /mnt/sys mount --bind /dev /mnt/dev 📊 Анализ占用 места Проверка占用 по директориям # Размер домашней директории du -h /home # Размер проекта/приложений du -h /opt/project # Общая статистика по разделу df -h / Почему du -h:\n-h - человекочитаемый формат (K, M, G) Показывает реальное占用 на диске, а не размер файлов Помогает найти «пожирателей» места Поиск больших файлов # Найти файлы \u0026gt; 100MB find / -type f -size +100M -exec ls -lh {} \\; # Топ-10 самых больших директорий du -h / | sort -rh | head -10 📋 Миграция данных через rsync Базовая синхронизация # Копировать домашнюю директорию и проекты на USB rsync -av /home /opt/project /mnt/usb/ Опции rsync:\n-a - archive mode (сохраняет права, ссылки, времена) -v - verbose (показывает процесс копирования) Продвинутая синхронизация # С прогрессом и удалением лишних файлов на целевом диске rsync -av --progress --delete /home /opt/project /mnt/usb/ # С сжатием для медленных соединений rsync -avz --progress /home /opt/project /mnt/usb/ Почему rsync, а не cp:\nДокопирует только изменённые файлы при повторном запуске Сохраняет все метаданные (владелец, права, времена) Показывает прогресс и скорость Можно прервать и продолжить позже Проверка после копирования # Сравнить размеры исходника и копии du -sh /home /opt/project du -sh /mnt/usb/home /mnt/usb/project # Проверить контрольные суммы (опционально) md5sum /home/user/.bashrc md5sum /mnt/usb/home/user/.bashrc 🔄 Загрузка с USB (опционально) Изменение boot-конфигурации # Для OrangePI с U-Boot # Отредактировать /boot/boot.cmd или /boot/uEnv.txt # Указать USB как корневой раздел # Пример для uEnv.txt: setenv bootargs \u0026#39;console=ttyS0,115200 root=/dev/sda1 rootwait\u0026#39; Или через fstab # Смонтировать USB как корень при загрузке # /etc/fstab /dev/sda1 / ext4 defaults,noatime 0 1 Зачем загружаться с USB:\nРазгрузка eMMC от записи (системные логи, кэш) Увеличение срока службы встроенного накопителя Лёгкая замена/апгрейд без перепрошивки 🛡 Восстановление после сбоя Если система не загружается # Загрузиться с live-образа (SD-карта или сеть) # Смонтировать eMMC и USB как описано выше # Использовать rsync для восстановления данных Если eMMC полностью деградировал # Перенести систему на USB полностью rsync -avx / /mnt/usb/ # Переустановить загрузчик на USB # Для U-Boot: dd if=/usr/lib/u-boot/orangepi_pc_plus/u-boot-sunxi-with-spl.bin of=/dev/sda bs=1024 seek=8 ⚠️ Операции с загрузчиком требуют точного соответствия модели платы!\n🔧 Полезные команды для диагностики # Проверить здоровье eMMC (если поддерживается) smartctl -a /dev/mmcblk0 # Проверить ошибки записи в логах dmesg | grep -iE \u0026#39;error|fail|mmc\u0026#39; # Узнать модель и скорость USB-накопителя lsusb -t hdparm -I /dev/sda # Проверить скорость чтения/записи dd if=/dev/zero of=/mnt/usb/test bs=1M count=1024 conv=fdatasync dd if=/mnt/usb/test of=/dev/null bs=1M ⚠️ Частые проблемы # USB не определяется → Проверить питание: некоторым SSD нужен внешний блок → Попробовать другой порт USB 3.0 → Проверить dmesg | tail после подключения # Ошибка монтирования → Проверить файловую систему: fsck /dev/sda1 → Убедиться, что раздел не занят: umount /dev/sda1 # rsync прерывается → Использовать --partial для возобновления: rsync -av --partial /source /dest → Проверить стабильность питания # chroot не работает → Смонтировать псевдо-ФС до chroot: mount -t proc proc /mnt/proc mount --bind /dev /mnt/dev → Проверить архитектуру: uname -m Ссылки 🌐 OrangePI Official Wiki 📦 Armbian Documentation 🔧 rsync Man Page 💾 eMMC vs SSD Lifespan ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/linux/orangepi/storage-recovery/","summary":"\u003cp\u003eOrangePI и другие ARM-одноплатники часто используют eMMC или SD-карты с ограниченным ресурсом записи. Со временем накопитель заполняется, деградирует или выходит из строя. Эта статья описывает метод восстановления данных и миграции на внешний носитель (USB SSD/HDD) через chroot-окружение.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e💡 Метод универсален: подходит для OrangePI, Raspberry Pi, NanoPi и других ARM-систем.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003chr\u003e\n\u003ch2 id=\"-подготовка\"\u003e📦 Подготовка\u003c/h2\u003e\n\u003ch3 id=\"что-потребуется\"\u003eЧто потребуется\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eКомпонент\u003c/th\u003e\n          \u003cth\u003eТребования\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eUSB-накопитель\u003c/td\u003e\n          \u003ctd\u003eSSD/HDD, объём ≥ данных на eMMC\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eLive-образ\u003c/td\u003e\n          \u003ctd\u003eЛюбой Linux с поддержкой ARM (опционально)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eДоступ\u003c/td\u003e\n          \u003ctd\u003eroot или sudo, физический доступ к плате\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eСеть\u003c/td\u003e\n          \u003ctd\u003eEthernet или WiFi (для удалённого доступа)\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"проверка-подключённых-накопителей\"\u003eПроверка подключённых накопителей\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Показать все MMC-устройства (eMMC, SD-карта)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003els /dev/mmc*\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Показать все блочные устройства\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elsblk\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Показать разделы и точки монтирования\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edf -h\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003cstrong\u003eОжидаемый вывод\u003c/strong\u003e:\u003c/p\u003e","title":"OrangePI: Восстановление и миграция данных"},{"content":"WSL (Windows Subsystem for Linux) - подсистема для запуска нативных Linux-приложений прямо в Windows. Без виртуальной машины, без двойной загрузки.\nWSL1 - трансляция системных вызовов (быстро, но не 100% совместимо)\nWSL2 - полноценное ядро Linux в лёгкой виртуализации (полная совместимость, чуть больше ресурсов)\n💡 Используй WSL2. Почти без накладных расходов, но с полной поддержкой Docker, systemd и всех фич Linux.\nТребования ОС: Windows 10 (2004+, сборка 19041+) или Windows 11 Архитектура: x64 или ARM64 Права: Администратор (для установки) Виртуализация: Включена в BIOS/UEFI (Hyper-V Platform) Проверить виртуализацию:\nsysteminfo | findstr /I \u0026#34;Virtualization\u0026#34; # Должно быть: \u0026#34;Гипервизор обнаружен\u0026#34; или \u0026#34;Virtualization Enabled\u0026#34; Установка (один командой) # Запусти PowerShell от имени Администратора wsl --install Это сделает всё:\n✅ Включит компоненты WSL и VirtualMachinePlatform ✅ Скачает и установит Ubuntu (дистрибутив по умолчанию) ✅ Настроит WSL2 как версию по умолчанию Перезагрузи компьютер после выполнения.\nУстановка вручную (если --install не работает) # 1. Включить компоненты dism /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart # 2. Перезагрузиться shutdown /r /t 0 # 3. Скачать и установить ядро WSL2 # https://aka.ms/wsl2kernel # 4. Задать WSL2 по умолчанию wsl --set-default-version 2 # 5. Установить дистрибутив из Microsoft Store # Или через winget: winget install Ubuntu.Ubuntu.24.04 Первый запуск # После перезагрузки откроется терминал с установкой Linux # Задай имя пользователя и пароль (не отображается при вводе - это нормально) # Обновить пакеты (Ubuntu/Debian) sudo apt update \u0026amp;\u0026amp; sudo apt upgrade -y # Установить базовые инструменты sudo apt install -y git curl wget build-essential Управление дистрибутивами # Список установленных wsl --list --verbose # или кратко: wsl -l -v # Запустить конкретный дистрибутив wsl -d Ubuntu-24.04 wsl -d Debian # Остановить (выключить) дистрибутив wsl --terminate Ubuntu-24.04 # Остановить все wsl --shutdown # Задать версию (1 или 2) wsl --set-version Ubuntu-24.04 2 # Задать дистрибутив по умолчанию wsl --set-default Ubuntu-24.04 # Экспорт / импорт wsl --export Ubuntu-24.04 D:\\backups\\ubuntu.tar wsl --import MyUbuntu D:\\wsl\\MyUbuntu D:\\backups\\ubuntu.tar --version 2 # Удалить дистрибутив (все данные будут потеряны!) wsl --unregister Ubuntu-24.04 Доступ к файлам Из Linux → в Windows # Windows-диски смонтированы в /mnt/ ls /mnt/c/Users/ponfertato/Documents # Открыть проводник в текущей папке explorer.exe . Из Windows → в Linux # Открыть домашнюю папку пользователя в проводнике \\\\wsl$\\Ubuntu-24.04\\home\\kirill # Или из терминала: explorer.exe \\\\wsl$\\Ubuntu-24.04\\home\\kirill ⚠️ Не редактируй Linux-файлы из Windows-приложений напрямую (через \\\\wsl$). Это может повредить метаданные. Используй Linux-инструменты внутри WSL.\nСеть и порты # Узнать свой IP в WSL ip addr show eth0 | grep inet # Windows и WSL используют общую сеть (localhost пробрасывается) # Запусти веб-сервер в WSL: python3 -m http.server 8000 # Доступен из Windows по: # http://localhost:8000 Если порты не пробрасываются:\n# Проверить, включена ли настройка wsl --status # Включить автоматический проброс (если отключён) # В %USERPROFILE%\\.wslconfig: [wsl2] networkingMode=mirrored localhostForwarding=true Интеграция с терминалом и редактором Использовать Windows Terminal # Установить из Microsoft Store или: winget install Microsoft.WindowsTerminal # WSL-профили добавляются автоматически # Переключайся между оболочками: Ctrl+Shift+1/2/3... VS Code + WSL # Внутри WSL: code . # Откроет VS Code на Windows с подключением к WSL-окружению # Установи расширение \u0026#34;Remote - WSL\u0026#34; если потребуется Доступ к Windows-программам из WSL # Запустить Notepad из Linux: notepad.exe /mnt/c/Users/ponfertato/notes.txt # Запустить PowerShell: powershell.exe Get-Process Docker в WSL2 # Установить Docker Desktop для Windows winget install Docker.DockerDesktop # В настройках Docker Desktop: # Settings → Resources → WSL Integration → включить твой дистрибутив # Проверить в WSL: docker run hello-world 💡 Docker работает нативно в WSL2 - без дополнительной настройки внутри Linux.\nsystemd в WSL (для сервисов) # Включить systemd (WSL 0.67.6+) # Создать/отредактировать: /etc/wsl.conf [boot] systemd=true # Применить: # Из PowerShell: wsl --terminate Ubuntu-24.04 wsl -d Ubuntu-24.04 # Проверить: systemctl status Теперь работают: systemctl start nginx, enable docker и другие сервисы.\nПолезные настройки (.wslconfig) Файл: %USERPROFILE%\\.wslconfig (создай, если нет)\n[wsl2] # Память: 4 ГБ (или 50% от ОЗУ) memory=4GB # Процессоры: 4 ядра processors=4 # Своп: 2 ГБ swap=2GB # Диск: динамический, до 256 ГБ diskSize=256GB # Сеть: режим зеркалирования (лучшая совместимость) networkingMode=mirrored # Автозапуск: выключить autoShutdown=true # Таймаут бездействия: 10 минут idleTimeout=600000 Применить: wsl --shutdown, затем запустить дистрибутив снова.\nЧастые проблемы # WSL не запускается, ошибка 0x80370102 → Включи виртуализацию в BIOS → Проверь: \u0026#34;Панель управления\u0026#34; → \u0026#34;Программы\u0026#34; → \u0026#34;Включение компонентов Windows\u0026#34; → Hyper-V Platform # Ошибка \u0026#34;Виртуальная машина не запустилась\u0026#34; → Запусти от администратора: bcdedit /set hypervisorlaunchtype auto → Перезагрузись # Медленный доступ к файлам в /mnt/c → Храни проекты внутри Linux-файловой системы: ~/projects, а не в /mnt/c/... → Используй VS Code Remote WSL для редактирования # Не работает sudo / пароль не принимается → Сброс пароля: # В PowerShell: wsl -d Ubuntu-24.04 -u root # Внутри WSL: passwd kirill # Конфликт портов с Windows → Проверь, что не занято: netsh interface ipv4 show excludedportrange protocol=tcp → Или смени порт в приложении Бэкап и миграция # Экспорт дистрибутива wsl --export Ubuntu-24.04 D:\\wsl-backups\\ubuntu-$(Get-Date -Format \u0026#39;yyyy-MM-dd\u0026#39;).tar # Импорт на другом ПК wsl --import Ubuntu-24.04 D:\\WSL\\Ubuntu D:\\wsl-backups\\ubuntu-2026-03-16.tar --version 2 # Настроить пользователя по умолчанию после импорта # Создать: /etc/wsl.conf в импортированном дистрибутиве [user] default=kirill Ссылки 🌐 Официальная документация WSL 📦 Дистрибутивы в Microsoft Store ⚙️ Настройка .wslconfig 🐳 Docker + WSL2 ","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/blog/windows/wsl/","summary":"\u003cp\u003eWSL (Windows Subsystem for Linux) - подсистема для запуска нативных Linux-приложений прямо в Windows. Без виртуальной машины, без двойной загрузки.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eWSL1\u003c/strong\u003e - трансляция системных вызовов (быстро, но не 100% совместимо)\u003cbr\u003e\n\u003cstrong\u003eWSL2\u003c/strong\u003e - полноценное ядро Linux в лёгкой виртуализации (полная совместимость, чуть больше ресурсов)\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e💡 Используй WSL2. Почти без накладных расходов, но с полной поддержкой Docker, systemd и всех фич Linux.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003chr\u003e\n\u003ch2 id=\"требования\"\u003eТребования\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eОС\u003c/strong\u003e: Windows 10 (2004+, сборка 19041+) или Windows 11\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eАрхитектура\u003c/strong\u003e: x64 или ARM64\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eПрава\u003c/strong\u003e: Администратор (для установки)\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eВиртуализация\u003c/strong\u003e: Включена в BIOS/UEFI (Hyper-V Platform)\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eПроверить виртуализацию:\u003c/strong\u003e\u003c/p\u003e","title":"WSL2: Полный гайд для разработчика"},{"content":"Мы рады сообщить, что в нашу команду присоединился новый участник - iluvcocacola! 🎉\niluvcocacola принесет с собой свежие идеи и уникальный опыт, которые помогут нам достичь новых высот в нашем проекте. Мы уверены, что его/ее навыки и энтузиазм станут ценным дополнением к нашей команде.\nПочему это важно? Добавление нового человека в команду всегда приносит новые перспективы и возможности для роста. Мы верим, что iluvcocacola поможет нам улучшить наши процессы и достичь поставленных целей.\nПожалуйста, присоединяйтесь к нам в приветствии iluvcocacola и поддержите его/ее в этом новом начинании. Мы с нетерпением ждем совместной работы и достижения успехов вместе!\nОжидания Сотрудничество: Мы надеемся на активное участие iluvcocacola в командных обсуждениях и проектах. Идеи: Мы поощряем новые идеи и подходы, которые могут улучшить нашу работу. Поддержка: Команда всегда готова поддержать iluvcocacola в процессе адаптации и обучения. Добро пожаловать в команду, iluvcocacola! Мы рады, что ты с нами!\n","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/news/team/iluvcocacola/","summary":"\u003cp\u003eМы рады сообщить, что в нашу команду присоединился новый участник - \u003cstrong\u003eiluvcocacola\u003c/strong\u003e! 🎉\u003c/p\u003e\n\u003cp\u003eiluvcocacola принесет с собой свежие идеи и уникальный опыт, которые помогут нам достичь новых высот в нашем проекте. Мы уверены, что его/ее навыки и энтузиазм станут ценным дополнением к нашей команде.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u003cem\u003e\u003cstrong\u003eПочему это важно?\u003c/strong\u003e\u003c/em\u003e \u003cbr\u003e\nДобавление нового человека в команду всегда приносит новые перспективы и возможности для роста. Мы верим, что iluvcocacola поможет нам улучшить наши процессы и достичь поставленных целей.\u003c/p\u003e","title":"Добро пожаловать, iluvcocacola, в команду!"},{"content":"ArchiSteamFarm: Steam-менеджер 🎮 Автопилот для ваших Steam-аккаунтов под нашим управлением.\nЧто делает:\n⚙️ Автоматическая активация раздач игр 🃏 Автофарминг карточек и значков 👥 Управление несколькими аккаунтами из одного интерфейса 📊 Логирование действий и уведомления о событиях 🔐 Изоляция сессий и защита от блокировок Как пользоваться:\nЗапросите доступ у администратора Предоставьте минимальные данные: логин + SharedSecret (опционально) Бот работает в фоне - вы получаете карточки, мы следим за стабильностью Безопасность:\nДанные шифруются на уровне конфига Доступ бота ограничен только фармингом Полный контроль аккаунта остаётся у вас Доступ: по запросу • Связаться\n","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/services/archisteamfarm/","summary":"\u003ch3 id=\"archisteamfarm-steam-менеджер-\"\u003eArchiSteamFarm: Steam-менеджер \u003ca href=\"https://github.com/JustArchiNET/ArchiSteamFarm\"\u003e🎮\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003eАвтопилот\u003c/strong\u003e для ваших Steam-аккаунтов под нашим управлением.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eЧто делает:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e⚙️ Автоматическая активация раздач игр\u003c/li\u003e\n\u003cli\u003e🃏 Автофарминг карточек и значков\u003c/li\u003e\n\u003cli\u003e👥 Управление несколькими аккаунтами из одного интерфейса\u003c/li\u003e\n\u003cli\u003e📊 Логирование действий и уведомления о событиях\u003c/li\u003e\n\u003cli\u003e🔐 Изоляция сессий и защита от блокировок\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eКак пользоваться:\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eЗапросите доступ у администратора\u003c/li\u003e\n\u003cli\u003eПредоставьте минимальные данные: логин + SharedSecret (опционально)\u003c/li\u003e\n\u003cli\u003eБот работает в фоне - вы получаете карточки, мы следим за стабильностью\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eБезопасность:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eДанные шифруются на уровне конфига\u003c/li\u003e\n\u003cli\u003eДоступ бота ограничен только фармингом\u003c/li\u003e\n\u003cli\u003eПолный контроль аккаунта остаётся у вас\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eДоступ:\u003c/strong\u003e\nпо запросу • \u003ca href=\"/potatoenergy-site/team/\"\u003eСвязаться\u003c/a\u003e\u003c/p\u003e","title":"ArchiSteamFarm: Steam-менеджер"},{"content":"Authelia: Защита доступа 🔒 Единый вход на все сервисы Potato Energy с защитой уровня enterprise.\nЧто делает:\n🔐 Единый аккаунт для всех сервисов - больше не нужно запоминать пароли 📱 Двухфакторная аутентификация (TOTP, WebAuthn, push-уведомления) 🎯 Гибкие политики доступа: по пользователю, IP, устройству 🛡️ Защита от брутфорса и подозрительных входов 📋 Детальные логи авторизаций для администраторов Как пользоваться:\nПри первом входе в любой сервис создайте аккаунт Authelia Настройте 2FA в личном кабинете (рекомендуется) Входите в сервисы одним кликом - авторизация общая Для администраторов: Управление правами, принудительная 2FA, аудит сессий - всё в единой панели.\nДоступ: автоматически при регистрации\n","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/services/authelia/","summary":"\u003ch3 id=\"authelia-защита-доступа-\"\u003eAuthelia: Защита доступа \u003ca href=\"https://www.authelia.com/\"\u003e🔒\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003eЕдиный вход\u003c/strong\u003e на все сервисы Potato Energy с защитой уровня enterprise.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eЧто делает:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e🔐 Единый аккаунт для всех сервисов - больше не нужно запоминать пароли\u003c/li\u003e\n\u003cli\u003e📱 Двухфакторная аутентификация (TOTP, WebAuthn, push-уведомления)\u003c/li\u003e\n\u003cli\u003e🎯 Гибкие политики доступа: по пользователю, IP, устройству\u003c/li\u003e\n\u003cli\u003e🛡️ Защита от брутфорса и подозрительных входов\u003c/li\u003e\n\u003cli\u003e📋 Детальные логи авторизаций для администраторов\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eКак пользоваться:\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eПри первом входе в любой сервис создайте аккаунт Authelia\u003c/li\u003e\n\u003cli\u003eНастройте 2FA в личном кабинете (рекомендуется)\u003c/li\u003e\n\u003cli\u003eВходите в сервисы одним кликом - авторизация общая\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eДля администраторов:\u003c/strong\u003e\nУправление правами, принудительная 2FA, аудит сессий - всё в единой панели.\u003c/p\u003e","title":"Authelia: защита цифрового пространства"},{"content":"Diun: Страж актуальности контейнеров 🔄 Персональный ассистент по обновлениям Docker-образов.\nЧто делает:\n🔍 Мониторит теги образов в Docker Hub, GitHub и приватных реестрах 📩 Присылает уведомления в Telegram, Discord при выходе новых версий 📋 Детальный лог изменений с ссылками на релизы Как пользоваться:\nDiun работает в фоне - настройка не требуется Вы получаете уведомление, когда для сервиса доступно обновление Администратор применяет обновление или настраивает авто-апдейт Для администраторов: Гибкие правила, фильтрация, уведомления - всё в конфиге.\n","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/services/diun/","summary":"\u003ch3 id=\"diun-страж-актуальности-контейнеров-\"\u003eDiun: Страж актуальности контейнеров \u003ca href=\"https://github.com/crazy-max/diun\"\u003e🔄\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003eПерсональный ассистент\u003c/strong\u003e по обновлениям Docker-образов.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eЧто делает:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e🔍 Мониторит теги образов в Docker Hub, GitHub и приватных реестрах\u003c/li\u003e\n\u003cli\u003e📩 Присылает уведомления в Telegram, Discord при выходе новых версий\u003c/li\u003e\n\u003cli\u003e📋 Детальный лог изменений с ссылками на релизы\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eКак пользоваться:\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eDiun работает в фоне - настройка не требуется\u003c/li\u003e\n\u003cli\u003eВы получаете уведомление, когда для сервиса доступно обновление\u003c/li\u003e\n\u003cli\u003eАдминистратор применяет обновление или настраивает авто-апдейт\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eДля администраторов:\u003c/strong\u003e\nГибкие правила, фильтрация, уведомления - всё в конфиге.\u003c/p\u003e","title":"Diun: Страж актуальности контейнеров"},{"content":"Drawpile: Совместное творчество 🎨 Кооперативный сервер для рисования в реальном времени.\nЧто делает:\n✏️ Совместное рисование на одном холсте: до 8+ пользователей 🖌️ Полноценные инструменты: слои, кисти, выделение, трансформация 💬 Встроенный чат для координации в процессе 🎥 Запись сессий с возможностью воспроизведения 📤 Экспорт результата в PNG/PSD Как подключиться:\nЗагрузите клиент с drawpile.net или запустите онлайн-версию в вашем браузере. Запустите → \u0026ldquo;Connect\u0026rdquo; → введите адрес: connect.potatoenergy.ru:27750 Выберите ник, присоединитесь к сессии или создайте свою Правила: Уважайте чужое творчество, не спамьте в чат, координируйте действия. Детали - в описании сессии.\nСтатус: https://status.potatoenergy.ru/history/drawpile\nДоступ: connect.potatoenergy.ru:27750 • публичный, регистрация не требуется\n","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/services/drawpile/","summary":"\u003ch3 id=\"drawpile-совместное-творчество-\"\u003eDrawpile: Совместное творчество \u003ca href=\"https://drawpile.net/\"\u003e🎨\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003eКооперативный сервер\u003c/strong\u003e для рисования в реальном времени.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eЧто делает:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e✏️ Совместное рисование на одном холсте: до 8+ пользователей\u003c/li\u003e\n\u003cli\u003e🖌️ Полноценные инструменты: слои, кисти, выделение, трансформация\u003c/li\u003e\n\u003cli\u003e💬 Встроенный чат для координации в процессе\u003c/li\u003e\n\u003cli\u003e🎥 Запись сессий с возможностью воспроизведения\u003c/li\u003e\n\u003cli\u003e📤 Экспорт результата в PNG/PSD\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eКак подключиться:\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eЗагрузите клиент с \u003ca href=\"https://drawpile.net/download\"\u003edrawpile.net\u003c/a\u003e или запустите \u003ca href=\"https://web.drawpile.net/\"\u003eонлайн-версию\u003c/a\u003e в вашем браузере.\u003c/li\u003e\n\u003cli\u003eЗапустите → \u0026ldquo;Connect\u0026rdquo; → введите адрес: \u003ccode\u003econnect.potatoenergy.ru:27750\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eВыберите ник, присоединитесь к сессии или создайте свою\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eПравила:\u003c/strong\u003e\nУважайте чужое творчество, не спамьте в чат, координируйте действия. Детали - в описании сессии.\u003c/p\u003e","title":"Drawpile: Совместное творчество"},{"content":"Error-Pages: Кастомные страницы ошибок 🚨 Дружелюбные сообщения вместо стандартных \u0026ldquo;404 Not Found\u0026rdquo;.\nЧто делает:\n🎨 Стильные страницы для 4xx/5xx ошибок в едином бренде Potato Energy 🌍 Автоопределение языка и тёмная/светлая тема 🔧 Полезные подсказки: \u0026ldquo;проверьте URL\u0026rdquo;, \u0026ldquo;вернитесь на главную\u0026rdquo;, \u0026ldquo;напишите в поддержку\u0026rdquo; 📊 Логирование ошибок для администраторов ⚡ Лёгкие статические страницы - загружаются даже при сбоях бэкенда Как это работает:\nПри ошибке доступа Nginx/Traefik перенаправляет на кастомную страницу Вы видите понятное сообщение с вариантами действий Администратор получает уведомление о критических сбоях Для администраторов: Гибкая настройка текстов, редиректов и стилей через единый конфиг.\nДоступ: автоматически • срабатывает при ошибках\n","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/services/error-pages/","summary":"\u003ch3 id=\"error-pages-кастомные-страницы-ошибок-\"\u003eError-Pages: Кастомные страницы ошибок \u003ca href=\"https://github.com/tarampampam/error-pages\"\u003e🚨\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003eДружелюбные сообщения\u003c/strong\u003e вместо стандартных \u0026ldquo;404 Not Found\u0026rdquo;.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eЧто делает:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e🎨 Стильные страницы для 4xx/5xx ошибок в едином бренде Potato Energy\u003c/li\u003e\n\u003cli\u003e🌍 Автоопределение языка и тёмная/светлая тема\u003c/li\u003e\n\u003cli\u003e🔧 Полезные подсказки: \u0026ldquo;проверьте URL\u0026rdquo;, \u0026ldquo;вернитесь на главную\u0026rdquo;, \u0026ldquo;напишите в поддержку\u0026rdquo;\u003c/li\u003e\n\u003cli\u003e📊 Логирование ошибок для администраторов\u003c/li\u003e\n\u003cli\u003e⚡ Лёгкие статические страницы - загружаются даже при сбоях бэкенда\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eКак это работает:\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eПри ошибке доступа Nginx/Traefik перенаправляет на кастомную страницу\u003c/li\u003e\n\u003cli\u003eВы видите понятное сообщение с вариантами действий\u003c/li\u003e\n\u003cli\u003eАдминистратор получает уведомление о критических сбоях\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eДля администраторов:\u003c/strong\u003e\nГибкая настройка текстов, редиректов и стилей через единый конфиг.\u003c/p\u003e","title":"Error-Pages: Кастомные страницы ошибок"},{"content":"Grafana: Видимость каждого бита 📈 Мониторинг работы всех сервисов Potato Energy в реальном времени.\nЧто показывает:\n🖥️ Дашборды по CPU, RAM, дискам, сети для каждого сервиса 🔄 Статус контейнеров, аптайм, логи в одном интерфейсе 🚨 Визуализация алертов: видите проблему до того, как она станет критичной 📊 Гибкие графики: от простых метрик до сложных запросов к Prometheus 📤 Экспорт отчётов в PNG/PDF для презентации или аудита Как пользоваться:\nОткройте grafana.potatoenergy.ru Просматривайте публичные дашборды без авторизации или войдите под учётной записью Potato Energy (через Authelia) Авторизуйтесь для создания своих графиков и доступа к дополнительным дашбордам Для группы dev: Редактирование дашбордов, управление источниками данных, настройка уведомлений.\nСтатус: https://status.potatoenergy.ru/history/grafana\nДоступ: grafana.potatoenergy.ru • просмотр открыт, редактирование - по правам\n","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/services/grafana/","summary":"\u003ch3 id=\"grafana-видимость-каждого-бита-\"\u003eGrafana: Видимость каждого бита \u003ca href=\"https://grafana.com/\"\u003e📈\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003eМониторинг работы\u003c/strong\u003e всех сервисов Potato Energy в реальном времени.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eЧто показывает:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e🖥️ Дашборды по CPU, RAM, дискам, сети для каждого сервиса\u003c/li\u003e\n\u003cli\u003e🔄 Статус контейнеров, аптайм, логи в одном интерфейсе\u003c/li\u003e\n\u003cli\u003e🚨 Визуализация алертов: видите проблему до того, как она станет критичной\u003c/li\u003e\n\u003cli\u003e📊 Гибкие графики: от простых метрик до сложных запросов к Prometheus\u003c/li\u003e\n\u003cli\u003e📤 Экспорт отчётов в PNG/PDF для презентации или аудита\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eКак пользоваться:\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eОткройте \u003ccode\u003egrafana.potatoenergy.ru\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eПросматривайте публичные дашборды без авторизации или войдите под учётной записью Potato Energy (через Authelia)\u003c/li\u003e\n\u003cli\u003eАвторизуйтесь для создания своих графиков и доступа к дополнительным дашбордам\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eДля группы \u003ccode\u003edev\u003c/code\u003e:\u003c/strong\u003e\nРедактирование дашбордов, управление источниками данных, настройка уведомлений.\u003c/p\u003e","title":"Grafana: Видимость каждого бита"},{"content":"Home Assistant: Умный дом 🏠 Центр управления для ваших умных устройств под вашим контролем.\nЧто делает:\n💡 Управление светом, устройствами, розетками из одного интерфейса 🤖 Автоматизации: \u0026ldquo;если темно → включить свет\u0026rdquo;, \u0026ldquo;если ушёл → выключить всё\u0026rdquo; 🔐 Локальная работа - без облаков и зависимости от интернета 📊 Энергомодуль: отслеживание потребления и оптимизация затрат 🌐 Поддержка 1000+ устройств: Zigbee, Z-Wave, Wi-Fi, Matter Как пользоваться:\nОткройте home.potatoenergy.ru (доступ только для группы hass) Выберите устройство или сценарий в дашборде Создайте свою автоматизацию через визуальный редактор Для группы hass: Полный доступ к конфигурации, интеграциям, логам и резервным копиям.\nДоступ: home.potatoenergy.ru • по учётным данным Potato Energy (только по правам группы hass)\n","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/services/home-assistant/","summary":"\u003ch3 id=\"home-assistant-умный-дом-\"\u003eHome Assistant: Умный дом \u003ca href=\"https://www.home-assistant.io/\"\u003e🏠\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003eЦентр управления\u003c/strong\u003e для ваших умных устройств под вашим контролем.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eЧто делает:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e💡 Управление светом, устройствами, розетками из одного интерфейса\u003c/li\u003e\n\u003cli\u003e🤖 Автоматизации: \u0026ldquo;если темно → включить свет\u0026rdquo;, \u0026ldquo;если ушёл → выключить всё\u0026rdquo;\u003c/li\u003e\n\u003cli\u003e🔐 Локальная работа - без облаков и зависимости от интернета\u003c/li\u003e\n\u003cli\u003e📊 Энергомодуль: отслеживание потребления и оптимизация затрат\u003c/li\u003e\n\u003cli\u003e🌐 Поддержка 1000+ устройств: Zigbee, Z-Wave, Wi-Fi, Matter\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eКак пользоваться:\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eОткройте \u003ccode\u003ehome.potatoenergy.ru\u003c/code\u003e (доступ только для группы \u003ccode\u003ehass\u003c/code\u003e)\u003c/li\u003e\n\u003cli\u003eВыберите устройство или сценарий в дашборде\u003c/li\u003e\n\u003cli\u003eСоздайте свою автоматизацию через визуальный редактор\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eДля группы \u003ccode\u003ehass\u003c/code\u003e:\u003c/strong\u003e\nПолный доступ к конфигурации, интеграциям, логам и резервным копиям.\u003c/p\u003e","title":"Home Assistant: Интеллектуальное ядро вашего дома"},{"content":"Mastodon: Ваше федеративное пространство 🌐 Социальная сеть без цензуры, где вы владеете своими данными.\nЧто делает:\n📝 Публикация постов, тредов, изображений и видео без алгоритмической ленты 🌍 Федерация через ActivityPub: общение с пользователями Mastodon, Pixelfed, PeerTube 🔒 Гибкая приватность: посты только для подписчиков, локальные сообщения, CW-теги 🎨 Кастомные эмодзи, темы оформления и модерация контента 🛡️ Локальная модерация и блокировка спама - вы контролируете своё пространство Как присоединиться:\nПерейдите на social.potatoenergy.ru Войдите под учётной записью Potato Energy (через Authelia) Настройте профиль и начните публиковаться - вы уже в федерации Для модераторов: Инструменты репорта, silencе/блокировки, федеративные правила - всё в админ-панели.\nСтатус: https://status.potatoenergy.ru/history/mastodon\nДоступ: social.potatoenergy.ru • по учётным данным Potato Energy\n","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/services/mastodon/","summary":"\u003ch3 id=\"mastodon-ваше-федеративное-пространство-\"\u003eMastodon: Ваше федеративное пространство \u003ca href=\"https://joinmastodon.org/\"\u003e🌐\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003eСоциальная сеть без цензуры\u003c/strong\u003e, где вы владеете своими данными.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eЧто делает:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e📝 Публикация постов, тредов, изображений и видео без алгоритмической ленты\u003c/li\u003e\n\u003cli\u003e🌍 Федерация через ActivityPub: общение с пользователями Mastodon, Pixelfed, PeerTube\u003c/li\u003e\n\u003cli\u003e🔒 Гибкая приватность: посты только для подписчиков, локальные сообщения, CW-теги\u003c/li\u003e\n\u003cli\u003e🎨 Кастомные эмодзи, темы оформления и модерация контента\u003c/li\u003e\n\u003cli\u003e🛡️ Локальная модерация и блокировка спама - вы контролируете своё пространство\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eКак присоединиться:\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eПерейдите на \u003ca href=\"https://social.potatoenergy.ru/\"\u003esocial.potatoenergy.ru\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eВойдите под учётной записью Potato Energy (через Authelia)\u003c/li\u003e\n\u003cli\u003eНастройте профиль и начните публиковаться - вы уже в федерации\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eДля модераторов:\u003c/strong\u003e\nИнструменты репорта, silencе/блокировки, федеративные правила - всё в админ-панели.\u003c/p\u003e","title":"Mastodon: Ваше федеративное пространство"},{"content":"Mindustry: Индустриальные войны 🏭 Стратегическая песочница о строительстве производств и тактических боях.\nЧто на сервере:\n⚙️ Сложные производственные цепочки: руда → переработка → логистика → армия 🔫 PvE-кампании против волн врагов и PvP-сражения до 16 игроков 🗺️ Ротация карт: песочница, выживание, захват секторов 🗳️ Голосование за карты, паузы и рестарты - демократия в действии 💬 Синхронизация чата с Discord: общайтесь в игре и из браузера Как подключиться:\nЗапустите Mindustry актуальной версии Откройте \u0026ldquo;Multiplayer\u0026rdquo; → \u0026ldquo;Add Server\u0026rdquo; Введите адрес: connect.potatoenergy.ru:6567 Подключайтесь и стройте! Правила: Без гриферства, уважайте тайминги, координируйтесь в чате. Детали - на сервере.\nСтатус: https://status.potatoenergy.ru/history/mindustry\nДоступ: connect.potatoenergy.ru:6567 • публичный, регистрация не требуется\n","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/services/mindustry-server/","summary":"\u003ch3 id=\"mindustry-индустриальные-войны-\"\u003eMindustry: Индустриальные войны \u003ca href=\"https://mindustrygame.github.io/\"\u003e🏭\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003eСтратегическая песочница\u003c/strong\u003e о строительстве производств и тактических боях.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eЧто на сервере:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e⚙️ Сложные производственные цепочки: руда → переработка → логистика → армия\u003c/li\u003e\n\u003cli\u003e🔫 PvE-кампании против волн врагов и PvP-сражения до 16 игроков\u003c/li\u003e\n\u003cli\u003e🗺️ Ротация карт: песочница, выживание, захват секторов\u003c/li\u003e\n\u003cli\u003e🗳️ Голосование за карты, паузы и рестарты - демократия в действии\u003c/li\u003e\n\u003cli\u003e💬 Синхронизация чата с Discord: общайтесь в игре и из браузера\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eКак подключиться:\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eЗапустите Mindustry актуальной версии\u003c/li\u003e\n\u003cli\u003eОткройте \u0026ldquo;Multiplayer\u0026rdquo; → \u0026ldquo;Add Server\u0026rdquo;\u003c/li\u003e\n\u003cli\u003eВведите адрес: \u003ccode\u003econnect.potatoenergy.ru:6567\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eПодключайтесь и стройте!\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eПравила:\u003c/strong\u003e\nБез гриферства, уважайте тайминги, координируйтесь в чате. Детали - на сервере.\u003c/p\u003e","title":"Mindustry: Индустриальные войны на картофельной энергии"},{"content":"Minecraft: Безграничный мир 🎮 Песочница для творчества и совместных приключений на Potato Energy.\nЧто на сервере:\n⚡ Высокопроизводительный движок (Paper) - без лагов даже с редстоун-схемами 🔄 Автобэкапы мира каждые 30 минут - прогресс в безопасности 💬 Синхронизация чата с Discord: общайтесь в игре и из браузера 🛡️ Античит - защита от гриферов и читеров 🧩 Плагины на качество жизни: телепорты, приват территорий, экономика Как подключиться:\nЗапустите Minecraft версии 1.16.5 Откройте \u0026ldquo;Сетевая игра\u0026rdquo; → \u0026ldquo;Добавить сервер\u0026rdquo; Введите адрес: connect.potatoenergy.ru:25565 Подключайтесь и исследуйте! Правила: Без гриферства, уважайте чужие постройки, координируйтесь в чате. Детали - на сервере.\nСтатус: https://status.potatoenergy.ru/history/minecraft\nДоступ: connect.potatoenergy.ru:25565 • публичный, при входе требуется регистрация\n","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/services/minecraft-server/","summary":"\u003ch3 id=\"minecraft-безграничный-мир-\"\u003eMinecraft: Безграничный мир \u003ca href=\"https://minecraft.net/\"\u003e🎮\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003eПесочница для творчества\u003c/strong\u003e и совместных приключений на Potato Energy.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eЧто на сервере:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e⚡ Высокопроизводительный движок (Paper) - без лагов даже с редстоун-схемами\u003c/li\u003e\n\u003cli\u003e🔄 Автобэкапы мира каждые 30 минут - прогресс в безопасности\u003c/li\u003e\n\u003cli\u003e💬 Синхронизация чата с Discord: общайтесь в игре и из браузера\u003c/li\u003e\n\u003cli\u003e🛡️ Античит - защита от гриферов и читеров\u003c/li\u003e\n\u003cli\u003e🧩 Плагины на качество жизни: телепорты, приват территорий, экономика\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eКак подключиться:\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eЗапустите Minecraft версии \u003ccode\u003e1.16.5\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eОткройте \u0026ldquo;Сетевая игра\u0026rdquo; → \u0026ldquo;Добавить сервер\u0026rdquo;\u003c/li\u003e\n\u003cli\u003eВведите адрес: \u003ccode\u003econnect.potatoenergy.ru:25565\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eПодключайтесь и исследуйте!\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eПравила:\u003c/strong\u003e\nБез гриферства, уважайте чужие постройки, координируйтесь в чате. Детали - на сервере.\u003c/p\u003e","title":"Minecraft: Безграничный мир картофельной энергии"},{"content":"Nextcloud: Ваше облако ☁️ Безопасное хранилище файлов с инструментами для работы под вашим контролем.\nЧто делает:\n📁 Синхронизация файлов между ПК, телефоном и веб-интерфейсом ✍️ Совместное редактирование документов (OnlyOffice/Collabora) 🎥 Видеозвонки через Talk с шифрованием и записью 📅 Календари, задачи, контакты - синхронизация по CardDAV/CalDAV 🔐 Шифрование данных на сервере + двухфакторная аутентификация Как пользоваться:\nОткройте cloud.potatoenergy.ru Войдите под учётной записью Potato Energy (через Authelia) Загружайте файлы, создавайте документы, приглашайте коллег Для администраторов: Управление квотами, внешними хранилищами, аудит логов, интеграция с Authelia.\nСтатус: https://status.potatoenergy.ru/history/nextcloud\nДоступ: cloud.potatoenergy.ru • по учётным данным Potato Energy\n","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/services/nextcloud/","summary":"\u003ch3 id=\"nextcloud-ваше-облако-\"\u003eNextcloud: Ваше облако \u003ca href=\"https://nextcloud.com/\"\u003e☁️\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003eБезопасное хранилище\u003c/strong\u003e файлов с инструментами для работы под вашим контролем.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eЧто делает:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e📁 Синхронизация файлов между ПК, телефоном и веб-интерфейсом\u003c/li\u003e\n\u003cli\u003e✍️ Совместное редактирование документов (OnlyOffice/Collabora)\u003c/li\u003e\n\u003cli\u003e🎥 Видеозвонки через Talk с шифрованием и записью\u003c/li\u003e\n\u003cli\u003e📅 Календари, задачи, контакты - синхронизация по CardDAV/CalDAV\u003c/li\u003e\n\u003cli\u003e🔐 Шифрование данных на сервере + двухфакторная аутентификация\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eКак пользоваться:\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eОткройте \u003ca href=\"https://cloud.potatoenergy.ru/\"\u003ecloud.potatoenergy.ru\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eВойдите под учётной записью Potato Energy (через Authelia)\u003c/li\u003e\n\u003cli\u003eЗагружайте файлы, создавайте документы, приглашайте коллег\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eДля администраторов:\u003c/strong\u003e\nУправление квотами, внешними хранилищами, аудит логов, интеграция с Authelia.\u003c/p\u003e","title":"Nextcloud: Ваше цифровое рабочее пространство"},{"content":"Open WebUI: ИИ-помощник 🤖 Интеллектуальный ассистент для решения повседневных задач под вашим контролем.\nЧто делает:\n🧠 Работа с локальными и облачными LLM (Llama, Mistral, GPT-совместимые API) 🔍 RAG-поиск: загрузите PDF/DOC/TXT - ИИ ответит по содержанию документа 🌐 Веб-поиск на русском с цитированием источников 🎥 Анализ видео по ссылке: транскрипция + саммари + ответы на вопросы 📤 Экспорт диалогов в Markdown/PDF, шаринг чатов по ссылке Как пользоваться:\nОткройте chat.potatoenergy.ru Войдите под учётной записью Potato Energy (через Authelia) Выберите модель, загрузите файл или задайте вопрос - готово Для продвинутых: Настройка системных промптов, подключение внешних API, управление контекстом, веб-хуки.\nСтатус: https://status.potatoenergy.ru/history/open-web-ui\nДоступ: chat.potatoenergy.ru • по учётным данным Potato Energy\n","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/services/open-webui/","summary":"\u003ch3 id=\"open-webui-ии-помощник-\"\u003eOpen WebUI: ИИ-помощник \u003ca href=\"https://github.com/open-webui/open-webui\"\u003e🤖\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003eИнтеллектуальный ассистент\u003c/strong\u003e для решения повседневных задач под вашим контролем.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eЧто делает:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e🧠 Работа с локальными и облачными LLM (Llama, Mistral, GPT-совместимые API)\u003c/li\u003e\n\u003cli\u003e🔍 RAG-поиск: загрузите PDF/DOC/TXT - ИИ ответит по содержанию документа\u003c/li\u003e\n\u003cli\u003e🌐 Веб-поиск на русском с цитированием источников\u003c/li\u003e\n\u003cli\u003e🎥 Анализ видео по ссылке: транскрипция + саммари + ответы на вопросы\u003c/li\u003e\n\u003cli\u003e📤 Экспорт диалогов в Markdown/PDF, шаринг чатов по ссылке\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eКак пользоваться:\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eОткройте \u003ca href=\"https://chat.potatoenergy.ru/\"\u003echat.potatoenergy.ru\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eВойдите под учётной записью Potato Energy (через Authelia)\u003c/li\u003e\n\u003cli\u003eВыберите модель, загрузите файл или задайте вопрос - готово\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eДля продвинутых:\u003c/strong\u003e\nНастройка системных промптов, подключение внешних API, управление контекстом, веб-хуки.\u003c/p\u003e","title":"Open WebUI: Ваш интеллектуальный помощник"},{"content":"Portainer: Визуальный контроль инфраструктуры 🎛️ Панель управления всеми сервисами в одном месте.\nЧто делает:\n🐳 Управление контейнерами, образами, сетями и томами Docker через веб-интерфейс 📦 Развёртывание стеков из Docker Compose в один клик 🔄 Авто-деплой из Git-репозитория: пуш в репо → обновление сервиса 💻 Веб-терминал и логи контейнеров - доступ к отладке без SSH 📊 Мониторинг ресурсов: CPU, RAM, дисковое пространство в реальном времени Как пользоваться:\nОткройте portainer.potatoenergy.ru (доступ только для группы admin) Войдите под учётной записью Potato Energy (через Authelia) Выбирайте сервис → управляйте, перезапускайте, смотрите логи Для администраторов: Роли и права доступа, аудит действий, шаблоны развёртывания, интеграция с registries.\nДоступ: portainer.potatoenergy.ru • по учётным данным Potato Energy (только по правам группы admin)\n","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/services/portainer/","summary":"\u003ch3 id=\"portainer-визуальный-контроль-инфраструктуры-\"\u003ePortainer: Визуальный контроль инфраструктуры \u003ca href=\"https://www.portainer.io/\"\u003e🎛️\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003eПанель управления\u003c/strong\u003e всеми сервисами в одном месте.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eЧто делает:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e🐳 Управление контейнерами, образами, сетями и томами Docker через веб-интерфейс\u003c/li\u003e\n\u003cli\u003e📦 Развёртывание стеков из Docker Compose в один клик\u003c/li\u003e\n\u003cli\u003e🔄 Авто-деплой из Git-репозитория: пуш в репо → обновление сервиса\u003c/li\u003e\n\u003cli\u003e💻 Веб-терминал и логи контейнеров - доступ к отладке без SSH\u003c/li\u003e\n\u003cli\u003e📊 Мониторинг ресурсов: CPU, RAM, дисковое пространство в реальном времени\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eКак пользоваться:\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eОткройте \u003ccode\u003eportainer.potatoenergy.ru\u003c/code\u003e (доступ только для группы \u003ccode\u003eadmin\u003c/code\u003e)\u003c/li\u003e\n\u003cli\u003eВойдите под учётной записью Potato Energy (через Authelia)\u003c/li\u003e\n\u003cli\u003eВыбирайте сервис → управляйте, перезапускайте, смотрите логи\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eДля администраторов:\u003c/strong\u003e\nРоли и права доступа, аудит действий, шаблоны развёртывания, интеграция с registries.\u003c/p\u003e","title":"Portainer: Визуальный контроль инфраструктуры"},{"content":"Prometheus: Мониторинг инфраструктуры 📊 Система предупреждения о проблемах до их возникновения.\nЧто контролирует:\n🖥️ Метрики серверов: CPU, RAM, диск, сеть через node_exporter 🌐 Доступность сервисов: blackbox-проверки HTTP/TCP/ICMP 📈 Сбор метрик из приложений: Nextcloud, Home Assistant и других 🚨 Alertmanager: уведомления в Telegram/Discord при превышении порогов 🔍 Мощные запросы через PromQL для глубокого анализа Как это работает:\nPrometheus собирает метрики по расписанию (scrape) Вы видите графики в Grafana или настраиваете свои дашборды При аномалии срабатывает алерт - администратор получает уведомление Для администраторов: Гибкие правила алертинга, запись правил (recording rules), федерация метрик, долгосрочное хранение через Thanos.\nДоступ: через Grafana (grafana.potatoenergy.ru) • по учётным данным Potato Energy (управление - только по правам группы admin)\n","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/services/prometheus/","summary":"\u003ch3 id=\"prometheus-мониторинг-инфраструктуры-\"\u003ePrometheus: Мониторинг инфраструктуры \u003ca href=\"https://prometheus.io/\"\u003e📊\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003eСистема предупреждения\u003c/strong\u003e о проблемах до их возникновения.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eЧто контролирует:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e🖥️ Метрики серверов: CPU, RAM, диск, сеть через node_exporter\u003c/li\u003e\n\u003cli\u003e🌐 Доступность сервисов: blackbox-проверки HTTP/TCP/ICMP\u003c/li\u003e\n\u003cli\u003e📈 Сбор метрик из приложений: Nextcloud, Home Assistant и других\u003c/li\u003e\n\u003cli\u003e🚨 Alertmanager: уведомления в Telegram/Discord при превышении порогов\u003c/li\u003e\n\u003cli\u003e🔍 Мощные запросы через PromQL для глубокого анализа\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eКак это работает:\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003ePrometheus собирает метрики по расписанию (scrape)\u003c/li\u003e\n\u003cli\u003eВы видите графики в Grafana или настраиваете свои дашборды\u003c/li\u003e\n\u003cli\u003eПри аномалии срабатывает алерт - администратор получает уведомление\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eДля администраторов:\u003c/strong\u003e\nГибкие правила алертинга, запись правил (recording rules), федерация метрик, долгосрочное хранение через Thanos.\u003c/p\u003e","title":"Prometheus: всевидящее око инфраструктуры"},{"content":"Terraria: Приключения ⚔️ Кооперативный сервер для исследований, битв и творчества.\nЧто на сервере:\n🌍 Классический режим + экспертные ивенты для опытных игроков ⚔️ PvE-кооператив: боссы, ивенты, данжи - вместе веселее 🏗️ Общий мир с приватом построек (плагин TShock) 🔄 Автобэкапы мира каждые 30 минут - прогресс в безопасности 💬 Чат + Discord-синхронизация: общайтесь в игре и из браузера Как подключиться:\nЗапустите Terraria актуальной версии Откройте \u0026ldquo;Multiplayer\u0026rdquo; → \u0026ldquo;Join via IP\u0026rdquo; Введите адрес: connect.potatoenergy.ru:7777 Подключайтесь и начинайте приключение! Правила: Без гриферства, уважайте чужие постройки, не спамьте в чат. Детали - на сервере.\nСтатус: https://status.potatoenergy.ru/history/terraria\nДоступ: connect.potatoenergy.ru:7777 • публичный, регистрация не требуется\n","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/services/terraria-server/","summary":"\u003ch3 id=\"terraria-приключения-\"\u003eTerraria: Приключения \u003ca href=\"https://terraria.org/\"\u003e⚔️\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003eКооперативный сервер\u003c/strong\u003e для исследований, битв и творчества.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eЧто на сервере:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e🌍 Классический режим + экспертные ивенты для опытных игроков\u003c/li\u003e\n\u003cli\u003e⚔️ PvE-кооператив: боссы, ивенты, данжи - вместе веселее\u003c/li\u003e\n\u003cli\u003e🏗️ Общий мир с приватом построек (плагин TShock)\u003c/li\u003e\n\u003cli\u003e🔄 Автобэкапы мира каждые 30 минут - прогресс в безопасности\u003c/li\u003e\n\u003cli\u003e💬 Чат + Discord-синхронизация: общайтесь в игре и из браузера\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eКак подключиться:\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eЗапустите Terraria актуальной версии\u003c/li\u003e\n\u003cli\u003eОткройте \u0026ldquo;Multiplayer\u0026rdquo; → \u0026ldquo;Join via IP\u0026rdquo;\u003c/li\u003e\n\u003cli\u003eВведите адрес: \u003ccode\u003econnect.potatoenergy.ru:7777\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eПодключайтесь и начинайте приключение!\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eПравила:\u003c/strong\u003e\nБез гриферства, уважайте чужие постройки, не спамьте в чат. Детали - на сервере.\u003c/p\u003e","title":"Terraria: Приключения на картофельной энергии"},{"content":"Traefik: Умный маршрутизатор 🛠️ Ваш цифровой диспетчер, который направляет запросы к нужным сервисам.\nЧто делает:\n🔐 Авто-выпуск и обновление SSL-сертификатов (Let\u0026rsquo;s Encrypt) 🚦 Маршрутизация по доменам: grafana.*/ → Grafana, cloud.*/ → Nextcloud ⚡ Zero-downtime деплой: обновления сервисов без разрыва соединений 🧩 Middleware: аутентификация (Authelia), rate-limiting, редиректы, компрессия 📊 Экспорт метрик для Prometheus - видимость трафика в реальном времени Как это работает:\nВы вводите service.potatoenergy.ru в браузере Traefik проверяет правила, применяет SSL и middleware Запрос попадает в нужный контейнер - вы видите сервис Для администраторов: Динамическая конфигурация через Docker-лейблы и конфигурационные файлы, hot-reload без перезапуска, интеграция с Docker.\nДоступ: автоматически • основа маршрутизации всех сервисов Potato Energy\n","permalink":"https://potatoenergy.gitverse.site/potatoenergy-site/services/traefik/","summary":"\u003ch3 id=\"traefik-умный-маршрутизатор-\"\u003eTraefik: Умный маршрутизатор \u003ca href=\"https://traefik.io/\"\u003e🛠️\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003eВаш цифровой диспетчер\u003c/strong\u003e, который направляет запросы к нужным сервисам.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eЧто делает:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e🔐 Авто-выпуск и обновление SSL-сертификатов (Let\u0026rsquo;s Encrypt)\u003c/li\u003e\n\u003cli\u003e🚦 Маршрутизация по доменам: \u003ccode\u003egrafana.*/\u003c/code\u003e → Grafana, \u003ccode\u003ecloud.*/\u003c/code\u003e → Nextcloud\u003c/li\u003e\n\u003cli\u003e⚡ Zero-downtime деплой: обновления сервисов без разрыва соединений\u003c/li\u003e\n\u003cli\u003e🧩 Middleware: аутентификация (Authelia), rate-limiting, редиректы, компрессия\u003c/li\u003e\n\u003cli\u003e📊 Экспорт метрик для Prometheus - видимость трафика в реальном времени\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eКак это работает:\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eВы вводите \u003ccode\u003eservice.potatoenergy.ru\u003c/code\u003e в браузере\u003c/li\u003e\n\u003cli\u003eTraefik проверяет правила, применяет SSL и middleware\u003c/li\u003e\n\u003cli\u003eЗапрос попадает в нужный контейнер - вы видите сервис\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eДля администраторов:\u003c/strong\u003e\nДинамическая конфигурация через Docker-лейблы и конфигурационные файлы, hot-reload без перезапуска, интеграция с Docker.\u003c/p\u003e","title":"Traefik: Умный маршрутизатор"}]