Давным-давно, когда Linux был ещё на ядре 2.6, а PHP5 был глотком свежего воздуха, я впервые заинтересовался миром веб-технологий. Читал учебники, статьи, зависал на форумах, но все равно мало мог понять как код, который я вижу на экране, превращается в волшебные сайты с кнопками, формами и анимациями. Узнал про LAMP и его аналоги для Windows, узнал, что, оказывается, есть хостинги, где такие сайты размещаются. Как только появился внешний интернет без трафика, я поспешил перенести свои локальные поделия во внешний мир, попутно узнав про замечательный протокол FTP. Просто мир волшебных открытий был для меня, особенно когда узнал, что не нужно писать свой форум с нуля, а можно использовать что-то из phpBB, vBulletin и других уже готовых движков.

Главное из всего этого, что со временем я понял в общих чертах, как работает хостинг, что есть заветная папка public_html, куда нужно перенести все файлы, через PhpMyAdmin создать таблицу и все – вот у Вас рабочий сайт для дальнейшего использования. Много лет спустя, когда я погрузился в «увлекательный» мир финансов, бизнеса и закупок, пришло осознание, что я хочу всё-таки заниматься разработкой программных продуктов, а не составлением отчётов, которые нужно передать наверх.

И когда я переключился в мир .NET и начал его изучение, перечисленные ранее умения сыграли со мной злую шутку – я долго не мог понять, как мне найти хостинг для .NET приложений. Почему все известные мне хостинги с лёгкостью предоставляли возможность развернуть PHP приложения, причём даже предлагая какие-то предустановленные версии CMS, но днём с огнём не сыщешь хостинг под .NET. Мое непонимание принципа развертывания приложений усугубляли статьи, которые предлагали их размещать в подходящих сервисах типа Heroku, Digital Ocean или Azure – ведь это так просто и дешево… Потом конечно пришло понимание, что такой папки не существует, и приложения вообще не «хостятся» (на то они и приложения), но давайте будем честны – синьоры не рождаются со знанием и пониманием таких вещей, понимание очевидных вещей не всем сразу приходит.

Поэтому, как логичное продолжение прошлой статьи, где мы запускали локально наши приложения, мы перенесём их на внешний сервер и развернём базу данных, используя ssh и git, рассмотрим конкретные примеры через Github, заодно на практике найдём ответы на следующие вопросы, которые, скорее всего, озадачивают новичков, изучающих программирование в .NET. Цикл статей призван раскрыть следующие вопросы:

  • Как перенести код на внешний сервер и запустить его?

  • Как подключить SSL сертификат?

  • Как развернуть свою базу данных?

  • Как безопасно хранить чувствительные данные и использовать их на сервере?

  • Как автоматизировать разворачивание приложений?

Конкретно в этой статье мы рассмотрим базовые принципы публикации без лишних заморочек. В следующих статьях будем разбирать различные инструменты, позволяющие запускать одновременно несколько приложений в контейнерах, разворачивать базу данных, подключим сертификат и настроим автоматизацию CD процесса. В общем, будем усложнять решение по мере цикла статей.

Итак, начнем с самого начала и самого простого – создадим пустое приложение, используя актуальный .NET 8.0.

dotnet new razor -n SimpleApp
cd ./SimpleApp
dotnet run

После этого запустится браузер по пути, указанному в ./Properties/launchSettings.json. В моем случае это http://localhost:5144. При переходе мы увидим стандартное приветствие.

Допустим, у нас есть доменное имя, и мы хотим теперь сделать приложение доступным по нашему адресу и доступным в режиме 24/7, как это сделать? Для начала нужно арендовать VPS, для нашего простого и пустого приложения подойдет абсолютно любой. В качестве устанавливаемой операционной системы выберите что-нибудь из Debian семейства, например Ubuntu 22.04. После оплаты тарифа вам предоставят доступ к панели управления, где будет указан IP адрес, по которому можно обращаться с выделенной машиной, а также привязать к этому адресу ваш домен.

