<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Vasyl Kutsyk</title>
    <description>The latest articles on Forem by Vasyl Kutsyk (@kutsyk).</description>
    <link>https://forem.com/kutsyk</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F35870%2F03e39caa-e265-48bb-88fc-c4d43a4abdfa.jpg</url>
      <title>Forem: Vasyl Kutsyk</title>
      <link>https://forem.com/kutsyk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kutsyk"/>
    <language>en</language>
    <item>
      <title>Manage NGINX configurations inside Docker container</title>
      <dc:creator>Vasyl Kutsyk</dc:creator>
      <pubDate>Thu, 11 Nov 2021 12:15:06 +0000</pubDate>
      <link>https://forem.com/kutsyk/manage-nginx-configurations-inside-docker-container-9da</link>
      <guid>https://forem.com/kutsyk/manage-nginx-configurations-inside-docker-container-9da</guid>
      <description>&lt;p&gt;Originaly posted &lt;a href="https://kutsyk.medium.com/manage-nginx-configurations-inside-docker-container-2da58cd782b6"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I believe in any product there is a time when you have to configure a proxy server. Will it be to expose UI applications or just redirect requests to different APIs it depends, but time will come. I’ve made a simple example that will help you configure or investigate your NGINX docker container with configuration change on the fly.&lt;/p&gt;

&lt;p&gt;Don’t do this in your production environment.&lt;/p&gt;




