Де краще розгорнути свій .NET-застосунок, або Як подружити Heroku з .NET та Gitlab

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті.

Всім привіт!

Мене звати Олексій Михняк і я займаюсь розробкою вебзастосунків на .NET. Хоча я свій шлях починав з ігрової розробки на Unity, потім вирішив змінити свій стек на веброзробку і зіштовхнувся з новими проблемами: що робити з моїм готовим ASP.NET Core застосунком? Коли перший раз відкриваєш Microsoft Azure або Amazon Web Services, то просто губишся від кількості сервісів, які вони пропонують, тому вирішив написати статтю на цю тему. Ця стаття буде корисна для початківців або для тих, хто раніше не працював з Heroku.

Heroku — це хмарний сервіс, де ви можете розгорнути свій застосунок, але на відміну від Microsoft Azure або Amazon Web Services, має дуже простий користувацький інтерфейс, що дозволяє вам сфокусуватися на вивченні своєї платформи. Ще з великих переваг — те, що на Heroku можна розгортати свої застосунки безкоштовно. Оскільки повністю нічого безкоштовного в нашому світі не існує, додам невеличкий опис, як це працює. Heroku дає вам 550 безкоштовних годин роботи застосунку та ще додатково 450 годин, якщо додати валідну кредитну картку на місяць. Щоб ці години швико не закінчились, то Heroku вимикає (переводить в режим сну) неактивні застосунки. Тобто ті застосунки, на які не було виконано зовнішніх запитів протягом 30 хвилин. Про це можна почитати більш детально тут.

Heroku не користується популярністю серед .NET розробників через те, що він не підтримується за замовчуванням, тобто потрібно робити додаткові маніпуляції, про що ми сьогодні і поговоримо. Якщо ви початківець або взагалі не працювали з . NET та захочете відтворити все, що буде в цій статті, то вам потрібно буде:

  • скачати та встановити . NET SDK тут, я буду використовувати 5 версію;
  • скачати та встановити Docker тут;
  • як редактор коду можна використати VisualStudio Code, він абсолютно безкоштовний, займає мало місця та є на всі основні операційні системи, скачати можна тут та встановити розширення для C#;
  • зареєструватися на Heroku тут та встановити розширення для терміналу тут;
  • зареєструватися на GitLab тут.

Тепер можемо починати, створюємо наш тестовий проект за допомогою:

dotnet new sln -n HerokuWeb
dotnet new web -o HerokuWeb
dotnet sln add ./HerokuWeb/HerokuWeb.csproj

Запустити і перевірити можна за допомогою:

dotnet run -p HerokuWeb

Вебсервер запуститься на 5000 порті, тому потрібно перейти на http://localhost:5000/ та побачите «Hello World!». Як я вже згадував раніше, Heroku не підтримує .NET за замовчуванням, але ми можемо це обійти за допомогою контейнерізації. Тобто ми будемо розгортати не напряму .NET-застосунок, а контейнер, в якому буде запущений .NET-застосунок. Для цього можна використати стандартний Dockerfile для .NET, більше інформації про це можна почитати тут:

# https://hub.docker.com/_/microsoft-dotnet
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /source
# copy csproj and restore as distinct layers
COPY *.sln .
COPY HerokuWeb/*.csproj ./HerokuWeb/
RUN dotnet restore
# copy everything else and build app
COPY HerokuWeb/. ./HerokuWeb/
WORKDIR /source/HerokuWeb
RUN dotnet publish -c release -o /app --no-restore
# final stage/image
FROM mcr.microsoft.com/dotnet/aspnet:5.0
WORKDIR /app
COPY --from=build /app ./
ENTRYPOINT ["dotnet", "HerokuWeb.dll"]

та .dockerignore файл:

**/bin
**/obj

Перевірити можемо за допомогою команди:

docker build -t heroku-web .

Та після закінчення виконати:

docker run heroku-web

(щоб зупинити роботу контейнера потрібно натиснути CONTROL + C)
Далі за допомогою попередньо встановленого розширення для теміналу виконуємо:

heroku login

Відкриється браузер, де ви виконаєте вхід в свій Heroku-аккаунт і потім можна повертатися до терміналу. Далі створюємо свій перший Heroku-застосунок:

heroku apps:create oleksii-heroku-web --region eu

де oleksii-heroku-web — це ім’я вашого застосунку, яке повинно бути унікальним. Якщо не вказати жодного імені, то воно буде згенероване автоматично. Тепер можемо завантажити наш контейнер на Heroku:

heroku container:login
heroku container:push -a oleksii-heroku-web web
heroku container:release -a oleksii-heroku-web web

Також вам відразу буде доступне зовнішнє посилання на ваш застосунок:
oleksii-heroku-web.herokuapp.com
тобто воно має патерн https:// + ім’я Heroku-застосунка + .herokuapp.com/

Але, на жаль, нічого не буде працювати, лог з контейнеру можна переглянути ось тут:

heroku logs -a oleksii-heroku-web -t

(список всіх команд можна знайти тут)

Застосунок не працює через те, що Heroku динамічно виділяє порт, який ми повинні використати. Більше інформації можна прочитати тут. Для цього потрібно змінити наш Dockerfile:

