VPS для .NET / ASP.NET Core на Linux
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. Для нулевого простоя используйте два инстанса за балансировщиком.