Вступление
В этом руководстве я продемонстрирую на своём примере, как вы можете безболезненно разместить ваш проект. Надеюсь, кому-то пригодится. Обязательно просмотрите блок с дополнительной информацией.
Технологии
.NET 6 WebAPI
Heroku
Entity Framework Core 6
PostgreSQL

Heroku
Регистрируемся на сервисе Heroku. Трудностей быть не должно.



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


А теперь важный аспект. Перед тем, как деплоить проект, его необходимо собрать.
Переходим во вкладку Settings и в пункте Buildpacks добавляем ссылку на "сборочный пакет" .NET 6.

Осталось следующее: установить аддон Heroku Postgres с помощью Configure Add-ons во вкладке Overview:

Кликаем по аддону и переходим во вкладку Settings >> View Credentials, где находятся данные о нашей БД. Они нам понадобятся.

Конфигурационные файлы
Переходим во вкладку Settings >> Config Vars и добавим конфигурационный файл под именем "ASPNETCORE_ENVIRONMENT". Это файл ключ-значение в котором будет удобно конфигурировать нашу рабочую среду между Development / Production значениями.

Также здесь можно заметить такой файл как "DATABASE_URL". Это строка подключения к БД, предоставленная аддоном Heroku. Мы её будем использовать
Наш проект практически готов к публикации. Осталось его настроить.
Настройка проекта
Сразу скажу, что структура проекта, безусловно, может у каждого отличаться, но алгоритм действий будет одинаков при любом раскладе. Я продемонстрирую CRUD-проект. Условимся на том, что у вас объявлены соответствующие классы и сущности и осталось только настроить слой базы данных. Кратко ознакомимся.
Тема проекта: книжный магазин.
Приложение разделено на слои:
Domain (сущности)
Application (бизнес-логика)
Persistence (слой доступа к данным)
Presentation (web api)

Убедимся, что в сборке со сл��ем БД установлены все необходимые NuGet пакеты:

Если вы все делаете в одной сборке WebApi, этих пакетов будет достаточно.
Настройка контекста базы данных
Создадим интерфейс, который будет реализован контекстом BookStoreDbContext:
public interface IBookStoreDbContext { DbSet<Book> Books { get; set; } Task<int> SaveChangesAsync(CancellationToken cancellationToken); }
Объявим необходимые таблицы и вызываем базовый конструктор. В этом же классе можно переопределить protected метод OnModelCreating(), чтобы добавить начальные данные в таблицу, но это уже за рамками статьи.
public class BookStoreDbContext : DbContext, IBookStoreDbContext { public DbSet<Book> Books { get; set; } public BookStoreDbContext(DbContextOptions<BookStoreDbContext> options) : base(options) { } }
Создадим класс DbInitializer, который будет использоваться при старте приложения и методом Migrate() создавать БД на основе нашего контекста, если её нет, а также программным способом накатывать миграции.
public class DbInitializer { public static void Initialize(BookStoreDbContext context) { context.Database.Migrate(); } }
Переходим в файл конфигурации приложения appsettings.json, где укажем строку подключения DbConnectionнашей локальной БД.
Вместо # - укажите ваши данные:
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "ConnectionStrings": { "DbConnection": "Host=localhost;Database=#;Username=#;" }, "AllowedHosts": "*" }
Внедрение зависимостей
Добавим класс DependencyInjection для нашего контекста. В нем мы внедрим наш контекст базы данных.
Создадим метод GetConnectionString(), который получит данные о строке подключения из конфигурационного файла Heroku "DATABASE_URL".
Если в конфигурационном файле указана среда "Development" (разработка), то мы используем нашу локальную строку подключения к БД в файле asppsettings.json с её строкой подключения.
Подключим PostgreSql.
public static class DependencyInjection { public static IServiceCollection AddPersistence( this IServiceCollection services, IConfiguration configuration) { var connectionString = string.Empty; /* Проверим, в какой мы среде*/ if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development") { connectionString = configuration["DbConnection"]; } else { connectionString = GetConnectionString(); } services.AddDbContext<BookStoreDbContext>(options => { /* Подключаем PostgreSQL */ options.UseNpgsql(connectionString); }); services.AddScoped<IBookStoreDbContext>(provider => provider.GetService<BookStoreDbContext>()); return services; } public static string GetConnectionString() { /* Используем строку подключения из конфигурацинного файла, обеспеченного Heroku*/ var connectionUrl = Environment.GetEnvironmentVariable("DATABASE_URL"); connectionUrl = connectionUrl.Replace("postgres://", string.Empty); var userPassSide = connectionUrl.Split("@")[0]; var hostSide = connectionUrl.Split("@")[1]; var user = userPassSide.Split(":")[0]; var password = userPassSide.Split(":")[1]; var host = hostSide.Split("/")[0]; var database = hostSide.Split("/")[1].Split("?")[0]; return $"Host={host};Database={database};Username={user};Password={password};SSL Mode=Require;Trust Server Certificate=true"; }
В файле Program.cs нашего WebAPI внедрим контекст БД и вызовем необходимый метод Initialize():
using (var scope = app.Services.CreateScope()) { try { var context = scope.ServiceProvider.GetRequiredService<BookStoreDbContext>(); DbInitializer.Initialize(context); } catch (Exception) { } }
Добавим миграцию в проект с помощью команды add-migration Init:

Деплоим проект!
Вернёмся в Heroku и нажмём заветную кнопку Deploy Branch:

Заключение
Поздравляю! Можно переходить на сайт. Вы можете наблюдать за состоянием сборки вашего приложения во вкладке Activity.
В моём случае это получение информации о книгах.

Я надеюсь, что изложил максимально просто и понятно. Если исключить БД, то всего лишь необходимо подключить .NET buildpack и деплоить проект. Проблем быть не должно.
Всех благ!
Дополнительная информация
Heroku:
Ролик, который вдохновил меня на написание статьи:
https://www.youtube.com/watch?v=BqI1hu0gIb0&ab_channel=CoderFoundry
Аналогичная статья с размещением API вместе с Docker:
https://www.c-sharpcorner.com/article/deploy-a-net-api-to-heroku-through-github-actions/
Создание контекста БД и подключение PostgreSQL с помощью Entity Framework Core:
На всякий случай добавлю .NET Buildpack для размещения вашего приложения:
Более подробное описание добавления Entity Framework Core в проект:
