<?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: Francisco Javier Sánchez Fuentes</title>
    <description>The latest articles on Forem by Francisco Javier Sánchez Fuentes (@fransafu).</description>
    <link>https://forem.com/fransafu</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%2F317989%2F47b95d21-5f9f-4d26-a99d-89ec2df637d8.jpeg</url>
      <title>Forem: Francisco Javier Sánchez Fuentes</title>
      <link>https://forem.com/fransafu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/fransafu"/>
    <language>en</language>
    <item>
      <title>How to make Coverage in Golang?</title>
      <dc:creator>Francisco Javier Sánchez Fuentes</dc:creator>
      <pubDate>Sun, 15 Aug 2021 06:28:08 +0000</pubDate>
      <link>https://forem.com/fransafu/how-to-make-coverage-in-golang-3je3</link>
      <guid>https://forem.com/fransafu/how-to-make-coverage-in-golang-3je3</guid>
      <description>&lt;p&gt;Hi Everyone!&lt;/p&gt;

&lt;p&gt;In this post we'll to check about coverage in Golang.&lt;/p&gt;

&lt;p&gt;Alternatively, you can download the &lt;a href="https://github.com/fransafu/coverage-golang-example"&gt;Source code&lt;/a&gt; and follow the instructions in the README.md.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Run the tests and save the coverage profile in "coverage.out"&lt;/span&gt;
go &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;-coverprofile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;coverage.out ./...

&lt;span class="c"&gt;# View the coverage profile in your browser&lt;/span&gt;
go tool cover &lt;span class="nt"&gt;-html&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;coverage.out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Coverage in Golang
&lt;/h2&gt;

&lt;p&gt;For this example, we have to create an &lt;code&gt;user&lt;/code&gt; entity and store it in memory. This is the structure of the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.
├── README.md
├── cmd
│   └── main.go
├── go.mod
├── go.sum
└── internal
    └── user
        ├── storage.go
        ├── storage_test.go
        └── user.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  we need to write the program
&lt;/h2&gt;

&lt;p&gt;First of all, we need to declare the &lt;code&gt;user&lt;/code&gt; entity, the filename for this is 'user.go' (in the "internal" folder in called &lt;code&gt;user&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Package user describe user entity attributes and manage user storage&lt;/span&gt;
&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ID&lt;/span&gt;        &lt;span class="kt"&gt;uint64&lt;/span&gt;
    &lt;span class="n"&gt;FirstName&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;LastName&lt;/span&gt;  &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Age&lt;/span&gt;       &lt;span class="kt"&gt;uint16&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now, we have to create the user storage. In the same package, the &lt;code&gt;storage.go&lt;/code&gt; was created with the following structure and methods.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;UserStorage&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;DB&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// AddUser Add user information to the UserStorage database&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;us&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;UserStorage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;AddUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;us&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;us&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// FindUserByID find the user by ID&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;us&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;UserStorage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;FindUserByID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="kt"&gt;uint64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;us&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DB&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Count total users in the database&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;us&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;UserStorage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;us&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  We need to test the program
&lt;/h2&gt;

&lt;p&gt;For now, we have three methods of adding, searching, and counting your own users in storage. But we have to test that, so we add the &lt;code&gt;storage_test.go&lt;/code&gt; file with its test. The following code has three tests that make 100% coverage for UserStorage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;user_test&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"testing"&lt;/span&gt;

    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="s"&gt;"github.com/fransafu/coverage-golang-example/internal/user"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/stretchr/testify/assert"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestUserStorage_SaveUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;userStorage&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserStorage&lt;/span&gt;

    &lt;span class="n"&gt;user1&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;user1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;user1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FirstName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Francisco"&lt;/span&gt;
    &lt;span class="n"&gt;user1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LastName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Sanchez"&lt;/span&gt;
    &lt;span class="n"&gt;user1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;99&lt;/span&gt;

    &lt;span class="n"&gt;userStorage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userStorage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestUserStorage_SearchUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;userStorage&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserStorage&lt;/span&gt;

    &lt;span class="n"&gt;user1&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;user1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;user1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FirstName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Francisco"&lt;/span&gt;
    &lt;span class="n"&gt;user1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LastName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Sanchez"&lt;/span&gt;
    &lt;span class="n"&gt;user1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;99&lt;/span&gt;

    &lt;span class="n"&gt;userStorage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userStorage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FindUserByID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestUserStorage_EmptySearchUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;userStorage&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserStorage&lt;/span&gt;

    &lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userStorage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;userStorage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FindUserByID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you thinking about improving the tests with "Test Suite" or "Test Group", yes, this is the way, but for now, these examples are simple and atomic for this post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get the coverage
&lt;/h2&gt;

&lt;p&gt;To get the coverage in a Golang project you can use the "./..." wildcard and the Golang CLI will search for all tests declared in a project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Run the tests and save the coverage profile in "coverage.out"&lt;/span&gt;
go &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;-coverprofile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;coverage.out ./...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, we have the file &lt;code&gt;coverage.out&lt;/code&gt; that contains the coverage information but we need to view the results, the following command line shows the coverage program in the browser.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# View the coverage profile in your browser&lt;/span&gt;
go tool cover &lt;span class="nt"&gt;-html&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;coverage.out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can check all files that contain declared tests. If you don't declare a test file, you won't have coverage for that module.&lt;/p&gt;

&lt;p&gt;It's all for now, thanks for reading this post.&lt;/p&gt;

&lt;p&gt;:)!&lt;/p&gt;

