Подняла себе ИИ-помощника в Telegram за вечер: он живёт на сервере и пашет 24/7. Разбор
Короткая суть: за один вечер реально поднять личного ИИ-агента (Claude Code) на дешёвом VPS, авторизовать его под своей подпиской без всякого API-ключа и прицепить к Telegram-боту. Дальше он живёт на сервере сам по себе, не выключается вместе с ноутом и отвечает тебе в личку прямо с телефона. Всего четыре шага. Ниже расскажу, как я это сделала, сколько по-честному занял каждый этап и где красиво наступила на грабли. А главное, разберу, что там происходит под капотом, потому что «сделай так» без «почему так» это не про DTF.
Зачем вообще self-hosted ИИ
ИИ в браузере живёт во вкладке. Закрыл ноут, и помощник уснул вместе с тобой. Мне же хотелось другого: чтобы штука работала автономно, висела на сервере и была доступна с телефона в любой момент. Нужен был не чат, с которым ты сидишь и переписываешься, а именно агент, который умеет сам ходить в систему, запускать команды, читать файлы и что-то делать без няньки. Ну и классический DIY-зуд, чего уж там.
Сразу оговорюсь про деньги, потому что это первый вопрос в комментариях. Тут два разных кошелька, и их постоянно путают.
Как это работает: подписка против API-ключа
Claude Code можно оплачивать двумя способами, и устроены они принципиально по-разному. Первый: API-ключ. Ты платишь поштучно за токены, за каждый запрос и ответ по счётчику. Для агента, который висит онлайн круглые сутки и время от времени сам что-то делает, это лотерея по деньгам. Второй: подписка (Pro или Max). Фиксированная месячная плата, как за любой обычный сервис, и для постоянно живущего агента она кратно предсказуемее.
Ключевой технический момент: авторизоваться под подпиской это НЕ то же самое, что засунуть API-ключ в переменную окружения. Claude Code логинится интерактивно. Ты запускаешь его, он выдаёт ссылку, ты открываешь её в браузере, входишь в свой аккаунт, и токен доступа сохраняется локально в файле учётных данных (~/.claude/.credentials.json). Никакого ANTHROPIC_API_KEY в окружении, никакого headless-режима. Отсюда одна засада для сервера: первый вход надо сделать руками в живой сессии, потому что ссылку нужно открыть в браузере и подтвердить. После этого токен лежит в файле, и агент переживает перезапуски уже без тебя.
Шаг 1. Арендовать VPS (10 минут)
VPS это виртуальный сервер у хостера, твой личный кусок чужого железа. Топовый брать не надо, хватает дешёвой конфигурации: пара ядер, немного памяти, Ubuntu на борту. Грабля номер один, на ней спотыкаются почти все: не берите самый днищенский тариф с 512 МБ памяти. Установка на нём просто поперхнётся на середине. Возьмите что-то с 1–2 ГБ, разница в цене копеечная. На выходе хостер выдаёт две вещи: IP-адрес и пароль root.
Шаг 2. Подключиться по SSH
SSH это протокол для управления сервером из командной строки, зашифрованный туннель до чужой машины. Я подключалась через встроенный терминал в VS Code командой вида ssh root@IP. Тут меня, как новичка, ждали два маленьких затыка. Первый: при самом первом коннекте SSH показывает fingerprint сервера и спрашивает, доверяешь ли ты ему. Это защита от подмены сервера, просто пишешь yes. Второй меня реально сбил с толку: когда вводишь пароль, он вообще никак не отображается. Ни звёздочек, ни точек, будто клавиатура умерла. Так и задумано в целях безопасности, печатай вслепую и жми Enter. Я, честно, раза три стёрла и перепечатала.
Шаг 3. Поставить Claude Code и авторизоваться
Claude Code ставится одной командой из официального гайда, тут расписывать нечего. Запускаешь, он выдаёт ссылку на логин, ты входишь своим аккаунтом (см. выше про подписку), токен ложится в файл. И вот тут вылезает главная грабля всего проекта, про которую надо говорить отдельно и серьёзно.
Безопасность: почему root это реально опасно
Агент, чтобы быть автономным, работает в режиме без подтверждений. Флаг называется --dangerously-skip-permissions. Слово «dangerously» в названии не для красоты. Обычно Claude Code перед каждым опасным действием спрашивает разрешение, но для агента, который должен пахать сам, это смерть автономности: он будет дёргать тебя на каждый чих. Поэтому подтверждения отключают.
Но это ровно означает, что агент выполняет команды в системе сам, без твоего «ок». А теперь представь, что он запущен от root, то есть от всемогущего пользователя, которому в Linux можно вообще всё. Одна кривая команда, одна галлюцинация модели, одна неудачно понятая формулировка, и он может снести системные файлы. Не потому что «злой ИИ», а потому что ты дал автономному процессу неограниченные права. Поэтому здесь конкретная страховка:
- Заводишь отдельного непривилегированного пользователя специально под агента.
- Не даёшь ему sudo.
- Вешаешь deny-list на заведомо опасные команды (те же rm -rf, работа с дисками и системными разделами).
Изоляция тут не бюрократия, а буквально забор вокруг штуки, которая по твоей же воле действует сама. Если агент напортачит, он напортачит в пределах своей песочницы, а не в корне системы.
Шаг 4. Прицепить Telegram-бота
Идёшь к @BotFather в самом Telegram, создаёшь бота, получаешь токен. Токен это по сути пароль от бота, поэтому он живёт в закрытом файле с урезанными правами, а не в коде и тем более не в гите. Скармливаешь токен серверу, и всё: пишешь боту в личку, отвечает твой агент. А вот как это работает под капотом, стоит разобрать, потому что тут спрятана важная развилка.
Long polling против webhook: почему серверу не нужен белый IP
У Telegram есть два способа доставлять боту входящие сообщения. Первый, webhook: Telegram сам стучится на твой публичный HTTPS-эндпоинт. Звучит красиво, но для домашнего проекта это боль, потому что нужен белый IP, домен, валидный TLS-сертификат и проброс портов. Целый забор инфраструктуры вокруг простого бота.
Второй, long polling: твой сервер сам периодически спрашивает Telegram «есть новые сообщения для меня?» через метод getUpdates. Инициатива всегда на твоей стороне, ты исходящими запросами дёргаешь Telegram, а не он тебя. Связка из гайда использует именно long polling, и это меняет всё для домашнего сценария: раз сервер сам ходит наружу, ему не нужен ни публичный IP, ни проброс портов, ни домен, ни возня с сертификатами. Агент может спокойно сидеть за NAT на самом дешёвом VPS и всё равно получать сообщения.
Персистентность: как агент реально живёт 24/7
Вот момент, который новички упускают чаще всего, а он и есть суть всей затеи. Если просто запустить claude прямо в SSH-сессии, процесс будет жить ровно до тех пор, пока открыт терминал. Закрыл окно, разорвалась связь, операционка отправляет процессу сигнал SIGHUP, и он умирает. Это не «24/7», это «пока я не закрыл ноут», то есть ровно та проблема, от которой мы бежали.
Чтобы агент пережил и разрыв SSH, и перезагрузку сервера, его надо отвязать от терминала. Способов два. tmux – терминальный мультиплексор: запускаешь агента внутри tmux-сессии, а она живёт на сервере сама, даже когда ты отключился. systemd – штатный менеджер сервисов в Linux: оформляешь агента как системный сервис, и операционка сама запускает его при загрузке и поднимает, если он упал. Установщик из гайда настраивает автозапуск сам, но понимать механику важно: «живёт 24/7» это просто процесс, отвязанный от твоего терминала и переживающий reboot. Никакого волшебства.
Следующий уровень: агент по расписанию (крон)
И вот тут начинается самое вкусное. Раз агент постоянно онлайн и отвязан от тебя, ему можно вешать задачи по расписанию через cron, штатный планировщик в Linux. Пример: «каждое утро в 9:00 собери сводку по таким-то источникам и пришли мне в Telegram». Ставишь одну строчку в расписание, и агент сам, без единого твоего сообщения, в девять утра просыпается, делает работу и кидает результат в личку. Пока агент реактивный, он всего лишь чат в другой обёртке. А как только появляется расписание, он становится проактивным: работает по своей инициативе, а не по твоему триггеру. Ради этого перехода и стоит городить весь огород с сервером.
Собрала грабли в одну кучу
- Тариф 512 МБ. Установка захлебнётся на полпути. Берите от 1 ГБ памяти.
- Слепой ввод пароля по SSH. Символы не отображаются вообще никак, это норма.
- Fingerprint при первом коннекте. Просто ответь yes.
- Запуск под root. Категорически нет. Отдельный пользователь без sudo плюс deny-list, потому что агент действует автономно и без подтверждений.
- Наивный claude в SSH-сессии. Умрёт вместе с терминалом. Нужен systemd или tmux, иначе никакого 24/7.
- Первый логин. Он интерактивный, через браузер. В фоне самый первый вход не сделаешь.
- Токен бота в открытую. Это пароль. Только закрытый файл с урезанными правами, никакого гита.
Вывод
По итогу вечер работы, и у меня на сервере живёт личный ИИ-агент, которому я пишу в Telegram с телефона. Он не выключается вместе с ноутом, переживает перезагрузку сервера и умеет работать по расписанию сам. Вся магия собирается из простых кирпичей: подписка вместо поштучной оплаты, интерактивный логин с токеном в локальном файле, long polling вместо webhook (поэтому не нужен белый IP), systemd для настоящей персистентности и отдельный непривилегированный пользователь как страховка. Ничего сверхъестественного, просто надо понимать, зачем каждый кусок стоит на своём месте.
Полная пошаговая инструкция со всеми командами лежит здесь: guides.labopsai.pro/claude-code-server-setup.