Dockerize .Net Project
First of all, let’s assume that you are developing a web api or a web page serving the static files through a .Net core web api.
To run locally your project, you have to run on your command line this comnand:
$ dotnet run
And you will see an output like this:
Hosting environment: Development
Content root path: path/to/project/root/folder
Now listening on: http://[::]:5000
Application started. Press Ctrl+C to shut down.
Now to Dockerize this project your Dockerfile should look like this:
Note that in the lines 3 and 4 we are telling to dotnet that he has to run in Production mode and bind to the 5000 port. In line 9 we are building the project and the output files will be stored on the
To build and run the Docker image/container, these are the commands:
# Build the image
docker build -t Project-Image-Name .# Run the container
docker run -d -p 5000:5000 Project-Image-Name
In the last command the
-p 5000:5000 option can be used as
-p 80:5000 to bind the container port exposed (5000) to a host port (80).
This will work either in your local machine or in a cloud server (AWS EC2, Compute Engine by Google Cloud or any VPS).
Publishing on Heroku
The second part is a little less straightforward, but the steps are pretty simple.
Once the Heroku CLI is istalled, you have to login into Heroku and the Heroku Registry.
// Login using credentials (opens a web brower)
$ heroku login// Or use this for login directly form command line
$ heroku login -i// Login into Heroku container registry (more about this later)
// Trough Heroku Cli
$ heroku container:login// Trough Docker Cli
$ docker login --username=_ --password=$(heroku auth:token) registry.heroku.com
Create a Heroku app
This part can be done directly on your Heroku Dashboard
Also, you can create the app through the CLI.
// Create an app (on the root of the project), this will create an app with a random name that you can update later
$ heroku create
Now, that the app has been created we can push a Docker image to the Heroku Registry with an url like this
registry.heroku.com/<app-name>/<process-type> . In this case as we’ve created a “fancy-project” app with a single Dockerfile (a
web process type) the url will be like
Remeber that if your project is a multi-container application, every
Dockerfile has to be a different
worker for free dyno plans).
We could just push the Docker image to the registry and see what happen, but first we have to fix the
Dockerfile and our project.
One of the first things that you have to know about deploying Docker images to Heroku is that the are some limitations. In our use case we have to notice two important restrictions.
VOLUMEcommand is not supported. Heroku uses a “ephemeral filesystem” this means that all the files that you upload or save on the container (usually the
wwwrootfolder) won’t be persistent. You will have to look for another option for storing some static files.
- Heroku ignores your
EXPOSEcommand. Heroku dynamically assign a port to your container and just listens to that port (it doesn’t matter if your project tries to bind to ports 80, 8080 or 5000 through
PORTcommands) it can be accessed inside the container as
To workaround the point 1. it’s up to you, but to solve the issue with the second point we have a few things to do.
Note that we have deleted the
VOLUME and the
ENV command that used to tell in which port the dotnet had to run. The second part it’s because Heroku will inject a
PORT environment variable to the running container (the port that your project will have to use).
We have to update the project (specifically the
Program.cs file) to dinamically select on which port to run according to that
Note that the line 13 does the same that our first
ENV ASPNETCORE_URL http://+:5000 but this time we are using the
PORT variable injected by Heroku.
Build, Push & Release
Finally it’s time to build the image…
docker build -t registry.heroku.com/<app-name>/<process-type>
docker build -t registry.heroku.com/fancy-project/web .
Push to Heroku’s registry…
docker push registry.heroku.com/<app-name>/<process-type>
docker push registry.heroku.com/fancy-project/web
Releasing the app
heroku container:release <process-type> --app <app-name>
heroku container:release web --app fancy-project
After a few moments the app will be released and you can manage it from the Heroku Dashboard o access directly from the url (something like
To join our community Slack 🗣️ and read our weekly Faun topics 🗞️, click here⬇