Friday, May 19, 2017

Running ASP.NET Core MVC Application inside a Docker Linux Container from Windows

I have been having some quality time with Docker recently and wanted to get an ASP.NET Core application running in a Docker Linux Container which will run inside my Windows machine. Was having some hard time getting it to work initially, but with some great help and guidance from a fellow MVP, Alex Thissen (@alexthissen), managed to get it up and running.

Here in this post, I assume you have some basic knowledge on Docker, Docker Images/Containers. And for some of the commands, I might not be explaining what each arguments of the command does, hoping you will do --help on those.

So let’s start.

So on my machine, I have Docker for Windows installed, and there under settings, I have my local C:\ drive shared with Containers.
image
Shared Drives
Now let’s create a folder (I am creating on my Desktop, make sure the drive you are creating the folder in, is shared like above) and I am naming it as a DockerWebApp.

Open up a PowerShell window and change the directory to DockerWebApp folder.
PS C:\Users\Jaliya\Desktop\DockerWebApp> dotnet new mvc
PS C:\Users\Jaliya\Desktop\DockerWebApp> dotnet restore
PS C:\Users\Jaliya\Desktop\DockerWebApp> code .
Now the project will get opened in Visual Studio Code. I have Docker extension for VS Code installed. If you haven’t installed, I suggest you do so, so we can create Docker related files pretty easily. So using the extension, I am creating a Dockerfile as follows.
Dockerfile
Docker for VS Code - Adding Dockerfile
So my Dockerfile looks like this.
FROM microsoft/aspnetcore:1.0.1
LABEL Name=dockerwebapp Version=0.0.1
ARG source=.
WORKDIR /app
EXPOSE 30000
COPY $source .
ENTRYPOINT dotnet dockerwebapp.dll
For now, I am not going to do any changes here, but I am going to delete the other Docker files which got created inside the project which are docker-compose.debug.yml and docker-compose.yml to make things not confusing.

Now let’s publish our application.
PS C:\Users\Jaliya\Desktop\DockerWebApp> dotnet publish -c Release
And since I haven’t specify any specific output path, application will get published to bin\Release\netcoreapp1.1\publish folder.
image
Publish folder
Now let’s move to back to our Dockerfile and do following changes.
FROM microsoft/aspnetcore:1.0.1
LABEL Name=dockerwebapp Version=0.0.1
ARG source
WORKDIR /app
EXPOSE 30000
COPY ${source:-bin/Release/netcoreapp1.1/publish} .
ENTRYPOINT dotnet DockerWebApp.dll
Here first what I have done is, I don’t want to copy the whole project folder to my Image, I am just copying the publish folder. Then I have renamed the dll name in the ENTRYPOINT as in the file name in the publish folder (well I have spent quite sometime figuring out an issue because of this name mismatch).

Now let’s build the Docker Image, so I can create a Container out of it.

For that I am running the following command.
PS C:\Users\Jaliya\Desktop\DockerWebApp> docker build -t dockerwebapp .
I am seeing the following output.
image
docker build -t dockerwebapp .
All seem to be good, there is a warning at the end, we can basically ignore that for now for the sake of this demo. Now let’s run the following command to confirm whether our image is created.
PS C:\Users\Jaliya\Desktop\DockerWebApp> docker images
SNAGHTML82e020a
docker images
Yes, it is created, now let’s try to run it.
PS C:\Users\Jaliya\Desktop\DockerWebApp> docker run dockerwebapp
Now I am getting an error “The specified framework 'Microsoft.NETCore.App', version '1.1.2' was not found.”.
image
docker run dockerwebapp
Of course, I have been using an older aspnetcore image, I am changing the Dockerfile as follows.
FROM microsoft/aspnetcore:1.1.2
LABEL Name=dockerwebapp Version=0.0.1
ARG source
WORKDIR /app
EXPOSE 30000
COPY ${source:-bin/Release/netcoreapp1.1/publish} .
ENTRYPOINT dotnet DockerWebApp.dll
Here is the link where you can find the list ASP.NET Core Docker image information.
https://hub.docker.com/r/microsoft/aspnetcore/

Now let’s run a docker build again.
PS C:\Users\Jaliya\Desktop\DockerWebApp> docker build -t dockerwebapp .
image
docker build -t dockerwebapp .
Now let’s run the image again.
image
docker run dockerwebapp
Yes, it seem to be working. Let’s run the following command in a new PowerShell Window to see the status of all the running Containers.
PS C:\Users\Jaliya> docker ps
Here note that I am running the command from another directory. You can run docker ps from sitting inside any directory.
image
docker ps -a
Now from let’s try to access to site http://localhost:30000 from a browser.
image
Site can't be reached
That’s because I haven’t mapped Container ports and host machines ports. I can easily to fix it by running docker run specifying port mappings.
PS C:\Users\Jaliya\Desktop\DockerWebApp> docker run -p 30000:80 dockerwebapp
image
docker run -p 30000:80 dockerwebapp
And now if I check for running Containers, I can see the ports are mapped.
image
docker ps
Now let’s browse to http://localhost:30000 back again. And this time, it works!
image
Site is running
In this post, I have used following commands in the background.
# List running containers
docker ps
 
# List all containers
docker ps -a
 
# List all images
docker images
 
# Stop given container
docker stop {container_name}

# Stop all containers
docker stop $(docker ps -aq)
 
# Delete given container
docker rm {container_name}
 
# Delete given image
docker rmi {image_id}
 
# Delete all containers
docker rm $(docker ps -a -q)
 
# Delete all images
docker rmi $(docker images -q)

# Remove all stopped containers
docker container prune

# Remove all images which are not used by existing containers
docker image prune -a

# Remove all unused containers, networks, images (both dangling and unreferenced), and optionally, volumes.
docker system prune
Hope you find this post helpful.

Again huge thanks goes out to Alex Thissen (@alexthissen) for all his help.

More reads,
Running and Exploring a Docker Linux Container

Happy Coding.

Regards,
Jaliya

2 comments:

  1. Have you pushed this resulting image to the public Docker hub? Basically as I understand, this seems to be a Debian based image so the same image should be able to spawn containers on a Linux host as well right?

    ReplyDelete
    Replies
    1. Thank you for your interest in this post. I am sorry, No, I didn't push the image that I have created here to Docker Hub. But I believe we should be able to run this Image on a Linux host (well I am seeing no reason for why we can't). Will try that out soon and will put a comment.

      Thanks again.

      Delete