Running ASP.NET Boilerplate Module Zero Core Template on Docker

0
66

Introduction

In this article, I will show you how to run ABP module zero core template on Docker, step by step. And then, we will discuss alternative scenerios like web farm with using Redis and Haproxy

As you now, Docker is the most popular software container platform. Many of developers want to use it for it’s advantages. I won’t go into the details of how to install/configure Docker on windows or what are the advantages of using Docker. There are documents about this in here. And there is a Getting Started document as well.

And also you should download Redis, too.

What is ABP Module Zero Core Template?

Module zero core template is a starter project template that is developed with using ASP.NET Boilerplate Framework. This a .net core project that is a Single Page Application with using Angular4. And also there is a multi-page MVC application, as well.But in this article, I will explain angular4 version.

In module zero core template project there are two seperate projects, one is Angular4 project as web UI and the host project that is used by angular UI. Let’s examine it to better understand the project before running it on Docker.

Getting Started

Creating Template From Site

First, I will download module zero core template from https://www.aspnetboilerplate.com/Templates site.

Before preparing project to run on Docker, let’s run the project, first. I am opening the .sln file in folder ProjectName\aspnet-core

Creating Database with Using EF Migrations

Before running project, we should create database with using EF migrations on Package Manager Console. First, I am setting Acme.ProjectName.Web.Host as start up project. (right-click Host project and select Set as Startup Project). And than, in Package Manager Console, I am running update-database command, while EntityFrameworkCore project is selected. Steps for creating database are;

  • Set Host project as Startup Project.
  • Open Package Manager Console and select Acme.ProjectName.EntityFrameworkCore as default project.
  • Run update-database command.

Running Host Project

And now, Host project is ready to run. We can run it (ctrl+f5). When I run it, a page like the one below welcomes us.

Host project is just developed for showing which services are included in API. All these services are served in application layer of project and used by Angular UI. 

Running Angular Project

Host project is already run and we can run Angular project that uses APIs. To run Angular project, make sure you have node and npm installed on your machine. First, I am running cmd on location ProjectName\angular and running npm install or just yarn command to prepare project for running.

And I am running npm start command to run project.

And cmd final screen output.

Now, Angular project is running. When you browse localhost:4200 you will see it is running.

You can log in with default user credentials. User name:admin Password:123qwe 

When you logged in, you will see the following screen.

Check HERE for more details.

Steps for running Angular project are;

  • Run cmd on location ProjectName\angular.
  • Run yarn or npm install command(I used yarn for above example).
  • Run npm start command.
  • Browse localhost:4200 to see angular project is running.

And now, whole project is running properly. Project is ready to run on docker, now. We can go to the next step.

Running Project on Docker

Before we start, let’s get to understand files and folders that are added to project to configure Docker environment. There is a folder that named docker under ProjectName/aspnet-core

In docker/ng folder there is a docker-compose.yml file and two powershell script to run docker compose(up.ps1) and stop(down.ps1) it. And there is one more folder and a powershell script file that is into it.

This script file to build and publish host and agular project. And also, this script copies the files that is into docker folder to build folder. First, I will run the build-with-ng.ps1 script on location ProjectName/aspnet-core/build.

After running script, when you look at the build folder, you will see the outputs folder. 

Now, there is a folder that named host. This folder contains publish files of host project. And ng folder contains publish files of angular project. And then, I will run the up.ps1 script to run these two project on docker under location ProjectName/aspnet-core/build/outputs.

Angular and host projects are running now. Browse localhost:9901 for Host Project and localhost:9902 for Angular UI.

Actually it is very easy to run Module Zero Core Template on docker.

Steps for running Module Zero Core Template on docker are;

  • Run build-with-ng.ps1 powershell script on location ProjectName/aspnet-core/build.
  • Run up.ps1 powershell script on location ProjectName/aspnet-core/build/outputs.
  • Run down.ps1 if you stop docker containers.

NOTE: Application on docker is connecting the local database that is on our machine. 

Module Zero Core Tepmlate Web Farm on Docker with Using Redis and Haproxy

As you can see at above image, in a web farm there are more than one web servers, there is a load balancer at the front of these servers and a server to store sharing sessions/caches. 

In our example, angular application will be client, haproxy will be load balancer, host app will be web servers and redis will be shared server.

