{"id":36882,"date":"2017-02-20T10:45:06","date_gmt":"2017-02-20T18:45:06","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/webdev\/?p=9255"},"modified":"2017-02-20T10:45:06","modified_gmt":"2017-02-20T18:45:06","slug":"lets-try-wcf-self-hosted-services-in-a-container","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/lets-try-wcf-self-hosted-services-in-a-container\/","title":{"rendered":"Let\u2019s Try WCF Self-Hosted Services in a Container"},"content":{"rendered":"<p>Microservices are a hot architecture concept right now, and we hear a lot of interest in the architecture concepts.\u00a0 Many of the ideas and capabilities behind microservices are already possible with the WCF frameworks for client and server creation.\u00a0 There is one tenet about microservices that you can not do with WCF: run inside of a container.\u00a0 Until now\u2026\u00a0\u00a0 In this article, we\u2019re going to take a look at running a simple WCF self-hosted service inside of a Docker container. The architecture that we are going to assemble in this article is quite simple:\u00a0 our self-hosted HTTP service will run inside of a Docker container on our workstation and we will be able to use a client on the same machine to connect through the container and interact with the service.\u00a0 The following diagram illustrates the desired configuration: <figure id=\"attachment_9296\" aria-labelledby=\"figcaption_attachment_9296\" class=\"wp-caption aligncenter\" ><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspnet\/wp-content\/uploads\/sites\/16\/2017\/02\/0-architecture-300x157-1.png\" alt=\"Architecture of our sample\" class=\"wp-image-9296 size-medium\" title=\"Architecture of our sample\" width=\"300\" height=\"157\" \/><figcaption id=\"figcaption_attachment_9296\" class=\"wp-caption-text\">Architecture of our sample<\/figcaption><\/figure><\/p>\n<h2>WCF Services Run on Windows<\/h2>\n<p>WCF runs on the .NET framework, which means that it only runs on Windows.\u00a0 Fortunately, we have Windows Server Core images available to us.\u00a0 If we<\/p>\n<p><a href=\"https:\/\/www.docker.com\/products\/docker#\/windows\">install Docker for Windows<\/a> on Windows 10 or Windows Server 2016 with container support enabled, we can configure Docker to use Windows containers.\u00a0 Right click on the Docker whale icon in the system tray and you can choose to \u201cSwitch to Windows Containers\u201d to get started: <figure id=\"attachment_9265\" aria-labelledby=\"figcaption_attachment_9265\" class=\"wp-caption aligncenter\" ><img decoding=\"async\" src=\"\" alt=\"Switch to Windows Containers\" class=\"wp-image-9265 size-medium\" width=\"300\" height=\"241\" \/><figcaption id=\"figcaption_attachment_9265\" class=\"wp-caption-text\">Switch to Windows Containers<\/figcaption><\/figure> Lets open a command prompt and grab a copy of the Windows Server Core docker image to get started:<\/p>\n<pre>docker pull microsoft\/windowsservercore<\/pre>\n<p>We will build our minimal set of WCF requirements on top of this image.<\/p>\n<h2>Our WCF Sample Code<\/h2>\n<p>Let\u2019s build a simple service to add to a container and then a client to consume the service from the container.\u00a0 I will start with a service library project that is almost identical to the default project template for a WCF Service Library.\u00a0 I will simply change the GetDataUsingContract method to interpret the StringValue with a slightly different string:<\/p>\n<p>We can then add a simple Windows Console application to the solution that will serve as the host of our service.\u00a0 The Program class is simple and references the Service1 type from our ServiceLibrary project:<\/p>\n<p>The app.config for this project needs to contain some information about the address, endpoint, and behaviors of our service.\u00a0 Lets fill that out with some simple MetadataExchange and BasicHttpBinding:<\/p>\n<p>Finally, we need a client that will connect to the service and interact with the IService1 service contract.\u00a0 This is another Windows Console application.\u00a0 This time we add a service reference to the project and point to the MyServiceLibrary project.\u00a0 My solution looks like the following: <figure id=\"attachment_9295\" aria-labelledby=\"figcaption_attachment_9295\" class=\"wp-caption aligncenter\" ><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspnet\/wp-content\/uploads\/sites\/16\/2017\/02\/2-SolutionExplorer-2.png\" alt=\"My Solution Explorer\" class=\"wp-image-9295 size-full\" width=\"257\" height=\"442\" \/><figcaption id=\"figcaption_attachment_9295\" class=\"wp-caption-text\">My Solution Explorer<\/figcaption><\/figure> When I add the service, I right click on the WCFClientBasic project and choose \u201cAdd\u00a0 &#8211; Service Reference\u201d which brings up the following dialogue: <figure id=\"attachment_9275\" aria-labelledby=\"figcaption_attachment_9275\" class=\"wp-caption aligncenter\" ><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspnet\/wp-content\/uploads\/sites\/16\/2017\/02\/3-AddServiceReference-1.png\" alt=\"Add Service Reference\" class=\"size-full wp-image-9275\" width=\"586\" height=\"554\" \/><figcaption id=\"figcaption_attachment_9275\" class=\"wp-caption-text\">Add Service Reference<\/figcaption><\/figure> I clicked \u201cDiscover\u201d and located the entry from MyServiceLibrary to add to the WCFClientBasic project.\u00a0 With that reference added, I can write some simple client code to connect to the service and demonstrate some basic data interactions:<\/p>\n<p>With that code in place, that simply creates a client connection to the Service and executes the GetData and GetDataUsingDataContract, we can run this sample client code in the Visual Studio debugger and verify that it works.<\/p>\n<h2>Deploying the WCF Host to Docker<\/h2>\n<p>I\u2019ll start by creating a publish folder on disk inside of my solution. Next, I\u2019ll take the simple host application and copy the EXEs, DLLs, and config files into a folder named bin within the publish folder.\u00a0 I\u2019ll then create a Dockerfile at the root of publish with this content:<\/p>\n<p>This file directs Docker to add the WCF-HTTP Activation feature to Windows Server Core, and then copy our host content to the c:app folder.\u00a0 It exposes port 83, as was configured in our host\u2019s app.config file earlier.\u00a0 Finally, it launches the BasicHttpHost application.\u00a0 We can build this Dockerfile into a Docker image by executing the docker build command like so:<\/p>\n<pre>docker build -t wcfhost:latest -t wcfhost:1 .<\/pre>\n<p>This creates an image called \u201cwcfhost\u201d with a version of 1 that is also tagged as the latest version.\u00a0 This build step will take a few minutes for Windows to configure the WCF features inside the container.\u00a0 Once complete, you can launch an instance of your host with this command:<\/p>\n<pre>docker run -itd --name host wcfhost<\/pre>\n<p>We can then inspect the container to determine the IP address of our service.\u00a0 We can use a format string to grab the IP address directly from the container information:<\/p>\n<pre>docker inspect -f=\"{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}\" host<\/pre>\n<p>Copy that IP address into the app.config of the WCFClientBasic project and update the endpoint address from localhost:83 to your ip address (mine was 172.19.18.87).\u00a0 You should then be able to run your WCFClientBasic and have it attach to the container, returning the expected text results in a console window: <figure id=\"attachment_9285\" aria-labelledby=\"figcaption_attachment_9285\" class=\"wp-caption aligncenter\" ><img decoding=\"async\" src=\"\" alt=\"Results from Docker\" class=\"wp-image-9285 size-mediumlarge\" width=\"500\" height=\"127\" \/><figcaption id=\"figcaption_attachment_9285\" class=\"wp-caption-text\">Results from Docker<\/figcaption><\/figure><\/p>\n<h2>Summary<\/h2>\n<p>We\u2019ve shown how WCF services can be configured using the standard WindowsServerCore container image.\u00a0 There are other Windows options and features that can be configured in this container, based on your service\u2019s needs. The container architecture allows us to scale our service easily as well as deploy the same binaries and configuration that we run in development and staging into a production environment.<\/p>\n<p>Is this something that you might use with your existing WCF services?<\/p>\n<p>The WCF team is working on simplifying Docker integration with service creation and debugging.\u00a0 We would like to hear from you about how you use WCF services and what you want in a containerized WCF solution.\u00a0 Let us know your thoughts in the comment area below and we\u2019ll follow up as we work to bring container support to WCF.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Microservices are a hot architecture concept right now, and we hear a lot of interest in the architecture concepts.\u00a0 Many of the ideas and capabilities behind microservices are already possible with the WCF frameworks for client and server creation.\u00a0 There is one tenet about microservices that you can not do with WCF: run inside of [&hellip;]<\/p>\n","protected":false},"author":405,"featured_media":58792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[197,7257],"tags":[60],"class_list":["post-36882","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aspnet","category-wcf","tag-docker"],"acf":[],"blog_post_summary":"<p>Microservices are a hot architecture concept right now, and we hear a lot of interest in the architecture concepts.\u00a0 Many of the ideas and capabilities behind microservices are already possible with the WCF frameworks for client and server creation.\u00a0 There is one tenet about microservices that you can not do with WCF: run inside of [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/36882","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/405"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=36882"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/36882\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/58792"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=36882"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=36882"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=36882"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}