MAATRIX / Блог / VPS для .NET / ASP.NET Core на Linux

VPS для .NET / ASP.NET Core на Linux

Блог MAATRIX · 2026-07-07

ASP.NET Core давно кроссплатформенный и отлично работает на Linux. Разберём публикацию проекта, установку рантайма, запуск Kestrel под systemd и проксирование через nginx с TLS.

.NET на Linux: что важно знать

['Современный .NET (6/8 LTS) полностью работает на Linux без Mono и Windows-зависимостей. Встроенный веб-сервер Kestrel быстрый и продакшн-готовый, но наружу его принято закрывать nginx.', 'Публиковать можно двумя способами: framework-dependent (нужен установленный рантайм на сервере) или self-contained (рантайм упакован в сборку). Первый компактнее, второй не требует ставить .NET на VPS.', '
  • Kestrel — быстрый встроенный сервер.
  • Два режима публикации — с рантаймом или без.
  • LTS-версии — 3 года поддержки, стабильность для прода.
']

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK и США. Оплата картой РФ и по СБП.

Арендовать VPS для .NET

Установка рантайма

['Для framework-dependent публикации ставим ASP.NET Core Runtime из репозитория Microsoft.', '
sudo apt update\nsudo apt install -y wget nginx\nwget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb\nsudo dpkg -i packages-microsoft-prod.deb\nsudo apt update\nsudo apt install -y aspnetcore-runtime-8.0
']

Публикация приложения

['Собираем локально в конфигурации Release. Для self-contained укажите рантайм-идентификатор.', '
# framework-dependent\ndotnet publish -c Release -o ./publish\n\n# self-contained (рантайм не нужен на сервере)\ndotnet publish -c Release -r linux-x64 --self-contained true -o ./publish
', '
scp -r ./publish/* appuser@SERVER_IP:/opt/dotnetapp/
']

Запуск Kestrel под systemd

['Kestrel слушает локальный порт, systemd управляет процессом. Задаём окружение Production и адрес привязки.', '
[Unit]\nDescription=ASP.NET Core app\nAfter=network.target\n\n[Service]\nUser=appuser\nWorkingDirectory=/opt/dotnetapp\nExecStart=/usr/bin/dotnet /opt/dotnetapp/MyApp.dll\nRestart=always\nRestartSec=5\nEnvironment=ASPNETCORE_ENVIRONMENT=Production\nEnvironment=ASPNETCORE_URLS=http://127.0.0.1:5000\n\n[Install]\nWantedBy=multi-user.target
', 'Для self-contained в ExecStart укажите путь к бинарнику: /opt/dotnetapp/MyApp. Переменная ASPNETCORE_ENVIRONMENT=Production переключает приложение в боевой режим: отключает детальные страницы ошибок и включает production-конфигурацию из appsettings.Production.json.', 'Строки подключения и секреты не храните в appsettings — передавайте их через переменные окружения systemd или через EnvironmentFile с правами 600. .NET автоматически читает переменные с префиксом и мапит их на конфигурацию.', '
sudo systemctl daemon-reload\nsudo systemctl enable --now dotnetapp\njournalctl -u dotnetapp -f
', 'Проверить, что Kestrel действительно слушает локальный адрес, можно прямым запросом с сервера — так вы отделите проблемы приложения от проблем nginx.', '
curl -i http://127.0.0.1:5000/
']

nginx и заголовки прокси

['ASP.NET Core должен доверять заголовкам forwarded, чтобы корректно определять схему и IP клиента. В коде подключите ForwardedHeaders, а в nginx пробросьте нужные заголовки.', '
server {\n    listen 80;\n    server_name example.com;\n    location / {\n        proxy_pass http://127.0.0.1:5000;\n        proxy_http_version 1.1;\n        proxy_set_header Upgrade $http_upgrade;\n        proxy_set_header Connection keep-alive;\n        proxy_set_header Host $host;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n    }\n}
', '
sudo nginx -t && sudo systemctl reload nginx\nsudo certbot --nginx -d example.com
']

Железо и частые ошибки

['JIT-компиляция и работа GC в .NET чувствительны к скорости CPU и диска. AMD EPYC + NVMe у MAATRIX дают быстрый холодный старт и стабильную латентность, а от $8/мес и ежедневных бэкапов удобно держать прод. Локации UK/США и оплата из России (карта РФ, СБП, крипта, MAAT) решают вопрос зарубежного сервера.', '
  • Забыли ForwardedHeaders — приложение видит IP nginx, ломается редирект на HTTPS.
  • Несовпадение версии рантайма — сборка под 8.0 не запустится на рантайме 6.0.
  • ASPNETCORE_URLS на 0.0.0.0 — Kestrel торчит наружу мимо nginx.
']

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK и США. Оплата картой РФ и по СБП.

Арендовать VPS для .NET

Частые вопросы

Нужен ли Windows-сервер для .NET?

Нет. Современный .NET кроссплатформенный, ASP.NET Core на Linux работает штатно и часто дешевле в хостинге.

Self-contained или framework-dependent?

Self-contained не требует ставить рантайм на сервер и изолирует версию, но весит больше. Framework-dependent компактнее при установленном рантайме.

Как обновить .NET-приложение?

Скопируйте новую публикацию в каталог и выполните systemctl restart dotnetapp. Для нулевого простоя используйте два инстанса за балансировщиком.