Join us at SpringOne in San Francisco, Dec 6–8, and build the apps that make the world run.
Live is streaming live. Watch now.

.NET 4.x WCF Self Hosted App

This project demonstrates a Windows Service hosting a WCF Service. You could argue this is more of a Windows Service example than a WCF example, but it still demonstrates a common pattern for operationalizing WCF.

Dockerfile

Creates a user for the Windows Service to run under and installs the Service with installutil.exe.

FROM mcr.microsoft.com/dotnet/framework/runtime:4.7.2 AS runtime
SHELL [ "powershell" ]

WORKDIR /app
COPY SelfHostedWCFService/SelfHostedWCFService/. .

# Windows services need to run as some kind of user so we'll create one. This is just a legacy artifact 
# of how Windows Services work and the identity of this user isn't important to us so the creds aren't
# perticularly sensitive. I'm not even sure it makes sense to dial back the group the user is being put
# in to.
RUN New-LocalUser -Name "pksuser" -Password (ConvertTo-SecureString -AsPlainText "Pk$w0rd189PVTL!" -Force) \
    -FullName "PKS.User" -Description "LocalAdministrator"
RUN Add-LocalGroupMember -Group administrators -Member pksuser -Verbose

# Install the service into Windows
WORKDIR /app/bin/Release .
RUN C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe /username=.\pksuser /password=Pk$w0rd189PVTL! \
    /LogToConsole=true .\SelfHostedWCFService.exe

EXPOSE 8080

# The real business of the app lifecycle is managed by Windows due to this app being a Service so there isnt'
# really a need for us to worry about it in Docker. However, we do need some process to run that docker can
# watch so it knows we're still alive. This command let's Windows manage that lifecycle while we just watch
# the state of the service, exiting if the process dissapears thus destroying the container. 
# I'm open to better ideas.
CMD ["powershell", "while", \
    "((Get-Process | ? { $_.ProcessName -like 'SelfHostedWCFService'} | Measure).Count -gt 0)", \
    "{Start-Sleep -Seconds 1}"]

Kubernetes manifest.yml

---
apiVersion: v1
kind: Deployment
metadata:
  labels:
    app: windowsservicewcf
  name: windowsservicewcf
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: windowsservicewcf
      name: windowsservicewcf
    spec:
      containers:
      - name: webapp
        image: <DOCKER_CONTAINER_REPO/DOCKER_CONTAINER_IMAGE:tag here>
        ports:
        - containerPort: 8080
      tolerations:
      - key: "windows"
        operator: "Exists"
        effect: "NoSchedule"
      nodeSelector:
        beta.kubernetes.io/os: windows
---
apiVersion: v1
kind: Service
metadata:
  name: windowsservicewcf
  labels:
    app: windowsservicewcf
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: windowsservicewcf
  type: NodePort