Удалённая разработка на VPS: VS Code Remote-SSH, Cursor и JetBrains Gateway
Удалённая разработка на VPS через VS Code Remote-SSH, Cursor и JetBrains Gateway: подготовка сервера, ресурсы, Dev Containers, code-server и разбор типичных сбоев.
Интерфейс остаётся на вашем компьютере, а проект, терминал, языковые серверы и сборка работают на VPS. Ниже — устройство каждого инструмента, реальные требования к ресурсам и частые сбои. Сверено с документацией и исходным кодом, актуально на сентябрь 2026 года: VS Code 1.139 и Remote-SSH 0.128, Cursor 3.22, JetBrains 2026.2, code-server 4.139.
Что понадобится
- VPS на Ubuntu 24.04 — её официально поддерживают все три инструмента; подойдут Ubuntu 22.04 и Debian 12. Системы с glibc ниже 2.28 — Ubuntu 18.04, Debian 9, CentOS 7 — официально уже не поддерживаются. Ядра и память — в разделе «Сколько ресурсов нужно».
- Вход по SSH-ключу — см. «Консоль VNC и первое подключение» и «Усиление SSH».
- Локально — клиент OpenSSH (в macOS, Linux и Windows 10/11 он встроен) и VS Code, Cursor или платная IDE JetBrains: в бесплатных IntelliJ IDEA и PyCharm удалённой разработки нет.
- Для code-server — домен, направленный на сервер, см. «Как привязать домен к серверу».
Шаг 1. Оцените, что даёт сервер и чем за это платить
Что выигрываете:
- Ядра и NVMe.
npm install,cargo buildи индексация упираются в процессор и диск. Ноутбук не греется и может быть слабым. - Окружение как в продакшене. Тот же Linux, те же пакеты, Docker без Docker Desktop и его виртуальной машины.
- Быстрые загрузки.
git clone,docker pullи зависимости идут по каналу дата-центра. На ForestsNet Cloud входящий трафик не тарифицируется — в пакет идёт только исходящий.
Чем платите:
- Задержкой. В VS Code и Cursor редактор локальный, по сети ходят подсказки, переход к определению и терминал. В JetBrains часть подсказок при вводе считает бэкенд, поэтому официально нужны задержка до 200 мс и канал от 20 Мбит/с. Замерьте
pingиmtrдо тестовых адресов Looking Glass в Нидерландах и Германии. - Зависимостью от сети. Короткие обрывы переживаются (Шаг 4), а без связи работы нет.
- Ещё одним сервером. Его надо обновлять и защищать.
- Не всё переносится. Эмуляторы Android и iOS, GPU и графические приложения остаются локально.
Шаг 2. Подготовьте сервер
Заведите пользователя без root
Сервер IDE и расширения работают от имени того, кто подключился. Под root уязвимое расширение или вредоносный postinstall в npm-пакете получают весь сервер. Выполните под root:
adduser dev
usermod -aG sudo dev
install -d -m 700 -o dev -g dev /home/dev/.ssh
install -m 600 -o dev -g dev /root/.ssh/authorized_keys /home/dev/.ssh/authorized_keysПроверьте вход ssh dev@IP-сервера и закройте вход под root — см. «Усиление SSH».
Добавьте swap
Языковые серверы и сборка расходуют память пиками. Без swap на 2–4 ГБ в такой момент OOM killer убивает самый крупный процесс — обычно сервер IDE. Со swap вместо падения будет замедление:
sudo dd if=/dev/zero of=/swapfile bs=1M count=4096 status=progress
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstabdd, а не fallocate: по документации util-linux это самый переносимый способ получить файл без «дыр». Если swap занят постоянно, памяти мало — см. «Высокая нагрузка на сервер».
Поднимите лимит inotify
VS Code и JetBrains следят за файлами через inotify, одно наблюдение на каталог. С ядра 5.11 лимит по умолчанию рассчитан так, чтобы наблюдения заняли не больше 1% RAM, поэтому на небольшом VPS он невелик. Монорепозиторий или проект с .venv в него упирается: VS Code пишет «unable to watch for file changes in this large workspace», JetBrains переходит на медленное сканирование каталогов.
cat /proc/sys/fs/inotify/max_user_watches
echo 'fs.inotify.max_user_watches=524288' | sudo tee /etc/sysctl.d/60-inotify.conf
sudo sysctl --systemПамять ядра, около 1 КБ, тратится только на занятые наблюдения. Крупные каталоги исключите в files.watcherExclude — node_modules VS Code пропускает сам.
Не запрещайте проброс портов в sshd
Все три IDE работают через SSH-туннели. Если по совету чек-листа стоит AllowTcpForwarding no или DisableForwarding yes, подключение упадёт с open failed: administratively prohibited. При этом man sshd_config прямо говорит: пока у пользователя есть shell, такой запрет безопасности не добавляет. Проверьте — нужны allowtcpforwarding yes и disableforwarding no:
sudo sshd -T | grep -Ei 'allowtcpforwarding|disableforwarding'Шаг 3. Настройте SSH на своём компьютере
VS Code, Cursor и Toolbox App вызывают системный OpenSSH и читают ~/.ssh/config (в Windows — %USERPROFILE%\.ssh\config):
Host devbox
HostName 203.0.113.10
User dev
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
ServerAliveInterval 15
ServerAliveCountMax 3ServerAliveInterval 15иServerAliveCountMax 3— проверка сервера раз в 15 секунд. После трёх пропущенных ответов, примерно через 45 секунд, соединение закрывается, и IDE переподключается. По умолчанию проверок нет, и после сна ноутбукаsshможет долго висеть на мёртвом соединении.IdentitiesOnly yes— предлагать серверу только этот ключ. Иначе при пяти-шести ключах в агенте сервер оборвёт вход сToo many authentication failures: по умолчаниюMaxAuthTriesравен 6.
Проверьте ssh devbox в терминале: что не работает там, не заработает и в IDE.
Мультиплексирование. ControlMaster пускает все сессии через одно соединение, и пароль или второй фактор спрашиваются один раз. Документация VS Code советует его, если вход не по ключу:
Host devbox
ControlMaster auto
ControlPath ~/.ssh/cm-%C
ControlPersist 10mВ Windows OpenSSH он не работает. Если основное соединение умерло при смене сети, новые сессии ждут, пока его не закроет ServerAliveInterval; ускорить можно командой ssh -O exit devbox. При входе по ключу мультиплексирование необязательно: VS Code и так держит одно соединение на все окна.
Шаг 4. Подключитесь из VS Code
- Установите расширение Remote - SSH от Microsoft (
ms-vscode-remote.remote-ssh). - Нажмите
F1→ Remote-SSH: Connect to Host... →devbox, платформа — Linux. - File → Open Folder → каталог проекта, например
/home/dev/app.
Что ставится на сервер
Скрипт установки качает на сервер CLI code и сервер под точный коммит вашего VS Code: в 1.139 это архив на 215 МБ и около 620 МБ после распаковки, заметная часть — встроенный Copilot. CLI ложится в ~/.vscode-server/code-<коммит>, сервер — в ~/.vscode-server/cli/servers/Stable-<коммит>/server. Сервер слушает случайный порт на 127.0.0.1 и пускает только через SSH-туннель по токену, открывать порты не нужно.
С марта 2026 года VS Code обновляется каждую неделю, и каждое обновление ставит на сервер новую копию. CLI хранит пять последних, так что каталог дорастает до 3–4 ГБ. Очистить его можно командой Remote-SSH: Uninstall VS Code Server from Host....
Расширения
Темы и раскладки работают локально, а языковые серверы, линтеры, отладчики и Git — на сервере. Ставить их нужно туда, кнопкой Install in SSH: devbox; список для каждого нового хоста задаётся в remote.SSH.defaultExtensions. Значит, и память они съедают на сервере: у одного tsserver потолок по умолчанию — 3 ГБ (js/ts.tsserver.maxMemory).
Проброс портов
Запустили npm run dev на порту 5173 — VS Code заметит слушающий порт и пробросит его, откройте у себя http://localhost:5173. Это делает настройка remote.autoForwardPorts, по умолчанию она включена; порты видны на вкладке Ports. Постоянный проброс задайте в ~/.ssh/config:
Host devbox
LocalForward 127.0.0.1:5432 127.0.0.1:5432Проброшенный порт слушает только 127.0.0.1 вашего компьютера. Сервисы на сервере держите на 127.0.0.1 и не открывайте их порты в файрволе.
Если сервер не может скачать VS Code Server
По умолчанию VPS сам скачивает VS Code Server с update.code.visualstudio.com и vscode.download.prss.microsoft.com, а при неудаче VS Code качает архив на ваш компьютер и копирует по scp. Если исходящий HTTPS с сервера закрыт, включите такую загрузку сразу — в локальном settings.json:
"remote.SSH.localServerDownload": "always"Тогда каждое обновление — около 215 МБ через ваш канал на отдачу.
Если интернета нет и на вашем компьютере, разложите файлы вручную. Коммит — вторая строка вывода code --version. На машине с интернетом:
COMMIT=04c0d99f4fb0d8afe6ce4f0c58e31e183ac3e4b1
curl -L -o vscode-cli.tar.gz "https://update.code.visualstudio.com/commit:$COMMIT/cli-alpine-x64/stable"
curl -L -o vscode-server.tar.gz "https://update.code.visualstudio.com/commit:$COMMIT/server-linux-x64/stable"
scp vscode-cli.tar.gz vscode-server.tar.gz devbox:На сервере:
COMMIT=04c0d99f4fb0d8afe6ce4f0c58e31e183ac3e4b1
mkdir -p ~/.vscode-server/cli/servers/Stable-$COMMIT/server
tar -xzf vscode-server.tar.gz -C ~/.vscode-server/cli/servers/Stable-$COMMIT/server --strip-components=1
tar -xzf vscode-cli.tar.gz -C ~/.vscode-server
mv ~/.vscode-server/code ~/.vscode-server/code-$COMMITРасширения — через Extensions: Install from VSIX....
Обрывы и долгие процессы
VS Code переподключается сам, до восьми попыток, а сервер ждёт клиента три часа — файлы и терминалы возвращаются. Но терминал живёт, пока жив сервер. После закрытия всех окон сервер завершается через 5 минут, после обновления VS Code вы попадёте на новый сервер, а если сервер убьёт OOM killer, с ним завершится всё, что было запущено в терминале. Долгие сборки и миграции запускайте в tmux:
sudo apt install -y tmux
tmux new -s work
tmux attach -t workОтсоединиться, не останавливая процессы: Ctrl+B, затем D.
Шаг 5. Подключитесь из Cursor
Cursor — форк VS Code, но Remote-расширения Microsoft по лицензии разрешено использовать только с Visual Studio Code. С мая 2025 года у Cursor свои Remote SSH, Dev Containers и WSL от Anysphere, а расширения ставятся из Open VSX. Подключение то же: Remote-SSH: Connect to Host... → devbox. Отличия:
- Сервер ставится в
~/.cursor-serverи качается сdownloads.cursor.com; настройкаremote.SSH.localServerDownloadработает так же. - С версии 3.10 нужна glibc 2.28+. Сборку для glibc 2.17–2.27 Cursor выбирает сам, но только если у сервера есть интернет.
- С сентября 2026 года агент в окнах Remote SSH работает на сервере и ходит в API Cursor оттуда. Нет доступа — трафик автоматически идёт через ваш компьютер, принудительно это включает
"cursorAgentHost.remoteInferenceRoute": "always". - Установка идёт через
bash --login: вывод в~/.profileили~/.bashrc, автозапуск tmux и вопросы при входе её ломают. Мешают иnoexecна/run/user/<uid>, и зависший старый сервер — завершите его:pkill -f cursor-server.
Шаг 6. Подключитесь из JetBrains: Toolbox App или Gateway
На сервере работает IDE без интерфейса — бэкенд: индексирует проект, анализирует код, запускает сборку. У вас — тонкий JetBrains Client, связь идёт через SSH-туннель, а поверх него ещё TLS 1.3. Функция есть только в платных IDE: IntelliJ IDEA Ultimate, PyCharm Pro и других. Как подключиться:
- Toolbox App — путь, который рекомендует JetBrains. С версии 2.6 (апрель 2025 года) он работает через системный OpenSSH, так что действуют
~/.ssh/config, ProxyJump и второй фактор. - Экран приветствия IDE → Remote Development → SSH → New Connection.
- JetBrains Gateway объявлен устаревшим: удалённую разработку переносят в Toolbox App, дату окончания поддержки JetBrains не называет.
Бэкенд из Gateway и IDE ставится в ~/.cache/JetBrains/RemoteDev/dist, сервер качает его с download.jetbrains.com. Без исходящего доступа его можно загрузить с клиента — тогда на сервере нужно свободное место в четыре размера архива. Грабли:
- Порт и проброс. Бэкенду нужен свободный порт и
AllowTcpForwarding, поэтому shared-хостинг не подходит, а VPS подходит. - Бэкенд — это JVM. При нехватке памяти он не падает, а зависает. Поднимайте
-Xmxв.vmoptionsбэкенда, если хватает физической RAM, и держите swap — JetBrains рекомендует его даже в облаке. - Плагины чувствительнее к задержке. Плагины без разделения на клиентскую и серверную части рисуют интерфейс на сервере — на медленном канале это заметно сразу.
- Шумный
.bashrcломает и развёртывание бэкенда.
Fleet закрыт в декабре 2025 года, Code With Me сворачивают после версии 2026.1. Удалённой разработки это не касается.
Шаг 7. Запустите Dev Containers на сервере
Dev Containers описывают окружение в .devcontainer/devcontainer.json: образ, расширения, порты, команды после создания. Проще всего запускать их поверх Remote-SSH, локальный Docker не нужен:
- Установите Docker на сервер — см. «Docker и Docker Compose».
- Подключитесь через Remote-SSH и откройте папку проекта.
F1→ Dev Containers: Reopen in Container.
В Cursor то же делает расширение от Anysphere, в JetBrains — Dev Containers с Docker по SSH. Вариант с DOCKER_HOST=ssh://dev@devbox или docker context сложнее: нужен локальный Docker CLI, а bind-монтирования придётся переписать на пути сервера — локальную папку Docker в удалённый контейнер не смонтирует. Что учесть:
- Группа
docker— это root. Черезdocker run -v /:/hostеё участник меняет любой файл сервера. Документация VS Code сама советуетusermod -aG docker $USER; на личном сервере это допустимо, строже — rootless Docker. - Порты — через
forwardPorts, они идут через туннель редактора.appPortи-pвrunArgsпубликуют порт средствами Docker в обход ufw, прямо в интернет. Если публиковать нужно — только на локальный адрес:-p 127.0.0.1:5432:5432. - Никакого
DOCKER_HOST=tcp://без TLS. Открытый API Docker даёт root любому. - VS Code сам пробрасывает в контейнер ваш ssh-agent и учётные данные Git. Не открывайте в контейнере чужой репозиторий, пока в агенте ключи от продакшена.
Шаг 8. Откройте code-server в браузере
code-server от Coder — это VS Code в браузере, для планшета или чужого компьютера. Версии идут вслед за VS Code: 4.139.1 собрана на Code 1.139.1. Установка, первая команда только показывает план:
curl -fsSL https://code-server.dev/install.sh | sh -s -- --dry-run
curl -fsSL https://code-server.dev/install.sh | sh
sudo systemctl enable --now code-server@$USERКонфиг — ~/.config/code-server/config.yaml. Оставьте адрес 127.0.0.1 и вход по паролю, пароль можно хранить хешем argon2 (echo -n 'пароль' | npx argon2-cli -e):
bind-addr: 127.0.0.1:8080
auth: password
hashed-password: "$argon2i$v=19$m=4096,t=3,p=1$..."
cert: falseПосле правки — sudo systemctl restart code-server@$USER. Наружу — только через свой домен с TLS. Проще всего Caddy, он сам получит сертификат Let's Encrypt:
code.example.com {
reverse_proxy 127.0.0.1:8080
}Подробнее — «Caddy: автоматический HTTPS» и «Nginx: установка и первый сайт». В Nginx передавайте заголовки Host, Upgrade и Connection: без WebSocket редактор не работает. В файрволе откройте только 80 и 443 — см. «Файрвол ufw: порты».
Расширения code-server берёт из Open VSX: Pylance, C/C++, Live Share и Remote-расширений Microsoft там нет. openvscode-server от Gitpod для нового сервера не берите: последний релиз вышел в феврале 2026 года на VS Code 1.109, а Docker-образ слушает 0.0.0.0 без токена.
Сколько ресурсов нужно
Официальные минимумы — это запуск самого инструмента, а память съедают языковые серверы и проект. Ориентиры:
- VS Code и Cursor. Microsoft требует от 1 ГБ RAM и советует 2 ГБ и 2 ядра. На практике: 2 vCPU и 4 ГБ для типичного веб-проекта или Python, 4 vCPU и 8 ГБ для монорепозитория на TypeScript или Rust.
- JetBrains. Официальный минимум — 4 vCPU, 8 ГБ RAM (3 ГБ свободны под IDE) и 10 ГБ диска, причём частота процессора важнее числа ядер. На форуме поддержки описан бэкенд IntelliJ IDEA 2025.3: около 3 ГБ в простое, до 8 ГБ на пиках.
- Dev Containers — плюс все сервисы из
devcontainer.json. Реальное потребление покажетdocker stats, место под образы —docker system df. - code-server — по документации от 1 ГБ и 2 ядер, на деле как VS Code.
- Диск. До 3–4 ГБ на
~/.vscode-server, около 10 ГБ на бэкенд JetBrains, плюс образы Docker. NVMe ускоряет всё, что работает с тысячами мелких файлов: индексацию,npm install, сборку.
Swap на 2–4 ГБ ставьте всегда. Кто ест память, покажут free -h и ps aux --sort=-rss | head. Какой сервер взять под остальные задачи разработчика — в обзоре «VPS для разработчиков».
Безопасность
- Agent forwarding для IDE не нужен, только для
git pushпо SSH с сервера. Remote-SSH сам его не включает: настройкаremote.SSH.enableAgentForwardingлишь уважаетForwardAgentиз~/.ssh/config. Документация VS Code показываетForwardAgent yesдляHost *— так не делайте. Пока вы подключены, root на сервере или вредоносное расширение могут входить с вашими ключами на GitHub и другие серверы: ключи не утекут, но ими воспользуются. Лучше отдельный ключ на сервере с доступом к одному репозиторию — см. «Деплой из Git». Если форвардинг нужен, включайте его только дляHost devbox, аssh-add -h(OpenSSH 8.9+) ограничит, куда ходит пересланный ключ. - Наружу — только SSH, плюс 80 и 443 для code-server. Опубликованные порты Docker обходят ufw, поэтому проверяйте, что реально слушает сервер:
sudo ss -tlnp. Правила — в статье «Файрвол ufw: порты», защита от перебора паролей — в «Fail2ban: защита от брутфорса». - Расширения — это код с вашими правами. Ставьте их от известных издателей и не храните на сервере секреты продакшена.
Диагностика
Начинайте с журнала: F1 → Remote-SSH: Show Log в VS Code и Cursor, ssh -v devbox в терминале. Если не пускает и терминал — см. «Не могу подключиться по SSH».
- «Could not establish connection to "devbox"». Причина — в строках журнала выше. Если
ssh devboxработает, выполните Remote-SSH: Kill VS Code Server on Host... — сервер поставится заново. Проверьте место (df -h ~) и журнал~/.vscode-server/cli/servers/*/log.txt. open failed: administratively prohibited. Запрещён проброс TCP — см. Шаг 2.- «The remote host may not meet VS Code Server's prerequisites for glibc and libstdc++». glibc ниже 2.28, проверка —
ldd --version. Обход через sysroot документирован, но проще переустановить ОС — см. «Переустановка ОС и выбор шаблона». wget download failedилиcurl download failed. VS Code Server не скачался на VPS. Проверьте с негоcurl -sI https://update.code.visualstudio.com: DNS, исходящий 443, прокси. Обход —localServerDownloadиз Шага 4; у Cursor то же сdownloads.cursor.com.- IDE тормозит, окно переподключается, процессы пропадают. Скорее всего, OOM:
sudo dmesg -T | grep -Ei 'out of memory|killed process'. Добавьте swap или памяти, отключите тяжёлые расширения; в JetBrains поднимите-Xmx. С лета 2026 года в трекере VS Code открыты отчёты об утечке памяти с Copilot Chat в сессиях Remote-SSH, вплоть до гигабайтов у удалённого процесса расширений. Если память тает на глазах, отключите Copilot Chat и сравните. - «Unable to watch for file changes in this large workspace». Кончился лимит inotify — см. Шаг 2.
- Отваливается при смене сети или после сна. Добавьте
ServerAliveInterval(Шаг 3), зависшее основное соединение закройтеssh -O exit devbox, долгие процессы держите в tmux.
Источники
- VS Code: Remote Development using SSH, FAQ, Linux prerequisites, Tips and Tricks, лимит inotify, Develop on a remote Docker host, Sharing Git credentials
- Исходный код VS Code: check-requirements-linux.sh, download_cache.rs, ipc.net.ts, serverLifetimeService.ts; issues #324809 и #246885
- Cursor: свои расширения Remote, агент на удалённом хосте, сборка для старой glibc, сбой установки из-за оболочки
- JetBrains: системные требования, prerequisites, требования Toolbox App, troubleshooting, security model, переход с Gateway на Toolbox, Split Mode, лимит inotify, лицензии, Toolbox App 2.6, Fleet, Code With Me, память бэкенда
- code-server: requirements, guide, FAQ, CVE-2025-47269; openvscode-server — релизы
- Docker и Dev Containers: Packet filtering and firewalls, Port publishing, Docker daemon attack surface, Rootless mode, devcontainer.json reference
- OpenSSH и Linux: ssh_config(5), sshd_config(5), ssh-add(1), ограничение ключей в агенте, inotify в ядре, swapon(8)