Docker in Visual Studio 2015

Visual Studio 2015 has a plugin available from the marketplace called Visual Studio Tools for Docker. This gives you syntax highlighting for Dockerfiles, but it doesn't integrate Visual Studio with Docker for .NET Framework apps. With Visual Studio 2015, you can add Docker support to a .NET Core project, but you need to manually write your own Dockerfile and Docker Compose files for full .NET.

Also, there's no integrated debugging for applications running in Windows containers. You can still debug code running in a container, but you need to manually configure the setup. I'll demonstrate how to do this now using the same approach as Visual Studio 2017, and with some of the same compromises.

In Visual Studio 2017, you can mount the folder containing the remote debugger from the host into your container. When you run the project, Visual Studio starts a container and executes the msvsmon.exe from the host that is the remote debugger agent. You don't need to install anything in your image to provide the debugging experience.

The remote debugger in Visual Studio 2015 is not so portable. You can mount the debugger from the host in the container, but when you try to start the agent, you'll see errors about missing files. Instead, you need to install the remote debugger into your image.

I have this set up in a folder called ch11-webapi-vs2015. In the Dockerfile for this image, I use a build-time argument to conditionally install the debugger if the configuration value is set to debug. This means that I can build locally with the debugger installed, but when I build for deployment, the image doesn't have the debugger:

ARG configuration

RUN if ($env:configuration -eq 'debug') `
{ Invoke-WebRequest -OutFile c: tools_setup_x64.exe -UseBasicParsing -Uri http://download.microsoft.com/download/1/2/2/1225c23d-3599-48c9-a314-f7d631f43241/rtools_setup_x64.exe; `
Start-Process c: tools_setup_x64.exe -ArgumentList '/install', '/quiet' -NoNewWindow -Wait }

I use the same approach as Visual Studio 2017 to mount the source directory on the host into the container when running in debug mode, but I create a custom website rather than using the default one:

ARG source
WORKDIR C:web-app
RUN Remove-Website -Name 'Default Web Site';`
New-Website -Name 'web-app' -Port 80 -PhysicalPath 'C:web-app'
COPY ${source:-.Dockerpublish} .

The :- syntax in the COPY instruction specifies a default value if the source argument is not provided. The default is to copy from the published web application unless it is specified in the build command. I have a core docker-compose.yml file with the basic service definition and a docker-compose.debug.yml file that mounts the host source location, maps the debugger ports, and specifies the configuration variable:

services:
ch11-webapi-vs2015:
build:
context: ..
dockerfile: .DockerDockerfile
args:
- source=.Dockerempty
- configuration=debug
ports:
- "3702/udp"
- "4020"
- "4021"
environment:
- configuration=debug
labels:
- "com.microsoft.visualstudio.targetoperatingsystem=windows"
volumes:
- ..WebApi.NetFx:C:web-app
The label specified in the compose file attaches a key-value pair to the container. The value isn't visible inside the container, unlike an environment variable, but it is visible to external processes on the host. In this case, it is used by Visual Studio to identify the operating system of the container.

To start the app in debug mode, I use both Compose files to start the application:

docker-compose -f docker-compose.yml -f docker-compose.debug.yml up -d

Now, the container is running my web app using Internet Information Services (IIS) inside the container, and the Visual Studio remote debugger agent is running as well. I can connect to a remote process in Visual Studio 2015 and use the IP address of the container:

The debugger in Visual Studio attaches to the agent running in the container, and I can add breakpoints and view variables, just like debugging to a local process. In this approach, the container is using the host mount for the content of the web app. I can stop the debugger, make changes, rebuild the app, and see the changes in the same container without having to start a new container.

This approach has the same benefits and drawbacks as the integrated Docker support in Visual Studio 2017. I'm running my app in a container for local debugging, so I get all the features of the Visual Studio debugger and my app is running in the same platform I'll use in other environments. But I won't be using the same image because the Dockerfile has conditional branches, so it produces different outputs for the debug and release modes.

There is an advantage to manually building debugger support in your Docker artifacts. You can construct your Dockerfile with conditioning so that the default docker image build command produces the production-ready image without requiring any additional artifacts. This example still does not use a multi-stage build, though, so the Dockerfile is not portable and the application needs to be compiled before it can be packaged.

In development, you build the image once in debug mode, run the container, and then attach the debugger whenever you need to. Your integration tests build and run the production image, so only the inner loop has the additional debugger components.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.227.4