Deploying Multi-Container Services on Azure Service Fabric
Tags: azure, servicefabric, docker, microservices
Published: 2020-04-14 00:58:59

---
title: Deploying Multi-Container Services on Azure Service Fabric
published: true
date: 2020-04-13 00:00:00 UTC
tags: azure, servicefabric, docker, microservices
cover_image: https://sahansera.dev/static/9932328fc3bacd336005d98df44e5010/17e59/chuttersnap-9cCeS9Sg6nU-unsplash.webp
canonical_url: https://sahansera.dev/deploying-multi-container-services-on-azure-service-fabric/
---

To give you a bit of context on what we will be looking at today, we will have one goal - to deploy a microservices application to Azure with Service Fabric. My preferred choice of a cloud these days would be Azure since I have been working on it for a while now.

To keep things simple, we will be looking at the deployment of a multi-container application rather than worrying too much about what the application does.

### Prerequisites

If you followed my [previous post](https://sahansera.dev/getting-started-with-azure-service-fabric/), you would already have the below mentioned installed on your developer workstation.

1. Docker Desktop
2. Azure account
3. Azure Service Fabric SDK and tooling

### Creating a demo app

Now that we have some basic understanding of what Azure Sevice Fabric is capable of, let’s look at what we are going to building today

1. Create a containerised React app
2. Create a containerised .NET Core service
3. Create a Service Fabric project
4. Wrap our above-mentioned service in the Service Fabric project
5. Build a CI/CD pipeline in Azure DevOps

At a glance, this will be the architecture of our demo project.

### Scaffolding our multi-container application

You can clone my Github repository to get started.

```bash
git clone https://github.com/sahan91/deploying-containers-on-service-fabric.git
```

The folder structure is as follows:

![ProjectStructure.jpg](https://sahansera.dev/static/5e180521697f43f878078db4211e7c34/f67cc/ProjectStructure.jpg)

For each project, I have created a Dockerfile. What they basically do is, build each project and expose a port from their respective containers.

_Web - Dockerfile_

```docker
# Stage 1 - the build process
FROM node as build-deps
WORKDIR /usr/src/app
COPY web-client/package.json web-client/yarn.lock ./
RUN yarn --no-bin-links
COPY ./web-client/. ./
RUN yarn build

# Stage 2 - the deploy process
FROM nginx
COPY --from=build-deps /usr/src/app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
```

The reason for having stages here is because we don’t want to include the source code in the container since we only need to copy the executable or the build output over to the container.

_ProductCatalog - Dockerfile_

For the .NET Core project, we have a bit more involved since we need to have the .NET Core 3.1 SDK to build the project and .NET Core 3.1 runtime to run the project.

```docker
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY ./*.sln .
COPY ./ProductCatalog/*.csproj ./ProductCatalog/
RUN dotnet restore

# Copy everything else and build
COPY ./ProductCatalog/. ./ProductCatalog
WORKDIR /app/ProductCatalog
RUN dotnet publish -c Release -o app

# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS runtime
WORKDIR /app
COPY --from=build-env /app/ProductCatalog/app .
ENTRYPOINT ["dotnet", "ProductCatalog.dll"]
```

### Building and tagging images

We can run the following command to test out our images locally.

If you haven’t used Docker Hub before. Here’s a [quick intro](https://ropenscilabs.github.io/r-docker-tutorial/04-Dockerhub.html) to creating a repository and pushing images.

In a terminal, navigate to `ProductCatalog/` folder and run the following command

```bash
docker build -f . -t <your_docker_hub_username>/service-fab:product-catalog-img
```

Now change directory to `Web/` folder, let’s build and tag backend service’s Docker image

```bash
docker build -f . <your_docker_hub_username>/service-fab:web-shop-img
```

### Pushing the images to Docker Hub

In order for Service Fabric to fetch and build our container images, we need to first push them to a container registry. I’m using Docker Hub here as an example. But you can use any other registry such as GCR, ACR etc. These repositories can be either public or private.

Make sure you are already logged in to Docker service from the command line,
```bash
docker login --username=yourhubusername --email=youremail@company.com
```

Check the image ID using,
```bash
docker images
```

This will come in handy in the following command.

Now let’s push the images with,
```bash
docker push <image_name>
```

We need to run this command twice for both frontend and backend images we created.

### Configuring Service Fabric project

Let’s open up `WebShop` solution in Visual Studio. You can configure the credentials in your Service Fabric project.

**Frontend configuration** 
_WebShopClientPkg/ServiceManifest.xml_

```xml
<!-- Code package is your service executable. -->
<CodePackage Name="Code" Version="1.0.0">
  <EntryPoint>
    <!-- Follow this link for more information about deploying Windows containers to Service Fabric: https://aka.ms/sfguestcontainers -->
    <ContainerHost>
      <ImageName> **index.docker.io/sahan/service-fab:web-shop-img** </ImageName>
    </ContainerHost>
  </EntryPoint>
  <!-- Pass environment variables to your container: -->
  <!--
  <EnvironmentVariables>
    <EnvironmentVariable Name="VariableName" Value="VariableValue"/>
  </EnvironmentVariables>
  -->
</CodePackage>
```

**Backend service configuration** 
_WebShopApiPkg/ServiceManifest.xml_

```xml
<!-- Code package is your service executable. -->
<CodePackage Name="Code" Version="1.0.0">
  <EntryPoint>
    <!-- Follow this link for more information about deploying Windows containers to Service Fabric: https://aka.ms/sfguestcontainers -->
    <ContainerHost>
      <ImageName> **index.docker.io/sahan/service-fab:product-catalog-img** </ImageName>
    </ContainerHost>
  </EntryPoint>
  <!-- Pass environment variables to your container: -->
  <!--
  <EnvironmentVariables>
    <EnvironmentVariable Name="VariableName" Value="VariableValue"/>
  </EnvironmentVariables>
  -->
</CodePackage>
```

Note how I have replaced the path to the Docker Hub registry in both configs.

### Creating a Service Fabric cluster

Before deploying our services, we need to create a Service Fabric cluster in Azure. In the Azure portal, just type in `service fabric` and click on `Create service fabric cluster`.

Now, fill in the cluster info as shown below.

![service-fabric.png](https://sahansera.dev/static/f8e46bfa1ce3dd6705ae079b26298806/11d19/service-fabric.png)

In the cluster configuration step, you will be asked to set the Node type count. Just set it to 2 to denote frontend and backend services. In the same page, you will be asked how many nodes you want to create for each node type. Select _Single node cluster,_ for now, otherwise, you will be charged for the total number of VMs. However, this is not recommended for production-grade apps.

In order to expose our frontend and backend services let’s enter endpoints as port `80` and `81` respectively.

![service-fabric-1.png](https://sahansera.dev/static/d19b46189464ad5deb38fff07e86a3a5/11d19/service-fabric-1.png)

Next up, we need to create a key vault for our service fabric cluster. This is a very important step and make sure to select the `Azure Virtual Machines for deployment` checkbox. You will also need to enter a name for the certificate. We will cover this in a bit. Give it some time to create the key vault and proceed to the next step.

![service-fabric-2.png](https://sahansera.dev/static/578213ce8e749222afb5d68cb9405598/11d19/service-fabric-2.png)

![service-fabric-3.png](https://sahansera.dev/static/66a929672c9d2a1993f9b5712187ff24/11d19/service-fabric-3.png)

Once it’s up, you will see your cluster like so,

![service-fabric-4.png](https://sahansera.dev/static/4e32146d33d31913ba191ce1bfc6d49c/11d19/service-fabric-4.png)

It may take up to 15 minutes until your VMs start to appear under the Nodes list.

### Installing client certificate

In order to be able to access the Service Fabric dashboard, you need to install the client certificate from the key vault.

1. Head over to Azure Portal → `Key Vault` → _Select the key vault we created in the previous step’s Certificates_
2. Select the certificate (there should be only 1 at this stage)
3. Click _Download PFX/PEM format_

![service-fabric-5.png](https://sahansera.dev/static/9aa6725ce0e4ae1f8f421f50b79b571a/11d19/service-fabric-5.png)

Once downloaded double click the certificate. You don’t need to enter anything in the Password field and click Next and complete the wizard.

![service-fabric-6.png](https://sahansera.dev/static/aeb115e4dd6cd5c6f09e5b4d6dbc780a/11d19/service-fabric-6.png)

Now, you should be able to access the dashboard of your cluster. The link will be in Service Fabric home page in Azure Portal.

![service-fabric-7.png](https://sahansera.dev/static/7f00ac47d60afac3df37c46aa5f95437/11d19/service-fabric-7.png)

### Deploying to Azure

The fast and the quickest way to deploy your app is by using Visual Studio. Just right click on the service fabric project and select `Publish`

![service-fabric-8.png](https://sahansera.dev/static/34dee6de31af92d1c6df2d909d945a26/11d19/service-fabric-8.png)

![service-fabric-9.png](https://sahansera.dev/static/7c34c5c93dacbed146fea00a57a83407/11d19/service-fabric-9.png)

After about 5 minutes you should be able to see that our services have got deploy to the cluster. You can check that from the following URL:

`http://<yourclustername>.<yourclusterregion>.cloudapp.azure.com/`

Or, you can get the URL from service fabric portal and remember to delete the port number and revert it to `http://`

Our frontend running at port 80

![service-fabric-10.png](https://sahansera.dev/static/2f8ad0935573fcd5280c1aa29b23f4b8/11d19/service-fabric-10.png)

Our backend service running at port 81

![service-fabric-11.png](https://sahansera.dev/static/c7724ce7f9a9c5fe85594a8da7bd4f3c/11d19/service-fabric-11.png)

In my next post, we will look at how to set up an Azure DevOps build pipeline to deploy your services to a designated Service Fabric cluster. ✌

### References

1. [https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-overview](https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-overview)