One step further into Docker world, the biggest question I have to ask myself is “where do I want to go?“. What do I know about Docker? How could I explain in a simple sentence?
As far as I’ve known so far, Docker gives me a box (container), in which I can run something in an isolated environment. When I do not need it, I might throw it away. And when I need it, I can build it quickly.
Given that I have a box, and I can open the box, what will I put in? what should I do with the box?
As a developer, the first thing I want to try is to put some code inside the box and be able to run it. Yes! That’s right! I will put ASP.NET Core web application code into the box, and run it.
In this post, I will go through all the things I have learned, collected so far and put them into practice.
Hey, Boss! How Do I Get The Source, Docker Asked?
Calm down! Calm down! Docker. Let’s me show you where to get the stuff you need.
External – Mounted Volume
Docker can refer to the source from an external (relative to itself) system. In a development environment, it is our host system, the folder where we put our code.
I will install a container that specializes for .NET Core. Should be easy, just head over to Docker hub, find Microsoft. Take the microsoft/aspnetcore image. Time to type some fun commands with Docker in Powershell (I started to love CLI interface). Because I am going to use it for a while, I will pull aspnetcore image from the registry.
docker pull microsoft/aspnetcore hit enter. Boom! you have the image ready to serve you.
As a good habit should run the docker images and docker inspect to look into the container. Just to make sure everything is in place.
To connect, Docker introduces the Data Volume concept. You can read the full document at the website. However, I would like to go with the basic approach.
Think of Data Volume is a mean define a mapping between a location inside the Container and a location on the host machine.
We have
- A Docker container that can host and run a website.
- A folder where we develop our source code.
And Data Volume allows a running container access that folder. When it finishes, the folder is still intact. All the changes that the container made, persists there. Let’s try out.
I want to run a container that will start my website. Breaking down to small steps, when running a container, it must
- Start the container instance in background mode
- Connect to the folder where my code hosted (local drive)
- Start a Kestrel server to run my application
While experience, it seems I need to use the aspnetcore-build image instead. Because I need the Core SDK to run and build my application. Jump over the Powershell, I run my very first command with a smile. Boom! it does not work
Let’s try to make it worked first and then I will explain every single part in the command.
The best way we should do when investing an issue is to look into it, docker inspect command is your friend.
Something is wrong with the volume mapping.
After some investigations, the correct syntax that I should use
docker run --name coconut -i -p 5000:80 -v ${pwd}:/app -w /app microsoft/aspnetcore-build bash -c "dotnet restore && dotnet run"
In term of speaking language, the above command says
I want to run a container from the microsoft/aspnetcore-build image, named it as coconut. Once started, create a volume mapping between the current host folder (via ${pwd} keyword) and app folder in the container, create a port mapping between port 5000 (host machine) and port 80 (on the container). The finally runs the command dotnet run with under working folder app.
Just like before, I hit another error, saying that I should share the drive with the Docker. The solution is written here.
I must admit that thing is not easy as it seems. After struggling for a while, I finally manage to get it worked.
Pay attentions to
bash -c “dotnet restore && dotnet run”
The command instructs the container to restore NuGet packages and then run the application.
And
-p 5000:80
Once the application is started in the container, the website is exposed via port 80. Note: if you start an application on your host machine, it is exposed via port 5000. That is also why I take the port 5000 on the host machine.
Initially, I wanted to write both the data mounted volume and Dockerfile in one post. However, the more I get my hands dirty, the more I learn. It is better to recap what I reap.
Recap
To run a container that starts an aspnet core application, uses this command
docker run --name coconut -i -p 5000:80 -v ${pwd}:/app -w /app microsoft/aspnetcore-build bash -c "dotnet restore && dotnet run"
The port mapping (-p 5000:80) is very important. It allows you to access your website from the host browser. To know the port that dotnet exposes after running the website, you should look at the output in the container console.
To map your current working directory to a folder in the container, use -v ${pwd}:/app. The ${pwd} on Powershell will get the current directory.
Because I made many mistakes, I learn to use the docker stop/start/rm commands. Now they are mine 🙂
Evil is everywhere. You should use docker inspect to look inside the container.
One of the biggest achievements is the feeling of getting started, of getting into. I am able to use many commands at my disposal.
What’s Next?
Finish what I have started – Use Dockerfile to build and ship my applications.
Updated: Part 2 ASP.NET Core with Docker Container – Part 2 Dockerfile.