Skip to content

A proof of concept that an ASP.NET application with a relational database can be continuously integrated and deployed to Heroku!

License

Notifications You must be signed in to change notification settings

jeremymaya/herokufy-dotnet

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

herokufy-dotnet

Actions Status
Actions Status

Author: Kyungrae Kim

Endpoint: https://herokufy-dotnet.herokuapp.com


Description

This is a proof of concept that an ASP.NET web application with a relational database can be continuously integrated and deployed to Heroku by combining the power of Docker and GitHub Actions.

There are many blogs that explain either how to dockerize an ASP.NET web application or how to deploy the app to Heroku. However, all of them fell short of guiding me to deploy a useful ASP.NET web application with databases and environment variables. This document will fill that gap and go over how to deploy an ASP.NET web application with Heroku Postgres using Docker and GitHub.

Azure is often costly despite being one of the popular options for hosting ASP.NET web applications. This project has swapped the following from Azure to minimize the hosting cost while fully showcasing your project:

  • Azure App Services => Heroku
  • Azure SQL Database => Heroku Postgres
  • Azure Blob Storage (images) => Google Photos

For a more complicated deployment scenarios, please check out the follwoing projects:

  • Herokufy More - A further proof of concept involving multiple databases and environment variables
  • Async Inn API - A RESTful API backend featuring assets management and user management
  • Tiny Plants - An eCommerce website built using ASP.NET Core's MVC and Razor Pages

Hosting an ASP.NET application on Heroku

While Azure offers many great features and easy hosting options for ASP.NET web applications, it is EXPENSIVE. With recent Docker support for ASP.NET applications, it is now possible to host the application on Heroku!

Let's set up a continuous deployment to Heroku from a GitHub repository using GitHub Actions.

Deploying the database

You can run PostgreSQL in a development environment using Docker as well. For the instruction on how to run PostgreSQL locally via Docker, please follow the steps in Using Postgres Instead of SQL Server on Docker from Code-401-Async-Inn-API.

  1. Make sure your project is using the following packages from Nuget Package Manager:

    • EntityFrameworkCore
    • EntityFrameworkCore.Design
    • EntityFrameworkCore.PostgreSQL
    • Microsoft.EntityFrameworkCore.Tools (to run migration and update commands!)
  2. Set up a free-tier PostgreSQL database by following the steps in How to setup a free PostgreSQL database on Heroku

  3. Add the database URI to GitHub Secrets.

    Name: DATABASE_URL
    Value: Database URI
    
  4. Update the Dockerfile to accept DATABASE_URL as an argument by adding the following:

    ARG DATABASE_URL
  5. Update the workflow.yml to pass DATABASE_URL from GitHub Secrets by changing the following:

    heroku container:push web -a ${{ secrets.HEROKU_APP_NAME }}

    to

    heroku container:push web -a ${{ secrets.HEROKU_APP_NAME }} --arg DATABASE_URL=${{ secrets.DATABASE_URL }}
  6. Generate a database connection string that will work with the ASP.NET application with the below function taken from Deploying a Dockerized ASP.NET Core app using a PostgreSQL DB to Heroku - a HUGE thanks to n1ghtmare for the post!

    private string GetHerokuConnectionString(string connectionString)
    {
        string connectionUrl = WebHostEnvironment.IsDevelopment()
            ? Configuration["ConnectionStrings:" + connectionString]
            : Environment.GetEnvironmentVariable(connectionString);
    
        var databaseUri = new Uri(connectionUrl);
    
        string db = databaseUri.LocalPath.TrimStart('/');
        string[] userInfo = databaseUri.UserInfo.Split(':', StringSplitOptions.RemoveEmptyEntries);
    
        return $"User ID={userInfo[0]};Password={userInfo[1]};Host={databaseUri.Host};Port={databaseUri.Port};Database={db};Pooling=true;SSL Mode=Require;Trust Server Certificate=True;";
    }
  7. Run migration command remotely with the Heroku Postgres connection string.

    Your deployed web app should now work with Heroku Postgres! 🎉

Deploying the web app

  1. Add Docker Support by following the steps in Create a Multi-Container App with Docker Compose

    • Your Target OS should should be Linux
  2. Modify the generated Dockerfile to work with GitHub Actions and Heroku by following the steps in Deploying to Heroku from GitHub Actions.

    • IMPORTANT: Modify the workflow.yml file further by adding a cd command to change the current directory to where Dockerfile is located before running Heroku CLI commands

    For example:

    cd ./Herokufy/Herokufy
  3. Add the following to GitHub Secrets.

    Name: HEROKU_APP_NAME
    Value: Name of your Heroku application
    
    Name: HEROKU_API_KEY
    Value: Token
    

    You can generate the Heroku API key by following the steps in How should I generate an API key that allows me to use the Heroku Platform API?

    After a push and/or pull to the repo depending on your workflow.yml, the website should be now live on Heroku! 🎉


Credits