# ENTRYPOINT ["dotnet", "HerokuWeb.dll"]
CMD ASPNETCORE_URLS=http://*:$PORT dotnet HerokuWeb.dll

Тепер заново завантажуємо та релізимо наш контейнер:

heroku container:push -a oleksii-heroku-web web
heroku container:release -a oleksii-heroku-web web

Все тепер працює! На цьому закінчується перша частина статті, ми змогли подружити .NET та Heroku. Цього вже може бути досить для своїх домашніх проєктів, але можуть початися проблеми з розумінням, яка версія зараз знаходиться на Heroku, особливо якщо ви працюєте не одні на проєкті. Тому пропоную додати ще автоматичне розгортання за допомогою GitLab CI\CD.

Перш за все потрібно створити пустий git-проект на GitLab та додати HEROKU_API_KEY в Settings -> CI\CD -> Variables. Сам API key можна знайти в своєму Heroku-акаунті тут.

Далі створюємо heroku.yml файл, де говоримо, що будемо розгортати саме контейнер з Dokerfile:

build:
  docker:
    web: Dockerfile

та наш .gitlab-ci.yml файл:

variables:
  HEROKU_APP_NAME: "oleksii-heroku-web"
stages:
  - deploy
heroku-deploy:
  stage: deploy
  image: ruby:latest
  only:
    - main
  script:
    - apt-get update -qy
    - apt-get install -y ruby-dev
    - gem install dpl
    - dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_API_KEY

У нас буде всього один етап deploy, де ми запускаємо ruby та використовуємо dlp для розгортання на Heroku, більше інформації тут. Ще залишилось додати .gitignore файл, щоб не завантажувати зайвого, але він занадто великий, щоб я його вставляв в статтю, його можна скачати тут.

Тепер залишилось лише виконати перший коміт (цей блок команд можна знайти в себе в GitLab в секції Push an existing folder):

git init --initial-branch=main
git remote add origin git@gitlab.com:OleksiiMykhniak/heroku-test.git
git add .
git commit -m "Initial commit"
git push -u origin main

Можна насолоджуватися життям разом з Heroku + .Net + GitLab та працювати з простим git flow, коли розробка виконується в develop-гілці, а всі релізи відбуваються після мерджу в main.

Ще важливий ньюанс про Heroku: оскільки новостворений застосунок не знає, що потрібно завантажувати саме контейнер, то не можна відразу запускати GitLab CI\CD, а потрібно вручну виконати container:push та container:release.

Але для мене здалося цього замало, все одно потрібно виконати занадто багато для того, щоб розпочати новий домашній проєкт, тому я створив шаблон, який можна переглянути тут. Щоб його встановити потрібно виконати:

dotnet new --install Oleksii.Template.HerokuWeb::1.1.1

Тепер можна створювати нові проєкти з усіми потрібними файлама та динамічними змінними за подопомогою:

dotnet new herokuweb -o HerokuWeb2 -H oleksii-heroku-web

де o — це ім’я вашого застосунку, а H — це ім’я Heroku застосунку. Також шаблон містить README.md файл, де є коротка інструкція на той випадок, якщо ви щось забули.

P. S. Це була моя перша стаття на DOU та і взагалі, тому не впевнений, що навіть правильно опублікував цю статтю, якщо щось не так, пишіть, виправлю.

A для тих, хто любить більше візуалізації, то в мене ще є відеоверсія цього матеріалу на youtube-каналі.

👍НравитсяПонравилось5
В избранноеВ избранном5
LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Чудова стаття для початківців та студентів, дякую!

Спасибо за статью, схоронил

А коли є сенс використовувати Heroku? Якщо в нас є Azure, AWS,...

Наверное когда неохота ***ться с pem-ключами, создавать security groups, добавлять inbound/outbound rules, внимательно следить чтобы не дай бой при создании эластик бинсталк, не создался по дефолту ес2 инстанс, который не входит в free usage tier и вот эти вот все подобные прелести. Надо попробовать эту хироку.

Якщо в тебе взагалі не має досвіду роботи з Azure, AWS тоді я б радив спробувати хероку, оскільки там реально 2 кліки і все готово. Лише для .Net потрібно робити махінації з контейнером.
Ще одним плюсом є те що не потрібно прив’язувати кредитну картку, щоб отримати 550 годин роботи сервісу на місяць. Можемо уявити ситуація, ми тільки почали вивчати .Net (або програмування взагалі) розбираємось пару днів і хочемо показати комусь свої успіхи, бо це є основним мотиватором продовжувати вчитися і тут відкриваємо AWS, а там стільки кнопок, ще й потрібно кредитну картку ввести щоб почати роботи (ну раніше точно потрібно було, як зараз не знаю), явно може відбити все бажання вчитися.
Особисто я використовую для прототипів щоб перевірити якийсь МВП, або якщо ти робиш замовлення на фрілансі і ще не знаєш де замовник хоче розгорнути.

Не обязательно пихать своё приложение в контейнер, азуре веб аппс тоже вполне просто настроить.

Що буде з цим світом, якщо інтернет захоплять декілька корпорацій?

Подписаться на комментарии