</description>
      <category>go</category>
      <category>coverage</category>
      <category>testing</category>
      <category>example</category>
    </item>
    <item>
      <title>A brief introduction to Observability Driven-Development</title>
      <dc:creator>Francisco Javier Sánchez Fuentes</dc:creator>
      <pubDate>Sun, 27 Sep 2020 19:34:04 +0000</pubDate>
      <link>https://forem.com/fransafu/a-brief-introduction-to-observability-driven-development-5a9n</link>
      <guid>https://forem.com/fransafu/a-brief-introduction-to-observability-driven-development-5a9n</guid>
      <description>&lt;p&gt;Hi Everyone!&lt;/p&gt;

&lt;p&gt;Let's talk about the Observability Driven-Development and how it works.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why software development needs a "methodologies driven development"?
&lt;/h3&gt;

&lt;p&gt;First of all, I took advantage of this instance to share answers from another user to discuss with a short explanation of why software development "Driven-development" or "Driven-design" are needed.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;how come we don't have -Driven Development in other engineering disciplines, only in software? It's because other branches of engineering are faced with much lower levels of uncertainty. When engineering physical objects/systems. it is much cleared what are we building and what are the actual physical constraints (for example, when building a bridge).&lt;/em&gt; &lt;a href="https://dev.to/fransafu/comment/158ai"&gt;discuss source here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ok, you just keep in mind that &lt;strong&gt;"the software development process has uncertainty"&lt;/strong&gt; because we have the human factor in a transversal way throughout the process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Observability Driven-Development
&lt;/h2&gt;

&lt;p&gt;Now, Observability Driven-Development applies when you monitor your process before, during, and after the development process. The goal is to detect user experience issues or bugs that have not yet been reported. So at best, you can run into problems through observability.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the mean "Observability"?
&lt;/h3&gt;

&lt;p&gt;The concept of "Observability" doesn't have its origin in computer science and is applied to software engineering, it originated in systems theory issues where it was about "understanding a system through observation". So, this methodology aims to understand and improve a system by observing at startup or when it is mainly operational (production). The reason for observing a system in those processes is because when a system is running it is exposed to other unexpected actions by users.&lt;/p&gt;

&lt;h3&gt;
  
  
  What about it with other Driven development methodologies?
&lt;/h3&gt;

&lt;p&gt;The authors say that the methodology doesn't conflict with other methodologies such as TDD or BDD. Then, it is a complementary methodology in which DevOps, SRE, QA, Developers, and Product Owner participate where a monitoring system is used to understand where they can debug to find a problem or where they can improve a system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ODD doesn't say where the problems are, but it's useful to find them by observation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading :)&lt;/p&gt;

&lt;p&gt;I hope helpful this brief introduction.&lt;/p&gt;

