Цифровой дворник

selfhosting

Когда начинал, казалось, что Docker — это стандарт: compose, образы, всё из коробки. Но для домашнего сервера, где крутится 10+ сервисов, LXC на Proxmox оказался удобнее. Рассказываю, почему.

LXC — это почти VM, но легче

LXC — это изоляция на уровне ядра: у каждого контейнера свои процессы, своя сеть, свой корень. Но при этом он делит ядро и память хоста. По сути — «лёгкая VM без эмуляции железа».

В моей лабе каждый сервис — отдельный LXC: Caddy, Ollama, ComfyUI, Frigate, Kuma, Beszel, Immich. У каждого свой IP, свой systemd, свои порты. Никакого docker-compose — просто контейнер с сервисом.

Почему LXC удобнее Docker для дома

  • Обновления — pct upgrade, как обычная система. Не надо пересобирать образы
  • Бэкап — снапшот целиком через pct snapshot. Один снапшот = весь сервис со всеми данными
  • Ресурсы — лимиты CPU/RAM/диска выставляются на лету, без рестарта
  • Сеть — у каждого свой IP. Нет проброса портов и docker networks
  • Железо — GPU, USB, /dev пробрасываются напрямую в контейнер
  • Нагрузка — LXC практически не ест ресурсов: это просто процесс на хосте

Почему LXC лучше VM

VM эмулирует железо целиком — своя ОС, своё ядро, свои драйверы. Это дорого:

  • RAM — каждая VM резервирует память под свою ОС. 5 VM по 2 ГБ = 10 ГБ только на системы
  • Диск — каждая VM тащит свой образ ОС (гигабайты). LXC шарит корень хоста
  • Скорость — LXC стартует за секунды, VM — минуты
  • Нагрузка — на одном железе можно держать 20+ LXC, а VM — 3–5

LXC даёт почти ту же изоляцию, что и VM, но без эмуляции. Для дома — золотая середина.

Когда Docker всё-таки нужен

Честно: у меня Docker тоже есть — там, где готовый образ с кучей зависимостей проще поднять через compose (Frigate, Kuma). Но как только сервис начинает «жить» — переезжает в LXC.

Вывод: для домашнего хостинга LXC — это изоляция VM, скорость процесса и простота обычного Linux. Docker — для готовых образов, VM — когда нужна своя ОС целиком. Всё остальное — LXC.

#selfhosting

Обложка

Когда пришлось слезать с VMware на что-то реестровое, у всех всплыл один и тот же вопрос: «а на чём теперь крутить виртуалки?». Рынок мгновенно расцвёл — на карте уже больше трёх десятков логотипов. Но если открыть капот, почти всё сводится к двум гипервизорам: KVM и Xen. Разница — в обвязке.

Два столпа

KVM — гипервизор прямо в ядре Linux. Это не отдельная программа: ядро получает модуль kvm, и каждая виртуалка превращается в обычный процесс — qemu эмулирует ей железо (диски, сеть, PCI), а libvirt даёт единый API сверху. Плюс: виртуалка наследует весь зоопарк ядра — планировщик, memory management, cgroups. Минус: qemu сам по себе тяжёлый, и «поднять вручную» без libvirt быстро превращается в боль.

Xen — гипервизор отдельного типа: он стоит ниже операционных систем и запускает их как «домены». Есть привилегированный домен dom0 (управляющий) и рабочие domU. Классика Xen — паравиртуализация: гость знает, что он гость, и зовёт гипервизор напрямую, без полной эмуляции железа. Современный Xen умеет и HVM с аппаратной виртуализацией. Управляется через xapi/XAPI — тот же стек, что в XCP-ng.

Коротко: KVM — «виртуалка как процесс в Linux», Xen — «виртуалка как отдельный домен под гипервизором». Для админа разница чаще в обвязке, чем в производительности.

Кто на чём сидит

На oVirt (менеджмент поверх KVM) — целая пачка известных имён: РЕД Виртуализация, ROSA Virtualization, HOSTVM. Все трое — это KVM под капотом, а отличаются консолью, поддержкой и порталами для провайдеров.

На OpenStack (облачная платформа, тоже поверх KVM) — «Кибер Инфраструктура» и «Кибер Протект». Тут уже не просто виртуалки, а полноценный IaaS с тенантами и самообслуживанием.

На OpenNebula — «Альт Сервер Виртуализации» (basealt). Менее раскрученный, но тоже KVM-менеджмент.

Proxmox стоит отдельно: свой стек на KVM + LXC, без привязки к oVirt/OpenStack. Любимчик сисадминов за простоту.

«Собственная разработка» — самая интересная полка: БАЗИС.Dynamix, Брест, Астра, VMmanager, Space, ДаКом и остальные. Тут у каждого свой менеджмент-слой и свой гипервизор — но в ядре всё равно чаще всего KVM (реже Xen), просто написанный с нуля UI и кластерная логика.