&lt;p&gt;For the beginning, we need to understand how our NGINX docker image looks like.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dockerfile&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM nginx:stable-alpine
RUN rm -rf /usr/share/nginx/html/*
COPY ./dist/app /usr/share/nginx/html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the same directory that you created your Dockerfile, create folders directory &lt;strong&gt;dist/app&lt;/strong&gt; and put some dummy &lt;strong&gt;index.html&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is an example of &lt;strong&gt;index.html&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;h2&amp;gt;An Unordered HTML List&amp;lt;/h2&amp;gt;
&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;Coffee&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Tea&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Milk&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;h2&amp;gt;An Ordered HTML List&amp;lt;/h2&amp;gt;
&amp;lt;ol&amp;gt;
  &amp;lt;li&amp;gt;Coffee&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Tea&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Milk&amp;lt;/li&amp;gt;
&amp;lt;/ol&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Build your image:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker build -t nginx:latest .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;As the result, you should have your image ready to be started:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;REPOSITORY          TAG                 IMAGE ID            
nginx               latest              .....
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run your docker image:&lt;br&gt;
&lt;code&gt;docker run -d -p 8080:80 nginx&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Validate that everything is working smooth:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test-vm@vm-test:~/dockertest$ curl http://localhost:8080
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;h2&amp;gt;An Unordered HTML List&amp;lt;/h2&amp;gt;
&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;Coffee&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Tea&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Milk&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;h2&amp;gt;An Ordered HTML List&amp;lt;/h2&amp;gt;
&amp;lt;ol&amp;gt;
  &amp;lt;li&amp;gt;Coffee&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Tea&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Milk&amp;lt;/li&amp;gt;
&amp;lt;/ol&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you should enter into your container, to do that get a container id.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test-vm@vm-test:~/dockertest$ docker ps
CONTAINER ID   IMAGE  COMMAND  CREATED   STATUS  PORTS     NAMES                           
022c55a80088   nginx  "/d.…"   7 m ago   Up 7 m  8080      busy
test-vm@vm-test:~/dockertest$ docker exec -it 022c55a80088 /bin/sh
/ #
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Voila, we are in the container and can change everything on the fly.&lt;/p&gt;

&lt;p&gt;The configuration file itself is located in the default directory:&lt;br&gt;
&lt;code&gt;/etc/nginx/nginx.conf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can go there, modify configurations and easily validate them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/ # nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Validation of file is good, but to apply it, we need to restart our nginx service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/ # nginx -s reload
2021/11/10 12:01:50 [notice] 46#46: signal process started
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that’s it, now testing of configuration change for your NGINX service in Docker container is easier and no need for rebuilding on every change.&lt;/p&gt;




&lt;p&gt;Thanks for reading!&lt;br&gt;
If you have an interesting experience with live changes in Docker containers or you are interested in another topic, please add comments and upvote 👍. I’m interested in the dialog.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>nginx</category>
      <category>proxy</category>
    </item>
    <item>
      <title>Know your Azure environment better with Grafana</title>
      <dc:creator>Vasyl Kutsyk</dc:creator>
      <pubDate>Mon, 08 Nov 2021 15:09:27 +0000</pubDate>
      <link>https://forem.com/kutsyk/know-your-azure-environment-better-with-grafana-3o8o</link>
      <guid>https://forem.com/kutsyk/know-your-azure-environment-better-with-grafana-3o8o</guid>
      <description>&lt;p&gt;Originaly posted &lt;a href="https://kutsyk.medium.com/know-your-azure-environment-better-with-grafana-9dad281ff649" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Monitoring of production environment is an essential part of any products not depending on the size. But monitoring big production environments efficiently is the essential difference between good quality of service and bad service.&lt;/p&gt;

&lt;p&gt;Brief prehistory — our product is delivered to a few different clients. It means we have a multi-tenant environment and each of them requires proper monitoring. Every tenant has its own production subscription and independent infrastructure.&lt;/p&gt;




&lt;p&gt;At the start all our monitoring was organized on native Azure Cloud resources, meaning all data go into Application Insight (Log analytics) and dashboards were built in the same environment. But as a result when we needed to investigate the root cause of the issue in our environment we were spending approximately 1 hour finding an exact component that caused the issue. Which was really painful for our clients. Incidents were like the challenge of finding a needle in a haystack.&lt;/p&gt;

&lt;p&gt;Here is an example of a dashboard in Azure:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1250%2F1%2APixz8o0sX0YpK_hvG-_yYw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1250%2F1%2APixz8o0sX0YpK_hvG-_yYw.png" title="Azure resources monitoring dashboard" alt="Azure resources monitoring dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are using Azure I’m sure you know how bad their mobile compatibility is so I won’t even include a screenshot of that here.&lt;/p&gt;

&lt;p&gt;So points that we were missing here are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No multi-chart graphs&lt;/li&gt;
&lt;li&gt;No dynamic variables — to choose resources that we want to show easily&lt;/li&gt;
&lt;li&gt;One of the worst date pickers — that one can compete for worst design award&lt;/li&gt;
&lt;li&gt;Responsive view&lt;/li&gt;
&lt;li&gt;Represent data from another source than Azure metrics&lt;/li&gt;
&lt;li&gt;Complicated access management&lt;/li&gt;
&lt;li&gt;No change history&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;We started looking for a better approach in our observability and logically we tried the top open-source tool for this — Grafana.&lt;/p&gt;

&lt;p&gt;Grafana — is the open-source analytics &amp;amp; monitoring solution for every database. &lt;a href="https://grafana.com/grafana" rel="noopener noreferrer"&gt;https://grafana.com/grafana&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I won’t cover how to spin up your grafana instance. But I’ll show you how we improved our observability and how that improved our issue detecting mechanism.&lt;/p&gt;

&lt;p&gt;Some of the pros of using Grafana that we found are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Different data sources&lt;/li&gt;
&lt;li&gt;Responsive dashboards&lt;/li&gt;
&lt;li&gt;Multi-charts graphs&lt;/li&gt;
&lt;li&gt;Great choice of plugin&lt;/li&gt;
&lt;li&gt;Awesome date picker that just works&lt;/li&gt;
&lt;li&gt;Dynamic variables&lt;/li&gt;
&lt;li&gt;Clear access management&lt;/li&gt;
&lt;li&gt;Change history — versioning&lt;/li&gt;
&lt;li&gt;Reach community dashboards library&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these features brought a new level of observability to our reliability team.&lt;/p&gt;

&lt;p&gt;Here I’ll show you an example of how we are monitoring the load on our database depending on the number of requests and nodes from our API.&lt;/p&gt;

&lt;p&gt;We just need to choose Subscription in the first variable and all other variables will be automatically substituted with a proper value with dynamic queries.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1250%2F1%2Av6UoGxNFfW34vuIHRnWXfg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1250%2F1%2Av6UoGxNFfW34vuIHRnWXfg.png" title="Dynamic dashboard to check SQL stats depending on the number of requests to API and number of nodes" alt="Dynamic dashboard to check SQL stats depending on the number of requests to API and number of nodes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is only a brief example of all possibilities that become open for observabilities in Grafana for Azure resources. Availability to connect different data sources helps build a dashboard on which you can monitor your background jobs hosted in azure and the data layer which is hosted in Elastic search.&lt;/p&gt;

&lt;p&gt;To connect your Azure resources to Grafana you should use the Azure Monitor plugin — &lt;a href="https://grafana.com/grafana/plugins/grafana-azure-monitor-datasource/" rel="noopener noreferrer"&gt;https://grafana.com/grafana/plugins/grafana-azure-monitor-datasource/&lt;/a&gt;;&lt;/p&gt;

&lt;p&gt;With this plugin, you can create dynamic variables which will ease choosing the resource for which you want to get data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1250%2F1%2A56yS7__vHGot1C-3YyxkzA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1250%2F1%2A56yS7__vHGot1C-3YyxkzA.png" title="Example of dynamic variables with values from Azure Monitor plugin" alt="Example of dynamic variables with values from Azure Monitor plugin"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A full list of query requests is available on the plugin page. After you created your variables, you should configure your charts to use template variables for data source:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1250%2F1%2A5cQLywXxzyLiRUf9hBCmdw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1250%2F1%2A5cQLywXxzyLiRUf9hBCmdw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This gives you possibilities to build awesome dashboards that will help you detect issues more efficiently.&lt;/p&gt;

&lt;p&gt;Here are some of our dashboards:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1250%2F1%2ApapDzA-o-0lH7e9t_KVbEQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1250%2F1%2ApapDzA-o-0lH7e9t_KVbEQ.png" title="Service Bus monitoring" alt="Service Bus monitoring"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1250%2F1%2AR_yGIYW_vAUcztV9tVZPJQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1250%2F1%2AR_yGIYW_vAUcztV9tVZPJQ.png" title="Redis Cache monitoring" alt="Redis Cache monitoring"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Taking all these possibilities into 1 dashboard, we build a General dashboard that represents all important metrics of each system and shows if there are any issues. This decreased our time of detection from ~1h to ~10min. Which helped us prevent a lot of incidents in production and increased the speed of incident resolution.&lt;/p&gt;

&lt;p&gt;Our postmortems became more scientific, as we were able to see much more metrics and precision thanks to awesome date picker became mathematical instead of approximate.&lt;/p&gt;

&lt;p&gt;From the moment we introduced Grafana in our product, we are considering this as one of the best choices that we did to improve our monitoring.&lt;/p&gt;

&lt;p&gt;And what did you do to improve your observability?&lt;/p&gt;




&lt;p&gt;Thanks for reading!&lt;br&gt;
If you have an interesting experience with Grafana or you are interested in another topic, please add comments and upvote 👍. I'm interested in the dialog.&lt;/p&gt;

</description>
      <category>grafana</category>
      <category>azure</category>
      <category>monitoring</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