&lt;p&gt;More info about it in &lt;a href="https://www.infoq.com/articles/observability-driven-development/"&gt;infoq.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>introduction</category>
      <category>odd</category>
      <category>devops</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Detect and track your errors in production and fix it!</title>
      <dc:creator>Francisco Javier Sánchez Fuentes</dc:creator>
      <pubDate>Wed, 06 May 2020 01:40:24 +0000</pubDate>
      <link>https://forem.com/fransafu/detect-and-track-your-errors-in-production-and-fix-it-2hmk</link>
      <guid>https://forem.com/fransafu/detect-and-track-your-errors-in-production-and-fix-it-2hmk</guid>
      <description>&lt;p&gt;Hi Everyone!&lt;/p&gt;

&lt;p&gt;Today, I talk about track errors in production.&lt;/p&gt;

&lt;p&gt;Detecting errors is very important for Dev and DevOps team, It's much better when you detect de error and fix it before the client sends a notification, especially if your error is in production, for that you have many options :).&lt;/p&gt;

&lt;p&gt;First, you should put the correct format in the logs of your app, ok... if you don't have logs, maybe you should install the log module.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommend format:&lt;/strong&gt; [DATE][ENVIRONMENT][APP][PROCESS_ID/THREAD_ID] message: &lt;/p&gt;

&lt;p&gt;Why I put the "process id" or "thread id"? If you run the cluster mode or multicore (with thread) you need to know if the error causes a domino effect in another process/thread (anyway, this is optional).&lt;/p&gt;

&lt;p&gt;Ok, you have logs... your module of logs constantly block the I/O thread? is it efficient when printing your app logs? No? Ok... change your log module.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Don't forget the format of your logs and especially use an efficient logger.&lt;/p&gt;

&lt;p&gt;This is the way for improving your logs for seeing the errors in production... but, what about if I want to see the real-time error? (What??)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;R: &lt;a href="https://www.bugsnag.com/"&gt;Bugsnag&lt;/a&gt; or &lt;a href="https://sentry.io/welcome/"&gt;Sentry&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, you have to register, then get the client token. When you have the token, incorporate the Sentry/Bugsnag module into your application (use the token) and your &lt;strong&gt;app must send the error through the client&lt;/strong&gt;. That is all, you will see all error (nearly real-time) and if you configure logs by environment and client... much better :)&lt;/p&gt;

&lt;p&gt;Finally, I want to share the log module for Node.js I most use: &lt;a href="https://github.com/winstonjs/winston"&gt;Winston&lt;/a&gt;. If you want to read more about logs, &lt;a href="https://www.loggly.com/blog/benchmarking-popular-node-js-logging-libraries/"&gt;click here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This is applicable for other languages, runtime and more.&lt;/p&gt;

&lt;p&gt;Good luck guys!&lt;/p&gt;

&lt;p&gt;I hope you like this post :)&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>logs</category>
      <category>errors</category>
    </item>
    <item>
      <title>The first experience with k3s (lightweight Kubernetes). Deploy your first app!</title>
      <dc:creator>Francisco Javier Sánchez Fuentes</dc:creator>
      <pubDate>Mon, 04 May 2020 04:17:02 +0000</pubDate>
      <link>https://forem.com/fransafu/the-first-experience-with-k3s-lightweight-kubernetes-deploy-your-first-app-44ea</link>
      <guid>https://forem.com/fransafu/the-first-experience-with-k3s-lightweight-kubernetes-deploy-your-first-app-44ea</guid>
      <description>&lt;p&gt;Hi everyone!&lt;/p&gt;

&lt;p&gt;Today, I talk about k3s. It's a lightweight version of Kubernetes (k8s) and you can use for the Internet of Things (Can you imagine your own IoT cluster?) or Edge computing (distributed computing with the cluster?) ok, that is a little crazy but real.&lt;/p&gt;

&lt;h1&gt;
  
  
  TL;DR
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install k3s&lt;/span&gt;
curl &lt;span class="nt"&gt;-sfL&lt;/span&gt; https://get.k3s.io | &lt;span class="nv"&gt;K3S_KUBECONFIG_MODE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"644"&lt;/span&gt; sh &lt;span class="nt"&gt;-s&lt;/span&gt; -

