В прогоне курса бот «Кодиума» две недели жил бы на ноутбуке, если бы не одна мелочь: ноутбук закрывают на ночь. Заявка, отправленная в 23:40, уходит в пустоту, потому что программа, которая её принимает, спит вместе с компьютером. Владельцу школы нужен бот, который отвечает и ночью, и в выходные. Для этого бот переезжает на сервер.
Чему научишься в этом уроке:
• объяснить заказчику, почему бот живёт на сервере за рубежом, и показать замер;
• арендовать сервер Timeweb Cloud и войти на него по SSH-ключу;
• поручить агенту выкладку: отдельный пользователь, закрытый .env и служба, которая поднимает бота сама;
• проверить бота перезагрузкой сервера и поправить часовой пояс.
Сервер: компьютер, который не выключают
Представь камеру хранения на вокзале, только с розеткой и интернетом: ты арендуешь ячейку, кладёшь туда свою программу, и она работает круглые сутки, пока ты спишь. Такой арендованный компьютер в чужом здании называется сервером (слово уже было в словаре урока 0.3). Экрана и мышки у него нет: управляют им из своего терминала по защищённому каналу.
Почему не сервер в России
Сначала мы поставили бота «Кодиума» на сервер Timeweb Cloud в Новосибирске. Логика простая: данные учеников лучше держать в России. Агент выложил бота за один проход, служба запустилась. А потом бот перестал отвечать на /start.
Замер показал причину. Мы 20 раз подряд спросили Telegram «ты здесь?» (запрос getMe). С сервера в Новосибирске успешно прошли 10 из 20, остальные ждали ответа 10–15 секунд и обрывались. С домашнего компьютера в тот же час было 20 из 20. Яндекс с того же сервера открывался мгновенно, значит дело не в самом сервере, а в дороге до Telegram. В журнале бота стояло TelegramNetworkError: Request timeout error.
Тогда бот переехал на сервер Timeweb Cloud в Амстердаме: там тот же замер дал 20 из 20, а Яндекс Диск по-прежнему доступен. Чтобы не держать персональные данные за рубежом, бот их на сервере не хранит: имя и телефон проходят через него и сразу уходят в файл заявок на Яндекс Диске заказчика (это ты настроил в уроке 2.4). На сервере остаются только номер заявки, курс и даты, а в запасном pending.jsonl только номер, курс и время.
Это не юридическая консультация. Схема «сервер за рубежом, данные на Диске в России» снижает риск, но кто отвечает за персональные данные и что ещё нужно сделать по 152-ФЗ, решает заказчик со своим юристом. Твоя задача: честно описать заказчику, где что лежит.