Now, I am creating a configuration file for haproxy that named haproxy.cfg to location ProjectName\aspnet-core\docker\ng and modifying the docker-compose.yml, build-with-ng.ps1 and up.ps1 

haproxy.cfg

global
    maxconn 4096
    
defaults
    mode http
    timeout connect 5s
    timeout client 50s
    timeout server 50s
    
listen http-in
    bind *:8080
    
    server web-1 outputs_abp_host_1:80
    server web-2 outputs_abp_host_2:80
    
    stats enable
    stats uri /haproxy
    stats refresh 1s

Most important line of above code server web-1 and server web-2. I repreduced host applications. This will create two host application on docker container. 

Modified docker-compose.yml

version: '2'

services:

    abp_redis:
        image: redis
        ports:
            - "6379:6379"

    abp_host:
        image: abp/host
        environment:
            - ASPNETCORE_ENVIRONMENT=Staging
        volumes:
            - "./Host-Logs:/app/App_Data/Logs"

    abp_ng:
        image: abp/ng
        ports:
            - "9902:80"
            
    load_balancer:
        image: haproxy:1.7.1
        volumes:
            - "./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg"
        ports:
            - "9904:8080"

build-with-ng.ps1

I am only changing following line from

(Get-Content $ngConfigPath) -replace "21021", "9901" | Set-Content $ngConfigPath

to

(Get-Content $ngConfigPath) -replace "21021", "9904" | Set-Content $ngConfigPath

Because, now Angular UI will connect to haproxy, anymore. Haproxy distribute the requests to web servers.

And modified up.ps1

docker rm $(docker ps -aq)
docker-compose up -d abp_redis
sleep 3
docker-compose up -d abp_host
docker-compose up -d abp_ng
sleep 2
docker-compose scale abp_host=2
sleep 2
docker-compose up -d load_balancer

Finally, I am adding some code in host project to use redis cache to store cache data. Before this change we need to download abp redis cache extensitons. 

https://www.nuget.org/packages/Abp.RedisCache

I am installing this package to ProjectName.Web.Core project. And then, I am changing the ProjectNameWebCoreModule.cs like following.

Adding DependsOn for AbpRedisCacheModule (ProjectNameWebCoreModule.cs)

[DependsOn(...,
     typeof(AbpRedisCacheModule))]
public class ProjectNameWebCoreModule : AbpModule
{

And adding redis cache configuration to PreInitialize method (ProjectNameWebCoreModule.cs)

public override void PreInitialize()
{
 ...

  Configuration.Caching.UseRedis(options =>
    {
       var connectionString = _appConfiguration["Abp:RedisCache:ConnectionString"];
        if (connectionString != null && connectionString != "localhost")
        {
            options.ConnectionString = AsyncHelper.RunSync(() => Dns.GetHostAddressesAsync(connectionString))[0].ToString();
        }
 })
  
  ...

And I am adding redis configurations appsettings.staging.json, too.

appsettings.staging.json

{
  ...,
  "Abp": {
    "RedisCache": {
      "ConnectionString""outputs_abp_redis_1"
    }
  }
}

outputs_abp_redis_1 is the name of redis container and this name is defining by docker automatically. After this changing, host project will resolve the dns of machine that is deployed on. And now, when I run build-with-ng.ps1 and up.ps1 , web farm project will run.  And the result:

As you can see, all containers are working. When you browse localhost:9902 you can see Angular UI is working.

How Will I Know If Haproxy and Redis Work?

There are tools to track haproxy activity(haproxy web interface) and get redis stored data(redis cli).

Haproxy web interface

When you browse http://localhost:9904/haproxy you will see something like following.

When you navigate between on angular application pages or run any api on host project (http://localhost:9904), you can see that the haproxy is routing the requests to different machines. You can track which machine is running under Session rate>Cur tab that are changing for web-1 and web-2. 

Redis cli

To understand if redis is working, you can use redis-cli. While PowerShell is open, type redis-cli command to enter redis cli. Then to test if redis is running, write ping command and it will return PONG if it works. Now when I write keys * command, I should get the application cache keys.

As you can see, redis is working well. Cache keys stored on redis, correctly.

Source Code

You can get the modified source code here: https://github.com/alirizaadiyahsi/ModuleZeroCoreTemplateWebFarm

LEAVE A REPLY