&lt;span class="c"&gt;# Check if response the node with the current version&lt;/span&gt;
k3s kubectl get node

&lt;span class="c"&gt;# Create the namespace (only dev)&lt;/span&gt;
kubectl create namespace retail-project-dev

&lt;span class="c"&gt;# Download the manifest&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET &lt;span class="nt"&gt;-L&lt;/span&gt; https://gist.githubusercontent.com/fransafu/4075cdcaf2283ca5650e71c7fd8335cb/raw/19d7cfa0f82f1b66af6e39389073bcb0108c494c/simple-rest-golang.yaml &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; simple-rest-golang.yaml

&lt;span class="c"&gt;# Create ingress, service, and deployment&lt;/span&gt;
k3s kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; simple-rest-golang.yaml

&lt;span class="c"&gt;# Check ingress (its show your IP), service and pods&lt;/span&gt;
k3s kubectl get ingress,svc,pods &lt;span class="nt"&gt;-n&lt;/span&gt; retail-project-dev

&lt;span class="c"&gt;# Test cluster and app&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET http://YOUR_IP

&lt;span class="c"&gt;# That is the output&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"data"&lt;/span&gt;:&lt;span class="s2"&gt;"RESTful with two Endpoint /users and /notes - v1.0.0"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;K3s an initiative of &lt;a href="https://rancher.com/docs/k3s/latest/en/"&gt;Rancher&lt;/a&gt; so that you may create a k8s cluster but in lower requirements. You will be able to install k3s in a Raspberry and run your programs or microservices in High-Availability (HA). However, you have to be careful when you start your setup in case you if want HA.&lt;/p&gt;

&lt;h1&gt;
  
  
  Key concepts: Before continuing, you need to familiarize yourself with the following concepts
&lt;/h1&gt;

&lt;h4&gt;
  
  
  High-Availability (HA)
&lt;/h4&gt;

&lt;p&gt;When you need &lt;strong&gt;reliability&lt;/strong&gt;, a minimum amount of &lt;strong&gt;down-time&lt;/strong&gt;, &lt;strong&gt;redundant&lt;/strong&gt; instances of your programs or computers... you are looking for High-Availability. It's the main characteristic of this concept, so HA is the ability to provide service for your users although your cluster fails.&lt;/p&gt;

&lt;h4&gt;
  
  
  Kubeconfig
&lt;/h4&gt;

&lt;p&gt;It's a file used to configure access to Kubernetes, in this case specifically used by kubectl (it's a CLI for k8s). Moreover, used by CI/CD Pipeline for access to the cluster.&lt;/p&gt;

&lt;h4&gt;
  
  
  Artifacts
&lt;/h4&gt;

&lt;p&gt;An Artifact is a common concept of Software engineering to describe the component of software as part of code, description/documentation, and more. An Artifact is all "things" generated in process design, develop, implement, and maintain the software. Please, visit the following &lt;a href="https://softwareengineering.stackexchange.com/questions/106473/what-does-artifact-mean"&gt;link&lt;/a&gt; for more details.&lt;/p&gt;

&lt;h1&gt;
  
  
  Get started
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; This configuration is for development environment (non-production!!).&lt;/p&gt;

&lt;h3&gt;
  
  
  Install k3s in your laptop
&lt;/h3&gt;

&lt;p&gt;Run the next command for install and change permissions of Kubeconfig. By default, k3s start their own services.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sfL&lt;/span&gt; https://get.k3s.io | &lt;span class="nv"&gt;K3S_KUBECONFIG_MODE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"644"&lt;/span&gt; sh &lt;span class="nt"&gt;-s&lt;/span&gt; -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This command allow access to &lt;strong&gt;kubeconfig&lt;/strong&gt; (default path: /etc/rancher/k3s/k3s.yaml). For example, when used Kubectl.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check installation
&lt;/h3&gt;

&lt;p&gt;First, check your nodes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;k3s kubectl get node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the one node with the current version of k3s. Now, the following step maybe is unnecessary, but I want to show you the cluster API, k8s have good interoperability with good design of API.&lt;/p&gt;