Я тут укажу очевидное, но поверьте, для начинающих это не всегда очевидно и понятно. По сути, развертывание .NET приложений в какой-то внешней среде, будь то облако, или VPS ничем не отличается от обычного запуска приложения на вашей машине. Как вы запускаете приложение через dotnet run локально (или через IDE, или через docker) – тоже самое надо повторить, но на удаленной машине, предоставляемой провайдером. Вам не нужно какое-то специальное окружение, вам просто нужен компьютер с предустановленной операционной системой, где можно собрать и запустить приложение.
И всё развертывание .NET приложений и деплой сводится к простому переносу кода с вашей машины (или из системы контроля версий) на какую-то внешнюю виртуальную машину. Всё просто.

Тогда возможно у Вас появляется логичный вопрос: «А к чему тогда сложности с Heroku, Azure и другими специализированными сервисами для хостинга .NET приложений? Зачем их тогда использовать, если можно просто «скопировать» код на VPS и запустить?». И, если ответить кратко – то в нашем случае такие сервисы не нужны, как и не нужны для большого количества продакшн решений. Помимо того, что они стоят дороже обычной аренды VPS (если речь про длительное размещение), их основное преимущество – автоматизация развертывания ваших приложений после изменения кода, которое можно настроить и на обычном VPS путем использования различных инструментов, таких как Jenkins в более сложных задачах, или средствами Github / Gitlab в более простых случаях. Опять же, если интересно подробнее – гуглим CI/CD и все, что с ним связано. Это отдельная обширная тема и рассматривать сейчас ее не будем.

Копирование с использованием SSH

Итак, возвращаясь к нашему основному вопросу, как же скопировать код на арендованный VPS? Есть два способа, как обычно один простой, второй правильный. Начнем с простого, так как для каких-то простых одноразовых запусков его тоже вполне может быть достаточно. Это обычное копирование через ssh вашего проекта на арендованный VPS.

scp -r ~/SimpleApp root@100.92.66.104:/root/

где SimpleApp – папка с Вашим проектом, root – учетное имя, для доступа через ssh к VPS, 100.92.66.104 – адрес VPS, :/root/ - папка на VPS, куда следует скопировать код (указывайте удобный вам).

Тут стоит уточнить, что использовать root – плохая практика, но по умолчанию это единственная запись, которая существует в системе. После создания VPS стоит создать другую учетную запись, разрешить ей обращаться к sudo, отключить возможность удаленно подключаться через root, а также сменить порт с 22 на какой-либо отличный. Это сделать несложно, как именно – можно узнать в гугле или GPT. Если вдруг что-то пойдет не так, то у Вас всегда есть возможность через панель управления виртуализации подключиться через VNC.

После ввода пароля от root, папка с проектом будет скопирована и доступна по пути /root/SimpleApp. Подключаемся к VPS через ssh и проверяем.

ssh root@100.92.66.104
# ls /root/ | grep 'SimpleApp'
SimpleApp

Осталось совсем ничего – перейти в папку и запустить приложение. Для этого достаточно установить необходимую среду запуска для .NET приложений. Как это сделать подробно можно узнать здесь.

sudo apt-get update && \
  sudo apt-get install -y dotnet-sdk-8.0

Среда установлена, можем перейти в папку и запустить приложение.

cd SimpleApp && dotnet run
Вывод
Building...
warn: Mi-crosoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
      No XML encryptor configured. Key {bc671e4e-e40d-4f31-a79e-4badce1e734f} may be persisted to storage in unencrypted form.
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5144
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /root/SimpleApp

Запуск произошел успешно, а значит наше приложение доступно теперь по адресу локально, проверяем через lynx.

Lynx
lynx localhost:5144

К сожалению, по умолчанию извне наше приложение не будет доступно.

