VPSРейтинг
AI12 августа 2026 · 16 мин

MCP-сервер на VPS: подключаем LLM к своим сервисам

MCP — стандарт, через который нейросеть получает доступ к вашим файлам, базам и API. Разбираемся, как он устроен, и поднимаем свой MCP-сервер на Ubuntu: Docker, домен с HTTPS, вход по токену и подключение из Claude Code и Open WebUI.

Что такое MCP и какую проблему он решает

Языковая модель сама по себе умеет только читать текст и писать текст. Она не видит ваши файлы, не знает, что лежит в базе, и не может создать задачу в трекере. Чтобы это изменить, нужен посредник — код, который объясняет модели «вот доступные действия» и выполняет их, когда модель попросит.

До 2025 года такого посредника каждый писал сам. Если у вас 5 ИИ-клиентов и 10 сервисов, которые нужно к ним подключить, получается 50 отдельных интеграций — и все ломаются независимо друг от друга. Классическая задача «N×M».

MCP (Model Context Protocol) превращает 50 интеграций в 15. Сервис один раз поднимает у себя MCP-сервер и объявляет список инструментов в стандартном формате. Клиент один раз учится читать этот формат. Дальше любой клиент работает с любым сервером — так же, как любая USB-C зарядка подходит к любому телефону с этим разъёмом.

Три вещи, которые сервер может отдать клиенту

  • Инструменты (tools) — действия, которые модель может выполнить: прочитать файл, сделать запрос в базу, отправить сообщение. Самая используемая часть протокола.
  • Ресурсы (resources) — данные для чтения: содержимое файла, запись из базы, страница документации.
  • Промпты (prompts) — заготовки запросов, которые пользователь может выбрать в интерфейсе клиента.

Чем это отличается от плагинов и function calling. Function calling — умение модели сказать «вызови функцию X». Оно появилось раньше MCP, но описание функций и код их выполнения вы держите внутри своего приложения. Плагины — то же самое в формате конкретной платформы, и работают только на ней. MCP стоит уровнем выше: это протокол поверх function calling, который описывает, как инструменты объявляются и вызываются по сети. Один написанный MCP-сервер работает со всеми клиентами и не привязан ни к модели, ни к вендору.

Зачем для этого отдельный сервер

Большинство MCP-серверов из примеров в документации запускаются прямо на компьютере пользователя: клиент стартует программу и общается с ней через стандартный ввод-вывод. Никакой сети, никаких портов. Для одного человека за одним ноутбуком этого достаточно.

Отдельный сервер нужен, когда:

  • инструменты нужны с разных устройств — с рабочего ноутбука, домашнего компьютера и телефона, без установки чего-либо на каждом;
  • работа должна идти круглосуточно: сервер помнит контекст и остаётся доступен, когда ноутбук закрыт;
  • инструментами пользуется команда, и нужна одна точка входа с общими правами и логами;
  • сервис, к которому подключается модель, и так живёт на VPS — база, репозиторий, мониторинг. Держать MCP-сервер рядом с данными быстрее и безопаснее.

Два транспорта: stdio и Streamable HTTP

Транспорт — это способ доставки сообщений. Сам протокол от него не зависит: команды одинаковые, меняется только «труба». В актуальной спецификации 2026-07-28 их ровно два.

ТранспортКак работаетКогда выбирать
stdioКлиент сам запускает программу-сервер и пишет ей в стандартный вводВсё на одной машине. Портов не открывает, посторонним недоступен
Streamable HTTPСервер слушает один адрес вида /mcp, клиент шлёт туда обычные POST-запросыНаш случай. Сервер на VPS, клиенты подключаются по сети
HTTP+SSEДва адреса: отдельно для отправки, отдельно для получения ответовУстарел с марта 2025 года. Для нового не использовать

Старый транспорт HTTP+SSE держал постоянно открытое соединение, которое разрывалось при любом сбое сети и плохо переживало обычные обратные прокси. Streamable HTTP работает как привычный веб-сервис: один адрес, обычные запросы, ответ приходит либо целиком, либо потоком, если задача долгая. Именно поэтому его легко спрятать за Nginx.

Спецификация меняется, и это нормально

