Playing with ELK stack using Docker
Oct 30, 2018
2 minute read

The Goal

In here I just want to test how quick it is to setup ELK stack for an application by utilizing Docker.

Given the current landspace of Development we are now on the stage that every developer should be utilizing the containerization benefits on their projects.

A Quick testing of Elasticsearch and Kibana locally

Elasticsearch and Kibana should be on the same network, here we used one for both and exposes the port. Checking on our localhost:5601 should show us our running Kibana connected to our Elasticsearch.

docker network create elastic
docker run --name elasticsearch --network=elastic -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:6.4.2 
docker run --network=elastic -p 5601:5601 docker.elastic.co/kibana/kibana:6.4.2

Creating a .Net Core Web API

The following command should create a web api that will log an event to our Elasticsearch. We will use Serilog for logging.

dotnet new webapi

dotnet add package Serilog
dotnet add package Serilog.Extensions.Logging
dotnet add package Serilog.Sinks.ElasticSearch
dotnet restore

Setting up Serilog

On StartUp

public Startup(IConfiguration configuration)
{
    // Create Serilog Elasticsearch logger
    Log.Logger = new LoggerConfiguration()
        .Enrich.FromLogContext()
        .MinimumLevel.Debug()
        .WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://localhost:9200"))
        {
            MinimumLogEventLevel = LogEventLevel.Verbose,
            AutoRegisterTemplate = true
        })
        .CreateLogger();

    Configuration = configuration;
}

On Configure

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    // Set Serilog
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseMvc();
}

Logging an Event

Log.Information("Something eventful happen here!");

The Dockerfile

FROM microsoft/dotnet:sdk AS build-env
WORKDIR /app    

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

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

# Build runtime image
FROM microsoft/dotnet:aspnetcore-runtime
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "aspnet.elk.sample.dll"]

Creating our docker-compose

Here the app should be our webapi image push in a repository. I set the memory for the Elasticsearch to be lower than the default 1GB for deploying to resource constraint testing environment which is the purpose of this play around too. By running a docker-compose up -d against our docker-compose.yml, this can be deploy to any docker enabled machine quickly and at ease.

Our docker-compose.yml

version: '2.1'

services:
  elasticsearch:
    restart: always
    image: docker.elastic.co/elasticsearch/elasticsearch:6.4.2
    environment:
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - "discovery.type=single-node"
    ports:
      - 9200:9200

  kibana:
    restart: always
    image: docker.elastic.co/kibana/kibana:6.4.2
    ports:
      - 5601:5601
    depends_on:
      - elasticsearch

  app:
    restart: always
    image: jbalintac/cdc-demo
    ports:
      - 5050:80
    depends_on:
      - elasticsearch
      - kibana