Claude Code на VPS: агент, который работает без вашего ноутбука
Claude Code живёт в терминале, и это его сильная и слабая сторона одновременно: стоит закрыть крышку ноутбука — и сорокаминутная задача обрывается на середине. На сервере она не обрывается. Разбираем установку на Ubuntu, вход в аккаунт там, где нет браузера, и то, что агенту на сервере лучше не разрешать.
Проблема: агент привязан к вашей машине
Claude Code — это агент Anthropic для работы с кодом, и он не похож на подсказки в редакторе. Это отдельная программа в терминале: вы ставите задачу словами, а она сама читает файлы, ищет по коду, правит, запускает тесты и коммитит. Работа идёт минутами, иногда десятками минут, и всё это время процесс должен быть жив.
Отсюда четыре неудобства, с которыми сталкивается каждый, кто пользуется им всерьёз.
Длинная задача держит вас за столом
Закрыли ноутбук, отвалился Wi-Fi, уехали в метро — терминал закрылся, и вместе с ним умер процесс. Агент не «поставился на паузу», он просто перестал существовать вместе с недоделанной задачей.
Агент работает в вашей рабочей папке
У него есть доступ к shell. Даже с подтверждениями на каждую команду где-то рядом лежат ваши личные проекты, SSH-ключи и настроенное окружение — то, что вы собирали годами и чего не жалко потерять только на словах.
С телефона к нему не подойти
Идея «поставлю задачу из очереди в магазине» упирается в то, что агент запущен в терминале ноутбука, который лежит дома с закрытой крышкой.
Проект уже живёт на сервере
База, логи, деплой, docker compose — всё там. Агент на ноутбуке смотрит на всё это через щель в виде ssh-команд, а половину проверок сделать вообще не может.
Отдельный VPS закрывает все четыре пункта разом. Агент работает на машине, которая не выключается; если сервер отведён только под него, ломать там нечего; подойти к нему можно с любого устройства, где есть SSH; а проект и его окружение — прямо под рукой.
Что понадобится
Аккаунт с доступом к Claude Code
Подписка Claude Pro (20 $ в месяц, 17 $ при оплате за год) или Max (от 100 $). На бесплатном плане Claude Code не работает. Альтернатива — аккаунт Claude Console с оплатой за токены: тогда вместо входа по подписке используется API-ключ.
VPS с Ubuntu и 4 ГБ памяти
Официальные требования: Ubuntu 20.04+ или Debian 10+, процессор x64 или ARM64, 4 ГБ оперативной памяти. Сам агент скромный — на диске он занимает 237 МБ, а его диагностика на чистой Ubuntu отработала с пиком памяти 180 МБ. Четыре гигабайта нужны не ему, а тому, что он запускает: сборкам, тестам, контейнерам. Под один небольшой проект хватает и 2 ГБ, но со свопом.
Локация сервера — в стране, где Claude обслуживается
Anthropic работает с ограниченным списком стран. Германия, Нидерланды, Казахстан, Турция, Армения в нём есть; России и Беларуси в нём нет. С сервера в необслуживаемой стране установка упадёт ещё на скачивании с ответом App unavailable in region или простым 403. Актуальный список — на странице supported countries у Anthropic. То же требование относится и к браузеру, в котором вы будете входить в аккаунт на третьем шаге.
Про канал можно не думать. Агент обменивается с сервером Anthropic текстом: ваш запрос, куски файлов, ответ. Гигабитный порт для этого не нужен, подойдёт любой обычный тариф. Важнее не скорость, а стабильность связи — при сетевой ошибке Claude Code повторяет запрос сам.
Шаг 1. Отдельный пользователь и своп
Ставить агента под root не надо, и причин на это две. Первая техническая: если запустить установщик из корня файловой системы, он начинает сканировать её целиком и на слабой машине зависает. Вторая важнее: агент запускает команды в shell, и пусть он делает это с правами обычного пользователя, а не администратора.
adduser dev
usermod -aG sudo dev
cp -r ~/.ssh /home/dev/
chown -R dev:dev /home/dev/.sshПервая команда заведёт пользователя dev и спросит пароль, вторая даст ему право на sudo, две последние скопируют ваш SSH-ключ, чтобы заходить сразу под новой учёткой. Если вы входите на сервер по паролю, а не по ключу, копирование пропустите — но лучше сначала настроить вход по ключу, об этом есть отдельная статья.
Дальше зайдите на сервер уже под dev и поставьте то, что понадобится в следующих шагах:
sudo apt update
sudo apt install -y git tmuxЗатем — минимальный файрвол. Наружу у этого сервера ничего смотреть не должно, кроме SSH:
sudo ufw allow 22/tcp
sudo ufw enableВторая команда переспросит, не оборвёт ли включение файрвола ваше SSH-соединение. Отвечайте y: порт 22 разрешён первой строкой, и связь не пропадёт.
И своп. Установщику Claude Code нужно примерно 512 МБ свободной памяти; если их нет, его убивает OOM-killer и установка обрывается с кодом 137. На маленьком сервере, где память уже занята базой и приложением, это случается легко, поэтому своп-файл делаем заранее:
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstabПоследняя строка нужна, чтобы своп подключался после перезагрузки. Проверить, что он работает: free -h — в строке Swap появятся 2 ГБ.
Шаг 2. Установка
Официальный установщик — одна команда. Выполнять её нужно от пользователя dev и обязательно из домашней папки, а не из корня:
cd ~
curl -fsSL https://claude.ai/install.sh | bashСкрипт скачает бинарник в ~/.local/share/claude/versions/ и поставит на него симлинк ~/.local/bin/claude. В конце он почти наверняка напишет предупреждение:
⚠ Setup notes:
● Native installation exists but ~/.local/bin is not in your PATH.Пугаться не нужно. Ubuntu добавляет ~/.local/bin в PATH автоматически, но только если папка существовала на момент входа в систему — а до установки её не было. Поэтому просто выйдите и зайдите по SSH заново:
exit
ssh dev@ВАШ_IP
claude --versionДолжна напечататься версия вида 2.1.246 (Claude Code). Если вместо неё вы видите bash: claude: command not found, значит автоматика не сработала — пропишите путь руками:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrcПолную диагностику установки печатает отдельная команда — она ничего не запускает и не меняет, только показывает состояние:
claude doctorClaude Code doctor
Running: native (2.1.246)
Platform: linux-x64
Path: /home/dev/.local/share/claude/versions/2.1.246
Config install method: native
Search: OK (bundled)
Auto-updates: enabled
Auto-update channel: latest
No installation issues found.Обновления. Нативная установка обновляется сама в фоне: Claude Code проверяет наличие новой версии при запуске и время от времени во время работы, скачивает её и применяет при следующем старте. Обновить немедленно — claude update. Ставить руками ничего не нужно, и это одна из причин выбрать установщик, а не npm.
Шаг 3. Вход в аккаунт, когда браузера нет
Это единственное место, где установка на сервер отличается от установки на ноутбук, и именно здесь обычно застревают. Claude Code входит в аккаунт через браузер, а на сервере браузера нет. Штатное решение — команда, которая читает код авторизации из обычного ввода:
claude auth loginОна напечатает длинную ссылку и остановится в ожидании:
Opening browser to sign in…
If the browser didn't open, visit: https://claude.com/cai/oauth/authorize?code=true&client_id=…
Paste code here if prompted >Дальше три действия:
- Скопируйте ссылку целиком и откройте её в браузере на своей машине. Ссылка длинная, и терминал может перенести её на несколько строк — следите, чтобы в буфер попало всё до последнего символа.
- Войдите в аккаунт Claude и подтвердите доступ. Браузер покажет код авторизации.
- Вставьте код в терминал сервера и нажмите Enter. Появится
Login successful.
Код живёт недолго, поэтому не откладывайте вставку: если между шагами прошло много времени, вы получите OAuth error: Invalid code и всё придётся повторить. Проверить результат:
claude auth status{
"loggedIn": false,
"authMethod": "none",
"apiProvider": "firstParty",
"analyticsDisabled": false
}После успешного входа loggedIn станет true. Если вы заходите не по подписке, а по аккаунту Claude Console, добавьте флаг: claude auth login --console.
Где лежит доступ и почему это важно. На Linux вход сохраняется в файл ~/.claude/.credentials.json с правами 600 — читать его может только владелец. Это, по сути, ключ от вашей подписки: не копируйте его на другие машины и следите, чтобы он не попадал в бэкапы, которые уезжают к третьим лицам. Токен продлевается сам; за три дня до истечения Claude Code напишет при запуске Your login expires in 3 days · run /login to renew.
Для скриптов и запусков по расписанию есть второй способ — годовой токен. Команда claude setup-token проводит через тот же вход в браузере, но вместо сохранения печатает токен в терминал; его кладут в переменную окружения:
export CLAUDE_CODE_OAUTH_TOKEN=ВАШ_ТОКЕНТакой токен умеет только отправлять запросы к модели: управление с телефона через него не поднимется. Для обычной работы он не нужен — хватит обычного входа.
Шаг 4. Первый запуск в проекте
Claude Code всегда запускают из папки проекта — оттуда он берёт контекст, права на файлы и настройки. Заберите проект на сервер и зайдите внутрь:
mkdir -p ~/projects && cd ~/projects
git clone https://github.com/ВАШ_АККАУНТ/myapp.git
cd myapp
claudeСамый первый запуск проведёт через короткую настройку: предложит выбрать тему оформления терминала (сменить её потом можно командой /theme) и спросит, доверяете ли вы файлам в этой папке. Второй вопрос — не формальность: в проекте могут лежать настройки, которые Claude Code подхватывает автоматически, поэтому отвечать «да» стоит только для своего кода.
Дальше просто пишите задачу словами. Несколько команд, которые пригодятся сразу:
| Команда | Что делает |
|---|---|
/status | показывает, каким способом выполнен вход и какая модель выбрана |
/usage | сколько израсходовано из лимитов плана за сутки и за неделю |
/model | сменить модель: Opus для сложного, Sonnet для рутины и дешевле |
/clear | начать разговор с нуля, когда переключаетесь на другую задачу |
/compact | сжать длинную переписку, сохранив суть |
Esc | остановить агента прямо посреди действия |
Привычка нажимать /clear при смене задачи экономит больше лимита, чем любые другие настройки: Claude Code отправляет всю переписку с каждым запросом, и вопрос в один абзац внутри разговора, который тянется с утра, стоит как весь этот разговор.
Если привычнее редактор. VS Code умеет подключаться к серверу по SSH через расширение Remote - SSH: файлы открываются как локальные, а claude запускается в его встроенном терминале. Работает это ровно так же, но с одной оговоркой — терминал редактора такая же обычная сессия, поэтому tmux из следующего шага всё равно нужен.
Шаг 5. tmux — чтобы обрыв связи не убивал задачу
Без этого шага сервер не даёт главного. Если вы запустили claude прямо в SSH-сессии, то при её обрыве процесс агента убивается вместе с терминалом — ровно так же, как на ноутбуке. Сервер работает, а задача не доделана.
Лечится это tmux — программой, которая держит терминальные сессии отдельно от вашего подключения. Вы отцепляетесь, а всё, что внутри, продолжает работать.
tmux new -s claudeВы попадёте в новую сессию с именем claude — внешне это обычный терминал с полоской внизу. Запускайте агента прямо в ней:
cd ~/projects/myapp
claudeДальше три сочетания:
Ctrl+B, затем D
Отцепиться от сессии. Агент продолжает работать, вы возвращаетесь в обычный терминал и можете закрывать SSH.
tmux attach -t claude
Вернуться к сессии — хоть через минуту с того же ноутбука, хоть через час с телефона. Вы увидите ровно то, что происходило без вас.
tmux ls
Посмотреть список живых сессий, если вы забыли, что и где запускали.
Проверьте связку до того, как доверите ей настоящую работу: поставьте агенту любую задачу на пару минут, нажмите Ctrl+B, D, закройте окно терминала целиком, зайдите заново и сделайте tmux attach -t claude. Задача должна оказаться доделанной.
Перезагрузку сервера tmux не переживает — сессии создаются заново. Если хочется, чтобы пустая сессия поднималась автоматически, добавьте строку в crontab -e:
@reboot /usr/bin/tmux new-session -d -s claude -c /home/dev/projects/myappПосле перезагрузки достаточно будет сделать tmux attach -t claude и запустить claude — папка уже будет правильной. А чтобы продолжить прерванный разговор, а не начинать с нуля, запускайте claude --continue: история сессий лежит на диске и перезагрузку переживает спокойно.
Шаг 6. Управление с телефона
У Claude Code есть режим Remote Control: сессия остаётся на вашем сервере — там же файлы, там же команды, — но писать ей можно из приложения Claude на телефоне или из браузера на claude.ai/code. Это второй по важности повод держать агента на VPS: сервер не спит, а вы подключаетесь к нему откуда угодно и без SSH-клиента.
Два условия:
- нужна подписка Pro, Max, Team или Enterprise — с API-ключом режим не работает;
- в папке проекта нужно хотя бы раз запустить
claudeи принять диалог доверия, иначе подключиться будет не к чему.
Запускается флагом — лучше всего внутри той же сессии tmux:
cd ~/projects/myapp
claude --remote-control "myapp на сервере"Это обычная интерактивная сессия, просто доступная ещё и снаружи: печатать можно и в терминале, и с телефона, история везде одна. Внизу под полем ввода появится индикатор /rc active — выберите его стрелкой вниз и нажмите Enter, чтобы открыть панель со ссылкой на сессию и QR-кодом. Наведите на код камеру телефона, и вы окажетесь в этом же разговоре.
Если терминал на сервере вам вообще не нужен, есть второй режим — без дефисов в начале:
claude remote-control --name "myapp"Процесс работает как сервер и только ждёт подключений; нажатие пробела покажет QR-код. Внутри tmux это превращается в постоянно доступного агента: подключился с телефона, поставил задачу, закрыл приложение.
Если режим не включается. Remote Control не работает, когда переменная ANTHROPIC_BASE_URL указывает не на api.anthropic.com (например, вы завели прокси к API), и когда выставлены DISABLE_TELEMETRY, DO_NOT_TRACK или CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC — от них зависит проверка доступности функции. Что именно мешает, покажет claude doctor: у него есть отдельный раздел Remote Control со списком причин.
Шаг 7. Что агенту разрешать
По умолчанию Claude Code спрашивает подтверждение перед каждой командой в shell и перед каждой правкой файла; без вопросов он только читает. Это нормальный режим для работы за столом, но на сервере, куда вы заходите раз в час, каждое подтверждение — остановка на час.
Соблазн решить это флагом --dangerously-skip-permissions («не спрашивай ничего») велик, и название выбрано не случайно. На сервере с боевой базой или рабочими ключами так делать не стоит. Правильный ответ — песочница: команды выполняются с настоящими ограничениями операционной системы, а не на честном слове.
На Linux песочнице нужны два пакета:
sudo apt install -y bubblewrap socatНа Ubuntu 24.04 и новее есть дополнительная деталь: политика AppArmor по умолчанию запрещает bwrap создавать пространства имён, без которых изоляция не работает. Проверьте:
sysctl kernel.apparmor_restrict_unprivileged_usernsЕсли ответ 0 или команда говорит, что такого параметра нет, всё уже в порядке. Если 1 — добавьте профиль:
sudo tee /etc/apparmor.d/bwrap > /dev/null <<'EOF'
abi <abi/4.0>,
include <tunables/global>
profile bwrap /usr/bin/bwrap flags=(unconfined) {
userns,
include if exists <local/bwrap>
}
EOF
sudo systemctl reload apparmorПрофиль разрешает создавать пространства имён самому bwrap, а не тем командам, которые он потом запускает внутри. После этого перезапустите Claude Code и выполните в сессии:
/sandboxОткроется панель с вкладками. На вкладке Mode выберите автоматическое разрешение — тогда команды, которые удалось запустить в песочнице, выполняются без вопросов. Внутри песочницы команда может писать только в папку проекта и во временный каталог сессии, а на первый выход в новый домен Claude Code всё равно спросит разрешение. Что не удаётся изолировать — по-прежнему идёт через обычные подтверждения. Если единственная вкладка в панели — Dependencies, значит какой-то пакет всё ещё не установлен.
Выбор в панели сохраняется в .claude/settings.local.json конкретного проекта. Чтобы песочница работала во всех проектах сразу, пропишите её в личных настройках:
{
"sandbox": {
"enabled": true
}
}Три правила, которые важнее любых настроек:
- у пользователя
devне должно быть ключей от прода и доступов к боевым базам. Если агент должен пушить в репозиторий — заведите для этого отдельный deploy-ключ с доступом только к нужному проекту, а не копируйте на сервер свой личный; - проект держите в git и почаще коммитьте: единственная реальная страховка от неудачной правки — возможность откатиться;
- порт наружу открывать не нужно. Claude Code не поднимает веб-интерфейс и все соединения инициирует сам, так что снаружи у сервера остаётся только SSH.
Задачи по расписанию
Раз агент живёт на сервере, ему можно давать работу и без вас. Флаг -p запускает Claude Code без интерактивного режима: один запрос, ответ в стандартный вывод, выход.
cd ~/projects/myapp
claude -p "Посмотри git log за последние сутки и напиши, что изменилось, в трёх пунктах" \
--allowedTools "Read,Bash(git log *),Bash(git diff *)"Флаг --allowedTools здесь не украшение, а необходимость. В режиме -p спрашивать разрешение не у кого, поэтому команду, которая не разрешена явно, агент выполнить не сможет — и вернёт вам не результат, а объяснение, почему не смог. Пробел перед * важен: Bash(git log *) разрешает команды, начинающиеся с git log, а Bash(git log*) заодно разрешило бы и git log-something.
Такой вызов кладётся в cron как любая другая команда. Один нюанс: cron запускается с урезанным окружением и ~/.local/bin в его PATH не входит, поэтому путь пишем полностью:
0 9 * * 1-5 cd /home/dev/projects/myapp && /home/dev/.local/bin/claude -p "Проверь, какие зависимости отстали от свежих версий, и перечисли самые важные" --allowedTools "Read,Bash(npm outdated),Bash(npm outdated *)" < /dev/null >> /home/dev/claude-cron.log 2>&1Две детали, без которых строка работает хуже, чем могла бы. < /dev/null нужен потому, что в режиме -p Claude Code сначала ждёт данные на стандартном вводе и, не дождавшись, три секунды спустя пишет в лог предупреждение; явное перенаправление это убирает.
А команда npm outdated разрешена двумя записями не по ошибке: Bash(npm outdated) — это точное совпадение, а Bash(npm outdated *) — совпадение по началу строки. Одна другую не заменяет, поэтому, когда команду можно вызвать и с аргументами, и без них, пишут обе.
Если нужен машинно-читаемый ответ, добавьте --output-format json — в поле result будет текст, а рядом окажутся идентификатор сессии и расчётная стоимость запроса. Разбирать его удобно утилитой jq (sudo apt install -y jq):
claude -p "Одной строкой: чем занимается этот проект?" --output-format json | jq -r '.result'И ещё одна тонкость на будущее: у -p есть режим --bare, который пропускает загрузку хуков, MCP-серверов, скиллов и CLAUDE.md и потому стартует быстрее. В нём Claude Code не читает сохранённый вход вообще — авторизоваться придётся через ANTHROPIC_API_KEY.
Сколько это стоит
Расходов два, и они не связаны между собой.
Доступ к модели
Подписка Pro — 20 $ в месяц, Max — от 100 $. Внутри подписки расход ограничен не деньгами, а окнами: скользящим пятичасовым и недельным. Упёрлись — Claude Code скажет, когда окно обновится. Альтернатива — оплата по токенам через Claude Console; для ориентира, в корпоративных внедрениях средний расход держится около 13 $ на разработчика в активный день работы.
Сервер
Тариф на 2 ядра и 4 ГБ памяти в европейском дата-центре стоит примерно от 800 до 1700 ₽ в месяц (цены на август 2026) — разброс зависит скорее от провайдера, чем от характеристик. Диска на 40–60 ГБ хватает: сам Claude Code занимает 240 МБ, остальное уйдёт под проект и зависимости.
Отдельная строка расхода, о которой узнают не сразу, — длинные разговоры. Claude Code отправляет всю переписку с каждым запросом, поэтому сессия, открытая с утра, к вечеру расходует лимит на любой мелочи. Команда /usage честно показывает, на что ушло, и подсвечивает поведение, которое съело больше десятой доли расхода.
Частые проблемы
bash: claude: command not found сразу после установки
Установка прошла, но ~/.local/bin не попал в PATH текущей сессии. Сначала просто перезайдите по SSH — на Ubuntu этого обычно достаточно. Если не помогло, проверьте, видит ли оболочка папку:
echo $PATH | tr ':' '\n' | grep -Fx "$HOME/.local/bin"Пусто — добавьте строку export PATH="$HOME/.local/bin:$PATH" в ~/.bashrc. Проверить, что бинарник вообще на месте, можно напрямую: ~/.local/bin/claude --version.
Установка обрывается словом Killed и кодом 137
Классика маленьких VPS: установщику не хватило памяти, и его убил OOM-killer. Сообщение так и говорит — нужно примерно 512 МБ свободной памяти. Сделайте своп из первого шага и запустите установку заново; перед этим можно освободить память, остановив тяжёлые сервисы. Смотреть, что происходит, удобно через free -h.
App unavailable in region или 403 при скачивании
Дальше установка не пойдёт: Claude Code недоступен из страны, где стоит сервер. Проверить, добирается ли машина до сервера загрузок:
curl -sI https://downloads.claude.ai/claude-code-releases/latestОтвет 403 означает либо необслуживаемую локацию, либо фильтр на пути (корпоративный прокси, блокировка провайдера). Первое лечится только сменой локации сервера.
OAuth error: Invalid code. Please make sure the full code was copied
Код авторизации либо протух, либо скопировался не целиком. Повторите claude auth login и пройдите шаги быстрее, а код копируйте выделением всей строки, а не по частям. Если ссылка в терминале переносится на несколько строк и мешает копировать, разверните окно терминала пошире перед запуском команды.
This organization has been disabled при живой подписке
В окружении лежит переменная ANTHROPIC_API_KEY — вероятно, от старого проекта. Она приоритетнее входа по подписке, и Claude Code честно пытается работать по чужому ключу. Уберите её:
unset ANTHROPIC_API_KEY
grep -n ANTHROPIC_API_KEY ~/.bashrc ~/.profile 2>/dev/nullЕсли grep что-то нашёл — удалите строку, иначе переменная вернётся при следующем входе. Проверить, какой способ авторизации активен сейчас, можно командой /status в сессии.
В cron агент отвечает Not logged in · Please run /login
Задание запускается не от того пользователя, у которого выполнен вход. Учётные данные лежат в домашней папке (~/.claude/.credentials.json), поэтому crontab нужно редактировать от dev, а не через sudo crontab -e — последний правит расписание пользователя root, у которого никакого входа нет.
Коротко: порядок действий
- VPS с Ubuntu 22.04 или 24.04, 4 ГБ памяти, локация — в стране, которую Anthropic обслуживает
- Пользователь
devс правомsudo, файрвол только на 22 порт, своп-файл на 2 ГБ curl -fsSL https://claude.ai/install.sh | bashиз домашней папки, затем перезайти по SSHclaude --versionиclaude doctor— убедиться, что всё на местеclaude auth login: открыть ссылку в браузере на своей машине, вставить код обратно в терминалgit cloneпроекта, первый запускclaudeв его папке, принять диалог доверияtmux new -s claudeи запускать агента только внутри tmux; проверить, что задача переживает обрыв SSHclaude --remote-control, если нужен доступ с телефона; QR-код — в панели индикатора/rc activebubblewrapиsocat, профиль AppArmor на Ubuntu 24.04, включить песочницу через/sandbox- Не хранить в этой учётке боевые ключи и не выключать подтверждения флагом
--dangerously-skip-permissions - Регулярные задачи — через
claude -pс явным--allowedToolsи полным путём к бинарнику в cron
Claude Code работает только с серверов в странах, которые обслуживает Anthropic. Собрали тарифы в немецких дата-центрах — с ценами, локациями и характеристиками
VPS в Германии 2026 →