How to deploy your .Net API on Heroku with Docker and Github Actions

How to deploy your .Net API on Heroku with Docker and Github Actions

Heroku is a cheap and simple hosting platform to host your apps. Basic hosting costs around 5$/month for many hours of active app. That means that you can host multiple applications for that cost.

Create your app on Heroku

Click "New" and choose "Create new app".

Add "App name", choose a region, and click "Create app".

Add a database (if you need it)

In your app "Overview" click "Configure Add-ons".

Postgres is the only official database on Heroku so further instructions will be given based on it. Choose "Heroku Postgres".

Configure database connection in your project

The easiest way to configure a connection with the database is by using the library HerokuDbConnector. It will build a database connection string for you.

dotnet add package HerokuDbConnector

In your Program.cs, before you add the db context, configure the connection string depending on the environment. If it is production, use the HerokuDbConnector builder.

    string connectionString;
    if (builder.Environment.IsProduction()) {
        connectionString = new HerokuDbConnector.HerokuDbConnector().Build();
    }
    else {
        connectionString = builder.Configuration.GetConnectionString("Default")!;
    }

    builder.Services.AddDbContext<YourApplicationDbContext>(o => o.UseNpgsql(connectionString));

Create Dockerfile

Your Dockerfile will consist of three parts: build ASP.NET API, add support for ASPNETCORE_ENVIRONMENT in Dockerfile, and set PORT variable for Heroku hosting.

# Build ASP.NET API
# Match your .Net version, for me it was .Net 8
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["YourApi/YourApi.csproj", "YourApi/"]
RUN dotnet restore "YourApi/YourApi.csproj"
COPY . .
WORKDIR "/src/YourApi"
RUN dotnet build "YourApi.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "YourApi.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
# Adds support for ASPNETCORE_ENVIRONMENT in Dockerfile
ARG ENVIRONMENT
ENV ASPNETCORE_ENVIRONMENT ${ENVIRONMENT}
# For Heroku hosting:
# Dockerfile cannot have EXPOSE
# Application must be using $PORT variable given by Heroku
ARG PORT
CMD ASPNETCORE_URLS=http://*:$PORT dotnet YourApi.dll

Create a Github Action workflow

First, you have to get your Heroku API Key. Go to your "Account Settings" in Heroku.

Then reveal your API Key.

Next, you have to add a repository secret.

Go to your API repository, next "Settings", then "Action" in "Secrets and variables". Click "New repository secret".

The name is up to you. In the Secret field paste your Heroku API Key. Click "Add secret".

Now, you can create a Github Action file.

Go to "Action" and choose "Set up a workflow yourself".

name: Deploy - API

# Action will be trigger manually (worflow_dispatch) or by pushing on main brach 
on:
  push:
    branches: 
      - main

  workflow_dispatch:

jobs:
  build-api:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Deploy to Heroku
        uses: akhileshns/heroku-deploy@v3.12.12 
        with:
          # Name of the secret you have added in your repo
          heroku_api_key: ${{secrets.HEROKU_KEY}}
          heroku_app_name: your-heroku-app-name 
          heroku_email: your-heroku-account@email.com
          usedocker: true
          appdir: path/to/your/Dockerfile/directory
          docker_build_args: |
            ENVIRONMENT
        env:
          ENVIRONMENT: Production

And... that's it :) After deployment, your API (and database) will be hosted on Heroku.