Мораль

По данным исследования рынка на 2025 год, больше половины известных решений — это не уникальные технологии, а разные упаковки над одними и теми же открытыми гипервизорами. Поэтому выбирать стоит не по логотипу, а по трём вещам: кто поддержит, как переживается потеря узла и насколько честно работает живая миграция. «Под капотом» у большинства — одно и то же, а вот «что снаружи» — разное.

#selfhosting #network

Обложка

Цикл «Виды связности и SDN», часть 1.

Оси этой части: карта координат — уровень, underlay/overlay, управление, топология, шифрование.

Слово SDN успело побывать всем: технологией, архитектурой, пунктом в коммерческом предложении и наклейкой на обычном VPN с веб-интерфейсом. Из-за этого обсуждение часто начинается вопросом «что лучше — L3, mesh или WireGuard?» Примерно как «что лучше — грузовик, дизель или кольцевая дорога?»

Чтобы дальше не путаться, сначала разложим связность по отдельным осям. Через весь цикл используется одна лаборатория: офис за NAT, ЦОД A с белым IPv4, ЦОД B за CGNAT, облачная ВМ, ноутбук администратора и небольшой Kubernetes-кластер. Эту же инфраструктуру будем соединять разными способами.

Уровень сети

На L2 мы переносим Ethernet-кадры и имеем дело с MAC-адресами, ARP, broadcast и VLAN. Такой overlay может сделать вид, что две виртуальные машины в разных ЦОДах подключены к одному коммутатору.

На L3 мы переносим IP-пакеты и маршрутизируем отдельные сети. За каждым узлом или площадкой может находиться собственная подсеть, а остальная система должна знать путь до неё.

Сервисный overlay идёт ещё выше. Он может вообще не выдавать участнику адрес общей виртуальной сети, а предоставлять доступ только к конкретному приложению: например, к crm.internal:443. Так работает часть ZTNA-решений и OpenZiti.

Underlay и overlay

Underlay — сеть, которая уже умеет доставить внешний пакет от одного узла до другого. Это может быть Интернет, операторский L3VPN, собственная магистраль или IP-фабрика ЦОД.

Overlay — логическая сеть поверх неё. Исходный пакет помещается внутрь другого пакета и едет по underlay как груз в контейнере. VXLAN, Geneve, IPIP, GRE, WireGuard и IPsec делают это по-разному, но общая идея одна.

Overlay способен скрыть устройство нижележащей сети от конечных систем. Но он не чинит потери, перегруженные каналы, сломанный PMTUD и неправильную маршрутизацию под ним. Он только добавляет ещё одно место, где можно искать проблему.

Кто принимает решения

У сети может быть центральный контроллер. Он знает участников, выдаёт адреса, распространяет политики и сообщает узлам, как связаться друг с другом.

При этом пользовательский трафик не обязан идти через контроллер. В Tailscale, NetBird и похожих системах управление централизовано, а data plane по возможности строится напрямую между участниками.

Другой вариант — распределённый control plane. Например, маршрутизаторы обмениваются маршрутами по BGP, и каждый самостоятельно строит таблицу пересылки.

Есть смешанные схемы: центральная база хранит желаемое состояние, локальные агенты применяют политики, а маршруты распространяются распределённым протоколом.

Топология

Point-to-point — один туннель между двумя участниками.

Hub-and-spoke — все филиалы подключаются к центральному хабу. Просто управлять, но хаб становится транзитной точкой и потенциальным местом отказа.

Partial mesh — прямые связи создаются только там, где они нужны.

Full mesh — каждый участник может иметь прямую связь с каждым. Число потенциальных пар растёт квадратично; счёт и выбор топологии — в части 6.

Dynamic mesh не обязан держать все туннели постоянно. Контроллер может выдать двум узлам координаты друг друга только при появлении трафика.

Шифрование

VXLAN, Geneve, IPIP и GRE сами по себе не защищают содержимое. Они решают задачу переноса пакета, а не конфиденциальности.

MACsec шифрует связь на L2 между соседними устройствами. IPsec и WireGuard защищают IP-трафик между узлами. TLS и mTLS защищают конкретные прикладные соединения.

Иногда эти слои складываются: пакет приложения уже защищён TLS, затем попадает в VXLAN, а весь межузловой трафик дополнительно помещается в WireGuard. Без расчёта MTU такой сетевой матрёшке быстро становится тесно.

Где здесь SDN

Software-defined networking начинается там, где желаемая логика сети описывается программно и отделяется от конкретного устройства, пересылающего пакет.

Контроллеру говорят: «эта группа может обращаться к сервису, эти две сети изолированы, а маршрут площадки должен иметь два выхода». Он переводит это намерение в правила OVS, eBPF-программы, маршруты BGP, ACL или конфигурации туннелей.

Генератор десяти peer-конфигов WireGuard — это автоматизация, а не SDN. Между таким скриптом и OVN с распределёнными логическими маршрутизаторами лежит заметная архитектурная дистанция: во втором случае есть модель намерения, отдельный control plane и независимый data plane.

Пять вопросов перед выбором

Перед обсуждением продукта полезно ответить:

  1. Нам нужен Ethernet или маршрутизация IP?
  2. Какая сеть уже существует между узлами?
  3. Кто будет распространять адреса, маршруты, ключи и политики?
  4. Нужны прямые связи или допустим центральный транзит?
  5. Какое содержимое и между какими точками должно быть зашифровано?

После этого сравнение становится честнее. VXLAN конкурирует с Geneve как способ инкапсуляции. BGP и контроллер OVN решают задачу распространения состояния. WireGuard добавляет защищённый транспорт. Mesh описывает отношения между участниками.

Где это ломается

  • Overlay не чинит сломанный underlay: потери, асимметрия и фильтр ICMP остаются на месте.
  • «Пинг проходит» не означает исправный HTTPS: обычно виноват MTU, а не приложение.
  • Контроллер и data plane — разные отказы; зелёная панель не доказывает, что пакеты ходят напрямую.
  • Full mesh на схеме ещё не означает, что все пары реально подняты и нужны.
  • Сравнение «VXLAN vs контроллер vs WireGuard» почти всегда смешивает разные оси.

В следующей части разберём underlay и overlay подробнее: что именно вкладывается в туннель, откуда берётся потерянный MTU и почему «пинг проходит» ещё не означает исправную связность.

Предыдущая часть: —

Оглавление цикла: «SDN без магии: карта видов связности»

Следующая часть: «Underlay и overlay: сеть под сетью»

Схема

#network #selfhosting

Робот-дворник собирает статьи в своём блоге

1) Боль: хватит жить на чужом Telegraph

Telegraph классный для быстрых заметок, но это чужой сервис. Нет контроля над доменом, нет нормального RSS, картинки лежат «где-то там», а аналитику нельзя встроить. Для «Цифрового дворника» хотелось полноценный блог, которым мы управляем сами.

2) Что хотели от платформы

  • self-hosted без внешних SaaS;
  • Markdown-редактор;
  • один Go-бинарник + SQLite (без MySQL/PostgreSQL);
  • single-user режим и аскетичный UI без отвлекающих «порталов»;
  • HTTPS через Caddy (Let's Encrypt);
  • картинки — на своём paste-хостинге (paste.example.ru);
  • каталог по тегам и RSS из коробки;
  • веб-аналитика Umami (umami.example.ru);
  • в Telegram-канал — только превью с обложкой и аннотацией, читать — на сайте (articles.example.ru).

3) Альтернативы и почему не они (кратко)

  • Ghost — мощно, но стек Node + внешняя БД, тяжеловато ради одного блога.
  • WordPress — перебор по функциональности и операционным хлопотам.
  • Hugo/Jekyll — требуют сборки/деплоя, нет живого редактора в браузере.
  • Notion/Obsidian Publish — не self-hosted и/или платно/закрыто.
  • Telegraph — оставили запасным вариантом для набросков, но не для основного блога.

Выбор платформы: тяжёлые комбайны против маленького бинарника

4) Почему WriteFreely

  • один бинарник на Go;
  • хранение в SQLite;
  • single-user режим, минимализм;
  • Markdown и RSS из коробки;
  • есть HTTP API для автопубликации из пайплайна.

5) Как ставили (кратко)

  • LXC-контейнер с systemd и выделенным пользователем приложения;
  • сервис writefreely.service, автозапуск и перезапуск при падениях;
  • Caddy как reverse_proxy перед приложением + автоматический Let's Encrypt;
  • регистрация и федерация отключены (single-user блог без чужих аккаунтов).

6) Грабли по пути — только то, что реально встретили

  • writefreely --config — это интерактивный конфигуратор, а не путь к файлу. В юните systemd нужен флаг -c /opt/writefreely/config.ini, иначе сервис «уходит» в диалоговый режим и не стартует.
  • Бинд на 127.0.0.1 + reverse proxy с другого хоста = 502. Если прокси живёт вне контейнера с приложением, слушаем внутренний IP (например, 10.0.x.x:8080), а в Caddy проксируем именно на него, а не на loopback.
  • API v0.17.2 игнорирует поле appearance (режим тизеров на главной). Пришлось сделать анонсы чистым CSS (ограничение высоты + затухание), без участия API.

7) Что не получилось пока — Instant View

Встроенный редактор Telegram (instantview.telegram.org) сейчас не может забрать страницу блога из РФ: «Can't fetch page». Внешний входящий трафик на 80/443 до лабы режется, а IV-редактор ходит снаружи, поэтому он банально не видит наш сайт. Сам шаблон (XPath) готов и лежит в проекте — как только появится доступ снаружи (или настроим прокси), подключим IV и вернём красивый ⚡️-превью в канале. Это ограничение сети, а не блога.

