Part 1 – Web Farm Example (Docker, Redis Cache, Haproxy, .Net Core Web API)

In these article series, I will try to create a web farm sample step by step. In this sample, there will be a web api project as a web server (.net core framework) and a load balancer (haproxy). I will reproduce the web api to test load balancer. These web api projects will use the same cache server(redis) to sharing data. Finally, I will simulate this web farm on docker.

Web farm working simulation

I won’t go into the details of how to install/configure docker on windows. There are documents about this in here. And there is a Getting Started document as well.

Creating Web API Project

First I create basic web api project from template.

Create an asp.bet core web application (.net core)

Select the web api template

And I change the values controller to set/get/remove memory cache keys.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Distributed;
 
namespace WebFarmExample.Controllers
{
    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        private readonly IDistributedCache _memoryCache;
 
        public ValuesController(IDistributedCache memoryCache)
        {
            _memoryCache = memoryCache;
        }
 
        [HttpGet("SetCacheData")]
        public IActionResult SetCacheData()
        {
            try
            {
                var time = DateTime.Now.ToLocalTime().ToString(CultureInfo.InvariantCulture);
                var cacheOptions = new DistributedCacheEntryOptions
                {
                    AbsoluteExpiration = DateTime.Now.AddYears(1)
                };
                _memoryCache.Set("serverTime"Encoding.UTF8.GetBytes(time), cacheOptions);
 
                return Json(new { status = true });
            }
            catch (Exception ex)
            {
                return Json(new { ex = ex });
            }
        }
 
        [HttpGet("GetCacheData")]
        public string GetCacheData()
        {
            try
            {
                var time = Encoding.UTF8.GetString(_memoryCache.Get("serverTime"));
                ViewBag.data = time;
 
                return time;
            }
            catch (Exception ex)
            {
                return ex.GetBaseException().Message;
            }
        }
 
        [HttpGet("RemoveCacheData")]
        public bool RemoveCacheData()
        {
            _memoryCache.Remove("serverTime");
 
            return true;
        }
 
        // GET api/values
        [HttpGet]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1""value2" };
        }
 
        // GET api/values/5
        [HttpGet("{id}")]
        public string Get(int id)
        {
            return "value";
        }
 
        // POST api/values
        [HttpPost]
        public void Post([FromBody]string value)
        {
        }
 
        // PUT api/values/5
        [HttpPut("{id}")]
        public void Put(int id, [FromBody]string value)
        {
        }
 
        // DELETE api/values/5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }
    }
}

Configure Web API Project for Docker

To run web api project on docker, first, I am adding a Dockerfile to project root folder. And I am modifying it like following.

FROM microsoft/aspnetcore:1.1.2
 
WORKDIR /app
COPY . .
 
ENTRYPOINT ["dotnet""WebFarmExample.dll"]

Above lines, there is a config : aspnetcore:1.1.2 this is the version of aspnetcore.mvc version in .csproj file;


Also, we should change “Copy To Output Directory” property of Dockerfile to “Copy always” to copy this file to publish folder. If we don’t set this property, we should add Dockerfile to publish folder manually.

Change docker file property

Now, web api project is ready to publish and run it on docker.

Prepare Powershell Scripts to Build Web API Project And Run Docker

First, I prepared a powershell script that named build-all.ps1 to publish web api project and build Dockerfile to create docker image.

# COMMON PATHS

$dockerFolder = (Get-Item -Path "./" -Verbose).FullName
$dOutputFolder = Join-Path $dockerFolder "outputs"
$slnFolder = Join-Path $dockerFolder "../"
$webapiFolder = Join-Path $slnFolder "WebFarmExample"

## CLEAR ######################################################################

Remove-Item $dOutputFolder -Force -Recurse
New-Item -Path $dOutputFolder -ItemType Directory

## RESTORE NUGET PACKAGES #####################################################

Set-Location $slnFolder
dotnet restore

## PUBLISH WEB API PROJECT ###################################################

Set-Location $webapiFolder
dotnet publish --output (Join-Path $dOutputFolder "webapi")

## CREATE DOCKER IMAGES #######################################################

# Webapi
Set-Location (Join-Path $dOutputFolder "webapi")

docker rmi ali/webapi -f
docker build -t ali/webapi .

## FINALIZE ###################################################################

Set-Location $dockerFolder

Actually, above script is the basic powershell script to create a publish folder for web api project and move this folder to  WebFarmExample > docker_config > outputs.

All our docker files and powershell scripts are located in WebFarmExample > docker_config.

I created a docker-compose.yml to manage docker images.

version: '2'

services:

    ali_webapi:
        image: ali/webapi
        environment:
            - ASPNETCORE_ENVIRONMENT=Development
        ports:
            - "9901:80"

And up.ps1 for docker compose commands.

docker rm $(docker ps -aq)
docker-compose up -d ali_webapi

Publish Web API project on Docker

To publish web api project and run it on docker, I am opening powershell window on WebFarmExample > docker_config and runnig build script.

poweshell build web api project

When I run this command, it creates an ouputs folder that contains wep api publish folder in following location.

powershell script web api publish

As you can see, Dockerfile is published, too. Now, we can run up.ps1 script.

powershell script to docker compose up

Now, web api project is running on docker. Let’s check if it is realy working! First, I will check if the docker container is running. When I run the command docker ps, I can see the container is running.

Powershell script to list container

And I am checking it with browser. I set port in docker-compose.yml, before.

web api project browser test

I finished web api step. At next step, I will try to add redis cache to store web api keys.

Source code of the project finished version: https://github.com/alirizaadiyahsi/WebFarmExample

Part 2 – Web Farm Example (Docker, Redis Cache, Haproxy, .Net Core Web API)

Part 3 – Web Farm Example (Docker, Redis Cache, Haproxy, .Net Core Web API)

 

#net-core, #docker, #haproxy, #redis-cache, #web-api, #web-farm