netstat -tuln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 127.0.0.1:5144          0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:5555            0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN     
tcp6       0      0 ::1:5144                :::*                    LISTEN     
tcp6       0      0 :::22                   :::*                    LISTEN     
tcp6       0      0 :::5555                 :::*                    LISTEN     
udp        0      0 127.0.0.53:53           0.0.0.0:*                          

Чтобы наше приложение было доступно извне по доменному имени или IP адресу, нужно использовать обратный прокси. Для этого отлично подойдет Nginx. Настроить его несложно, а если использовать ChatGPT – то вообще просто. Его нужно поставить, настроить по своему вкусу (в примере переадресация входящих внешних запросов на 80 порт на наш локальный 5144).

Установка и настройка Nginx

Если NGINX еще не установлен на вашем сервере, вы можете установить его, используя пакетный менеджер apt на Ubuntu:

apt update
apt install nginx

Создайте новый файл конфигурации для вашего веб-приложения в директории /etc/nginx/sites-available/ и создайте символическую ссылку на него в /etc/nginx/sites-enabled/, чтобы активировать конфигурацию. В нашем конкретном примере, это веб-приложение, работающее на порту 5144:

nano /etc/nginx/sites-available/mydotnetapp

Добавляем в него следующую конфигурацию

server {
    listen 80;
    server_name asyncnoway.ru; # Замените на ваш домен или IP-адрес
location / {
    proxy_pass http://localhost:5144; # Перенаправление на ваше .NET приложение
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection keep-alive;
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

}

Добавляем ссылку

ln -s /etc/nginx/sites-available/mydotnetapp /etc/nginx/sites-enabled/

Проверяем на наличие ошибок

nginx -t

И если все ок , то перезагружаем сервис

systemctl restart nginx

Теперь NGINX будет принимать входящие соединения на порт 80 и перенаправлять их на ваше .NET веб-приложение, работающее на порту 5144. Можем подключиться по доменному имени или IP (смотря, что вы добавили в /etc/nginx/sites-available/mydotnetapp)

Лучшее – враг хорошего.
Конечно, такой способ сложно назвать хорошим, и я заочно согласен со всеми возмущенными таким подходом. Однако, если вам надо быстро что-то развернуть и проверить, вы не используете систему контроля версий, то это вполне себе действенный способ. В идеале, лучше, конечно, использовать не dotnet run, так как приложение запускается в Development окружении, а все-таки делать релиз и запускать его в Production окружении. Нужно ли конкретно это Вам – Вам же и решать, как это сделать можете легко найти в интернете.

Копирование с использованием GIT

Все же стоит понимать, что указанный выше способ имеет несколько весомых недостатков. Во-первых, скорость копирования через ssh довольно медленная, а значит с увеличением проекта копирование будет занимать все больше времени. Во-вторых, если проект живой и вы постоянно что-то в нем меняете, то при каждом изменении придется копировать все файлы. Либо копировать только измененные файлы, но надо как-то фиксировать их изменения. Собственно, именно для этого и предназначен git. При использовании системы контроля версий на VPS будут обновляться только измененные файлы, подтягивая обновления через git pull из сервиса хранения кода. Использовать Github или Gitlab – вопрос исключительно вкуса и в контексте нашей задачи между ними лишь одна существенная разница: при попытке клонировать или обновить приватный репозиторий для гитлаба достаточно вести логин-пароль от учетной записи, а для гитхаба такая возможность недоступна из-за соображений безопасности, поэтому придется изгаляться с созданием ключей и их добавлением. Если вы используете публичный репозиторий, то разницы никакой нет. Поэтому в дальнейшем я буду использовать приватный репозиторий Github, но все действия полностью аналогичны и для Gitlab, за исключением добавлением ключа для аутентификации. Приступим.

Самым простым способом будет отправка проекта, используя какую-либо IDE – VSCode, Rider или Visual Studio. В таких системах системах можно раз сохранить токен учетной записи и избегать проблем с доступом при работе с Github, а все взаимодействие будет строиться через нажатие кнопочек, но мы разберем все это через консоль без привязки к какой-либо среде разработки.
Нужно создать приватный репозиторий в Github с именем нашего приложения — для простоты просто на сайте Github. Затем создадим локальный репозиторий, сделаем первый коммит и отправим приложение в удаленный репозиторий.

dotnet new gitignore
Шаблон "файл gitignore dotnet" успешно создан.

git init
Initialized empty Git repository in /Users/vasjen/SimpleApp/.git/
git add . && git commit -m "Init"
git remote add origin https://github.com/vasjen/SimpleApp.git
git push -u origin master
Enumerating objects: 98, done.
Counting objects: 100% (98/98), done.
Delta compression using up to 4 threads
Compressing objects: 100% (94/94), done.
Writing objects: 100% (98/98), 914.56 KiB | 2.34 MiB/s, done.
Total 98 (delta 33), reused 0 (delta 0)
remote: Resolving deltas: 100% (33/33), done.
To https://github.com/vasjen/SimpleApp.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

Загрузка произошла успешно, в нашем удаленном репозитории появился наш проект с нашим коммитом. Теперь для того, чтобы перенести приложение нужно всего лишь клонировать репозиторий через git clone, а после изменения кода их обновить через git pull. Но, как и говорил ранее, поскольку наш репозиторий приватный, он доступен только вам самим по умолчанию, а значит на VPS надо явно указать вашу учетную запись для аутентификации. Переключаемся в консоль VPS

git clone https://github.com/vasjen/SimpleApp
Cloning into 'SimpleApp'...
Username for 'https://github.com': vasjen
Password for 'https://vasjen@github.com': 
remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/vasjen/SimpleApp/'

Как видим по логам, просто через ввод связки логин-пароль это сделать невозможно, в отличии от Gitlab. Поэтому, нужно создать SSH ключ и указать его в Github

ssh-keygen -t rsa -b 4096 -C "vasjen@github.com" #замените на имя вашей учетной записи
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa
cat ~/.ssh/id_rsa.pub

Выведенный ключ полностью копируем и вставляем в свой профиль Github, в секцию ключей. Указываем удобное имя, ключ помечаем как авторизационный. Пробуем клонировать еще раз через ssh

git clone git@github.com:vasjen/SimpleApp.git
Cloning into 'SimpleApp'...
The authenticity of host 'github.com (140.82.121.3)' can't be es-tablished.
ED25519 key fingerprint is SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'github.com' (ED25519) to the list of known hosts.
remote: Enumerating objects: 98, done.
remote: Counting objects: 100% (98/98), done.
remote: Compressing objects: 100% (61/61), done.
remote: Total 98 (delta 33), reused 98 (delta 33), pack-reused 0
Receiving objects: 100% (98/98), 914.56 KiB | 1.92 MiB/s, done.
Resolving deltas: 100% (33/33), done.

Теперь мы можем работать с нашим приватным репозиторием. В случае, если мы добавим что-то в проект и запушим в репозиторий, мы можем легко подтянуть изменения без необходимости копировать весь проект с нашего компьютера.

git pull
Already up to date. # на текущий момент проект в актуальном состоянии

Далее, повторяем шаги из начала – запускаем приложение удобным вам способом, будь то простой запуск через dotnet run или релиз приложения.

Контейнеризация приложения

Пока мы находимся внутри VPS, все работает как надо. Но стоит нам разорвать SSH сессию, наше приложение перестанет работать, чего мы бы вряд ли хотели. Предлагаю придерживаться стандартов запуска приложений и создадим dockerfile. Заодно протестируем подтягивание изменений проекта через Git. Создадим простой dockerfile для нашего приложения и расположим рядом с остальными файлами проекта.

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /app

COPY *.csproj ./
RUN dotnet restore

COPY . ./
RUN dotnet publish -c release -o /app

FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY --from=build /app ./

EXPOSE 8080

ENTRYPOINT ["dotnet", "SimpleApp.dll"]

Теперь обновим наш репозиторий, закоммитим изменения и отправим их в наш Github

git commit -m "added dockerfile"
git push
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 457 bytes | 45.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/vasjen/SimpleApp.git
   e7ae45d..66da0a3  master -> master

Подключаемся к VPS, переходим в папку с проектом и подтягиваем обновления репозитория.

ssh root@100.92.66.104
cd SimpleApp
git pull
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 1), reused 3 (delta 1), pack-reused 0
Unpacking objects: 100% (3/3), 437 bytes | 437.00 KiB/s, done.
From github.com:vasjen/SimpleApp
   e7ae45d..66da0a3  master     -> origin/master