Instant View: дверь пока заперта, превью отложено

8) Итог

Теперь у нас свой аккуратный блог на articles.example.ru, а в Telegram остаются лаконичные превью. Картинки — с нашего paste.example.ru, каталог — по тегам, RSS работает, аналитику даёт umami.example.ru. Минимум движущихся частей, максимум контроля.

#selfhosting #openclaw #lifehacks

Обложка

Представь: ты лежишь на диване, пишешь в Telegram: «Сколько занято места на основном диске?» — и через несколько секунд получаешь ответ. Или: «Перезапусти контейнер с медиасервером». И он перезапускает. Никаких ноутбуков, никакой возни с терминалом — всё в одном чате, у тебя в кармане.

Раньше за такое брали месяц жизни, рюкзак скриптов и немного седых волос. Сейчас — один вечер и примерно пять баксов на API. Я прошёл путь от «ну ща опять писать свои кроны» до «бот сам всё делает» за пару часов. И да, без ручного кодинга — только Cursor (ИИ-редактор кода), OpenClaw (агент), DeepSeek API и Telegram-бот. Дальше — как это повторить без боли, оторванно от любой «моей конкретной лабы». Пойдём по шагам. Будет просто, честно и без заклинаний.

Шаг 1. Cursor — наш «монтажник»

Сверхкратко: Cursor — это редактор кода с ИИ, который не только подсказывает, но и может сам выполнять команды в терминале. Агентный режим, Composer — всё это fancy-мод, где он берёт твой промпт «сделай вот это» и реально лезет в консоль, редачит конфиги, перезапускает сервисы. В нашем сценарии Cursor — это руки, которые всё соберут.

Что нужно до старта: – У тебя есть Proxmox (или любая домашняя виртуализация) и SSH-доступ к хосту. Не важно, где крутится — дома, на даче, в гараже — главное, чтобы ты мог зайти по SSH. – Ты готов наделить агента доступом к твоему Proxmox через API-токен, чтобы тот управлял контейнерами/ВМ. Да, именно токен — никого не пустим, кроме него, и в любой момент отзовём.

Дальше — по пунктам:

1) Скачиваем Cursor. Заходим на cursor.com, ставим, регистрируемся. Есть бесплатный тариф — нам хватит, мы не пишем гигабайт кода, мы настраиваем.

2) В Cursor открываем терминал (обычно это панель снизу, можно через меню View → Terminal), подключаемся по SSH к серверу, где будет жить агент. Стандартно: – «ssh user@hostname» — тут у каждого своё, главное — чтобы Cursor видел терминал и мог в нём действовать. – Не забываем ключи/пароли — как обычно входишь, так и тут.

3) Настраиваем на стороне Proxmox доступ по токену. Можно через UI: Datacenter → Permissions → API Tokens. Или одной командой в консоли Proxmox (я так и сделал, быстрее): pveum user token add root@pam!openclaw --privsep 0 Эта штука создаёт токен с именем openclaw для root@pam и отключает привилегии-сепарацию, чтобы агенту не пришлось упираться в ограничения, когда он, например, рестартит контейнер. Не забываем потом аккуратно ограничить, что нужно, но для старта — так быстрее.

4) Ставим OpenClaw на сервер через Cursor. В терминале (внутри Cursor) даём ИИ-промпт типа: «Установи OpenClaw на этот сервер: curl -fsSL https://openclaw.ai/install.sh | bash, потом запусти onboarding». Cursor воспримет это как задачу: выполнит установочный скрипт, дождётся, спросит, куда ставить, как запускать, и проведёт первичную настройку (onboarding). Если где-то не поймёт — спросит тебя. Тут главное — не стесняться отвечать по-человечески, он нормально такие штуки переваривает.

На что обратить внимание во время установки: – OpenClaw спросит базовые вещи о том, где хранить конфиги и как стартовать сервисы. Я всегда соглашаюсь на дефолты, а потом в конфиге поправляю — так быстрее. – Если сервер чистый, возможно, подтянутся зависимости. Нормально. Пусть тянет. – После onboarding у тебя будет базовый конфиг OpenClaw и запущенный gateway (его фронт, который принимает запросы от каналов — в нашем случае от Telegram).

И да, сразу лайфхак: держи отдельное окно терминала с правами рута. Иногда удобнее самому подсказать системе путь, поправить права на папку или логи посмотреть. Cursor умный, но ты здесь главный.

Шаг 2. DeepSeek — мозг помощника

Агент без мозга — это просто симпатичный автомат. Нам нужен LLM-провайдер, который будет думать дёшево и шустро. Я выбрал DeepSeek — регаемся на platform.deepseek.com, кидаем на баланс $5 (хватит надолго, правда), создаём API-ключ. Без фокусов, всё стандартно: «Create API key», копируем куда-нибудь в секретики (я кидаю в менеджер паролей — не в блокнот на рабочем столе, ага).

