This weekend I decided to try setting up a simple Web API with .NET Core and Docker running it on Linux. The process was really straightforward. I got it up and running almost immediately. So I decided to share the process.

Set up Docker

I began setting up Docker on my Windows 10 computer. I only have Windows 10 Home so I don’t have Hyper-V so I had to set up Docker Toolbox, which uses VirtualBox as a VM. If you have Windows 10 Pro/Enterprise version of Windows 10 (with Hyper-V) I would recommend Docker for Windows instead.

After setting up Docker I recommend running Docker Quickstart Terminal. It will set everything up for you. You could also run Kitematic which is a GUI and comes with Docker Toolbox. It will also set everything up for you.

Set up .NET Core SDK

Next you need to download the .NET Core SDK to be able to create .NET Core projects and use the dotnet CLI.

Create a Web API project

Next you need to create a .NET Core Web API project. I would recommend choosing the Web Application (.NET Core) otherwise you’re depending on the .NET Framework will only be able to run it on a Windows platform.

Next you can choose a scaffolding template. I chose Web API because I only want to create a simple API without MVC and views.

Now it will create your .NET Core Web API project.

dotnet CLI

The .NET Core tooling package is awesome and comes with a dotnet command line utility which you can use to create new projects, build and run them, package and publish them. Check out the documentation for more details. We will for now only be using restore, build and run.

Running the API

Go into your project directory and type the following:

This will restore/retrieve all packages you have defined in package.json, build the project and run it. You should see something like the following:

Now go to http://localhost:5000/api/values and you should see some values. By default it will run the API on port 5000 but we’ll change that later on.

To turn off the API just press CTRL+C.

Dockerizing the API

Creating a Dockerfile

Now to the fun part, Dockerizing the API! The API runs on an isolated webserver called Kestrel and as a foreground job, which makes it work really well with Docker.

Go ahead and create a new Dockerfile in your project directory with the following content:

Let’s go through this step by step.

FROM microsoft/dotnet:latest

Pull the latest microsoft/dotnet Docker image and build on top of that. We use that as a base because it contains .NET Core SDK, dotnet CLI, Kestrel webserver, etc.

COPY . /api

Copy everything in the current directory (.) to a new directory /api in our new Docker image. This is basically just copying our Web API project into the new Docker image.

WORKDIR /api

Set the working directory as our /api directory where our Web API project lives, so all commands will be executed there.

RUN [“dotnet”, “restore”]

Run the dotnet restore command, which will restore all packages defined in our project.json file.

RUN [“dotnet”, “build”]

Run the dotnet build command, which will build our project.

ENV ASPNETCORE_URLS http://*:5000

Set an environment variable ASPNETCORE_URLS defining the listening port for our API. This is where you can change your listening port to whatever you desire. The * just binds the listener to all interfaces. I think you can also use 0.0.0.0.

EXPOSE 5000/tcp

Just informs Docker that the container listens on the specified network ports at runtime. Change this to whatever value you defined in the ASPNETCORE_URLS environment variable.

ENTRYPOINT [“dotnet”, “run”]

Set the entrypoint for our Docker image, so each time we run the container it executes dotnet run, which fires up our Web API.

Building a Docker image

Next we’ll create a Docker image based on our Dockerfile. Just go ahead and type the following in your project directory:

This will build a new Docker image called myapi based on your current directory (.) and your Dockerfile.

After the image has been built you can type docker images to list your images. You should see something like this:

If you get an error you probably have to connect the Docker Engine to your VM. You can do that by typing docker-machine env and following the instructions.

Running a Docker container

Next we’ll run our Docker image in a new Docker container. Just type the following:

This will run the myapi Docker image in a new detached container exposing port 5000 from the host to port 5000 in the container and output the ID (some hash) of your new container.

Now to make sure your container is running type: docker ps. You should see something like this:

To stop the container you can just type docker stop with your container ID or name (obtained via docker ps). To start the container again you can just type docker start with your container ID or name.

I recommend you use --name name_of_container when running your Docker containers so you get a unique name, otherwise Docker generates some gibberish, like in this case evil_wing.

Browsing your API

Now based on how you’re running Docker you need to find the IP address of your VM. If you’re running Docker via Hyper-V you should be able to run http://localhost:5000/api/values

If you’re not running Docker via Hyper-V and using Docker Machine with VirtualBox or something, you can type docker-machine ls which will show the VM you’re running and its IP address. Then you should see something like this:

As you can see my VM has IP 192.168.99.100 so my API is accessible on http://192.168.99.100:5000/api/values

Publishing the image on Docker Hub

If you would like to publish your Docker image or run it on another computer, I recommend using Docker Hub. You get one private repository for free but unlimited public repositories.

Just create an account, then type docker login and enter your username and password in the prompt.

When you type docker ps you can see that your image name is myapi. Now that we have a Docker Hub account we have to rename the images so it’s connected to our account name. My docker account name is gaui so I type the following:

Now I can push my image to my Docker Hub account, with the following command:

And you should see the following:

And it shows up on my Docker Hub:

Then on my other server I can just type docker pull gaui/myapi and run it.