Меньше чем за два года MCP пережил пять редакций. Последняя, 2026-07-28, заметно упростила Streamable HTTP: убрала сессии и отдельный поток для уведомлений. Клиенты умеют определять версию собеседника и откатываться на старое поведение, так что смешанные пары «новый клиент — старый сервер» работают. Практический вывод для вас: фиксируйте версии образов и пакетов, а не ставьте всё по тегу latest. Ниже версии зафиксированы везде.

Что мы построим

Официальные MCP-серверы — filesystem, memory, git и остальные из репозитория проекта — умеют только stdio: они рассчитаны на запуск рядом с клиентом. Чтобы вынести такой сервер на VPS, между ним и сетью ставят мост: он принимает HTTP-запросы и переводит их в стандартный ввод-вывод. Мы используем Supergateway — маленький мост в одном контейнере, которому не нужно ничего, кроме Docker. Сразу оговорка: это тонкая прослойка без собственной логики, и обновляется она редко — версия 3.4.3 вышла в октябре 2025. Для перевода stdio в HTTP этого достаточно, а проверку доступа мы намеренно возлагаем не на неё, а на Nginx.

Схема: что за чем стоит
Claude Code / Open WebUI / другой клиент
        │  HTTPS + токен
        ▼
   Nginx (порт 443, сертификат Let's Encrypt)
        │  проверяет токен, проксирует на localhost
        ▼
   Supergateway в Docker (127.0.0.1:8001)
        │  переводит HTTP в stdio
        ▼
   MCP-сервер (видит только папку /opt/mcp/data)

В качестве первого MCP-сервера возьмём официальный filesystem — он даёт модели чтение и запись файлов в одной разрешённой папке. Это самый наглядный пример: сразу видно, что модель получила новые возможности, и сразу понятно, где проходит граница прав.

Почему не Docker MCP Gateway

У Docker есть свой официальный шлюз с каталогом готовых серверов. Он хорош, но рассчитан прежде всего на Docker Desktop, а на голом Docker Engine ставится отдельным бинарником-плагином. И у него была показательная уязвимость: в режиме HTTP до версии 0.28.0 шлюз не проверял заголовок Origin, из-за чего обычная веб-страница в браузере жертвы могла достучаться до всех подключённых MCP-серверов (CVE-2025-64443). Схема из этой статьи проще, состоит из стандартных кирпичей и с самого начала закрыта токеном.

Шаг 1. Подготовка сервера

Подойдёт любой VPS с Ubuntu 22.04 или новее и 1 ГБ оперативной памяти. Ставим Docker с официального скрипта — версия из репозитория Ubuntu старая и не содержит нужного плагина Compose.

Установка Docker
sudo apt update && sudo apt upgrade -y
curl -fsSL https://get.docker.com | sudo sh
sudo docker compose version

Последняя команда должна напечатать версию Compose — значит, всё встало. Теперь создаём рабочие папки:

Папки проекта
sudo mkdir -p /opt/mcp/data
cd /opt/mcp

/opt/mcp/data — единственная папка, которую увидит MCP-сервер. Всё остальное на сервере для него не существует.

Шаг 2. Запускаем MCP-сервер

Создайте файл /opt/mcp/docker-compose.yml — папка принадлежит root, поэтому редактор нужно открыть через sudo: sudo nano /opt/mcp/docker-compose.yml.

/opt/mcp/docker-compose.yml
services:
  mcp-filesystem:
    image: supercorp/supergateway:3.4.3
    container_name: mcp-filesystem
    restart: unless-stopped
    command: >
      --stdio "npx -y @modelcontextprotocol/server-filesystem@2026.7.10 /data"
      --outputTransport streamableHttp
      --port 8000
      --healthEndpoint /healthz
    volumes:
      - ./data:/data
    ports:
      - "127.0.0.1:8001:8000"

Что здесь важно:

  • --stdio "..." — команда запуска самого MCP-сервера. Supergateway поднимет её и будет переводить HTTP в стандартный ввод-вывод. Версия пакета зафиксирована через @2026.7.10.
  • /data в конце команды — единственная папка, к которой разрешён доступ. Она же подключена как том из ./data.
  • --outputTransport streamableHttp — тот самый актуальный транспорт. Адрес внутри контейнера получится /mcp.
  • 127.0.0.1:8001:8000 — порт слушает только сам сервер. Без этой привязки Docker открыл бы порт всему интернету в обход ufw. Наружу сервис отдаст только Nginx.
Запуск
cd /opt/mcp
sudo docker compose up -d

При первом запуске контейнер скачивает пакет MCP-сервера — это занимает 10–30 секунд. Проверяем, что мост жив:

Проверка
curl http://127.0.0.1:8001/healthz

Должно ответить ok. Если ответа нет — смотрите sudo docker compose logs mcp-filesystem.

Шаг 3. Проверяем, что сервер отдаёт инструменты

Проверить MCP-сервер можно обычным curl — под капотом это JSON-RPC поверх HTTP. Спросим список инструментов:

Список инструментов
curl -s -X POST http://127.0.0.1:8001/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

В ответ придёт длинный JSON со списком: read_text_file, write_file, list_directory, search_files и другие. Заголовок Accept обязателен — клиент по спецификации должен объявлять, что понимает оба формата ответа.

Теперь по-настоящему вызовем инструмент. Сначала положим в папку файл:

Тестовый файл и вызов инструмента
echo "Проверка MCP" | sudo tee /opt/mcp/data/note.txt

curl -s -X POST http://127.0.0.1:8001/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call",
       "params":{"name":"read_text_file","arguments":{"path":"/data/note.txt"}}}'