Дальше снова подключаем Cursor-руки: – В чат с Cursor (или в Composer/Agent Mode) даём задачу: «Добавь в конфиг OpenClaw провайдера deepseek, вот ключ, вот формат: models.providers.deepseek = { baseUrl: "https://api.deepseek.com", apiKey: "..." }». – Подставляем свой ключ вместо многоточия. Просим Cursor найти файл конфигурации (обычно это openclaw.json в рабочей директории OpenClaw) и аккуратно вставить этот блок. – Затем просим перезапустить gateway, чтобы изменения подхватились. Формулировка из серии: «Перезапусти gateway, чтобы конфиг обновился» — норм. Cursor поймёт и сделает.

После этого у нас — живой, мыслящий помощник. Он уже умеет рассуждать, объяснять свои шаги, анализировать твои команды. И — самое приятное — ты за это не платишь космос: DeepSeek реально экономит.

Врезка: помощник подключён

Шаг 3. Telegram — лицо помощника

Без Telegram всё это было бы просто милым CLI-аттракционом. Но мы хотим, чтобы ассистент жил там, где мы живём — в чате.

Делаем так: 1) Открываем Telegram, пишем @BotFather. 2) Команда /newbot, даём боту имя и username (должен заканчиваться на bot). Например, «homelabhelperbot», но ты придумай что-нибудь своё. BotFather вернёт токен вида 123456:ABC-DEF... — это пароль от твоего бота, никому не показываем. Реально никому. Даже соседу-админу, который «только посмотреть». 3) Узнаём свой Telegram ID. Самый простой способ — написать любому сервисному боту типа @userinfobot. Он в ответ скажет твой numeric ID. Сохраняем его туда же, где и ключи.

Теперь подключаем Telegram к OpenClaw через Cursor: – Говорим Cursor: «Настрой Telegram в OpenClaw: channels.telegram.botToken = <токен>, dmPolicy: "allowlist", allowFrom: [мой Telegram ID]. Мой ID: <число>». – Смысл: – botToken — это тот самый токен от BotFather. – dmPolicy: “allowlist” — политика приватности: отвечать только тем, кто явно разрешён. – allowFrom — массив ID, кому разрешено писать этому боту (вначале просто ты). Остальным — тишина и покой. Удобно, если бот видит публичные чаты: ничего лишнего он не скажет.

Просим Cursor перезапустить gateway, чтобы Telegram-канал подхватился. Через минуту можно уже написать своему боту «привет», и он ответит чем-то приветливым, если всё ок.

Врезка: Telegram подключён

Шаг 4. Кормим знаниями

Сейчас у нас есть мозг (DeepSeek), руки (Cursor+OpenClaw), и лицо (Telegram). Чего не хватает? Памяти о твоей конкретной инфраструктуре. Без неё бот будет гадать: «А где у нас там сервис на 8080?», «А как подключаться к контейнеру номер N?». Нам нужна база знаний.

Самый простой и рабочий подход — три файла в рабочей папке агента: – MEMORY.md — что где живёт, какие сервисы, порты, дисклеймеры, карта твоего хозяйства. – TOOLS.md — как подключаться: какие хосты, какими методами, где лежат ключи. Креды — не в открытом виде в файле, а ссылками на хранилище секретов или описание, откуда брать (и пусть Cursor спросит, когда надо). – AGENTS.md — правила поведения: «не трогай прод без бэкапа», «если делаешь апдейт — сперва план/пруф/подтверждение», «всё логируем».

Тут меня ждал приятный сюрприз: Cursor очень неплохо оформляет это дело, если ты ему нормальным человеческим языком расскажешь, как у тебя всё устроено. Пример диалога с Cursor: – Я: «Создай файлы MEMORY.md, TOOLS.md, AGENTS.md в рабочей папке OpenClaw. Заполни их по моему описанию. Я сейчас пришлю список сервисов и как мы к ним подключаемся». – Дальше я диктую: – MEMORY.md: перечисляю свои сервисы (без подробных секретов), какие запущены в контейнерах/ВМ, на каких портах крутятся (типа «reverse-proxy слушает 80/443», «медиасервер на 8096» и т.д.), что из этого важное, что второстепенное, где бэкапы. – TOOLS.md: говорю, как подключаемся к Proxmox через API-токен (тот, что мы создали), что SSH-ключи лежат в определённой директории (без выкладывания приватного! просто путь и заметку: «доступ у Cursor есть в рамках агента, спрашивай у меня, если что»), какие команды можно выполнять для статуса, где логи смотреть. – AGENTS.md: расписываю правила. Мои любимые пункты: – «Никогда не перезагружай хосты без явного разрешения». – «Перед обновлением системных пакетов — спроси подтверждение». – «Если видишь, что диск близок к заполнению — сформируй план: что чистим, что архивируем, что переносим. Не действуй втихую». – «Если не уверен — задай уточняющие вопросы в чат перед любыми деструктивными действиями». – «Все изменения — с кратким отчётом в конце в чат».

