ASP.NET 5: публикуем приложение на Linux
Всем привет. В прошлой статье я описывал, что изменилось в ASP.NET для разработчика. В продолжении цикла хочу рассказать о том, как и куда можно опубликовать ASP.NET 5 приложение.
В рамках данной статьи я буду использовать облачный сервис Azure Virtual Machines, но проблем с повторением ниже описанного «на земле» возникать не должно.
Где достать Azure бесплатно?
Есть несколько способов:
1. Можно зарегистрировать бесплатный месячный триал на сайте azure.com;
2. Для студентов и стартапов есть программы DreamSpark и BizSpark;
3. MSDN подписка.
О последнем пункте хочу рассказать чуть подробнее. Понимаю, что это не по теме статьи, но наболело:). Недавно от одного из специалистов, который занимается формированием спецификации на закупку ПО в одной софтверной компании, услышал фразу, которая мягко говоря, повергла меня в ступор: «Мы год назад купили Visual Studio с MSDN, но из-за того, что на MSDN форумах и сайтах с документацией вообще сложно что-то найти и всё не понятно, разработчикам приходится ходить на StackOverflow, и потому MSDN подписка нам больше не нужна, и платить за нее мы не хотим». Мне, конечно, хотелось сказать, мол, вы что, переплатили $1000 за лицензию на пользователя за доступ к ресурсам, которые итак бесплатные? Но решил лишний раз его не расстраивать и промолчал, тихо улыбнувшись.
У меня, как у человека, который занимается в том числе и разработкой, есть много претензий к MSDN форумам и документации (я тоже всё ищу на StackOverflow, и никаких тут иллюзий нет), но MSDN подписка, которая продается с Visual Studio — это совсем другое! Кстати, Visual Studio Pro стоит порядка $500, а MSDN к ней — еще $1000. Так вот, в двух словах о MSDN подписках:
— Доступ ко всему ПО, которое когда-либо создавал MS + ключи активации. Например, клиентская Windows в MSDN начинается с версии 3.11 и заканчивается Windows 10 всех редакций. Та же история с Windows Server, SQL Server, SharePoint и прочее.
Ниже пример страничка выбора софта:
— Бесплатный Azure на сумму от $50 до $150;
— Бесплатный аккаунт для разработчика в Office365;
— Бесплатный доступ к курсам Plularsight;
— Бесплатный доступ для публикации приложений в Windows Store;
— Новые версии ПО в подписке появляются раньше, чем официальный релиз. Это сделано для того, чтоб разработчики могли адаптировать свои решения до официального выхода релиза.
Все ПО предоставляется для тестирования приложений, которые вы разрабатываете. Иными словами, MSDN — это целая экосистема для разработчика.
Так же вам понадобится Visual Studio 2015 любой редакции. На всякий случай — вот ссылка на бесплатную редакцию Visual Studio Community
Важно:
1. После установки Visual Studio нужно обновить Microsoft ASP.NET and Web Tools 2015 до beta 8 (на сейчас это последняя версия).
2. Запустить «Developer Command Prompt for VS2015» и выполнить 2 команды: dnvm setup и dnvm upgrade.
Будем публиковать проект, который создавали в прошлой статье.
Так, ну вроде предполетную подготовку мы сделали, теперь давайте публиковаться.
Публикация на Linux VM
Разворачиваем в Azure новую виртуалку под Ubuntu 15.04 (можно и Ubuntu 14.04). Виртуалку можно взять ExtraSmall, ее вполне достаточно для теста.
На портале Azure нажимаем «New»:
Далее COMPUTE -> VIRTUAL MACHINE -> FROM GALLERY:
Выбираем Ubuntu 15.04 и жмем кнопку «далее»:
На следующей странице:
— Задаем имя винтуалки в поле «Virtual machine name»;
— Tier выбираем Basic;
— Size выбираем A0 (shared core, 768 MB memory);
— New user name оставляем «azureuser»;
— Убираем галочку «Upload compatible SSH key for authentication»;
— Задаем пароль для нашего «azureuser» в поле «New password» и «Confirm» (эти параметры будут использоваться для доступа к машине через ssh);
— Жмем далее.
На след. странице:
— Меняем Region/Affinity group/Virtual network на «West Europe» (это ближайший к нам дата центр. Локация — Амстердам, Нидерланды);
— Жмем далее.
И тут жмем «done»:
Сейчас пошел процесс создания виртуалки. После ее создания качаем ssh клиент (я использую Putty) и коннектимся к нашей виртуалке. Хост или IP виртуалки можно взять на портале Azure, в разделе «Dashboard». Логин и пароль мы задавали при создании VM.
Настройка виртуальной машины для хостинга ASP.NET 5 веб сайта
После соединения первое, что нам нужно сделать, это заменить файл Sources.list. Это делается только на виртуалках, поднятых в Azure. В файле Sources.list прописывается список URL к репозиториям, откуда Ubuntu качает обновления или дополнительные модули.
Зачем нужно менять? Sources.list в Azure смотрит на какие-то Azure-овые репозитории, в которых нет половины модулей, которые нам нужны.
Простой способ заменить Sources.list:
1. Идем на портал repogen.simplylinux.ch;
2. Выбираем страну «Netherlands», релиз Ubuntu 15.05 и ставим все чекбоксы в разделах «Ubuntu Branches» и «Ubuntu Updates»;
3. Матаем вниз и нажимаем кнопку «Generate List»;
4. После этого, вверху появится скрипт, который нужно запустить в командной строке для обновления файла.
Копируем его и запускаем в командной строке Putty. После выполнения будет следующая картина:
Далее, обновляем apt-get (утилита для установки дополнительных модулей и обновлений Ubuntu) командой «sudo apt-get update», дабы подтянулся новый Sources.list:
Устанавливаем unzip командой «sudo apt-get install unzip»:
Устанавливаем DNVM командой «curl -sSL raw.githubusercontent.com/...t/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh»:
Далее необходимо поставить DNX. Но перед этим нужно доустановить компоненты, которые он использует. Для этого выполняем «sudo apt-get install libunwind8 gettext libssl-dev libcurl3-dev zlib1g» (На вопрос «Do you want to continue? [Y/n]» вводим «Y»):
Ну и, собственно, сам DNX устанавливаем командой «dnvm upgrade -r coreclr»:
Приступим к установке компонентов для веб сервера Kestrel командой «sudo apt-get install make automake libtool curl» (На вопрос «Do you want to continue? [Y/n]» вводим «Y»):
Далее по очереди (хотя можно и все сразу) строки:
— «curl -sSL github.com/...buv/archive/v1.4.2.tar.gz | sudo tar zxfv — -C /usr/local/src»
— «cd /usr/local/src/libuv-1.4.2»
— «sudo sh autogen.sh»
— «sudo ./configure»
— «sudo make»
— «sudo make install»
— «sudo rm -rf /usr/local/src/libuv-1.4.2 && cd ~/»
— «sudo ldconfig»
Теперь нам необходимо как-то передать наши исходники вебсайта на Ubuntu сервер в облаке.
Для этих целей я предпочитаю клиент «WinSCP». Это файловый менеджер, который, в том числе, работает по протоколу SFTP. Коннектимся к нашей машине:
Теперь открываем наш созданный в предыдущей статье проект в Visual Studio и публикуем его в файл:
Идем в папку PublishOut (точную ссылку на нее напишет Visual Studio после публикации) и спускаемся в \approot\src\, открываем Project.json, в котором нам нужно:
— Заменить строку: «„webroot“: „../../../wwwroot“» на «„webroot“: „wwwroot“»;
— Затем в команду «web» добавить параметр «—server.urls http://*:5000».
В итоге Project.json должен выглядеть так:
На Ubuntu сервере мы создадим нашу собственную директорию для вебсайта «DemoWEB».
Теперь берем WinSCP и заходим в папку «PublishOut\approot\src\[Имя вашего проекта]» в левой части приложения. В правой части экрана, на удаленном сервере, создаем новую директорию, например «DemoWEB»:
Ну и, собственно, заходим в новосозданную директорию и копируем файлы на сервер:
Возвращаемся в Putty и командой «cd ./DemoWEB/» переходим в директорию с нашим веб сайтом (посмотреть содержимое директории можно командой «ll»):
Далее, нам необходимо восстановить библиотеки нашего проекта, согласно файла «Project.json». Выполняем «dnu restore». Дожидаемся окончания восстановления и стартуем Kestrel командой «dnx web».
Важно: «web» я выделил не зря. Если кто внимательно читал предыдущую статью, то знает, что «web» — это указатель на команду, которую запустит DNX. Это один из параметров в Project.json:
Если у вас не так, то команда для запуска веб сервера соответственно будет: «dnx [Ваш вариант]». В общем случае успешный старт выглядит так:
Как видим, сервер стартовал по порту «5000». Для того, чтоб убедится, что наше веб приложение работает, необходимо на портале Azure зайти в панель управления виртуальной машины, перейти в раздел «Endpoints» и открыть порт 5000, а за одно и
В итоге настройка портов будет выглядеть так:
Собственно, если мы сейчас в браузере откроем наш веб сайт по порту 5000, мы его увидим:
Для того, чтобы наше веб приложение стало доступно по порту 80, необходимо поставить проксю (Linux злой и не разрешает не привилегированным пользователям цепляться к
Для профилактики запускаем «sudo apt-get update». Теперь, собственно, команда для установки nginx: «sudo apt-get install nginx -y».
Далее конфигурируем nginx для запуска при старте виртуалки командой «sudo update-rc.d nginx defaults».
Создаем конфигурационный файл для нашего вебсайта (я использую встроенный редактор vi). Выполняем «sudo vi /etc/nginx/conf.d/asp5-on-ubuntu.cloudapp.net.conf». Внимание: полужирным я выделил имя хоста, в моем случае это «asp5-on-ubuntu». У вас, наверняка будет другой — замените на свой.
После выполнения команды откроется редактирование:
Вставляем (вставка в Putty осуществляется кликом правой кнопкой мышки. Тут Ctrl+V для вставки не используется! Это же Linux :)
server { listen 80; server_name asp5-on-ubuntu.cloudapp.net www.asp5-on-ubuntu.cloudapp.net; client_max_body_size 10M; location / { proxy_pass http://127.0.0.1:5000; proxy_redirect off; proxy_set_header HOST $host; proxy_buffering off; } }
Для выхода из режима редактирования жмем ESC. Для сохранения изменений и выхода из редактора жмем ZZ (Shift + Z + Z).
Создаем кэш директорию для Nignx веб-сервера командами:
«sudo mkdir /var/cache/nginx»
«sudo chown www-data:www-data /var/cache/nginx»
Стартуем nginx командой: «sudo service nginx start» (команда для остановки: «sudo service nginx stop», для перезапуска: «sudo service nginx restart»).
Стартуем Kestrel командой: «dnx web».
Теперь вебсайт доступен по порту 80.
С этим разобрались. Как видите, всё очень просто и нет почти никакой ручной работы:).
На самом деле я специально в деталях показал, что к чему, потому что в интернете есть куча примеров, которые не работают — они работали в предыдущих версиях (до beta7) ASP.NET. Существует и простой способ: в галерее Azure есть уже настроенная виртуалка под ASP.NET 5. Кому лень всё делать руками — берите ее (правда она пока еще beta5):
Docker
Теперь приступим к Docker. Это еще один способ опубликовать приложение на Linux. Я не буду вдаваться в суть, что такое Docker, об этом достаточно написано на их сайте. Итак, для начала необходимо скачать Visual Studio 2015 Tools for Docker. После установки этого аддона у вас при публикации появится еще один способ «Docker Container»:
Выбираем его и в открывшемся окне нужно выбрать, на какой хост вы будете публиковать ваш сайт — на существующий или на новый. Я собираюсь сделать новый, а вы уж как знаете. Если новый, то это новая Azure VM с установленным Docker:
Сейчас Visual Studio поднимает новую виртуалку с Docker-ом. После того, как мы в Visual Studio увидели «Successfully deployed template...», нажимаем еще раз кнопку Publish, открывается уже другое окно:
Обратите внимание на «Dockerfile». Мы используем ASP.NET 5 beta8. Я не знаю, какой файл генерит Visual Studio, но последний мы можем стянуть из git. Нас интересует «1.0.0-beta8-coreclr»:
Закрываем визард публикации и добавим наш Dockerfile в проект:
Еще раз нажимаем Publish, и, о чудо :), он тут:
Жмем Publish и дожидаемся окончания публикации. Это займет минут 10, при этом в output консоли творится реально какой-то ад... Microsoft долго шел к красивым прогресбарам, и тут на тебе, опять куча текста:) Но это всё Linux виноват:)
После публикации Visual Studio попробует открыть вебсайт в браузере, который пошлет вас на все 404 стороны (пробовал все варианты: и порты переставлять, и разные Dockerfile, и давал Visual Studio самой сгенерить Dockerfile, никак).
Эхх.... Опять все делать руками:(. Вообще полезно такие статьи готовить — этот процесс помогает познать то, с чем на самом деле сталкиваются разработчики.
Но сразу всех утешу: неработоспособность аддона Visual Studio скорее всего связана с тем, что совсем недавно вышел ASP.NET 5 beta8, с которым мы сейчас имеем дело ASP.NET 5 beta5 публикуется нормально). Я не зря сделал эту прелюдию с Visual Studio. Когда ASP.NET 5 выйдет в релиз, вся эта красота будет работать. А сейчас мы пройдем процесс «голой» инсталляции. Пройдя этот путь, вам будет плевать, какая версия ASP.NET у вас стоит и какой Dockerfile использовать, потому что вы сами себе кузнец в этом случае.
Собственно, создаем новую Ubuntu виртуалку (рекомендую размер A1 или A2, так как от нехватки оперативной памяти A0 захлебывается), открываем на Azure портале порты: 80, 5000 (хотя последний мы использовать не будем) и обновляем Sources.list аналогично тому, как мы делали в начале статьи.
Раз уж мы руками будем все устанавливать, есть смысл сразу ставить последнюю версию Docker, посему мы будем сетапить все так, как указано на официальном сайте Docker.
Итак, добавляем новый GPG ключ командой «sudo apt-key adv —keyserver hkp://pgp.mit.edu:80 —recv-keys 58118E89F3A912897C070ADBF76221572C52609D»:
Добавляем Docker репозиторий в Sources командой «sudo vi /etc/apt/sources.list.d/docker.list». В терминале откроется редактор vi, копируем строчку «deb apt.dockerproject.org/repo ubuntu-vivid main» и кликом правой кнопкой мыши вставляем в редактор.
Нажимаем кнопку «Esc» для выхода из режима редактирования и «ZZ» (Shift + Z + Z) для сохранения изменений (рекомендую потренироваться с редактором vi, это полезный навык при работе с Linux).
В итоге файл выглядит так:
Обновляем apt-get командой «sudo apt-get update».
Убеждаемся, что apt-get сморит в правильный репозиторий командой «sudo apt-cache policy docker-engine»:
Устанавливаем Docker командой «sudo apt-get install docker-engine»:
Запускаем демон (на виндовом языке — служба) Docker командой «sudo service docker start».
Дабы убедится, что Docker работает, попробуем запустить стандартный HelloWorld командой «sudo docker run hello-world»:
Наш HelloWorld должен появится в списке Docker образов. Это можно проверить командой «sudo docker images»:
Давайте добавим нашего пользователя в группу Docker, дабы избавится от постоянного «sudo» в каждой команде «sudo usermod -aG docker azureuser»:
Теперь нужно перелогинится в терминале (закрыть и открыть Putty).
После этого зальем наш проект на сервер. Это можно сделать используя WinSCP, как мы делали ранее. Создаем директорию «DemoWEB», копируем в нее файлы нашего проекта.
Dockerfile я использовал «1.0.0-beta8-coreclr», который взял тут. Нужно открыть этот файл текстовым редактором и в конце добавить строчки:
COPY . /app
WORKDIR /app
RUN ["dnu", "restore"]
EXPOSE 5000
ENTRYPOINT ["dnx", "web"]
Результат будет выглядеть так:
Соответственно, копируем этот файл в нашу директорию «DemoWEB». Итог должен быть такой:
Возвращаемся в Putty, идем в нашу папку «DemoWEB» командой «cd ./DemoWEB». Запускаем сборку среды командой «docker build -t demo .» (demo — это название нашего образа. Можете свое указать). Точка в конце команды обязательна! Теперь можно минут 10 пойти погулять.
Нагулялись? Если вы в итоге увидели это:
Значит, процесс сборки закончился. Запускаем наш Docker image командой «docker run -t -d -p 80:5000 demo» (порт 5000 прописан в нашем Project.json, если кто забыл):
Наслаждаемся результатом:
Заключение
В заключении хочу сказать, что готовить статью было не просто. Нужно было самому все проделать и убедиться, что все работает. Проблема в том, что куча примеров, которые опубликованы на разных источниках, может когда-то и работали, но теперь нет. Более того, мне, как человеку, привыкшему к Windows Server, ковыряться в Linux было вдвойне сложно. Зато я теперь умею пользоваться редактором vi, управлять процессами, работать с git, работать с файлами, да что там, nginx и docker поднимать! В общем, могу претендовать на начинающего админа Linux :)
Для особо интересующихся этой тематикой — попробуйте запустить контейнер «1.0.0-beta8» (мы сейчас запустили coreclr, но есть еще mono).
На всякий случай, вот ссылка на исходники, включая Dockerfile, которые я заливал на сервер.
Если вам не удается повторить то, что делал я — пишите в комментариях, будем разбираться вместе.
Предыдущие части:
— ASP.NET 5 — взгляд внутрь. Об изменениях ядра и инфраструктуры
— ASP.NET 5: что изменилось для разработчика