&lt;p&gt;Note: The API of k3s is a little bit least than API k8s in terms of interoperability&lt;/p&gt;

&lt;p&gt;Secondly, you should get the credentials. In the next step, you view the kubeconfig and you can see how k3s configure that file. The main concepts you need know is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cluster: Basic configs fo certificates and server IP.&lt;/li&gt;
&lt;li&gt;Context: Is a group access parameters, for example, the namespace access by default.&lt;/li&gt;
&lt;li&gt;kind: This word define what kind is the config file (you will see it in many files).&lt;/li&gt;
&lt;li&gt;users: Yes! Here are the credentials for users.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; The common format for files of k8s and k3s is &lt;strong&gt;YAML&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/rancher/k3s/k3s.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, copy &amp;amp; paste server IP in your browser (&lt;a href="https://127.0.0.1:6443"&gt;https://127.0.0.1:6443&lt;/a&gt;), click enter and put the credentials for access, then It's showing you all paths of your k3s. You probably won't use them but &lt;strong&gt;you need to know they exist&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploy your application
&lt;/h3&gt;

&lt;p&gt;If you don't have any application, you can use my sample app &lt;/p&gt;

&lt;p&gt;This project is deployed under the name of &lt;strong&gt;'retail-project'&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;First, you must &lt;strong&gt;create a namespace&lt;/strong&gt;, the namespace is a logical division in your cluster, is used for encapsulate groups of application and configuration, if the namespace has a problem, this problem doesn't impact another namespace. A good practice is to create al least two namespaces by the project (prod: production and dev: development).&lt;/p&gt;

&lt;p&gt;For this example only create the development environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create namespace retail-project-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perfect! now, deploy your apps. but before that, I should explain about configuration the manifest for creating artifacts (resources into the cluster).&lt;/p&gt;

&lt;p&gt;Previously, I talked about the main format of config files is YAML and each config file has a &lt;strong&gt;Kind&lt;/strong&gt; label followed a description of the artifact (resources). Ok, when you specified the "kind" of artifact and run the command &lt;strong&gt;apply&lt;/strong&gt; over k3s, It creates a group(s) of Pods, ReplicaSet, Deployment, or another artifact.&lt;/p&gt;

&lt;p&gt;Concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://kubernetes.io/docs/concepts/workloads/pods/pod/"&gt;Pod&lt;/a&gt;: A Pod is a group of one or more containers (such as Docker containers).&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/"&gt;ReplicaSet&lt;/a&gt;: A ReplicaSet’s purpose is to maintain a stable set of replica Pods running at any given time.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/"&gt;Deployment&lt;/a&gt;: A Deployment's purpose is to declare how many instances of Pod need and create a ReplicaSet for that, and declare what image of app use for creating instances in a Pod.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; All these definitions are from official k8s documentation, except Deployment.&lt;/p&gt;

&lt;p&gt;Ok, let's deploy the app. I hope these concepts help your knowledge about artifacts of k8s and k3s.&lt;/p&gt;

&lt;h4&gt;
  
  
  Prepare the template
&lt;/h4&gt;

&lt;p&gt;Well, this template has 3 sections, the first section is app definition (simple-rest-golang-deployment), also the Kind is a Deployment, that is important because a Deployment generates the number of replicas (in this case is two) through the ReplicaSet so that It generates the Pods. Therefore, ReplicaSet is responsible of Pods, and Deployment is responsible of ReplicaSet. It's important to understand the hierarchy.&lt;/p&gt;

&lt;p&gt;Deployment uses the name "simple-rest-golang-deployment" in the namespace "retail-project-dev" and It generates two replicas of simple-rest-golang from Docker registry repository with the name "fransafu/simple-rest-golang:1.0.0".&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Note: *&lt;/em&gt; If you want to read more about resources of containers &lt;a href="https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#meaning-of-cpu"&gt;Click here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Download the file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET &lt;span class="nt"&gt;-L&lt;/span&gt; https://gist.githubusercontent.com/fransafu/4075cdcaf2283ca5650e71c7fd8335cb/raw/19d7cfa0f82f1b66af6e39389073bcb0108c494c/simple-rest-golang.yaml &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; simple-rest-golang.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or you can copy &amp;amp; paste the template in a file: &lt;strong&gt;'simple-rest-golang.yaml'&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;---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: simple-rest-golang-deployment
  namespace: retail-project-dev
spec:
  replicas: 2
  selector:
    matchLabels:
      app: simple-rest-golang
  template:
    metadata:
      labels:
        app: simple-rest-golang
    spec:
      containers:
        - name: simple-rest-golang
          image: fransafu/simple-rest-golang:1.0.0
          resources:
            requests:
              memory: "64Mi"
              cpu: "100m"
            limits:
              memory: "128Mi"
              cpu: "500m"
          ports:
          - containerPort: 8080
          imagePullPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: simple-rest-golang-service
  namespace: retail-project-dev
spec:
  ports:
  - port: 80
    targetPort: 8080
    name: tcp
  selector:
    app: simple-rest-golang
--------
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: simple-rest-golang-ingress
  namespace: retail-project-dev
  annotations:
    kubernetes.io/ingress.class: "traefik"
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: simple-rest-golang-service
          servicePort: 80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Apply the template
&lt;/h4&gt;

&lt;p&gt;Now, create the ingress, service, and pods from manifest&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;k3s kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; simple-rest-golang.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;deployment.apps/simple-rest-golang-deployment created
service/simple-rest-golang-service created
ingress.networking.k8s.io/simple-rest-golang-ingress created
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Check your cluster and apps
&lt;/h4&gt;

&lt;p&gt;First, you need to see your resources in k3s cluster&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;k3s kubectl get ingress,svc,pods &lt;span class="nt"&gt;-n&lt;/span&gt; retail-project-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take your IP from the field ADDRESS. Then replace below "YOUR_IP" with your IP.&lt;/p&gt;

&lt;p&gt;Perfect, run the next command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET http://YOUR_IP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you get the following output, congratulation! Your cluster work fine :)&lt;/p&gt;

&lt;p&gt;That is the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{"data":"RESTful with two Endpoint /users and /notes - v1.0.0"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations! You have k3s cluster in your computer :)&lt;/p&gt;

&lt;p&gt;I hope this tutorial is helpful!&lt;/p&gt;

</description>
      <category>introduction</category>
      <category>k3s</category>
      <category>kubernetes</category>
      <category>go</category>
    </item>
    <item>
      <title>Docker for all #1: Introduction</title>
      <dc:creator>Francisco Javier Sánchez Fuentes</dc:creator>
      <pubDate>Sat, 11 Apr 2020 03:56:33 +0000</pubDate>
      <link>https://forem.com/fransafu/docker-for-all-1-introduction-29e4</link>
      <guid>https://forem.com/fransafu/docker-for-all-1-introduction-29e4</guid>
      <description>&lt;p&gt;Hi Everyone!&lt;/p&gt;

&lt;p&gt;I wrote an introduction about how does use with docker (is very simple), I hope you like :)!!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Docker?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;"Docker is an open platform for developing, shipping, and running applications"&lt;/strong&gt; -- Docker docs&lt;/p&gt;

