DEV Community

loading...
Cover image for Deploying .NET Core to Heroku

Deploying .NET Core to Heroku

Andrew Robilliard
🍁 πŸ₯ // Senior Developer // CompSci and InfoSys graduate from the University of Auckland
・4 min read

I've always loved coding in C#. Equally, I love using Heroku to host personal projects - they have a nice UI, and a free tier!

However, there are a few limitations. Notably, .NET Core is not supported out of the box 😒. We can fix that!

The Fix

While Heroku isn't able to run C# code directly, they do have support for Docker containers. With that our solution is clear - dockerize all the things!

Deploying a .NET Core App to Docker

The following is not meant to be a .NET Core course, but you might pick up some basics on navigating the base files if you're a beginner. What we will cover:

  • Creating a new .NET Core MVC project from the command-line
  • Modifying the base files to be Heroku & Docker compatible
  • Configuring a new Heroku app
  • Deploy our app to Heroku πŸš€

1. Getting Started

Before we get into changing some code, we need to get our foundation components in order. Before continuing, you should have:

  1. .NET Core installed on your device
    • I'm using v3.1 for this tutorial, which can be found here
  2. Docker installed on your device
    • You can follow the steps here
  3. A Heroku account! - https://signup.heroku.com/
  4. Install the Heroku CLI, which allows us to communicate with the Container Registry.

With those out of the way, we're ready to go.

2. Creating a New .NET Core App

First off, we need to create our new .NET Core app. I'll be following the steps for setting up a basic .NET Core MVC project, which can be found here.

3. Setting Up a New Dockerfile

The dockerfile required is pretty basic, with nothing too complex happening.

# Dockerfile

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# Copy everything else and build
COPY . .
RUN dotnet publish -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
WORKDIR /app
COPY --from=build-env /app/out .

# Run the app on container startup
# Use your project name for the second parameter
# e.g. MyProject.dll
ENTRYPOINT [ "dotnet", "HerokuApp.dll" ]
Enter fullscreen mode Exit fullscreen mode

Additionally, you should probably setup a .dockerignore file to keep your image size down.

# .dockerignore

bin/
obj/
Enter fullscreen mode Exit fullscreen mode

If you want to test out your container, you can run

docker build -t YourAppName .

# The name variable (abc) is simply used to refer to the 
# container later when we want to close everything down.
docker run -d -p 8080:80 --name abc YourAppName
Enter fullscreen mode Exit fullscreen mode

Navigate to http://localhost:8080 and you should see your app running.

All looking okay? Great! Lets shutdown the container locally. We don't need it running here if it's about to be up on the internet!

docker rm --force abc
Enter fullscreen mode Exit fullscreen mode

4. Configuring a New App in Heroku

  1. Sign into Heroku, and create a new app from your personal dashboard at https://dashboard.heroku.com/apps
    • You'll need to provide an app name, and deployment region
  2. Heroku will then display the various deployment options. We're going to be using Container Registry Heroku Deployment Options

5. Releasing to Heroku πŸš€

Last but not least, let's get it online.

1. Using the command-line, login to the Heroku container registry

heroku container:login
Enter fullscreen mode Exit fullscreen mode

2. If you didn't above, make sure you build your docker
container!

docker build -t YourAppName .
Enter fullscreen mode Exit fullscreen mode

3. Push your newly built container up to Heroku

# 'YourAppName' should be the name of the app you 
# configured in Heroku in step 4.
heroku container:push -a YourAppName web
Enter fullscreen mode Exit fullscreen mode

4. Finally, release!

heroku container:release -a YourAppName web
Enter fullscreen mode Exit fullscreen mode

Now, if you just navigate to https://your-app-name.herokuapp.com, you should see the base app. Wait... that didn't work! What happend?!
Alt Text

Take a look at the heroku logs

heroku logs --tail
Enter fullscreen mode Exit fullscreen mode

Within the scary looking logs, you'll see that .NET Core failed to start 'Kestrel', which is the web server for .NET Core. This means our app wasn't able to launch 😒.
Alt Text
If you remember when we started our docker container locally back when we configure it, one of the parameters we passed was a port. When Heroku gives us a port to use, our app needs to know about it!

Modify the end of the Dockerfile to be

# Dockerfile

# ...

# ENTRYPOINT [ "dotnet", "HerokuApp.dll" ]
# Use the following instead for Heroku
CMD ASPNETCORE_URLS=http://*:$PORT dotnet HerokuApp.dll
Enter fullscreen mode Exit fullscreen mode

This allows the our container to use the Heroku-provided port on startup.

Re-deploy everything to Heroku:

  1. Build docker image
  2. Do a heroku container:push
  3. Do a heroku container:release

And voila - your very own .NET Core app hosted on the web.

Conclusion

I hope the above tutorial is helpful, and allows some newbies to get started on their own .NET Core side projects.

If anyone reading has some extra tips, or a better approach, please leave a comment below!

Thanks for reading πŸ‘‹

Discussion (11)

Collapse
m_kunc profile image
Martin Kunc

Thanks Andrew, this was exactly the problem I run into.
I tried to use EXPOSE $PORT and ENV ASPNETCORE_URLS=http://*:$PORT
but for some strange reason only passing ENV var on command line helped.
Really helpfull post, thank you !

Collapse
nomediganlucho profile image
Luis Gabriel Fabres

Hi, I followed all the steps in your tutorial, but after doing the release, when entering the page of the app that I published, I get an error that says:
Error: Missing required flag:
-a, --app APP app to run command against.

My application is called miappmvc and the commands that I enter in the heroku CLI are:
heroku container: push -a miappmvc web
heroku container: release -a miappmvc web

there it says that I am missing a flag. Do you know what flag it refers to?

Collapse
alrobilliard profile image
Andrew Robilliard Author

Hi Luis,

It looks like you're nearly there! The error you're getting is just referring to the app flag '-a', which you're already including.

I suspect the issue is with the commands you're running. It should be:
heroku container:push -a miappmvc web
heroku container:release -a miappmvc web

(no space after "container:")

Collapse
olcay profile image
Olcay Bayram

Great job! If you do not want to use Docker, there is also a third party buildpack for .NET Core; github.com/jincod/dotnetcore-build...

Collapse
kudostoy0u profile image
Kudos Beluga

Lifesaver. Thank you so much! :D
Here's what I got at the end:
herokunett.herokuapp.com/

Collapse
alrobilliard profile image
Andrew Robilliard Author

Nice job getting it live! Thanks for sharing 😁

Collapse
ravehunter05 profile image
Francisco Paul Sotelo Rocha

thank you so much, that was very usefull

Collapse
matteodellirocioli profile image
MatteoDelliRocioli

Man you are a legend!
Thank you so much for this article! I hope you are doing well 😁

Collapse
boreal_root profile image
Boreal β˜„

Andrew, thanks.

It worked!

Collapse
shricharan29 profile image
shricharan29

will it also work for dotnet 4.7

Collapse
lukerobinett profile image
Luke Robinett

Thank you. I was intimidated by the idea of containers but this doesn't sound difficult at all. Question: what if we need a SQL database with our app?