Cursor на основе твоего описания создаст эти файлы, положит рядом с конфигом OpenClaw, и — барабанная дробь — теперь твой помощник знает контекст. На вопрос «что у меня крутится на 8080?» он уже не будет импровизировать, а залезет в MEMORY.md и ответит по факту твоей инфры.

Плюс: когда ты добавляешь новый сервис, достаточно дописать пару строк в MEMORY.md и, при необходимости, в TOOLS.md (как к нему подключаться, как проверять). Универсально, без плясок со скриптами. Хочешь — диктуй Cursor голосом через диктовку, он всё превратит в аккуратные записи.

Финал: что получилось

Теперь у меня в Telegram живёт ассистент, который: – Понимает мою инфраструктуру. – Может проводить проверки и выполнять команды. – Думает через DeepSeek, пишет по-русски, объясняет шаги. – Не говорит с чужими — dmPolicy: “allowlist” рулит.

Примеры живых запросов из чата: – «Проверь статус сервисов». Агент идёт по TOOLS.md: если там указано, как проверять — делает. Например, дергает systemctl или контейнерные статусы, смотрит логи, умеет объяснить, если что-то лежит. – «Сколько занято места на диске». Он знает, как залогиниться по SSH и что запустить (df -h, zfs list — зависит от твоих инструментов, ты это опишешь в TOOLS.md), и вернёт внятный ответ. – «Обнови конфиг роутера». Тонкий момент: для сетевых устройств опиши в TOOLS.md, как ты к ним подключаешься и как безопасно применять конфиги (и обязательно правило в AGENTS.md — без бэкапа и плана — ни шагу). Агент выполнит твой протокол: снимет копию, применит изменения, проверит доступность, отчитается. – «Перезапусти контейнер с медиасервером». Тут пригодится Proxmox API-токен: агент умеет через него дёргать контейнеры/ВМ. Ты только укажи, какой ID или как искать по имени — и добавь это в MEMORY.md, чтобы он не путал «media» и «media-test».

Всё это — из Telegram, с телефона. Если утром в дороге надо быстро проверить «жив ли reverse-proxy», набираешь одну строку — и готово. Если у тебя привычка каждую субботу обновлять контейнеры, поручаешь боту: «Сделай апдейт, но сперва список, что именно поменяется». Он сделает план, ты согласуешь, он применит, пришлёт отчёт. Красота.

Что дальше можно прикрутить: – Мониторинг. Попроси агента раз в день/неделю делать сводку: температура, место, аптайм, статусы ключевых сервисов. Он сам кинет тебе отчёт в чат. – Автоалерты. Если в логах повторяется ошибка — пинг тебе в личку. Ты задаёшь правила словами, агент оформляет. – Канал с постами. Если нравится публичность — сделай отдельный канал, куда агент будет постить апдейты: «контейнеры обновлены», «сделан снепшот», «свободно 20% места». А в личке останутся приватные вопросы и команды.

И да, главный кайф — ты не писал ни строчки кода руками. Все «закрутки гаек» сделал Cursor: где нужно — поправил конфиг, где нужно — перезапустил gateway, где нужно — уточнил у тебя, как правильно. Ты не борешься с синтаксисом и флагами, ты говоришь с ассистентом человеческим языком.

Как это выглядит в задачах для Cursor (чтобы было под рукой)

Вот те самые фразы, которые у меня реально сработали. Можно копировать и адаптировать:

  • Установка OpenClaw: «Установи OpenClaw на этот сервер: curl -fsSL https://openclaw.ai/install.sh | bash, потом запусти onboarding. Если потребуются права рута — запроси. По окончании покажи, где лежит openclaw.json и как перезапускать gateway».

  • Добавление DeepSeek: «Добавь в конфиг OpenClaw провайдера deepseek, вот ключ, вот формат: models.providers.deepseek = { baseUrl: "https://api.deepseek.com", apiKey: "..." }. Вставь в openclaw.json и перезапусти gateway».

  • Подключение Telegram: «Настрой Telegram в OpenClaw: channels.telegram.botToken = <токен>, dmPolicy: "allowlist", allowFrom: [<мой Telegram ID>]. После правок перезапусти gateway».

  • Память и правила: «Создай рядом с openclaw.json файлы MEMORY.md, TOOLS.md, AGENTS.md. Я пришлю описание инфры — оформи в структурированные списки и таблицы. Сформируй чек-лист для AGENTS.md: как подтверждать опасные операции, как логировать, как делать бэкапы перед изменениями».

  • Проксмокс-токен (на стороне Proxmox, если нужно через CLI): pveum user token add root@pam!openclaw --privsep 0