Ответ содержит "text":"Проверка MCP\n". Сервер работает. Обратите внимание на путь: внутри контейнера папка называется /data, а не /opt/mcp/data — модель тоже будет видеть её именно так.

Шаг 4. Домен, HTTPS и вход по токену

Сейчас сервер доступен только с самого VPS. Чтобы подключаться снаружи, нужны три вещи: домен, сертификат и проверка на входе. Без последней любой, кто узнает адрес, получит полный доступ к вашим файлам — MCP-сервер сам по себе никого не спрашивает.

Направьте A-запись поддомена (например mcp.example.com) на IP сервера — без этого сертификат не выпустится. Ставим Nginx:

Установка
sudo apt install -y nginx certbot python3-certbot-nginx
sudo ufw allow 'Nginx Full'

Придумайте токен — это пароль для доступа к серверу. Сохраните вывод, он понадобится в клиенте:

Генерация токена
openssl rand -hex 32

Создайте /etc/nginx/sites-available/mcp, подставив свой домен и токен:

/etc/nginx/sites-available/mcp
map $http_authorization $mcp_ok {
    default                        "0";
    "Bearer ВАШ_ТОКЕН_ИЗ_OPENSSL"  "1";
}

server {
    listen 80;
    server_name mcp.example.com;

    location = /fs {
        if ($mcp_ok = "0") { return 401; }

        proxy_pass http://127.0.0.1:8001/mcp;
        proxy_http_version 1.1;
        proxy_set_header Host   $host;
        proxy_set_header Origin "";

        # Потоковые ответы: не копить в буфере и не рвать по таймауту
        proxy_buffering off;
        proxy_cache off;
        proxy_read_timeout 3600s;
    }
}

Разберём непривычные строки:

  • map сравнивает присланный заголовок Authorization с вашим токеном. Не совпало — переменная равна нулю, и запрос получает 401 ещё до контейнера. Блок map стоит вне server — это обязательно, иначе Nginx не запустится.
  • location = /fs — знак равенства означает точное совпадение адреса. Снаружи открыт ровно один путь, а не всё дерево. Внутренний /mcp в proxy_pass подставляется автоматически, в клиенте его писать не нужно.
  • proxy_set_header Origin "" — убираем заголовок, который шлёт браузер. MCP-клиенты его не отправляют, так что на работу это не влияет, а вот запросу со случайной веб-страницы лишний повод выглядеть доверенным мы не даём. Настоящая защита здесь — токен.
  • proxy_buffering off и большой proxy_read_timeout нужны для потоковых ответов: по умолчанию Nginx копит ответ в буфере и обрывает соединение через 60 секунд.

Включаем сайт и выпускаем сертификат — certbot сам допишет секцию с HTTPS и редирект с 80-го порта:

Включение и сертификат
sudo ln -s /etc/nginx/sites-available/mcp /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

