Исходные данные

  1. VPS-хостинг на основе Ubuntu 22.04.05 LTS.

  2. На VPS установлены:

    • nginx 1.18.0 в качестве реверс-прокси.

    • .Net нужной версии.

  3. Приобретено доменное имя, по которому обеспечен доступ к сайту.

  4. Разработку приложений и настройку VPS ведем из под ОС Windows 10x64 Professional.

Цель

  1. Заставить одновременно работать несколько ASP.Net Core приложений на одном VPS.

  2. Каждое приложение должно быть доступно по адресу: http://поддомен_приложения.домен.

1. Создаем поддомен (на примере masterhost.ru)

Заходим в редактор DNS https://cp.masterhost.ru/dns и погнали!

2. Публикуем приложение

dotnet publish -r linux-x64

3. Задаем приложению уникальный порт

Так как у сетевых приложений должны быть уникальные (сетевые) порты, а по умолчанию все ASP.Net Core приложения работают на 5000 порту, то необходимо сконфигурировать наши приложения. В папке publish находим appsettings.json. По умолчанию он выглядит так:

и добавляем в него раздел "Kestrel" со следующим параметрами:

 "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5005" // Change this to your desired port
      }
    }
  }

Итоговый файл appsettings.json должен выглядеть примерно так:

Теперь, если запустить наше приложение из командной строки, то можно убедиться ,что оно работает на порту 5005.

И это даже несмотря на то, что мы сейчас работаем под ОС Windows 10x64 Professional, а опубликовали наше приложение под Linux.

Копируем приложение на VPS

Любым удобным способом (я использую FileZilla, подключаюсь по SFTP и перетаскиванием копирую каталог из одной панели в другую) копируем папку с опубликованным ASP.Net Core приложением например в каталог /var/www, в котором я для удобства создал подкаталог с именем приложения.

5. Проверяем работоспособность приложения на VPS

Переходим в каталог с нашим приложением (TestRazor.dll)

cd /var/www/TestRazor/publish/

и запускаем его

 dotnet TestRazor.dll
Всё прекрасно работает!
Всё прекрасно работает!

6. Настраиваем nginx

1. Создаем файл test-razor.config следующего содержания:

server {
        listen 80;
        listen 443;
        server_name test.s****ov.ru;

        location / {
        proxy_pass         http://127.0.0.1:5005;
        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;
        }
    }

Обратите внимание на параметр server_name (4 строка). Напротив него введите значение в формате свой_поддомен.свой_домен;

2. Копируем test-razor.configна VPS по пути: /etc/nginx/sites-available.

3. Создаем символическую ссылку на test-razor.config

sudo ln -s /etc/nginx/sites-available/test-razor.config /etc/nginx/sites-enabled/

4. Проверяем конфигурацию.

sudo nginx -t
Видим, что всё хорошо!
Видим, что всё хорошо!

5. Перезапускаем nginx.

sudo systemctl restart nginx

В случае проблем с перезапуском nginx Проверьте каталог /etc/nginx/sites-enabled на предмет кривых/левых символических ссылок и удалите таковые, если они есть.

7. Оформляем наше приложение в виде службы (создаем Unit)

На компьютере создаем файл test_razor.service такого содержимого:

[Unit]
Description= Тестовое ASP.Net Core приложение

[Service]
WorkingDirectory=/var/www/TestRazor/publish
ExecStart=/usr/bin/dotnet /var/www/TestRazor/publish/TestRazor.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=Raven
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_NOLOGO=true
[Install]
WantedBy=multi-user.target

Обращаем внимание на правильность путей, указанных в параметрах WorkingDirectory и ExecStart

сохраняем его.

Копируем test_razor.service на VPS по пути по пути /etc/systemd/system

Проверяем работоспособность службы.

systemctl start test_razor.service
systemctl status test_razor.service

8. Итоговая проверка работоспособности приложения и его доступности по url

Ну, вот в общем-то и всё. Повторяем этот алгоритм для второго приложения, не забывая присваивать ему уникальный порт и свой поддомен. Всем удачи! Жду обратной связи в комментариях под статьей.

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


  1. GennPen
    01.01.2025 19:32

    Самая вишенка при запуске службы:

    User=root


    1. saminet Автор
      01.01.2025 19:32

      Спасибо за ценное замечание! Исправил на User=www-data


  1. miss_polly
    01.01.2025 19:32

    Отличная статья, но у меня возникли несколько вопросов. Почему вы не упомянули настройку HTTPS? В продакшен-среде это критически важно, особенно если приложение обрабатывает чувствительные данные. Так же, как вы предлагаете организовать логи? Текущая настройка службы не указывает, куда перенаправляются логи, что может усложнить диагностику проблем. Будет здорово, если вы дополните статью этими моментами! Спасибо!


    1. saminet Автор
      01.01.2025 19:32

      Благодарю Вас за положительный отзыв и полезные замечания! Учту.