Важные оговорки (чтобы не наступить на грабли)

  • Токены и ключи — это пароли. Храним в менеджере паролей. В чат не кидаем. В конфиги вставляем через Cursor, не публикуем скриншоты в чат-поддержку.
  • allowFrom — твой белый список в Telegram. Пока ассо правильно не настроен, пусть отвечает только тебе. Потом можно расширить, если есть семья/коллеги.
  • Агент — это исполнитель. Его надо научить твоим правилам: «без бэкапа — ни шага», «всё опасное — с подтверждением», «сначала план, потом действие». Пропиши это в AGENTS.md, и ты удивишься, насколько послушнее становится система.
  • DeepSeek дешёвый, но не бесплатный. Следи за расходами — обычно это копейки, но метрика рулит.
  • OpenClaw — это шина. Если ты хочешь, чтобы агент реально умел, скажем, лезть в контейнеры или в роутер — опиши путь: куда подключаться, какие команды, где конфиги. Без магии: «не знаешь — спроси». Он спросит.

Маленькие трюки, которые сэкономили мне время

  • Попроси Cursor после каждого шага оставлять в чате короткий «что сделал / как откатить». Иногда очень выручает.
  • В MEMORY.md добавь раздел «Критично важные сервисы». Пусть в отчётах они идут первыми.
  • В TOOLS.md положи раздел «Диагностика»: команды для быстрого анализа проблем сети/диска/CPU. Потом ты просто пишешь: «Запусти стандартную диагностику» — и получаешь понятный отчёт.
  • Если боишься, что агент что-то поломает — напиши: «Все операции — в dry-run, кроме явно подтверждённых». Для многих действий dry-run — это просто «покажи план и команды». Работает.
  • Раз в неделю проси бота: «Проведи самоаудит: что можно оптимизировать». Он предложит: чистка логов, ротация бэкапов, архивирование. Иногда попадаются шикарные идеи.

Что получилось в итоге (по ощущениям)

  • Субъективно — как будто у тебя появился дежурный дежурный. Пока ты на встрече, он проверил статусы. Пока ты делал кофе, он собрал отчёт. Пока ты думал «надо бы перезапустить медиасервер» — он уже спрашивает: «сделать сейчас?».
  • Важные штуки стали ближе. Раньше «посмотреть место на диске» — это лезть в SSH, вспоминать логины, пароли, команды. Сейчас — одна строка в чате. Разница чувствуется.
  • Никакой запертой магии. Ты в любой момент можешь открыть конфиг, посмотреть MEMORY.md, поправить AGENTS.md, и агент станет другим — без перекомпиляций и отпусков в ретрит.

Мораль

ИИ-агенты — это не магия, а инструмент. Ты объясняешь словами, что нужно, агент делает. Если он не понял — уточняет. Один вечер — и у тебя есть свой цифровой ассистент по дому, который сидит в Telegram, знает твою инфру и вежливо выполняет просьбы. И да, всё это без «я сейчас напишу скриптик на коленке» — за тебя писарем и монтажником выступил Cursor.

Если кратко по чек-листу: – Ставим Cursor (бесплатка ок). – На сервере ставим OpenClaw: curl -fsSL https://openclaw.ai/install.sh | bash, запускаем onboarding. – Заводим Proxmox API-токен: pveum user token add root@pam!openclaw --privsep 0. – Берём DeepSeek API-ключ, добавляем в openclaw.json: models.providers.deepseek = { baseUrl: "https://api.deepseek.com", apiKey: "..." }. – Делаем Telegram-бота через @BotFather, настраиваем: channels.telegram.botToken = <токен>, dmPolicy: "allowlist", allowFrom: [<твой Telegram ID>]. – Кормим MEMORY.md, TOOLS.md, AGENTS.md. – С радостью переписываемся с собственным ассистентом и больше не бегаем по серверам ради мелочи.

А у тебя есть свой помощник? Что бы ты поручил ему в первую очередь?

#openclaw #selfhosting

Обложка

Боль – Proxmox-сервер живёт в чужой сети, за чужим NAT. Шлюз не мой, портов не даёт, статику режет (только DHCP). Белого IP нет вообще. Классика «сервер лежит непонятно где».

Но снаружи у меня всё работает: – HTTPS для lab.example (Caddy, сертификаты Let's Encrypt) – SSH-доступ к роутерам – Мониторинг, фото, локальные LLM — открываются из любого интернета

Решение Три кита, на которых вывез всю историю: 1) Виртуальная сеть, изолированная от внешней шизофрении – Поднял вторую сеть br1 (198.51.100.0/24) без IP на хосте. Внутри неё живут сервисы: Beszel, Uptime Kuma, Immich, Ollama, Hermes. – Шлюз и NAT — отдельный LXC-контейнер с Caddy (198.51.100.1): он делает masquerade из внутренней сети в наружу, ip_forward=1.