&lt;p&gt;Is technology for encapsulating application. All applications when running with docker have the own environment and isolate another app running over the same operating system.&lt;/p&gt;

&lt;h2&gt;
  
  
  How's use docker?
&lt;/h2&gt;

&lt;p&gt;You can develop an application, they create Dockerfile with all dependencies and step for the run, then you should test docker in localhost and validate for deploy.&lt;/p&gt;

&lt;p&gt;List of validations before deploy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The behavior of the app is correct?&lt;/li&gt;
&lt;li&gt;Request and Response it's fine (maybe unit testing)?&lt;/li&gt;
&lt;li&gt;The image is secure for production (validate with the author or check with your own skills)?&lt;/li&gt;
&lt;li&gt;Just have only necessary dependencies (production mode)?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When all validations pass, you must push all code to Git repository and run the Pipeline for deploy.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to deploy Docker?
&lt;/h2&gt;

&lt;p&gt;Actually have many options for deploy Docker, but principally, we can split this into two categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pipeline CI/CD&lt;/li&gt;
&lt;li&gt;Docker Cluster&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to make the build, test and deploy with your own hands... but I don't recommend this method (Shell Scripting)&lt;/p&gt;

&lt;h3&gt;
  
  
  Pipeline
&lt;/h3&gt;