Updating e7ae45d..66da0a3
Fast-forward
 dockerfile | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
 create mode 100644 dockerfile

Собираем образ приложение и запускаем контейнер с ним, повесим на тот же самый 5144 порт

docker build -t simpleapp .
docker run -p 5144:8080 -d simpleapp

Теперь наше приложение запущено в контейнере, локально доступно на таком же 5144 порту, и будет доступно после выхода из ssh.


В следующих статьях мы добавим SSL ключи и настроим работу через HTTPS, создадим базу данных и упакуем все зависимости в docker-compose файл, а также попробуем автоматизировать процесс обновления кода на VPS. Если есть вопросы и пожелания, какие темы стоит рассмотреть — оставляйте их в комментариях. Можете подписаться на мой телеграм, чтобы быть в курсе планов выхода следующих статей.

Комментарии (27)


  1. ColdPhoenix
    25.04.2024 16:09
    +1

    их основное преимущество – автоматизация развертывания ваших приложений после изменения кода, которое можно настроить путем использования различных инструментов, таких как Jenkins в более сложных задачах, или средствами Github / Gitlab в более простых случаях. Опять же, если интересно подробнее – гуглим CI/CD и все, что с ним связано.

    А на VPS нельзя?

    ИМХО странно писать про nginx и доступ извне когда приложение будет работать пока есть ssh-сессия.


    1. Vasjen Автор
      25.04.2024 16:09

      А на VPS нельзя?

      Я неправильно сформулировал мысль, спасибо что указали – подправлю. Имелось ввиду, что именно на VPS с помощью Jenkins и других инструментов можно сделать тоже самое.

      ИМХО странно писать про nginx и доступ извне когда приложение будет работать пока есть ssh-сессия.

      В следующей частей мы все это дело уже запустим нормально в контейнере и оно будет крутиться 24/7, как и полагается. И доступ из вне лишним не будет.


  1. nronnie
    25.04.2024 16:09
    +3

    К сожалению, по умолчанию извне наше приложение не будет доступно.

    У вас оно доступно, только на порту 5555 (судя по скриншоту). Вообще, если у вас отдельный VPS, то не лучше ли уж сразу поставить туда докер и развертывать приложение в докере - несколько лишних движений в начале, зато потом постоянное упрощение жизни. Зачем вы копируете на сервер весь проект, потом еще водружаете туда SDK и на месте его собираете? Чтобы его заранее собрать и "выбрать" из него только то что надо для запуска есть специальная команда dotnet publish.


    1. Vasjen Автор
      25.04.2024 16:09

      У вас оно доступно, только на порту 5555 (судя по скриншоту).

      На 5555 порту висит другое приложение на этом же VPS. То, которое мы делаем в рамках примера запускается на 5144, что и отражено в логах.

      Вообще, если у вас отдельный VPS, то не лучше ли уж сразу поставить туда докер и развертывать приложение в докере - несколько лишних движений в начале, зато потом постоянное упрощение жизни.

      Из реальных практических соображений – конечно лучше. Но данную статью составлял для начинающих и не хотел переусложнять такими вещами, как докер, хотя он и правда простой и является чуть ли не стандартом развертывания приложений. Но для полноты картины дополнил этим статью, спасибо Вам за указание на это.

      Зачем вы копируете на сервер весь проект, потом еще водружаете туда SDK и на месте его собираете?

      Опять же, для демонстрации, что так можно. Что деплой - это запуск вашего кода на удаленной машины. Хотел наглядно показать, что никакой сложности и магии в этом процессе нет, запуск и результат аналогичен локальному запуску. Далее идет работа с Git, что уже является правильным и нормальным вариантом.


      1. nronnie
        25.04.2024 16:09
        +5

        Опять же, для демонстрации, что так можно.

        Устанавливать средства разработки на (по сути боевой) сервер? Так нельзя.


      1. nronnie
        25.04.2024 16:09
        +1

        То, которое мы делаем в рамках примера запускается на 5144, что и отражено в логах.

        Ну так настройте просто launchSettings.json чтобы оно у вас слушало не только localhost, а либо все адреса, либо те которые доступны "снаружи". Либо в appsettings.json в разделе Kestrel это пропишите.


      1. Free_ze
        25.04.2024 16:09
        +1

        Далее идет работа с Git, что уже является правильным и нормальным вариантом.

        А как между собой связаны dotnet run и Git? И в статье, и в комментарии указываете на некую взаимосвязь между ними.


    1. mvv-rus
      25.04.2024 16:09
      +1

      не лучше ли уж сразу поставить туда докер

      А там докер точно нужен? Основная функция докера, AFAIK - изоляция разных приложений чтобы не было конфликта между их зависимостями. А тут мы имеем сервер ровно для одного приложения. Что от чего изолировать? Или я что-то в докере не понимаю?


      1. nronnie
        25.04.2024 16:09
        +1

        Основная функция докера, AFAIK - изоляция разных приложений

        Это да. Но докер сильно упрощает также установку, развертывание и управление софтом. У меня сейчас на десктопе в докере стоят для работы: MSSQL, Postgres, Pgadmin4, Mongo DB, Redis, RabbitMQ, Smtp4Dev (по-моему ничего не забыл). Все в любой момент очень легко парой команд удалить, переставить, заменить на другую версию (или поставить другую версию параллельно). Все прописано в общий файл compose.yaml, который лежит в гите - если надо, то вся конфигурация одним движением восстанавливается или переносится на другую машину. Я ко всем этим удобствам настолько привык, что ставить и поддерживать все это прямо в самой (хостовой) операционке - я такое себе уже даже и не представляю.


  1. kozlov_de
    25.04.2024 16:09

    .net проект имеет некоторые проблемы сборки под докер

    • с локальными (не с сайта) nuget packages - не помню как решать

    • с typescript - нужно включать node и npm в докер

    Сборка под докер это тоже публикация исходников и сборка в среде Linux, в самом докере. Почему не собирать npm в Винде не знаю.

    Зато разработка и тестирование в windows + visual studio одно удовольствие. Linux как страшный сон


    1. nronnie
      25.04.2024 16:09

      с локальными (не с сайта) nuget packages - не помню как решать

      Точно так же как решается локально - копировать пакеты внутрь контейнера и конфигурировать Nuget (тоже внутри контейнера). Первое - инструкция CP в Dockerfile, второе - инструкция RUN dotnet nuget add source ... там же. Node/npm точно так же ставится через RUN apt install .... А в крайнем .NET SDK появилась возможность собирать образы совсем без Dockerfile, когда при сборке отдельный контейнер для неё не используется вообще, вот, совсем недавняя статья про это: https://devblogs.microsoft.com/dotnet/streamline-container-build-dotnet-8/


  1. Drazd
    25.04.2024 16:09
    +3

    Чтобы наше приложение было доступно извне по доменному имени или IP адресу, нужно использовать обратный прокси.

    На самом деле уже нет. Могу путать версию, но толи с 6, толи с 7 версии ASP.NET появилась возможность настраивать HTTPS протокол с сертификатом непосредственно в Kestrel (через appsetting.json). Пример такой настройки:

    "Kestrel": {
    	"Endpoints": {
    		"Http": {
    			"Url": "http://0.0.0.0:80"
    		},
    		"Https": {
    			"Url": "https://0.0.0.0:443"
    		}
    	},
    	"Certificates": {
    		"Default": {
    			"Path": "cert.pem",
    			"KeyPath": "cert.key"
    		}
    	}
    }

    Но, конечно, Kestrel не дает всего разнообразия настроек веб-серверов как Apache2/httpd и Nginx, тем не менее, для стартовых небольших проектов вполне себе рабочая история


    1. Kano
      25.04.2024 16:09

      Kestrel предназначен для внутреннего использования. Для внешки надо смотреть на специализированные средства, например nginx


      1. nronnie
        25.04.2024 16:09
        +1

        В данном случае вполне и Kestrel пойдет.


      1. ColdPhoenix
        25.04.2024 16:09
        +2

        Уже нет, MS считает Kestrel довольно самостоятельным. см YARP.

        nginx более полезен когда нужно несколько приложений на одной VPS.


        1. nronnie
          25.04.2024 16:09
          +1

          Nginx вообще для этих целей устарел. Есть ведь, например, "Envoy", "Krakend", или "Ocelot", т.е. более специализированные решения, в отличии от Nginx, который просто веб-сервер общего назначения.

          Откуда пошла установка, что с ASP.NET обязательно использовать Nginx (или другой) реверс-прокси это вообще непонятно, потому что в конечном итоге этот реверс-прокси все равно тот самый Kestrel и вызывает - если он при этом не делает ничего типа балансировки, кеширования, переписывания URL, или чего-нибудь подобного, а просто прокидывает запросы "как есть", то какая тогда разница.


  1. Breathe_the_pressure
    25.04.2024 16:09

    А почему нет хостингов для .NET? Если в поисковике набрать "Windows хостинг", неужели ничего не выпадает?


    1. UranusExplorer
      25.04.2024 16:09
      +2

      .net уже давно не windows-only, можно и с Linux :)


    1. shai_hulud
      25.04.2024 16:09
      +2

      тем более что там даже Windows не надо, .NET [Core] можно хостить хоть под линуксом, хоть под макОС.


    1. nronnie
      25.04.2024 16:09

      Да есть (по крайней мере были) даже и просто "shared" хостинги для ASP.NET - я такие видел, точно. Насколько они сейчас актуальны, когда кругом облака с хостингом контейнеров или VPS - этого я в душе не знаю.


  1. sekoles
    25.04.2024 16:09

    А зачем тащить весь dotnet sdk, ведь наверняка можно только что-то из runtime установить?


    1. nronnie
      25.04.2024 16:09
      +2

      .NET SDK автору нужен, чтобы проект прямо на сервере зачем-то собирать.


      1. Vitimbo
        25.04.2024 16:09

        CICD, когда у тебя один сервер на всё


        1. nronnie
          25.04.2024 16:09

          Если проект на GitHub, то есть готовые "GitHub Actions". Можно прямо там сразу же собирать docker-образ, там же его размещать в их registry и на хостинге прямо оттуда в docker-е запускать. У GitLab и "Azure DevOps Services" все это тоже есть.


        1. Free_ze
          25.04.2024 16:09
          +3

          Тогда нужно идти до конца и запускать софтину под dotnet watch, чтобы там же и код писать.


          1. Vitimbo
            25.04.2024 16:09

            Суровые облачные технологии


  1. Miheev2
    25.04.2024 16:09

    А что делать, если на сервере приложение уже работает?
    Оно же не перезапустится само, да и файлы записать не даст.

    Надо сначала выключить. А как это сделать удалённо командой?