Почему боту не нужен домен
Бот может узнавать о новых сообщениях двумя способами. Long polling («долгий опрос»): бот сам раз за разом спрашивает Telegram «есть новое?». Вебхук: Telegram сам стучится к боту, и для этого у бота должен быть адрес сайта с защищённым соединением HTTPS.
Наш бот работает опросом, поэтому ему не нужны ни домен, ни HTTPS, ни открытый порт. Если заказчик когда-нибудь попросит вебхук, как ставятся домен и HTTPS, разобрано в уроке трека 2 про установку на сервер.
Шаг 1. Арендуй сервер
- Зарегистрируйся в Timeweb Cloud, раздел «Облачные серверы». Оплата в рублях.
- Регион выбери за рубежом: в прогоне был Амстердам.
- Система: Ubuntu 24.04 (Ubuntu это бесплатная разновидность Linux, самая частая на серверах). Боту хватает маленького сервера: в прогоне было 1 ядро и 1,9 ГБ памяти.
- Цены на 09.10.2026: самый дешёвый видимый тариф Cloud-40 (2 ядра, 2 ГБ, 40 ГБ) стоит 900 ₽ в месяц при оплате за год, помесячно около 1 000 ₽. Ещё два тарифа на странице спрятаны под «Показать ещё», их мы не раскрывали. Оплата почасовая: точную цену смотри в счёте Timeweb. Сервер списывает деньги, пока существует; учебный удали после миссии 2.8, если он не нужен заказчику.
Создание сервера по кнопкам, со снимками экрана, пройдено руками в уроке трека 2 про установку на сервер. Дойди там до шага, где сервер получил адрес, и возвращайся.
Шаг 2. Вход по SSH-ключу
Пароль похож на кодовый замок: подсмотрел цифры и вошёл. SSH-ключ похож на обычный ключ с замком. Замок (открытая половина ключа) висит на сервере, а сам ключ (закрытая половина) лежит только на твоём компьютере. SSH расшифровывается как «защищённая оболочка»: это защищённый канал, по которому ты управляешь сервером из терминала. В прогоне вход был только по ключу.
Ключ создаётся одной командой в PowerShell. На вопросы можно нажимать Enter:
ssh-keygen -t ed25519
Открытую половину (файл с окончанием .pub в папке .ssh твоего пользователя) вставь в панель Timeweb в раздел SSH-ключей при создании сервера. Закрытую не отправляй никому, даже агенту в чат. Проверка входа в PowerShell:
ssh root@<адрес сервера>
При первом входе ssh спросит, доверять ли серверу, и покажет его отпечаток. Набери yes и Enter, это нормально. Получилось войти, значит ключ работает. Набери exit: дальше на сервер ходит агент.
Шаг 3. Поручи выкладку агенту
Перед заданием останови бота у себя на компьютере: закрой окно, где он запущен, или нажми в нём Ctrl+C. Две копии бота одновременно спорят за сообщения Telegram, и бот на сервере начинает отвечать через раз. В прогоне первая просьба «выложи на сервер» закончилась странно: агенту не разрешили запускать команды, и он молча написал файлы-инструкции вместо выкладки. У тебя Claude Code спросит разрешение на каждую команду. Читай, что он собирается выполнить, и подтверждай (урок 1.7).
Вот задание прогона дословно, только адрес заменён. Последнюю строку курс добавил после того случая с файлами-инструкциями:
Теперь выложи бота на мой сервер, чтобы он работал круглосуточно без моего компьютера.
Сервер: Ubuntu 24.04, адрес <адрес сервера>, вход: ssh root@<адрес сервера> (ключ у меня уже настроен, пароль не нужен).
Как сделать:
- создай на сервере отдельного пользователя bot (не запускай бота от root), папка /opt/bot-kodium;
- скопируй туда файлы проекта по scp, КРОМЕ .venv, zayavki.db, логов и кэшей; файл .env скопируй отдельно и поставь права 600;
- создай на сервере виртуальное окружение и поставь зависимости из requirements.txt;
- сделай службу systemd bot-kodium: запуск от пользователя bot, автоперезапуск при падении, автозапуск после перезагрузки;
- запусти службу и покажи её статус и последние строки журнала (journalctl).
Локально бот сейчас остановлен — двух копий одновременно быть не должно. Добавь в README раздел «Как выложить на сервер и как обновить».
Выполни сам, не пиши инструкции вместо выполнения.
Что здесь что, по-простому:
- КРОМЕ .venv и zayavki.db. .venv собран под Windows и на Ubuntu не заработает, сервер делает свой. zayavki.db это файл твоей локальной базы с тестовыми заявками, на сервере бот заведёт новую.
- Пользователь bot. Жилец с ключом только от своей комнаты. Если в боте найдут дыру, взломщик получит комнату, а не весь дом (root).
- Права 600 на .env. Конверт, который может вскрыть только владелец. В файле лежат токен бота и токен Диска, правила те же, что в уроке 1.6.
- Служба systemd. Вахтёр сервера: запускает бота при включении и поднимает снова, если тот упал.
- Раздел README. Пригодится в уроке 2.6, когда будешь передавать бота.
Что должно получиться на сервере: файл службы /etc/systemd/system/bot-kodium.service. Набирать его не нужно, агент пишет его сам; сверься, что строки похожи:
[Unit]
Description=Telegram Bot Kodium
After=network.target
[Service]
Type=simple
User=bot
WorkingDirectory=/opt/bot-kodium
Environment=PYTHONUNBUFFERED=1
ExecStart=/opt/bot-kodium/.venv/bin/python bot.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
User=bot значит «от имени пользователя bot», Restart=always значит «поднимать после падения», а WantedBy=multi-user.target включает автозапуск при старте сервера.
Шаг 4. Проверь перезагрузкой
Служба, которая «вроде запущена», и служба, которая переживает перезагрузку, это разные вещи. В прогоне проверка была жёсткой: сервер перезагрузили, подождали минуту и снова вошли. Войди сам: ssh root@<адрес сервера> в PowerShell. Команду ниже набирай уже в этом окне, после входа на сервер, а не на своём компьютере. Соединение после неё оборвётся, так и должно быть.
reboot
Подожди минуту, снова войди по ssh и набери три команды проверки из прогона:
systemctl status bot-kodium
journalctl -u bot-kodium -n 20
systemctl is-enabled bot-kodium
Как читать ответ. active (running) в строке Active значит «служба работает». inactive (dead) значит «служба не запущена». enabled в ответе третьей команды значит «включён автозапуск после перезагрузки». Вторая показывает последние 20 строк журнала бота: там видны ошибки. Потом напиши боту /start с телефона: он должен ответить.