sudo certbot --nginx -d mcp.example.com

Проверяем защиту снаружи:

Без токена и с токеном
# ожидаем 401
curl -s -o /dev/null -w "%{http_code}\n" -X POST https://mcp.example.com/fs

# ожидаем список инструментов
curl -s -X POST https://mcp.example.com/fs \
  -H "Authorization: Bearer ВАШ_ТОКЕН_ИЗ_OPENSSL" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Если Nginx и certbot настраивать не хочется

MCP-сервер на Streamable HTTP — это обычное веб-приложение, поэтому его можно выложить на PaaS-платформу: вы отдаёте код, платформа собирает контейнер и выдаёт домен с готовым сертификатом. Весь этот шаг с Nginx и certbot тогда отпадает, а токен задаётся переменной окружения. Из русскоязычных платформ так работает Hostim. Ограничение важное: файловая система контейнера пересоздаётся при каждом деплое, поэтому наш пример с доступом к файлам сервера так не поднять — для него нужен VPS. Подходит для серверов, которые ходят в базу или во внешний API.

Шаг 5. Подключаем клиента

Claude Code

Одна команда на вашем рабочем компьютере:

Добавление сервера
claude mcp add --transport http my-files https://mcp.example.com/fs \
  --header "Authorization: Bearer ВАШ_ТОКЕН_ИЗ_OPENSSL"

claude mcp list

claude mcp list покажет статус: ✔ Connected — всё в порядке. Теперь можно просить «положи черновик статьи в файл draft.md» — и файл появится в /opt/mcp/data на сервере.

Open WebUI — полностью локальный вариант с Ollama

Если не хотите отправлять данные во внешние API, поставьте рядом Ollama с Open WebUI. Начиная с версии 0.6.31 Open WebUI понимает MCP нативно — и ровно по Streamable HTTP, который мы настроили.

  1. Откройте Admin Settings → Integrations и нажмите +.
  2. Тип — MCP (Streamable HTTP).
  3. URL — https://mcp.example.com/fs.
  4. Auth — Bearer, в поле ключа вставьте токен (только сам токен, без слова Bearer).
  5. Сохраните.

Два условия, без которых инструменты подключатся, но работать не будут. Первое: модель в Ollama должна уметь вызывать инструменты (tool calling) — в библиотеке Ollama такие модели собраны под фильтром Tools, на август 2026 это, например, qwen3.5, gemma4 и granite4.1. Второе: у Open WebUI должна быть задана переменная WEBUI_SECRET_KEY, иначе после перезапуска контейнера сохранённые ключи доступа перестанут расшифровываться. Добавлять MCP-серверы может только администратор.

Шаг 6. Добавляем второй сервер

Схема масштабируется копированием. Добавим memory — долговременную память: модель складывает туда факты и достаёт их в следующих разговорах. Дописываем в docker-compose.yml:

Добавить в /opt/mcp/docker-compose.yml
  mcp-memory:
    image: supercorp/supergateway:3.4.3
    container_name: mcp-memory
    restart: unless-stopped
    command: >
      --stdio "npx -y @modelcontextprotocol/server-memory@2026.7.4"
      --outputTransport streamableHttp
      --port 8000
      --healthEndpoint /healthz
    environment:
      MEMORY_FILE_PATH: /data/memory.json
    volumes:
      - ./memory:/data
    ports:
      - "127.0.0.1:8002:8000"

Отдельная папка ./memory — чтобы у каждого сервера были свои данные и он не видел чужие:

Создать папку и поднять
sudo mkdir -p /opt/mcp/memory
sudo docker compose up -d

И новый location в конфиге Nginx. После выпуска сертификата в файле стало два блока server: короткий с редиректом на HTTPS и основной с listen 443 ssl. Добавлять нужно в основной, рядом с уже существующим location = /fs:

Добавить в блок server в /etc/nginx/sites-available/mcp
    location = /memory {
        if ($mcp_ok = "0") { return 401; }

        proxy_pass http://127.0.0.1:8002/mcp;
        proxy_http_version 1.1;
        proxy_set_header Host   $host;
        proxy_set_header Origin "";

        proxy_buffering off;
        proxy_cache off;
        proxy_read_timeout 3600s;
    }
