WCF has always been a preferred framework for Service oriented applications until REST became popular. Even then WCF services are very relevant and widely used in the industry. Can we not create microservices using WCF? Should all the microservices follow REST principles only ? Not really.. WCF services can very well be deployed as Microservices and that’s exactly what we are going to learn in this post.

Prerequisites

Getting started

Since the focus of this post is to understand how we can deploy a WCF service in windows containers, we will be using the default WCF service created using WCF project template. (I will be using Visual Studio 2017, however the same works with 2015 as well)

This post is just an extension to the samples and readme provided in the below Microsoft github’s repo. The sample app can be downloaded from Github at : https://github.com/Microsoft/wcf-docker-samples/tree/master/4.6.2/WcfBasicIISHost

  1. Clone the repo and open the solution in VS 2017/2015.
  2. Open the Dockerfile located at the root directory.
  3. If the Dockerfile is not visible in Visual Studio, right click on Solution -> Add existing item and select the dockerfile present in the root folder of the solution.
  4. Build the project, right click the WcfServiceTest project and publish. Create a new publish profile and publish into a folder within the root directory of the solution. (This is a very important step, as we would be copying the published website from the local machine to the container from this folder). I have published the website within a folder called Published under the root directory.
  5. Modify the dockerfile to reflect the paths properly. The dockerfile should look like the one below
# install WCF basic docker image
FROM microsoft/wcf
# Next, this Dockerfile creates a directory for your application
RUN mkdir C:\WcfServiceTest
# configure the new site in IIS.
RUN powershell -NoProfile -Command \
Import-module IISAdministration; \
New-IISSite -Name "WcfServiceTest" -PhysicalPath C:\WcfServiceTest -BindingInformation "*:83:"
# This instruction tells the container to listen on port 83.
EXPOSE 83
# The final instruction copies the site you published earlier into the container.
COPY /Published/ C:\WcfServiceTest

As the comments indicate, we are trying to create the image for our app using microsoft/wcf image, we then create a new folder (wcfservicetest)within the container, and then add a new site to the IIS – note that the WCF image is built on top of microsoft/iis image, so we don’t have to install IIS – copy the contents of our published folder to the folder within the container (wcfservicetest) and then expose the port83 for the host to access the same.

Build the docker image

Next is to build the actual image using this dockerfile. To build an image use the below command from the root directory of the application(where the dockerfile is also present)


docker build -t wcf-iis-host .

You should be seeing the below output from your powershell window


Sending build context to Docker daemon 29.76 MB
Step 1/5 : FROM microsoft/wcf
---> a7bf2990ed31
Step 2/5 : RUN mkdir C:\WcfServiceTest
---> Using cache
---> 15b00b631be3
Step 3/5 : RUN powershell -NoProfile -Command Import-module IISAdministration; New-IISSite -Name "WcfServiceTest
" -PhysicalPath C:\WcfServiceTest -BindingInformation "*:83:"
---> Using cache
---> cd352e934940
Step 4/5 : EXPOSE 83
---> Using cache
---> 1d85bd85e4af
Step 5/5 : COPY /Published/ C:\WcfServiceTest
---> Using cache
---> ae55c6487ba4
Successfully built ae55c6487ba4

Run the built docker image

Now that image is available, we can run it using the below command. The below command runs the container in detached mode and maps the container port 83 to host port 83.


docker run -d -p 83:83 --name wcf-iis-host wcf-iis-host

Accessing the service running within the container

As per Docker docs and Microsoft docker hub’s instructions, accessing the running container using localhost is having issues (as of this writing) Hence to access the service we need to grab the IP address of the running container by using the below command,


docker inspect -f "{{.NetworkSettings.Networks.nat.IPAddress}}" wcf-iis-host

The last parameter is the container name that should match the name provided for --name argument while running the container. My command returned the IP address 172.24.218.147.

So to access the service WSDL, simply access http://172.24.218.147:83/Service1.svc and you should see the response as shown below:

WCF_Service_Container

Running the WCF Client

The solution also contains a WCF client to hit this service and get back the data. Modify the binding endpoints to point to the appropriate one. In my case the binding looks like below :


<client><endpoint address="http://172.24.218.147:83/service1.svc/Service1" binding ="basicHttpBinding" bindingConfiguration= "BasicHttpBinding_IService1" contract="ServiceReference1.IService1" name="BasicHttpBinding_IService1"/>
</client>

Running the client produces the below output :

WCF_Client

As of this writing http/https/NetTCP with anonymous access endpoints are supported for WCF, with more support and features getting added in future.

Advertisements