Building and Running a .NET Core Container from the CLI

Posted by

Visual Studio 2019 is a boon and a crutch for developers. Its rich features make it effortless to get applications up and running. That ease of use comes at the cost of not developing a deep understanding of how it all works behind the scenes. The same is true for its Docker integration.

It’s inevitable that you’ll eventually encounter an issue that requires you to dig into the Docker abstraction that Studio presents. I already dissected some of what’s going on with the past few posts. This time, I’ll look at the commands to build and run an ASP.NET Core container from the command line. But before we can look at those details, there’s a Visual Studio optimization that needs to be explained.

Container Fast Mode

Running an application that’s configured for Docker in Visual Studio is as effortless as pressing the Start Debugging button. The application is built, and then magically run in Docker. That magic is something called Container Fast Mode, which all Dockerized applications in Visual Studio use by default.

Fast Mode takes advantage of Docker’s multi-stage build process to optimize build time and image size. The process looks like this:

  • Build the application’s code as normal, outputting the compiled assemblies and symbols to the project’s bin folder.
  • Run the application in Docker
    • Download prerequisite images from Docker Hub and Microsoft’s Container Registry.
    • Execute only the base stage of the Dockerfile to create an intermediate Docker image. The base stage derives from the ASP.NET Core parent image, exposes port 80, and changes the working directory to /app.
    • Start a container with the image created in the previous step.
    • Mount the project folder (which includes bin and all of its assemblies) to the container.
    • Execute the application by invoking the right assembly in the bin folder on the container: dotnet dockerexplained.dll.

The default Visual Studio Dockerfile has fourteen steps split into four stages, including a dotnet restore, dotnet build, and dotnet publish. By running only the first stage, 75% of the Dockerfile is eliminated — resulting in some serious boosts to iteration time when testing incremental changes to an application.

Container Fast Mode can be disabled by editing the project file. The build process then follows the Dockerfile’s commands to the letter, just like the docker build command would — which is what we’ll look at now.

Building From the Dockerfile

Let’s look at the command to build the Dockerfile and then break down each of its components:

  • Open a command line to the solution folder containing your application.
  • Execute the following command:
    docker build -t dockerexplainedmanual -f "DockerExplained/Dockerfile" .
    • -t specifies the image’s name.
    • -f tells Docker where to find the Dockerfile
    • The period tells Docker to use the current folder as the build context.

The juggling of folders is awkward because of how Visual Studio structures the Dockerfile. The paths referred to within the Dockerfile are relative to the solution directory, not the project directory.

Now that the image has been built, it’s time to run it in a container.

Running in a Container

The run command can be executed from any path. It requires a few more parameters than the build command. Here’s how to start the container without blocking the terminal:

docker run -d -p 3333:80 -name mymanualrun dockerexplainedmanual

Here’s a breakdown of each of the parameters:

  • -d tells Docker to run the container in detached mode. Concretely, this means that the command line you’re executing the docker run from won’t be blocked. It’ll start the container and return you to the command prompt.
  • -p 3333:80 maps the host computer’s port 3333 to the container’s port 80. It means that if you go to localhost:3333, the traffic will hit port 80 in the container. That’s the port on which the ASP.NET Core application is listening.
  • --name tells Docker the name to give to the running container.
  • The final parameter is the image that should be run.

You should now be able to interact with the running application inside the container, be it a website or API, with tools such as Postman, Insomnia, or a plain old web browser.

Wrap Up

Building and running a container through the command line is easy. Visual Studio likes to hide the details, but they are still there if you look hard enough. It’s essential to know what’s happening behind the abstraction, so you can change settings in full confidence when the time comes.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s