Применить
sudo nginx -t && sudo systemctl reload nginx

Правило одно: новый сервис в Compose со своим портом на 127.0.0.1 плюс новый location в Nginx. Остальные официальные серверы подключаются так же — важно только не перепутать язык, на котором сервер написан:

СерверЧто даётКоманда для --stdio
sequential-thinkingПошаговые рассужденияnpx -y @modelcontextprotocol/server-sequential-thinking@2026.7.4
fetchЗагрузка веб-страницuvx --with mcp==1.29.0 mcp-server-fetch@2026.7.10
timeТекущее время и часовые поясаuvx --with mcp==1.29.0 mcp-server-time@2026.7.10

Серверы на Node запускаются через npx и работают на образе supercorp/supergateway:3.4.3. Серверы на Python запускаются через uvx, и им нужен другой образ — supercorp/supergateway:3.4.3-uvx. Зачем у них приписка --with mcp==1.29.0, объясняем в «Частых проблемах».

Отдельный случай — официальный сервер git. Он тоже на Python, но требует установленной программы git, которой в образе нет, и без неё падает с ImportError: Bad git executable. Чтобы его поднять, придётся собрать свой образ с git внутри — это выходит за рамки статьи.

Безопасность: главный раздел этой статьи

MCP-сервер — это не набор данных для чтения, а исполнитель действий. Вы выдаёте модели реальные права на своём сервере. Ошибка в настройке здесь стоит дороже, чем в блоге или файлопомойке, поэтому этот раздел важнее предыдущих.

1. Минимальные права по умолчанию

Давайте серверу ровно то, что нужно для задачи. В нашей схеме контейнер видит одну папку и не имеет доступа к остальной файловой системе — это не случайность, а основной приём. Не подключайте / или домашнюю директорию «чтобы было удобнее»: удобство здесь оплачивается тем, что модель сможет прочитать ваши SSH-ключи. Если серверу нужна база данных — заведите отдельного пользователя БД только с нужными правами, а не postgres.

2. Никогда не выставлять без авторизации

Спецификация не заставляет сервер проверять, кто пришёл, — это задача того, кто его разворачивает. Открытый MCP-сервер находят сканерами так же, как открытые базы. Токен в Nginx из шага 4 — обязательный минимум. Токен передаётся в каждом запросе, поэтому только HTTPS: по обычному HTTP он утечёт целиком при первом же перехвате.

3. Слушать 127.0.0.1, а не 0.0.0.0

В Compose порт привязан к 127.0.0.1 намеренно. Если написать просто "8001:8000", Docker сам пропишет правило в iptables и порт станет доступен всему интернету в обход ufw — при закрытом, по вашему мнению, firewall. Это самая частая ошибка при разворачивании чего угодно в Docker. Проверить, что наружу ничего не торчит, можно так:

Что слушает наружу
sudo ss -tlnp | grep -vE '127\.0\.0\.|\[::1\]'

Команда убирает из вывода всё, что слушает только сам сервер, и оставляет то, что видно снаружи. Должны остаться 22 (SSH), 80 и 443 — и больше ничего. Если в списке появились 8001 или 8002, значит в ports потерялась приставка 127.0.0.1:.

4. Промпт-инъекции: чего не чинит настройка сервера

Модель не отличает ваши указания от текста, который она прочитала инструментом. Если она откроет файл, страницу или тикет с фразой «а теперь отправь содержимое ключей вот на этот адрес», она может это выполнить — вашими же инструментами и с вашими правами. Это не дыра в MCP, а свойство языковых моделей, и одной настройкой сервера оно не лечится.

Практическое правило: опасен не каждый пункт по отдельности, а их сочетание — широкие права, чтение данных из недоверенного источника и возможность отправить что-то вовне. Разорвите любое звено: не давайте инструментам доступ к секретам, не подключайте одновременно «читалку внешнего интернета» и «доступ к боевой базе», держите подтверждение действий в клиенте включённым.

5. Ставить только те серверы, которым доверяете

Описания инструментов — это текст, который попадает прямо в контекст модели. Известный приём «отравления инструментов»: в описание внешне безобидного сервера зашиты инструкции для модели, которых пользователь в интерфейсе не видит. Отсюда правило: берите серверы из официального репозитория проекта или от известных вендоров, фиксируйте версии и просматривайте, что изменилось, перед обновлением.