Врезка: схема NAT/туннель– Зачем? Сервисы получают стабильную адресацию и жизнь, независимую от капризов внешнего мира.

2) Туннель, который сам уходит из-под NAT – Контейнер с Caddy инициирует SSH reverse-туннель к моему MikroTik с белым IP (203.0.113.20). – Внешние порты 443 и 80 на роутере редиректятся на 8443 и 8080, которые поднял SSH-туннель, — и уже по туннелю трафик попадает в Caddy. – Схема: интернет → MikroTik (белый IP) → SSH reverse → Caddy → сервисы в br1. – Снаружи всё приходит на 443/80, внутри туннеля — на 8443/8080.

3) Один вход — одна дверь – Весь внешний трафик встречает Caddy: раздаёт по доменам, сам продлевает TLS-сертификаты, на нём же ACL для админок. Одна точка входа — меньше боли и хаоса.

Бонус: SSH reverse-туннель, или «костыль, который стал фичей» Суть – Обычный SSH-туннель (-L) тянет удалённый порт к тебе. Reverse (-R) делает наоборот: машина за NAT сама стучится наружу и «пробрасывает» свой локальный порт на стороне сервера. – Натурально подходит для железок за CGNAT, подвалов и «дач».

Правильная картинка в моём кейсе:

Caddy (за NAT)  ──ssh -R──>  MikroTik (белый IP)
      │                           │
      └── на MikroTik открыты 8443/8080 → идут в мой localhost:443/80

Команды — как у меня Шаг 1. На MikroTik — разрешить SSH-форвардинг:

/ip ssh forwarding-enabled=both

Шаг 2. На MikroTik — локально перенаправить внешние 443/80 на 8443/8080 (куда слушает sshd для -R):

/ip firewall nat add chain=dstnat protocol=tcp dst-port=443 action=redirect to-port=8443
/ip firewall nat add chain=dstnat protocol=tcp dst-port=80  action=redirect to-port=8080

Шаг 3. На MikroTik — пропустить эти порты в firewall (до drop-правила):

/ip firewall filter add chain=input protocol=tcp dst-port=8443,8080 action=accept

Шаг 4. На Caddy (Linux) — поднять сам reverse-туннель:

ssh -R 8443:localhost:443 -R 8080:localhost:80 \
    -N -o ServerAliveInterval=30 -o ExitOnForwardFailure=yes \
    admin@203.0.113.20
  • -R 8443:localhost:443 — «порт 8443 на MikroTik идёт в мой localhost:443»
  • -N — только туннель
  • ServerAliveInterval=30 — keepalive, чтобы NAT не рвал соединение
  • ExitOnForwardFailure — падаем, если порт не поднялся

Шаг 5. Завернул это в systemd-сервис (mt-tunnel.service), чтобы жил после ребута и сам переподключался.

Итог: открываю https://router.lab.example — попадаю в Winbox роутера за NAT. Один вход — и весь дом за ним.

Почему это «костыль», но рабочий – SSH — это TCP поверх TCP: на потере пакетов ведёт себя хуже UDP-туннелей. – Одно длинное соединение, которое надо держать живым. – Ключ от роутера лежит на Caddy: его компрометация = доступ к роутеру.

Почему не WireGuard – Пробовал — не завёлся в непривилегированном LXC (нет /dev/net/tun). – SSH уже был настроен, ключи были — 5 минут до рабочего результата. – «Правильный» вариант — WG с TUN:

# на хосте PVE, в конфиге контейнера
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file 0 0

потом mknod /dev/net/tun c 10 200 внутри — и WG поднимается как надо.

Цифры и железки – Proxmox PVE 9.2: – br0 (192.0.2.0/24, DHCP, шлюз 192.0.2.1 — MAC от VMware, статику режут) – br1 (198.51.100.0/24, без IP на хосте) – Caddy lxc-gw: 198.51.100.1 (шлюз br1), NAT masquerade br1→wan, ip_forward=1 – SSH reverse-туннель: Caddy → admin@203.0.113.20 (MikroTik), 443→8443, 80→8080, keepalive=30 c, systemd-сервис mt-tunnel – MikroTik: /ip ssh forwarding-enabled=both; dstnat redirect 443→8443, 80→8080; firewall input accept tcp 8443/8080 (до drop) – Сертификаты: Let's Encrypt для lab.example (валиден до ноября 2026) – Сервисы в br1: – Beszel — 198.51.100.12 – Uptime Kuma — 198.51.100.14 – Immich — 198.51.100.15 – Hermes — 198.51.100.16 – Ollama — 198.51.100.17

Вывод Сервер может жить за любым NAT — хоть у соседа, хоть на «даче». Пока есть исходящий интернет, все сервисы доступны снаружи через один туннель и один шлюз. Костыль? Да. Рабочая фича? Тоже да.

#network #selfhosting