&lt;p&gt;It is a toolchain of jobs for build, test, upload to docker registry and deploy to cluster.&lt;/p&gt;

&lt;p&gt;The main options are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.gitlab.com/ee/ci/"&gt;Gitlab CI/CD&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://travis-ci.org/"&gt;TravisCI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://circleci.com/"&gt;CircleCI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://azure.microsoft.com/en-us/services/devops/pipelines/"&gt;Azure Pipeline&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/docs/ci-cd"&gt;GCP Pipeline&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I prefer the Gitlab.&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker Cluster
&lt;/h3&gt;

&lt;p&gt;The cluster is a manager of Docker applications and its responsible for stay running, deploy all services, and more.&lt;/p&gt;

&lt;p&gt;Actually existing many clusters for manage applications with Docker, the more famous is &lt;a href="https://kubernetes.io/"&gt;Kubernetes&lt;/a&gt;, also for the Internet of. Things (IoT) exists &lt;a href="https://k3s.io/"&gt;k3s&lt;/a&gt; (is the best option for IoT) and finally &lt;a href="https://docs.docker.com/engine/swarm/"&gt;Swarm&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Kubernetes have many implementations on the cloud &lt;a href="https://cloud.google.com/kubernetes-engine"&gt;GKE&lt;/a&gt;, &lt;a href="https://azure.microsoft.com/en-us/services/kubernetes-service/"&gt;AKS&lt;/a&gt;, &lt;a href="https://aws.amazon.com/eks/"&gt;EKS&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The main docker cluster for developing (non-production) is &lt;a href="https://kubernetes.io/docs/setup/learning-environment/minikube/"&gt;Minikube&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With that, you know de main concepts and stages for work with docker.&lt;/p&gt;

&lt;p&gt;Remember:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Develop&lt;/li&gt;
&lt;li&gt;Make Dockerfile&lt;/li&gt;
&lt;li&gt;Validate&lt;/li&gt;
&lt;li&gt;Push to Git (never forget)&lt;/li&gt;
&lt;li&gt;Run Pipeline&lt;/li&gt;
&lt;li&gt;Deploy to docker cluster&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Perfect :)! your app is running in high availability, with the best practices for deploy. &lt;strong&gt;Don't forget to do implement the 'Rollback' stage&lt;/strong&gt; useful when implementation fails (but surely it doesn't happen to you, however, implement the stage).&lt;/p&gt;

&lt;p&gt;Thanks for your time and I waiting for your feedback :)!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>introduction</category>
      <category>devops</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Hi I'm Francisco</title>
      <dc:creator>Francisco Javier Sánchez Fuentes</dc:creator>
      <pubDate>Sat, 11 Apr 2020 02:48:46 +0000</pubDate>
      <link>https://forem.com/fransafu/hi-i-m-francisco-1fcp</link>
      <guid>https://forem.com/fransafu/hi-i-m-francisco-1fcp</guid>
      <description>&lt;p&gt;Hi Everyone!&lt;/p&gt;

&lt;p&gt;My name is Francisco Sánchez, I living and work in Santiago of Chile.&lt;/p&gt;

&lt;p&gt;I have been coding for 5 years professionally for companies.&lt;/p&gt;

&lt;p&gt;I'm a Software Engineer with a specialist in Backend. The main interesting topics are Architecture, Design, and improve performance of Software, also check the cost of operations for IaaS, PaaS, and SaaS in AWS and GCP.&lt;/p&gt;

&lt;p&gt;I mostly program in theses languages: Javascript and Python.&lt;/p&gt;

&lt;p&gt;You can find me on Github as &lt;a href="https://github.com/fransafu"&gt;fransafu&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope to be a contribution to this community.&lt;/p&gt;

&lt;p&gt;Nice to meet you :)&lt;/p&gt;

</description>
      <category>introduction</category>
      <category>personal</category>
      <category>software</category>
      <category>enginner</category>
    </item>
  </channel>
</rss>