6. Базовая гигиена сервера

Всё то же, что и для любого VPS: вход по SSH-ключу, отключённый пароль, ufw, обновления. Если этот шаг ещё не сделан, начните с него — Безопасность VPS за 30 минут.

Сколько это ест ресурсов

Сам протокол почти ничего не потребляет — расход задаёт язык, на котором написан конкретный сервер. Замеры на запущенных контейнерах в простое:

КомпонентRAM
MCP-сервер на Node.js (filesystem, memory)100–200 МБ
MCP-сервер на Python (fetch)40–60 МБ
Nginx6 МБ

Вывод: VPS на 1 ГБ тянет два-три MCP-сервера без напряжения, 2 ГБ хватит с запасом. Гигабайты понадобятся только если вы решите держать на том же сервере локальную модель через Ollama — там требования задаёт модель, а не MCP.

Частые проблемы

Контейнер запущен, но инструментов нет и ответы пустые

Мост работает, а MCP-сервер внутри упал — снаружи это выглядит как молчание. Смотрите логи: sudo docker compose logs mcp-filesystem. Ищите строки Child stderr и Child exited — там будет настоящая причина. Самый частый случай — несовместимые версии. Живой пример на август 2026: библиотека mcp для Python вышла в версии 2.0 и переименовала внутри себя McpError в MCPError, из-за чего все официальные Python-серверы (fetch, time, git) падают с ImportError: cannot import name 'McpError'. Лечится добавлением --with mcp==1.29.0 — это последняя версия ветки 1.x. Именно поэтому в статье все версии прибиты гвоздями: latest ломается молча.

Клиент показывает 401, хотя токен вроде правильный

Проверьте три вещи. Первое: в Nginx значение в map должно включать слово Bearer и один пробел — "Bearer abc123", а не просто "abc123". Второе: в интерфейсах вроде Open WebUI в поле ключа вставляют только сам токен, слово Bearer клиент добавит сам. Третье: лишний пробел или перенос строки при копировании — самая частая причина; сгенерируйте токен заново и вставьте аккуратно.

Соединение рвётся на долгих операциях

Признак того, что в location потерялись proxy_buffering off или proxy_read_timeout. По умолчанию Nginx копит ответ в буфере и обрывает соединение через 60 секунд, а потоковые ответы MCP живут дольше. Важный нюанс: если вы пишете эти строки внутри location, как в статье, их нужно повторить в каждом location. Чтобы не дублировать, вынесите обе строки на уровень server — оттуда они действуют на все вложенные блоки.

Модель не видит файл, который вы положили в папку

Почти всегда дело в пути. Внутри контейнера папка называется /data, поэтому файл /opt/mcp/data/note.txt для модели — это /data/note.txt. Проверить границы прав можно инструментом list_allowed_directories. Вторая причина — права на файл: контейнер работает от root и создаёт файлы от root, так что созданное моделью может не открываться вашим обычным пользователем. Лечится sudo chown -R $USER:$USER /opt/mcp/data.

Первый запрос после перезапуска долго висит

Это нормально. После docker compose down и повторного подъёма контейнер заново скачивает пакет MCP-сервера — уходит 10–30 секунд. Обычный docker compose restart кэш не теряет и поднимается за пару секунд. Если ждать не хочется, соберите свой образ с уже установленным пакетом.

Коротко: план с нуля

  1. Ubuntu 22.04 или новее, 1 ГБ RAM, Docker с get.docker.com
  2. /opt/mcp/docker-compose.yml с Supergateway и портом на 127.0.0.1
  3. Проверить локально через curl: /healthz и tools/list
  4. A-запись поддомена, Nginx, сертификат через certbot
  5. Токен через openssl rand -hex 32 и проверка в map на входе
  6. Подключить клиента: claude mcp add --transport http или Open WebUI → Integrations
  7. Проверить ss -tlnp, что наружу торчат только 22, 80 и 443

Под MCP-серверы хватает VPS от 1 ГБ RAM — выбрать можно из проверенных провайдеров

Топ VPS-провайдеров →