Сервер для Claude Code и AI-разработки: как вынести кодинг в облако и работать даже с телефона
Практический гайд 2026: как поднять удалённый сервер под Claude Code, Cursor и других AI-агентов, не терять сессии при закрытом ноутбуке, работать безопасно и — важно для России — обойти геоблокировку Anthropic или уйти от неё на локальную модель.
Не хочу ничего читать — хочу, чтобы всё настроилиА я оплачу и начну люто вайбкодить. Соберём сервер, окружение и агента под ключ — с миграцией и поддержкой. Смотреть тарифы →Коротко о чём статья
Если вы запускаете AI-агента вроде Claude Code, задача «переписать модуль», «прогнать тесты», «отрефакторить проект» легко идёт десятки минут. Держать всё это на ноутбуке — значит зависеть от батареи, Wi-Fi в кафе и того, что крышку нельзя закрыть. Разработчики решают это одинаково: выносят рабочую среду на удалённый сервер, а сам агент запускают внутри tmux, чтобы процесс жил без вас. Подключаетесь по SSH хоть с ноутбука, хоть с телефона — задача считается на сервере.
Ниже — полный практический разбор: как это устроено, сколько нужно ресурсов, как настроить безопасность и бэкапы, пошаговая инструкция с реальными командами и честный разбор доступа к Anthropic из России. Без воды — максимум практики.
Что такое Claude Code
Claude Code — консольный AI-агент от Anthropic (компании, создавшей модели Claude). Он работает прямо в терминале: видит проект целиком, читает и правит файлы, запускает команды, гоняет тесты, коммитит в Git — выполняет инженерные задачи, а не просто подсказывает код, как чат в браузере.
Ключевое отличие от «ассистента в редакторе» — автономность. Вы ставите задачу словами, агент сам декомпозирует её, находит нужные файлы, вносит правки, проверяет результат, при необходимости откатывается и пробует иначе. Он умеет вызывать инструменты: файловую систему, шелл, поиск по коду, а через протокол MCP — внешние сервисы (базы, трекеры, браузер). По той же логике устроены Cursor в режиме агента, Windsurf, а также open-source Aider, Cline и Continue.
Практический вывод: агенту нужно живое рабочее окружение — файлы проекта, интерпретаторы (Node.js, Python), Git, доступ в интернет к API модели и пакетным реестрам, а иногда база и запущенные сервисы, чтобы проверять свои же правки. Чат в браузере всего этого не требует, а агент — требует. Поэтому вопрос «где всё это крутится» из бытового становится инфраструктурным: от него зависит, потеряете ли вы сессию, сколько будете ждать сборку и сможете ли подключиться с другого устройства.
Claude Code, Cursor, Aider, Cline, Continue: чем отличаются и что где запускать
AI-агентов много, и путаница здесь мешает выбрать инфраструктуру. Коротко о главных и о том, где физически исполняется их «рабочая» часть:
| Инструмент | Тип | Где живёт код и окружение | Модель | Особенность |
|---|---|---|---|---|
| Claude Code | терминальный агент | там, где запущен (сервер по SSH) | облачный Claude (Anthropic) | автономность, MCP, чистая работа в консоли |
| Cursor | редактор + агент | локально или на сервере через Remote-SSH | облачные (в т.ч. Claude, GPT) | привычный VS Code UI |
| Windsurf | редактор + агент | локально / Remote-SSH | облачные | похож на Cursor |
| GitHub Copilot | плагин редактора | в редакторе (можно на сервере) | облачный | подсказки + чат, слабее «агентности» |
| Aider | терминальный агент | на сервере | любой (в т.ч. локальный) | легко цепляется к своей модели |
| Cline / Continue | плагины VS Code | в редакторе на сервере | облачный или локальный | открытые, поддержка OpenAI-совместимого API |
Практический вывод для выбора сервера: терминальные агенты (Claude Code, Aider) идеально ложатся на схему «сервер + tmux» и работают даже с телефона. Редакторные (Cursor, Windsurf, Cline, Continue) требуют Remote-SSH или code-server, но окружение у них всё равно на сервере. А Aider/Cline/Continue ещё и умеют работать с локальной моделью — это ваш путь, если важна приватность или нужно обойти геоблок совсем.
Почему неудобно работать с ноутбука
Ноутбук — отличная «голова», но плохой «двигатель» для долгих агентных задач. Разберём по пунктам, потому что каждый — это реальный сорванный прогон:
- Сон и закрытая крышка. Закрыли ноутбук — система усыпляется, SSH-сессия рвётся, а запущенный в ней процесс получает сигнал завершения. Агент бросает задачу на середине, причём часто в «грязном» состоянии: часть файлов уже изменена, часть — нет.
- Батарея. Прогон интеграционных тестов, сборка фронта, инференс — всё это разряжает аккумулятор за час. В дороге без розетки вы физически ограничены во времени работы агента.
- Нестабильная сеть. Переключение Wi-Fi → LTE, метро, лифт, смена точки доступа — любой разрыв убивает голый SSH и REPL-сессии. Агент, который час назад начал рефакторинг, к моменту, когда вы вышли из метро, уже мёртв.
- Ресурсы. Docker с несколькими контейнерами, локальная база, dev-сервер фронта, сборщик и сам агент — ультрабук на 16 ГБ начинает свопиться и тормозить, вентиляторы уходят в потолок.
- Шум и температура. На созвоне с включённой сборкой ноутбук превращается в фен — не лучший фон для разговора с заказчиком.
- Привязка к одному устройству. Рабочий проект живёт на конкретном MacBook. Ушли с телефоном — в него уже не заглянуть, задачу не поставить, статус не проверить.
Всё это лечится одним архитектурным решением: вычисления и файлы живут на сервере, а устройство — просто «окно» к нему. Ноутбук может спать, разряжаться, терять сеть — на серверную сессию это не влияет.
Почему разработчики переходят на удалённые серверы
- Задача продолжается без вас. Агент считает на сервере — закрыли ноутбук, легли спать, утром смотрите готовый diff.
- Одна среда с любого устройства. MacBook, рабочий ПК, iPad, телефон — везде тот же проект, те же запущенные сервисы и то же состояние сессии.
- Мощность по требованию. Упёрлись в RAM или ядра — меняете тариф за минуты, а не покупаете новый ноутбук за недели.
- Изоляция экспериментов. «Грязные» действия агента изолированы на сервере/в контейнере, а не в вашей основной системе с рабочей почтой и банковскими вкладками.
- Стабильный белый IP и предсказуемое окружение. Вебхуки, публичные превью, доступ к внутренним сервисам — работают предсказуемо, а не «пока ноутбук в этой сети».
- Данные под контролем. Код и секреты — в одном месте, на вашем сервере, а не размазаны по трём устройствам и облачным синхронизациям.
Это не «для гиков»: это способ перестать терять время на перезапуски и синхронизацию и начать относиться к рабочей среде как к сервису, который всегда доступен.
Как это работает: схема
┌──────────────┐ SSH ┌──────────────────────────────────────┐
│ Ноутбук/ПК │ ───────────────▶ │ Удалённый сервер (VPS / выделенный) │
│ iPad/iPhone │ ◀─────────────── │ ┌───────────────┐ │
└──────────────┘ терминал / IDE │ │ tmux-сессия │ Git ↔ GitHub/GitLab │
любое │ │ Claude Code │ Docker-контейнеры │
устройство │ │ / Cursor SSH │ Node.js · Python │
│ └───────────────┘ NVMe · RAM · vCPU │
└───────────────────────────┬────────────┘
│ исходящий трафик
▼
API моделей / реестры / apt
Устройство держит только SSH-подключение и, при желании, интерфейс VS Code. Всё тяжёлое — на сервере. tmux удерживает сессию агента живой, даже когда SSH отвалился, а Docker изолирует то, что агент запускает. Ключевой принцип: состояние живёт на сервере, клиент — тонкий и заменяемый.
Важный нюанс для России: доступ к Anthropic
Скажем прямо, потому что это ломает половину «глянцевых» гайдов. Anthropic ограничивает доступ к своему API с российских IP — Claude Code, обращаясь к api.anthropic.com напрямую с сервера в РФ, упрётся в отказ. Это не проблема хостинга, это политика вендора. Значит, есть три честных пути, и вы выбираете по задаче:
Путь 1 — исходящий маршрут в разрешённый регион. На вашем сервере поднимается WireGuard/прокси, и через него идёт только трафик к API модели. Сам сервер остаётся в РФ (низкий пинг до вас, файлы и Git — в России), а «наружу к Anthropic» ходит через разрешённый маршрут. Возможно это только потому, что у вас полный root-доступ и настраиваемый сервер — на shared-хостинге так не сделать. Схематично: поднимаете WireGuard-клиент, добавляете в AllowedIPs только подсети API, остальной трафик идёт напрямую (split-tunnel) — так вы не гоняете через маршрут всю сборку и apt.
Путь 2 — своя модель, без внешних API. Вместо облачного Claude поднимаете локальную LLM для кодинга (Qwen2.5-Coder, DeepSeek-Coder и др.) на сервере с видеокартой и подключаете к ней агента, умеющего работать с OpenAI-совместимым эндпоинтом — Cline, Aider или Continue. Пример подключения Aider к локальному серверу модели:
# на GPU-сервере поднят OpenAI-совместимый эндпоинт (напр. через vLLM/Ollama)
export OPENAI_API_BASE=http://127.0.0.1:8000/v1
export OPENAI_API_KEY=local
aider --model qwen2.5-coder:32b
Геоблок исчезает как класс: ни запросы, ни код никуда не уходят, данные остаются в российской юрисдикции. Цена вопроса — нужен GPU (модель 7–14B комфортно живёт на RTX 4090, крупнее — A100). Это то, чего облачные AI-сервисы дать не могут в принципе.
Путь 3 — гибрид. Приватный код и рутина — на локальной модели; сложные задачи, где нужен топовый облачный агент, — через маршрут из пути 1.
Что важно понять: удалённый сервер полезен при любом пути — он держит окружение, tmux-сессии, Docker, Git, доступ с телефона. Вопрос доступа к конкретному вендору — отдельный слой, который решается настройкой, а путь 2 снимает его совсем.
Локальная LLM для кодинга: какие модели и как подключить
Путь «своя модель» заслуживает отдельного разбора, потому что для России это часто самое чистое решение: нет геоблока, нет оплаты за токены, код не покидает ваш сервер. Смысл такой: на сервере с видеокартой поднимается модель и отдаётся по OpenAI-совместимому HTTP-эндпоинту, а агент (Aider, Cline или Continue) настраивается на этот адрес.
Какие модели брать под кодинг и сколько нужно VRAM:
| Модель | Размер | VRAM (4-bit / fp16) | Видеокарта |
|---|---|---|---|
| Qwen2.5-Coder 7B | 7B | ~6 / ~16 ГБ | RTX 4090 |
| Qwen2.5-Coder 14B | 14B | ~10 / ~28 ГБ | RTX 4090 |
| Qwen2.5-Coder 32B | 32B | ~20 / ~64 ГБ | RTX 4090 (4-bit) / 2×4090 |
| DeepSeek-Coder V2 | крупная | 40+ ГБ | A100 80 ГБ |
Как поднять эндпоинт — два популярных варианта. Быстрый старт через Ollama:
curl -fsSL https://ollama.com/install.sh | sh
ollama pull qwen2.5-coder:14b
ollama serve # OpenAI-совместимый API на 127.0.0.1:11434
Для нагрузки и максимальной скорости — vLLM (лучше батчит запросы). Дальше подключаете агента. Пример для Cline (в settings.json VS Code на сервере):
{
"cline.apiProvider": "openai",
"cline.openAiBaseUrl": "http://127.0.0.1:11434/v1",
"cline.openAiModelId": "qwen2.5-coder:14b",
"cline.openAiApiKey": "local"
}
Пример для Continue (~/.continue/config.json):
{
"models": [{
"title": "Local Qwen2.5-Coder",
"provider": "openai",
"model": "qwen2.5-coder:14b",
"apiBase": "http://127.0.0.1:11434/v1",
"apiKey": "local"
}]
}
Что важно понимать: локальная модель уровня 14–32B хороша для рутины, рефакторинга, тестов и работы по знакомому коду; для самых сложных задач топовые облачные модели всё ещё сильнее. Отсюда и гибрид: приватная рутина — на локальной, тяжёлое — на облачной через маршрут. Но именно локальный путь даёт то, чего облако не даст: полную приватность и работу без внешних зависимостей — в российской юрисдикции.
Как настроить исходящий маршрут для API (WireGuard split-tunnel)
Разберём путь 1 подробно, потому что именно на нём спотыкаются. Задача: сервер стоит в России (быстро, дёшево, данные тут), но запросы к API модели должны уходить через разрешённый регион — и только они, а не весь трафик (иначе сборки, apt и Git будут ходить кругами и тормозить). Решение — split-tunnel: через VPN гоним лишь подсети API.
Общая логика (WireGuard):
# /etc/wireguard/wg-api.conf на вашем сервере (клиент)
[Interface]
PrivateKey = <ваш_приватный_ключ>
# без DNS/полного перехвата — только нужные маршруты ниже
[Peer]
PublicKey = <ключ_узла_в_разрешённом_регионе>
Endpoint = <адрес_узла>:51820
# split-tunnel: заворачиваем ТОЛЬКО подсети API, остальное — напрямую
AllowedIPs = <подсети_API>/32
PersistentKeepalive = 25
Поднимается и проверяется так:
sudo apt install wireguard
sudo wg-quick up wg-api
curl https://api.anthropic.com/ # проверяем, что доступ появился
ip route get <IP_из_подсети_API> # убеждаемся, что идёт через wg
Ключевой момент — в AllowedIPs только адреса API, а не 0.0.0.0/0. Тогда:
- обращения к модели идут через маршрут (геоблок обойдён);
- сборка,
apt,npm,git pushидут напрямую с быстрого российского канала; - ваши файлы и код физически остаются на сервере в РФ.
Управлять узлом-выходом должны вы сами (это ваша инфраструктура и ваша ответственность). Если возиться не хочется — это ровно тот случай, когда проще выбрать путь 2 (локальная модель): там маршрут не нужен вообще. Полный root-доступ на сервере позволяет реализовать любой из вариантов — на shared-хостинге это невозможно.
Как работать с телефона
Да, серьёзно — с телефона можно вести реальную разработку, если «мозги» на сервере.
- iOS: Blink Shell или Termius — полноценные SSH-клиенты с поддержкой ключей, mosh и сохранённых хостов. Blink дополнительно умеет держать соединение при сворачивании.
- Android: Termius или Termux (локальный терминал + SSH прямо на телефоне).
- Рабочий цикл: открыли приложение → подключились к серверу →
tmux attach→ вы внутри той же сессии агента, что и с ноутбука. Поставили задачу, свернули телефон — агент считает. - iPad с внешней клавиатурой + VS Code через
code-serverв браузере — это уже почти полноценная станция: редактор, терминал, отладчик.
Секрет удобства — mosh (mobile shell): в отличие от чистого SSH он переживает смену сети и сон устройства, мгновенно «оживляя» сессию при возврате. Ставится в пару команд:
sudo apt install mosh # на сервере
# на телефоне выбираете подключение по mosh в Termius/Blink
Реалистичный сценарий: вы в дороге, с телефона ставите агенту задачу «добавь эндпоинт и тесты», отсоединяетесь, через 20 минут снова открываете Termius, tmux attach — видите готовый diff, ревьюите его пальцем, мержите.
Как закрыть ноутбук и не потерять процесс
Главная боль новичков: запустил агента по SSH, закрыл крышку — процесс умер. Причина техническая: при разрыве терминала система шлёт процессам его группы сигнал SIGHUP, и агент, как любой foreground-процесс, завершается. Ноутбук ушёл в сон → SSH оборвался → SIGHUP → агент мёртв.
Решение — запускать агента не напрямую, а внутри tmux. tmux (terminal multiplexer) держит сессию на сервере независимо от вашего подключения. Оборвался SSH, закрылся ноутбук, сменилась сеть — сессия живёт, агент работает. Вернулись — tmux attach, и вы снова видите его вывод, будто и не уходили. По сути tmux превращает «сессию в терминале» в «фоновый сервис, к которому можно подключаться».
tmux — практика
Установка и базовый цикл:
sudo apt install tmux
tmux new -s claude # создать именованную сессию
# ... внутри запускаем агента, ставим задачу ...
# отсоединиться, оставив всё работать: Ctrl+b, затем d
tmux ls # список сессий
tmux attach -t claude # вернуться к сессии
tmux kill-session -t claude # закрыть, когда не нужна
Все команды tmux вводятся через префикс Ctrl+b, затем клавишу. Полезный минимум:
| Действие | Сочетание |
|---|---|
| Отсоединиться (detach) | Ctrl+b d |
| Новое окно | Ctrl+b c |
| Переключить окно | Ctrl+b 0..9 |
| Разбить панель вертикально | Ctrl+b % |
| Разбить горизонтально | Ctrl+b " |
| Переход между панелями | Ctrl+b ←↑↓→ |
| Прокрутка / копирование | Ctrl+b [ |
Конфиг ~/.tmux.conf, который сразу делает жизнь удобнее:
set -g mouse on # прокрутка и выделение мышью
set -g history-limit 100000 # длинная история вывода агента
setw -g mode-keys vi
set -g default-terminal "tmux-256color"
set -g status-interval 5
Практика организации: заводите отдельную сессию под задачу — tmux new -s refactor, tmux new -s tests. Так несколько агентных прогонов идут параллельно и не мешают друг другу; вы переключаетесь между ними одной командой. Внутри сессии удобно раскладывать панели: в одной агент, в другой — tail -f логов, в третьей — htop для контроля памяти. Если хотите, чтобы сессии переживали даже перезагрузку сервера, добавьте плагины tmux-resurrect/tmux-continuum — они сохраняют и восстанавливают раскладку.
Docker — изоляция окружений
AI-агент по определению выполняет команды. Давать ему полный доступ к «боевой» системе — риск: одна неудачная команда с rm -rf или sudo может задеть лишнее. Docker даёт дешёвую изоляцию: агент работает внутри контейнера с проектом, а хост-система остаётся чистой.
# dev-контейнер с Node, монтируем проект внутрь
docker run -it --rm \
-v "$PWD":/workspace -w /workspace \
--name devbox node:22 bash
Ещё удобнее описать окружение декларативно через devcontainer.json (его понимают VS Code, Cursor и часть агентов) или через docker-compose.yml, если рядом нужны база и очередь:
# docker-compose.yml — проект + база для проверки правок агента
services:
app:
image: node:22
working_dir: /workspace
volumes: [ ".:/workspace" ]
command: sleep infinity
db:
image: postgres:16
environment: { POSTGRES_PASSWORD: dev }
Плюсы для AI-разработки:
- Воспроизводимость — окружение зафиксировано в образе, «у меня работает» перестаёт быть аргументом.
- Безопасность — эксперименты агента ограничены контейнером; сломал —
docker rmи пересоздал за секунды. - Параллельность — несколько проектов и версий рантаймов рядом без конфликтов.
Отдельная посадочная под этот сценарий — сервер для Docker. А для полноценных песочниц с виртуальными машинами (каждому проекту — своя ВМ) поверх выделенного сервера ставят Proxmox: изоляция сильнее контейнерной, удобно для команды.
Git — рабочий процесс на сервере
Git на сервере — не только версии, но и страховка от агента: любые правки обратимы, если вы дисциплинированы.
git checkout -b agent/refactor # отдельная ветка под прогон агента
# ... агент работает, коммитит ...
git diff main...HEAD # смотрим весь объём изменений
git restore . # откат несохранённого, если неудачно
git reset --hard main # полный откат ветки
Правило: агент работает в отдельной ветке, вы ревьюите diff и мержите осознанно. Для параллельных задач удобны git worktree — несколько рабочих копий одного репозитория рядом, каждая в своей ветке и своей tmux-сессии:
git worktree add ../myapp-feature feature/new-api
SSH-ключ для GitHub/GitLab заводится на сервере (ваш ключ или отдельный deploy key) — тогда push/pull идут прямо с сервера, без прокладки через ноутбук.
Dotfiles и воспроизводимое окружение
Одно из главных преимуществ серверного подхода — окружение настраивается один раз и живёт постоянно, а не пересобирается на каждом новом устройстве. Чтобы не настраивать сервер «руками» и легко поднимать новый, держите конфигурацию в репозитории dotfiles: ваши .bashrc/.zshrc, .gitconfig, .tmux.conf, список нужных пакетов и алиасов.
# клонируем свои настройки на новый сервер и применяем
git clone https://github.com/you/dotfiles ~/.dotfiles
cd ~/.dotfiles && ./install.sh
Такой подход превращает поднятие нового сервера в 10-минутную операцию: склонировали dotfiles, прогнали установочный скрипт — и у вас привычные алиасы, настроенный tmux, ваш git config и любимая оболочка. Для команды это ещё и способ выровнять окружение: общий репозиторий базовых настроек + личные надстройки у каждого. А если рабочие проекты описаны через devcontainer.json, то и сам стек (версии Node, Python, системные библиотеки) поднимается одной командой — «у меня не воспроизводится» перестаёт существовать как проблема.
Отдельно полезно хранить в dotfiles шаблон ~/.tmux.conf и заготовку сессий: скрипт, который одной командой создаёт стандартную раскладку (агент, логи, htop) под новый проект. Это экономит минуты каждый день и делает работу единообразной.
Запуск и проверка сервисов проекта
Агенту часто нужно не просто написать код, а проверить, что он работает: поднять dev-сервер, дёрнуть эндпоинт, прогнать тесты против живой базы. На сервере это удобнее, чем на ноутбуке, потому что сервисы могут работать постоянно и быть доступны извне по белому IP.
# поднимаем зависимости проекта в фоне (в отдельной tmux-панели или через compose)
docker compose up -d db redis
npm run dev & # dev-сервер фронта/бэкенда
curl -s localhost:3000/health # агент и вы проверяете, что живо
npm test # прогон тестов
Практика: держите базу и вспомогательные сервисы в docker compose с restart: unless-stopped, тогда после перезагрузки сервера они поднимутся сами, и агенту всегда есть к чему обращаться. Если нужно показать превью заказчику или дёрнуть вебхук снаружи — белый IPv4 и (при желании) домен с TLS делают dev-сервер доступным по постоянному адресу, а не «пока ноутбук в этой сети». Для временного публичного доступа к локальному порту без настройки прокси удобны туннели (tailscale funnel или SSH-reverse-туннель) — но помните про безопасность и не выставляйте наружу лишнего.
Когда упёрлись в ресурсы: масштабирование без переезда с нуля
Хороший сценарий развития — начать скромно и расти по факту, а не покупать «с запасом». Признаки, что пора добавить ресурсов: сервер стабильно работает из свопа, сборки заметно замедлились, htop регулярно показывает загрузку памяти под потолок, тесты падают по OOM. Порядок действий обычно такой:
- 1. Апгрейд тарифа VPS. Часто достаточно поднять RAM/vCPU на текущем VPS — это самый быстрый шаг.
- 2. Переезд VPS → выделенный сервер. Когда упираетесь в потолок виртуализации или нужна вся производительность железа без соседей и много контейнеров/CI. Диск/конфигурацию можно перенести, а не пересобирать.
- 3. Добавление GPU-сервера под локальную модель — если решили уйти от внешних API или гонять инференс.
Важно, чтобы всё это происходило у одного провайдера и с помощью в миграции — тогда рост не превращается в проект «переехать и ничего не сломать». Возможность вырасти от VPS до выделенного сервера и добавить GPU в том же дата-центре сильно экономит нервы: инфраструктура растёт вместе с задачами, а не переживает болезненные переезды между площадками.
VS Code Remote (Remote-SSH)
Не хотите жить в чистом терминале — подключите привычный VS Code к серверу по SSH.
- 1. Установите расширение Remote - SSH.
- 2.
F1→ «Remote-SSH: Connect to Host» → добавьтеdev@SERVER_IP(или Tailscale-имя). - 3. VS Code открывает удалённую файловую систему: редактор, отладчик, интегрированный терминал, расширения — всё исполняется на сервере, локально остаётся только UI.
Важная деталь: расширения в Remote-SSH делятся на локальные (тема, шрифты) и «серверные» (линтеры, отладчики, language servers) — последние ставятся на сервер и работают там же, где код. Так же работает Cursor (он форк VS Code и поддерживает Remote-SSH): интерфейс и агент Cursor на ноутбуке, проект и его окружение — на сервере. Получаете и удобный редактор, и «неубиваемое» серверное окружение под ним.
code-server — свой Web IDE
code-server — это VS Code, открывающийся в браузере. Полезно, когда под рукой только планшет, чужой компьютер или вы не хотите ставить IDE локально: заходите на свой домен и получаете полноценную среду.
curl -fsSL https://code-server.dev/install.sh | sh
sudo systemctl enable --now code-server@$USER
# по умолчанию слушает 127.0.0.1:8080; пароль — в ~/.config/code-server/config.yaml
Наружу его отдают только за обратным прокси с TLS или внутри Tailscale. Пример Caddy как HTTPS-фронта (сам сертификат Caddy выпустит автоматически):
dev.example.ru {
reverse_proxy 127.0.0.1:8080
}
Правило безопасности: никогда не выставляйте code-server голым портом в интернет. Это открытая IDE с доступом к вашему коду, терминалу и ключам — её мгновенно найдут сканеры. Только TLS + пароль, а лучше — вообще не публичный порт, а приватная сеть (ниже).
Своя IDE на сервере vs облачные Codespaces и Gitpod
Резонный вопрос: зачем свой сервер, если есть GitHub Codespaces, Gitpod и другие облачные среды? Честное сравнение:
| Критерий | Свой сервер (VPS/выделенный) | Codespaces / Gitpod |
|---|---|---|
| Стоимость при постоянной работе | фиксированная, предсказуемая | почасовая, растёт с использованием |
| Данные и код | на вашем сервере, в РФ | в чужом облаке, за рубежом |
| Настройка окружения | полная свобода, root | ограничена платформой |
| Долгие фоновые процессы | живут в tmux сколько нужно | среда засыпает по таймауту |
| Локальная LLM | можно (свой GPU) | нельзя |
| Доступность из РФ | зависит от вашей настройки | часто требует обхода |
| Vendor lock-in | нет | есть |
Вывод: облачные IDE удобны для разовых задач и онбординга, но при постоянной работе, требованиях к приватности/юрисдикции и желании гонять долгие агентные прогоны свой сервер выигрывает и по деньгам, и по контролю. И только на своём сервере вы можете поставить рядом локальную модель.
Tailscale и Zero Trust
Открывать порты SSH/IDE всему интернету — значит собирать на них ботов и брутфорс. Современный подход — не открывать порты вообще, а строить приватную сеть.
Tailscale — это WireGuard-сеть поверх вашего аккаунта: сервер и все ваши устройства (ноутбук, телефон, iPad) получают приватные адреса и видят друг друга напрямую, а для остального интернета сервер закрыт. Это и есть Zero Trust: доступ по устройству и учётке, а не «кто угадал порт».
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
# опционально — встроенный SSH Tailscale с логами и ACL:
sudo tailscale up --ssh
После этого SSH и code-server слушают только приватный интерфейс tailscale0, публично на сервере — ничего. Дополнительно можно настроить ACL (кто из устройств к каким сервисам ходит) и MagicDNS (обращаться к серверу по имени, а не IP). Итог: брутфорсить нечего, а вы заходите на сервер из любой сети так, будто он в вашей локалке.
Безопасность
Минимальный, но обязательный набор для сервера с вашим кодом и секретами:
- Только SSH-ключи, пароли выключены. В
/etc/ssh/sshd_config:PasswordAuthentication noиPermitRootLogin no, затемsudo systemctl restart ssh. - Отдельный пользователь, не root. Работаем под обычным пользователем, привилегии — через
sudoпо необходимости. - Файрвол.
ufwс политикой «запрещено всё, кроме нужного»:
sudo ufw default deny incoming
sudo ufw allow in on tailscale0 # доступ только из приватной сети
sudo ufw enable
- fail2ban. Если SSH всё же смотрит наружу — банит переборщиков после нескольких неудач.
- Секреты — не в коде. Токены и ключи — в переменных окружения или
.envвне репозитория; в Git обязательно.gitignore. Утёкший в коммит токен считается скомпрометированным. - Отдельные ключи под агентов. У AI-агента — минимально нужные права и свой deploy-ключ, а не ваш главный. Если агент работает в Docker — ещё лучше.
- Автообновления.
unattended-upgradesдля критических патчей безопасности. - Принцип наименьших прав для агента. Не запускайте автономного агента под root и без изоляции: связка «отдельный пользователь + Docker + отдельная Git-ветка» делает любое его действие обратимым.
Отдельно про приватность: если код чувствительный, путь «локальная модель на своём сервере» — самый строгий, потому что ни строчки кода не уходит наружу, а сервер физически находится в российском дата-центре, под российской юрисдикцией.
Автозапуск, лимиты и мониторинг
Чтобы сервер работал сам, а агент не «съел» всю память, добавьте контроль.
Автозапуск рабочего окружения. Чтобы нужные сервисы (база, dev-сервер) поднимались после перезагрузки, оформляйте их как systemd-юниты или docker compose up -d с restart: unless-stopped. Сам агент запускать автостартом не стоит — он интерактивный, его место в tmux.
Лимиты ресурсов для агента. Если агент и его сборки живут в Docker, ограничьте контейнер, чтобы один прогон не положил сервер:
docker run -it --memory=4g --cpus=2 \
-v "$PWD":/workspace -w /workspace node:22 bash
Мониторинг. Держите под рукой инструменты, чтобы видеть, что происходит:
htop # процессы, память, нагрузка
ctop # мониторинг Docker-контейнеров
ncdu ~ # что занимает место на диске (node_modules растут быстро)
df -h # свободное место
Практика: заведите в tmux отдельную панель с htop — когда агент запускает тяжёлую сборку, вы сразу видите, упирается ли сервер в память, и вовремя добавляете RAM или ограничиваете контейнер, а не ловите «out of memory» посреди задачи.
Резервное копирование
Сервер — не повод забыть про бэкапы, а повод их упростить и автоматизировать.
- Git — первая линия. Всё закоммиченное и запушенное уже продублировано в удалённом репозитории. Но незакоммиченное и данные Git не спасёт.
- Снапшоты диска. Снимок всего сервера перед рискованными изменениями — откат за минуты. Делайте перед крупными прогонами агента и обновлениями.
- Файлы и данные — инкрементально.
resticилиborgс шифрованием и дедупликацией на второй адрес/диск:
# инициализация и ежедневный бэкап проекта (в cron)
restic -r /backup/repo init
restic -r /backup/repo backup ~/projects --exclude node_modules --exclude .git
restic -r /backup/repo forget --keep-daily 7 --keep-weekly 4 --prune
Правило 3-2-1 остаётся в силе: минимум две копии в разных местах, одна — вне основного сервера. Отдельный диск