Часовой пояс: заявка «из прошлого»
Часы сервера идут по всемирному времени UTC, это на 3 часа раньше московского. В прогоне бот записал время согласия на 3 часа раньше настоящего. Для заказчика это не мелочь: в споре о согласии дата важна.
В прогоне агент поправил это так: время берётся в поясе Europe/Moscow (часовой пояс Москвы) через модуль zoneinfo, и в уведомлении стало «Согласие: 09.10.2026 16:42 МСК». Пакет tzdata, без которого этот код не работает на Windows, ты добавил в уроке 2.4. Задание агенту:
Время согласия бери в поясе Europe/Moscow через zoneinfo и пиши в уведомлении с пометкой МСК. Проверь, что tzdata есть в requirements.txt. Обнови бота на сервере и перезапусти службу bot-kodium, выполни сам.
Запасной путь: Railway
Railway запускает бота без своего сервера: пробный период с разовыми 5 $ на 30 дней без карты, тариф Hobby 5 $ в месяц (цены на 09.10.2026). Платить только в долларах, картой российского банка не получится, поэтому основной путь курса Timeweb.
Если не получилось
- Агент написал deploy.ps1, DEPLOY.md и прочее, а на сервере пусто → ему не дали выполнить команды → скажи «выполни сам» и подтверждай запросы разрешений.
- Бот на сервере отвечает через раз, в журнале слово Conflict → бот запущен ещё и у тебя на компьютере → закрой локальное окно бота.
- В журнале
TelegramNetworkError: Request timeout error, бот молчит на /start → дорога до Telegram рвётся (так было в Новосибирске) → проверь регион сервера, переезжай за рубеж. - После reboot статус inactive (dead) → служба не включена в автозапуск →
systemctl is-enabled bot-kodium; если не enabled, попроси агента включить автозапуск и повтори перезагрузку. - Время согласия на 3 часа раньше → сервер в UTC → время через zoneinfo с поясом Europe/Moscow.
- ssh просит пароль вместо ключа → открытая половина ключа не попала на сервер → добавь её в панели Timeweb и пересоздай вход.
Контрольный вопрос. Заказчик спрашивает: «Почему не сервер в России? Так же проще с законом». Что ответить по фактам прогона?
Подсказка: Вспомни замер getMe: сколько из 20 и где.
На курсе задания проверяются автоматически. Решить первое задание бесплатно → · Подобрать курс
Контрольный вопрос. Ты перезагрузил сервер, вошёл снова, а бот не отвечает на /start. Статус службы: inactive (dead). Что проверить первым?
Подсказка: До перезагрузки бот работал. Что отвечает за запуск после включения сервера?
На курсе задания проверяются автоматически. Решить первое задание бесплатно → · Подобрать курс
Контрольный вопрос. Бот на сервере в Амстердаме пишет в уведомлении время согласия 13:42, а заявку отправили в 16:42 по Москве. Как починить?
Подсказка: На сколько часов UTC отстаёт от Москвы и что сделал агент в прогоне?
На курсе задания проверяются автоматически. Решить первое задание бесплатно → · Подобрать курс
Задание. МИССИЯ «Бот не спит». 1. Арендуй сервер Timeweb Cloud за рубежом (Ubuntu 24.04) и войди по SSH-ключу. 2. Останови бота у себя и поручи агенту выкладку заданием из урока. 3. Сломай и почини: перезагрузи сервер командой reboot и дождись, что бот поднялся сам. Если не поднялся, найди причину по разделу «Если не получилось». 4. Отправь боту тестовую заявку и проверь время согласия в уведомлении. Принято, если: приложен снимок systemctl status bot-kodium после перезагрузки со строкой active (running) и вывод systemctl is-enabled bot-kodium со словом enabled; снимок уведомления владельцу, где время согласия совпадает с московским и стоит МСК; одна фраза, какой регион сервера ты выбрал и почему. Адрес сервера, токены и телефон на снимках закрыты.
Подсказка: Сначала заставь бота пережить reboot, потом занимайся временем: это две разные поломки.
✅ Готово, если: программа запускается без ошибок и выводит то, что просят в задании.
На курсе задания проверяются автоматически. Решить первое задание бесплатно → · Подобрать курс
Что дальше
Бот работает круглые сутки без твоего ноутбука. Следующий шаг: передать его заказчику так, чтобы он мог жить без тебя, и оформить работу в кейс.
Итог:
• бот живёт на сервере Timeweb за рубежом, персональные данные уходят на Яндекс Диск;
• служба systemd поднимает бота сама, это проверено перезагрузкой;
• время согласия пишется по Москве, tzdata в зависимостях.
