<?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>DEV Community: Mitz</title>
    <description>The latest articles on DEV Community by Mitz (@bufferings).</description>
    <link>https://dev.to/bufferings</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%2F42684%2Fe65785f0-09e0-464b-91d4-ceb3f6b7346f.jpg</url>
      <title>DEV Community: Mitz</title>
      <link>https://dev.to/bufferings</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bufferings"/>
    <language>en</language>
    <item>
      <title>IntelliJ IDEs and CircleCI integration by 🌀CIclone!</title>
      <dc:creator>Mitz</dc:creator>
      <pubDate>Tue, 09 Aug 2022 14:59:23 +0000</pubDate>
      <link>https://dev.to/bufferings/intellij-ides-and-circleci-integration-by-ciclone-3c2c</link>
      <guid>https://dev.to/bufferings/intellij-ides-and-circleci-integration-by-ciclone-3c2c</guid>
      <description>&lt;p&gt;Samuraism Inc. has announced a new product: a plugin for JetBrains IDEs named &lt;strong&gt;CIclone&lt;/strong&gt; [sάɪkloʊn]&lt;/p&gt;

&lt;p&gt;&lt;a href="https://samuraism.com/products/ciclone"&gt;https://samuraism.com/products/ciclone&lt;/a&gt; (Ja)&lt;/p&gt;

&lt;h2&gt;
  
  
  🌀CIclone?
&lt;/h2&gt;

&lt;p&gt;🌀CIclone provides seamless integration of JetBrains IDEs with several CI services such as Jenkins, GitHub Actions, and CircleCI. It is a paid plugin, but the price is reasonable. In addition, it's available at no additional cost if we have a personal license with them. (and I have it :D)&lt;/p&gt;

&lt;p&gt;I checked the CircleCI integration of the plugin because I like CircleCI and I'm working for CircleCI as an engineer (๑•̀ㅂ•́)و✧&lt;/p&gt;

&lt;p&gt;The plugin seems super nice!&lt;/p&gt;

&lt;h2&gt;
  
  
  Execution result notification
&lt;/h2&gt;

&lt;p&gt;When we push code changes, CircleCI starts the pipeline. Then, 🌀CIclone tells us the result by the IDE notification. We don't need to switch to other applications, but we can keep coding on the IDE after the push and can know the execution result. nice&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Xmyq1_E3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6cco3muowlw2ypm6st5p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xmyq1_E3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6cco3muowlw2ypm6st5p.png" alt="Execution result notification" width="880" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Workflow execution results view
&lt;/h2&gt;

&lt;p&gt;Even after we receive notifications, we can still stay on the IDE and check the execution status (success/failed), the job list, and even the execution logs there. nice&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2r_zwJ2Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mc8fcm2cve5phq4tmden.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2r_zwJ2Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mc8fcm2cve5phq4tmden.png" alt="Workflow execution results view" width="880" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Jump to the failed tests
&lt;/h2&gt;

&lt;p&gt;If there are some tests failed, we can jump to the test cases on the source code. nice&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mlft3OTI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pwa6qs4a0uobw0bcugno.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mlft3OTI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pwa6qs4a0uobw0bcugno.png" alt="Jump to the failed tests" width="880" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In addition, we can run unit tests on the IDE from there. nice&lt;/p&gt;

&lt;h2&gt;
  
  
  Jump to CircleCI page
&lt;/h2&gt;

&lt;p&gt;It's also possible to jump to CircleCI page from the IDE. We just select the workflows or jobs on the view and click the following button, then the CircleCI site is open on the browser. nice&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HbKr7iuQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8inz7bsm04xfoehobzeh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HbKr7iuQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8inz7bsm04xfoehobzeh.png" alt="Jump to CircleCI page1" width="650" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, we can see the page like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EBM-mnhd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sdsdl39wpjzxh39thwzo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EBM-mnhd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sdsdl39wpjzxh39thwzo.png" alt="Jump to CircleCI page2" width="880" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Trigger pipeline
&lt;/h2&gt;

&lt;p&gt;We can trigger pipeline by clicking the execution button and specifying branch. nice&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D_yPwPUb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r624z9kc9buux6sb9qtd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D_yPwPUb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r624z9kc9buux6sb9qtd.png" alt="Trigger pipeline" width="644" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Rerun workflow
&lt;/h2&gt;

&lt;p&gt;Selecting the executed workflow, we can rerun the workflow from the rerun button. nice&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--x9Qu1HuA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jjwfyjgro63fzgs4u69s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x9Qu1HuA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jjwfyjgro63fzgs4u69s.png" alt="Rerun workflow" width="728" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  It seems super nice!
&lt;/h2&gt;

&lt;p&gt;With 🌀CIclone, now I can get CircleCI notifications in the IDE, check logs, re-run, etc., without switching apps while writing code, which seems very convenient!&lt;/p&gt;

&lt;p&gt;I don't have any Java projects right now, but I might try it with a Clojure or JavaScript project. If the language is not yet supported by 🌀CIclone, I don't think it is possible to jump to the code or execute UT, but still it is possible to see the CI results and receive notifications. I have a feeling that would be so useful!&lt;/p&gt;

&lt;p&gt;Below are notes on setting up this project&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a sample project: hello-ciclone
&lt;/h2&gt;

&lt;p&gt;I created a Maven project with Spring Initializr. It's been a while since I've used Java!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/bufferings/hello-ciclone"&gt;https://github.com/bufferings/hello-ciclone&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then I wrote a simple &lt;code&gt;config.yml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.1&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build-and-test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cimg/openjdk:17.0.3&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;checkout&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mvn -B -DskipTests clean package&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Test&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mvn test&lt;/span&gt;

&lt;span class="na"&gt;workflows&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;sample&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;build-and-test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clicked "Set Up Project" on the CircleCI project list:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jT5JQiv---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/chl4na4q51b0kg7jpu8s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jT5JQiv---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/chl4na4q51b0kg7jpu8s.png" alt="Set Up Project" width="880" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;select the config.yml in the main branch:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tmg7_v_5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pfop992to1y2xoobphz9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tmg7_v_5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pfop992to1y2xoobphz9.png" alt="select the config.yml" width="880" height="753"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, it automatically executes UT when I push code&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://app.circleci.com/pipelines/github/bufferings/hello-ciclone"&gt;https://app.circleci.com/pipelines/github/bufferings/hello-ciclone&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I added a few tests, and some of them succeed and some others fail.&lt;/p&gt;

&lt;p&gt;The project preparation is done.&lt;/p&gt;

&lt;h2&gt;
  
  
  IDEA configuration
&lt;/h2&gt;

&lt;p&gt;Next is a configuration on IDEA. I got license from Samuraism at first, then activated it. But I think we can try it without license for the 30 days trial period.&lt;/p&gt;

&lt;p&gt;Install plugin. Preferences &amp;gt; Plugins &amp;gt; Marketplace and type "ciclone" to find the plugin and install it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tz2nSx2u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i4x96nc0mqpzmvq0yvpn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tz2nSx2u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i4x96nc0mqpzmvq0yvpn.png" alt="Install plugin" width="880" height="627"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After rebooting IDEA, next was to set up CircleCI integration, Preferences &amp;gt; Tools &amp;gt; CircleCI&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xbd3-gN0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qiz0vawhumqifz1cdqm4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xbd3-gN0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qiz0vawhumqifz1cdqm4.png" alt="CircleCI integration" width="880" height="631"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wanted to get a new token from CircleCI, so I clicked the "Get Token" link to open CircleCI page for token generation:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1sgvyxsd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n9a5oxzvkf4gyk4toil2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1sgvyxsd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n9a5oxzvkf4gyk4toil2.png" alt="Get Token" width="880" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And "Create New Token" to generate a new token with some name and copied the value. Then pasted it to the config page of IDEA, and click "Import from existing project". I could see the list of my CircleCI projects:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YZGxKgta--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rikyi4lx1yc4uey96ib6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YZGxKgta--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rikyi4lx1yc4uey96ib6.png" alt="list of my CircleCI projects" width="880" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Chose the project I created just now and it became like this. The "Max Pipeline Size" seems the history count of the pipeline to retrieve. The default is five and I think it's good for me for now.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--u3EEP3P4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/we0a9sqixwixt98asa1x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--u3EEP3P4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/we0a9sqixwixt98asa1x.png" alt="CircleCI integration2" width="880" height="639"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clicked "Test"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8WQJJpKD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pzf6k3mwrs4r1fxrguat.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8WQJJpKD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pzf6k3mwrs4r1fxrguat.png" alt="Test" width="794" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It works!ヽ(=´▽`=)ﾉ&lt;/p&gt;

&lt;h2&gt;
  
  
  🌀CIclone View
&lt;/h2&gt;

&lt;p&gt;When we finish the configuration, we can see CircleCI tab at the bottom, so choosing it and click the sync button on the left top of the view to get the latest pipeline results:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rnh69ITK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f3baonu0nl716tgs6zhp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rnh69ITK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f3baonu0nl716tgs6zhp.png" alt="CIclone View" width="880" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can use it as I wrote in the first half of this article!&lt;/p&gt;

</description>
      <category>circleci</category>
      <category>ciclone</category>
      <category>jetbrains</category>
    </item>
    <item>
      <title>CircleCI Split Config Orb!</title>
      <dc:creator>Mitz</dc:creator>
      <pubDate>Thu, 21 Jul 2022 16:24:00 +0000</pubDate>
      <link>https://dev.to/bufferings/circleci-split-config-orb-4ba5</link>
      <guid>https://dev.to/bufferings/circleci-split-config-orb-4ba5</guid>
      <description>&lt;p&gt;I created a CircleCI Orb named Split Config. This is my private fun coding :)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://circleci.com/developer/orbs/orb/bufferings/split-config" rel="noopener noreferrer"&gt;https://circleci.com/developer/orbs/orb/bufferings/split-config&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Do you want to split your configuration file?
&lt;/h2&gt;

&lt;p&gt;Have you ever thought if you could split the &lt;code&gt;config.yml&lt;/code&gt; file of your CircleCI projects? Especially it could be bigger when the repository is a type of MonoRepo which includes multiple services in one repository.&lt;/p&gt;

&lt;p&gt;Good news! Split Config Orb is here for you!&lt;/p&gt;

&lt;h2&gt;
  
  
  Split Config Orb
&lt;/h2&gt;

&lt;p&gt;You can split your &lt;code&gt;config.yml&lt;/code&gt; into multiple configuration files. This Orb merges the split configs into one YAML when CircleCI starts and execute a pipeline with the merged configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Let's say you have multiple services in your repo like this:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2rdqf0y8ubxemrjth7q3.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2rdqf0y8ubxemrjth7q3.png" alt="File tree"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, it's empty but please imagine the source codes of each services are there :)&lt;/p&gt;

&lt;p&gt;Each service has a &lt;code&gt;config.yml&lt;/code&gt; for the service. For example. the config for service1 is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.1&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;service1-say-hello&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cimg/base:stable&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;checkout&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Say&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;hello"&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;echo&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Hello,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;World!1"&lt;/span&gt;

&lt;span class="na"&gt;workflows&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;service1-say-hello-workflow&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;common-say-hello&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;service1-say-hello&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;service2:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.1&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;service2-say-hello&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cimg/base:stable&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;checkout&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Say&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;hello"&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;echo&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Hello,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;World!2"&lt;/span&gt;

&lt;span class="na"&gt;workflows&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;service2-say-hello-workflow&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;common-say-hello&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;service2-say-hello&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;etc...&lt;/p&gt;

&lt;p&gt;The Orb merges these config files and it will be like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.1&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;common-say-hello&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cimg/base:stable&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;checkout&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Say hello&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo Hello, World! common&lt;/span&gt;
  &lt;span class="na"&gt;service1-say-hello&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cimg/base:stable&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;checkout&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Say hello&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo Hello, World!1&lt;/span&gt;
  &lt;span class="na"&gt;service2-say-hello&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cimg/base:stable&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;checkout&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Say hello&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo Hello, World!2&lt;/span&gt;
  &lt;span class="na"&gt;service3-say-hello&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cimg/base:stable&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;checkout&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Say hello&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo Hello, World!3&lt;/span&gt;
&lt;span class="na"&gt;workflows&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;service1-say-hello-workflow&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;common-say-hello&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;service1-say-hello&lt;/span&gt;
  &lt;span class="na"&gt;service2-say-hello-workflow&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;common-say-hello&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;service2-say-hello&lt;/span&gt;
  &lt;span class="na"&gt;service3-say-hello-workflow&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;common-say-hello&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;service3-say-hello&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to use
&lt;/h2&gt;

&lt;p&gt;It's super simple. You just need to prepare this &lt;code&gt;config.yml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.1&lt;/span&gt;

&lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="na"&gt;orbs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;split-config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bufferings/split-config@0.1.0&lt;/span&gt;

&lt;span class="na"&gt;workflows&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;generate-config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;split-config/generate-config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;find-config-regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.*/\.circleci/config\.yml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the Orb finds the config files according to the regex you specified, and merge them into one YAML file. After that, the Orb executes CircleCI pipeline with the generated YAML file.&lt;/p&gt;

&lt;p&gt;It uses the &lt;a href="https://circleci.com/docs/dynamic-config" rel="noopener noreferrer"&gt;Dynamic Config&lt;/a&gt; feature of CircleCI to start a new pipeline. By default, the feature is disabled, so please &lt;a href="https://circleci.com/docs/dynamic-config#getting-started-with-dynamic-config-in-circleci" rel="noopener noreferrer"&gt;enable the feature&lt;/a&gt; to get started.&lt;/p&gt;

&lt;p&gt;Then you will see something like this:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkin2j0oo2qj34mv0vf8b.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkin2j0oo2qj34mv0vf8b.png" alt="Example execution picture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's all!&lt;/p&gt;

&lt;p&gt;Are you interested in how it merges the configs?&lt;/p&gt;

&lt;h2&gt;
  
  
  How does it merge the configs?
&lt;/h2&gt;

&lt;p&gt;The Split Config Orb uses CUE to merge the YAML files.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CUE &lt;a href="https://cuelang.org/" rel="noopener noreferrer"&gt;https://cuelang.org/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CUE can import YAML file, convert them into CUE format, and merge them into one CUE config. In addition, it has a feature to export CUE config as YAML.&lt;/p&gt;

&lt;p&gt;I used these CUE features to merge your YAML configs. CUE is so powerful but I only use a small part of it. If you want to know more about CUE or how it merges multiple CUE configs, please check CUE specification!&lt;/p&gt;

&lt;h2&gt;
  
  
  For more details
&lt;/h2&gt;

&lt;p&gt;Please check the README in GitHub:&lt;br&gt;
&lt;a href="https://github.com/bufferings/orb-split-config" rel="noopener noreferrer"&gt;https://github.com/bufferings/orb-split-config&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wrote some usecases with working examples! Enjoy smaller configuration files&lt;/p&gt;

</description>
      <category>circleci</category>
      <category>cue</category>
    </item>
    <item>
      <title>Rethink Scrum from a Japanese cultural perspective #RSGT2021</title>
      <dc:creator>Mitz</dc:creator>
      <pubDate>Wed, 17 Feb 2021 13:18:18 +0000</pubDate>
      <link>https://dev.to/bufferings/rethink-scrum-from-a-japanese-cultural-perspective-rsgt2021-3jdd</link>
      <guid>https://dev.to/bufferings/rethink-scrum-from-a-japanese-cultural-perspective-rsgt2021-3jdd</guid>
      <description>&lt;p&gt;I joined Regional Scrum Gathering Tokyo 2021 held on 6-8 Jan.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://2021.scrumgatheringtokyo.org/"&gt;https://2021.scrumgatheringtokyo.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was an amazing event, organized as a mixed style of online and onsite this year. I enjoyed it a lot from the online. I watched many interesting sessions. Even after the event, we gathered on Discord to watch the recorded videos and have a talk.&lt;/p&gt;

&lt;p&gt;At the event, I talked about rethinking Scrum from a Japanese cultural perspective.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/bWAaRhrP_2Y"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;

&lt;p&gt;I have been working for Rakuten, Inc. for more than 10 years introducing Scrum to many teams. Last year, I was supporting a guy from oversea who joined the company at that time, he asked many questions to me and we talked a lot everyday.&lt;/p&gt;

&lt;p&gt;Answering his questions, I gradually understood his idea. It was totally different way of thinking for me. At the same time, I also understood how I think based on the Japanese culture.&lt;/p&gt;

&lt;p&gt;From that experience, I found the Japanese people may have a different perspective for Scrum. That's why I had this talk.&lt;/p&gt;

&lt;p&gt;In the session, I talked about &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does Scrum look the same from Japanese culture and another culture?&lt;/li&gt;
&lt;li&gt;Why is it so challenging to adopt Scrum in Japan?&lt;/li&gt;
&lt;li&gt;Rethink Scrum&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I'm glad if you enjoy my session video. I hope to join it onsite next year :)&lt;/p&gt;

</description>
      <category>scrum</category>
    </item>
    <item>
      <title>Istio 1.6.0 Canary Upgrade Trial</title>
      <dc:creator>Mitz</dc:creator>
      <pubDate>Sat, 23 May 2020 17:11:24 +0000</pubDate>
      <link>https://dev.to/bufferings/istio-1-6-0-canary-upgrade-trial-326j</link>
      <guid>https://dev.to/bufferings/istio-1-6-0-canary-upgrade-trial-326j</guid>
      <description>&lt;p&gt;While I am playing with Istio 1.5, it has become 1.6. Time flies...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://istio.io/news/releases/1.6.x/announcing-1.6/"&gt;https://istio.io/news/releases/1.6.x/announcing-1.6/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Istio LTS has 3 months release cycle. And the previous LTS becomes EOL after 3 months from the new LTS is released. Therefore I think it's important how to make it easy to handle upgrade.&lt;/p&gt;

&lt;p&gt;The good news is that Istio 1.6.0 supports Canary upgrade of Istio itself. It sounds interesting to me.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://istio.io/blog/2020/multiple-control-planes/"&gt;https://istio.io/blog/2020/multiple-control-planes/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I would like to try it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Environment
&lt;/h2&gt;

&lt;p&gt;I prepared a GKE cluster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ kubectl get nodes
NAME                                       STATUS   ROLES    AGE   VERSION
gke-cluster-1-default-pool-019aa731-6ztc   Ready    &amp;lt;none&amp;gt;   21m   v1.16.8-gke.15
gke-cluster-1-default-pool-019aa731-spbj   Ready    &amp;lt;none&amp;gt;   21m   v1.16.8-gke.15
gke-cluster-1-default-pool-019aa731-ztjz   Ready    &amp;lt;none&amp;gt;   21m   v1.16.8-gke.15
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And prepared &lt;code&gt;config.yaml&lt;/code&gt; file to install Istio which is a custom configuration for Istio install. I simply added Stackdriver integration, though it's not related to this article because I don't use anything of Stackdriver this time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;install.istio.io/v1alpha1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;IstioOperator&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;profile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;

  &lt;span class="na"&gt;addonComponents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;prometheus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;

  &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;global&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;proxy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;tracer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stackdriver"&lt;/span&gt;
      &lt;span class="na"&gt;logAsJson&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;telemetry&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;v2&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
        &lt;span class="na"&gt;prometheus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
        &lt;span class="na"&gt;stackdriver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
          &lt;span class="na"&gt;logging&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
          &lt;span class="na"&gt;monitoring&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
          &lt;span class="c1"&gt;# topology: true&lt;/span&gt;
          &lt;span class="na"&gt;configOverride&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Canary upgrade
&lt;/h2&gt;

&lt;p&gt;I followed this article:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://istio.io/docs/setup/upgrade/"&gt;https://istio.io/docs/setup/upgrade/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It introduces 2 types of upgrade:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Canary upgrades&lt;/li&gt;
&lt;li&gt;In place upgrades&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I will try canary upgrades this time from 1.5.4 to 1.6.0.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Istio 1.5
&lt;/h2&gt;

&lt;p&gt;At first, I install 1.5.4:&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;-L&lt;/span&gt; https://istio.io/downloadIstio | &lt;span class="nv"&gt;ISTIO_VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1.5.4 sh - 

❯ &lt;span class="nb"&gt;cd &lt;/span&gt;istio-1.5.4

&lt;span class="c"&gt;# I saved config.yaml with the contents I wrote above.&lt;/span&gt;
❯ bin/istioctl manifest apply &lt;span class="nt"&gt;-f&lt;/span&gt; config.yaml                   
- Applying manifest &lt;span class="k"&gt;for &lt;/span&gt;component Base...
✔ Finished applying manifest &lt;span class="k"&gt;for &lt;/span&gt;component Base.
- Applying manifest &lt;span class="k"&gt;for &lt;/span&gt;component Pilot...
✔ Finished applying manifest &lt;span class="k"&gt;for &lt;/span&gt;component Pilot.
  Waiting &lt;span class="k"&gt;for &lt;/span&gt;resources to become ready...
  Waiting &lt;span class="k"&gt;for &lt;/span&gt;resources to become ready...
  Waiting &lt;span class="k"&gt;for &lt;/span&gt;resources to become ready...
  Waiting &lt;span class="k"&gt;for &lt;/span&gt;resources to become ready...
  Waiting &lt;span class="k"&gt;for &lt;/span&gt;resources to become ready...
  Waiting &lt;span class="k"&gt;for &lt;/span&gt;resources to become ready...
- Applying manifest &lt;span class="k"&gt;for &lt;/span&gt;component IngressGateways...
✔ Finished applying manifest &lt;span class="k"&gt;for &lt;/span&gt;component IngressGateways.


✔ Installation &lt;span class="nb"&gt;complete&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, install our favorite bookinfo app:&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;# Enable sidecar auto injection&lt;/span&gt;
❯ kubectl label namespace default istio-injection&lt;span class="o"&gt;=&lt;/span&gt;enabled
namespace/default labeled

&lt;span class="c"&gt;# Deploy Bookinfo services&lt;/span&gt;
❯ kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; samples/bookinfo/platform/kube/bookinfo.yaml
service/details created
serviceaccount/bookinfo-details created
deployment.apps/details-v1 created
service/ratings created
serviceaccount/bookinfo-ratings created
deployment.apps/ratings-v1 created
service/reviews created
serviceaccount/bookinfo-reviews created
deployment.apps/reviews-v1 created
deployment.apps/reviews-v2 created
deployment.apps/reviews-v3 created
service/productpage created
serviceaccount/bookinfo-productpage created
deployment.apps/productpage-v1 created

&lt;span class="c"&gt;# Deploy Gateway&lt;/span&gt;
❯ kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; samples/bookinfo/networking/bookinfo-gateway.yaml
gateway.networking.istio.io/bookinfo-gateway created
virtualservice.networking.istio.io/bookinfo created

&lt;span class="c"&gt;# Get IP address of LB&lt;/span&gt;
❯ &lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;INGRESS_HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; istio-system get service istio-ingressgateway &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{.status.loadBalancer.ingress[0].ip}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Open the app with browser (My machine is Ubuntu)&lt;/span&gt;
❯ xdg-open http://&lt;span class="nv"&gt;$INGRESS_HOST&lt;/span&gt;/productpage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I can see a familiar bookinfo page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Upgrade to Istio 1.6
&lt;/h2&gt;

&lt;p&gt;Download 1.6.0:&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;-L&lt;/span&gt; https://istio.io/downloadIstio | &lt;span class="nv"&gt;ISTIO_VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1.6.0 sh - 
❯ &lt;span class="nb"&gt;cd &lt;/span&gt;istio-1.6.0
&lt;span class="c"&gt;# I saved config.yaml with the contents I wrote above.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Currently, my Istio version is 1.5.4:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ bin/istioctl version                                                     
client version: 1.5.4
control plane version: 1.5.4
data plane version: 1.5.4 &lt;span class="o"&gt;(&lt;/span&gt;7 proxies&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Run upgrade
&lt;/h2&gt;

&lt;p&gt;Then, upgrade the Istio following this document:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://istio.io/docs/setup/upgrade/"&gt;https://istio.io/docs/setup/upgrade/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;hm... though it says the command is like this:&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="nv"&gt;$ &lt;/span&gt;istioctl &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--set&lt;/span&gt; &lt;span class="nv"&gt;revision&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;canary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I guess I should specify my &lt;code&gt;config.yaml&lt;/code&gt; file, because it would be &lt;code&gt;deafult&lt;/code&gt; profile otherwise. So I checked the reference of the command:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://istio.io/docs/reference/commands/istioctl/#istioctl-install"&gt;https://istio.io/docs/reference/commands/istioctl/#istioctl-install&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It has &lt;code&gt;-f&lt;/code&gt; option, so I can try this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ bin/istioctl &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--set&lt;/span&gt; &lt;span class="nv"&gt;revision&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;canary &lt;span class="nt"&gt;-f&lt;/span&gt; config.yaml
✔ Istio core installed
✔ Istiod installed
✔ Ingress gateways installed
✔ Installation &lt;span class="nb"&gt;complete&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it seems worked. The result of watching pod is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; istio-system get pods &lt;span class="nt"&gt;-w&lt;/span&gt;
NAME                                    READY   STATUS    RESTARTS   AGE
istio-ingressgateway-7f76b9fc9f-ffr4j   1/1     Running   0          4m29s
istiod-6558b7b7f4-9d2dk                 1/1     Running   0          4m50s

&lt;span class="c"&gt;# I ran install command here&lt;/span&gt;

istiod-canary-848948494f-vrpz8          0/1     Pending   0          0s
istiod-canary-848948494f-vrpz8          0/1     Pending   0          0s
istiod-canary-848948494f-vrpz8          0/1     ContainerCreating   0          0s
istiod-canary-848948494f-vrpz8          0/1     Running             0          9s
istiod-canary-848948494f-vrpz8          1/1     Running             0          10s
istio-ingressgateway-ccbb848f5-b94mh    0/1     Pending             0          0s
istio-ingressgateway-ccbb848f5-b94mh    0/1     Pending             0          0s
istio-ingressgateway-ccbb848f5-b94mh    0/1     ContainerCreating   0          1s
istio-ingressgateway-ccbb848f5-b94mh    0/1     Running             0          8s
istio-ingressgateway-ccbb848f5-b94mh    1/1     Running             0          10s
istio-ingressgateway-7f76b9fc9f-ffr4j   1/1     Terminating         0          5m37s
istio-ingressgateway-7f76b9fc9f-ffr4j   0/1     Terminating         0          5m43s
istio-ingressgateway-7f76b9fc9f-ffr4j   0/1     Terminating         0          5m44s
istio-ingressgateway-7f76b9fc9f-ffr4j   0/1     Terminating         0          5m44s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, it became like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; istio-system
NAME                                   READY   STATUS    RESTARTS   AGE
istio-ingressgateway-ccbb848f5-b94mh   1/1     Running   0          7m16s
istiod-6558b7b7f4-9d2dk                1/1     Running   0          13m
istiod-canary-848948494f-vrpz8         1/1     Running   0          7m29s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What does it mean?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It adds &lt;code&gt;istiod-canary&lt;/code&gt; keeping the original &lt;code&gt;istiod&lt;/code&gt; as it is.&lt;/li&gt;
&lt;li&gt;Regarding &lt;code&gt;istio-ingressgateway&lt;/code&gt;, it stops the original one and deploys new one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I see... I looked into &lt;code&gt;istio-ingressgateway&lt;/code&gt; and found it became 1.6.0:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; istio-system get pods istio-ingressgateway-ccbb848f5-b94mh &lt;span class="nt"&gt;-o&lt;/span&gt; yaml | &lt;span class="nb"&gt;grep &lt;/span&gt;image: 
    image: docker.io/istio/proxyv2:1.6.0
    image: istio/proxyv2:1.6.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The version command shows this result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ bin/istioctl version
client version: 1.6.0
pilot version: 1.5.4
istiod version: 1.6.0
data plane version: 1.5.4 &lt;span class="o"&gt;(&lt;/span&gt;6 proxies&lt;span class="o"&gt;)&lt;/span&gt;, 1.6.0 &lt;span class="o"&gt;(&lt;/span&gt;1 proxies&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ah, it was like this before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ bin/istioctl version                                     
client version: 1.5.4
control plane version: 1.5.4
data plane version: 1.5.4 &lt;span class="o"&gt;(&lt;/span&gt;7 proxies&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It was separated from &lt;code&gt;control plane version&lt;/code&gt; into 2 parts: &lt;code&gt;pilot version&lt;/code&gt; and &lt;code&gt;istiod version&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Btw, it is &lt;code&gt;istio-ingressgateway&lt;/code&gt; which uses 1.6.0 in data plane version. It seems intended to update &lt;code&gt;ingress-gateway&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/istio/istio/issues/23923#issuecomment-630892188"&gt;https://github.com/istio/istio/issues/23923#issuecomment-630892188&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  At this point
&lt;/h2&gt;

&lt;p&gt;Data Plane remains 1.5.4. It should be 1.5.4, even though I restart the pods. Let's try:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ kubectl rollout restart deployment
deployment.apps/details-v1 restarted
deployment.apps/productpage-v1 restarted
deployment.apps/ratings-v1 restarted
deployment.apps/reviews-v1 restarted
deployment.apps/reviews-v2 restarted
deployment.apps/reviews-v3 restarted

❯ bin/istioctl version   
client version: 1.6.0
pilot version: 1.5.4
istiod version: 1.6.0
data plane version: 1.5.4 &lt;span class="o"&gt;(&lt;/span&gt;6 proxies&lt;span class="o"&gt;)&lt;/span&gt;, 1.6.0 &lt;span class="o"&gt;(&lt;/span&gt;1 proxies&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks good. They keep using 1.5.4.&lt;/p&gt;

&lt;h2&gt;
  
  
  Upgrade Data Plane
&lt;/h2&gt;

&lt;p&gt;As I tried now, each Pod still uses the previous version when we just install new &lt;code&gt;istiod-canary&lt;/code&gt;. We need to modify namespace label in order for the Pods to start using the new version.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ kubectl label namespace default istio-injection- istio.io/rev&lt;span class="o"&gt;=&lt;/span&gt;canary
namespace/default labeled

❯ kubectl get namespaces default &lt;span class="nt"&gt;--show-labels&lt;/span&gt;
NAME      STATUS   AGE   LABELS
default   Active   48m   istio.io/rev&lt;span class="o"&gt;=&lt;/span&gt;canary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I removed &lt;code&gt;istio-injection&lt;/code&gt; label from the &lt;code&gt;default&lt;/code&gt; namespace, where I installed bookinfo, and added &lt;code&gt;istio.io/rev=canary&lt;/code&gt; label. The reason why we need to remove &lt;code&gt;istio-injection&lt;/code&gt; label from the namespace is it has higher precedence than revision label for backward compatibility.&lt;/p&gt;

&lt;p&gt;Now they should start using new version when I restart them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ kubectl rollout restart deployment
deployment.apps/details-v1 restarted
deployment.apps/productpage-v1 restarted
deployment.apps/ratings-v1 restarted
deployment.apps/reviews-v1 restarted
deployment.apps/reviews-v2 restarted
deployment.apps/reviews-v3 restarted
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait for a while the Pods restart and check version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ bin/istioctl version
client version: 1.6.0
pilot version: 1.5.4
istiod version: 1.6.0
data plane version: 1.6.0 &lt;span class="o"&gt;(&lt;/span&gt;7 proxies&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is updated, yay! I also checked one of the container and found it used newer version of istiod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ bin/istioctl proxy-config endpoints details-v1-7bc48f795d-2fwzr &lt;span class="nt"&gt;--cluster&lt;/span&gt; xds-grpc &lt;span class="nt"&gt;-ojson&lt;/span&gt; | &lt;span class="nb"&gt;grep hostname&lt;/span&gt;
                &lt;span class="s2"&gt;"hostname"&lt;/span&gt;: &lt;span class="s2"&gt;"istiod-canary.istio-system.svc"&lt;/span&gt;,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Out of curiosity
&lt;/h2&gt;

&lt;p&gt;I wondered whether I can write &lt;code&gt;revision&lt;/code&gt; option in my &lt;code&gt;config.yaml&lt;/code&gt; file rather than setting it as a command line option.&lt;/p&gt;

&lt;p&gt;As a result, it works with this config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;install.istio.io/v1alpha1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;IstioOperator&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;profile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;

  &lt;span class="na"&gt;revision&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;v160"&lt;/span&gt;

  &lt;span class="na"&gt;addonComponents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;prometheus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;

  &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="c1"&gt;# omitted&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the first time, I wrote &lt;code&gt;v1.6.0&lt;/code&gt; but it didn't work, so I guess we can't use period as a revision name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ bin/istioctl &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; config.yaml
Error: failed to apply manifests: errors occurred during operation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  My thoughts
&lt;/h2&gt;

&lt;h3&gt;
  
  
  (1) How to clean up old version?
&lt;/h3&gt;

&lt;p&gt;I can still see old version resources such as &lt;code&gt;istiod&lt;/code&gt;, &lt;code&gt;sidecar-injector&lt;/code&gt; etc. But I'm not sure how to clean them up.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; istio-system
NAME                                   READY   STATUS    RESTARTS   AGE
istio-ingressgateway-ccbb848f5-b94mh   1/1     Running   0          62m
istiod-6558b7b7f4-9d2dk                1/1     Running   0          68m
istiod-canary-848948494f-vrpz8         1/1     Running   0          62m

❯ kubectl get mutatingwebhookconfigurations
NAME                                                 CREATED AT
istio-sidecar-injector                               2020-05-23T13:57:59Z
istio-sidecar-injector-canary                        2020-05-23T14:03:42Z
pod-ready.config.common-webhooks.networking.gke.io   2020-05-23T13:49:48Z
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Actially, it showed errors when I tried to install another istiod after I removed the original istiod. It seems to me the validation hook keep using old istiod and shows error?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ bin/istioctl &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; config.yaml                               
✔ Istio core installed                                                                                                                                                           
2020-05-23T15:31:02.866368Z     error   installer       failed to create &lt;span class="s2"&gt;"EnvoyFilter/istio-system/metadata-exchange-1.6-v160-2"&lt;/span&gt;: Internal error occurred: failed calling webhook &lt;span class="s2"&gt;"validation.istio.io"&lt;/span&gt;: Post https://istiod.istio-system.svc:443/validate?timeout&lt;span class="o"&gt;=&lt;/span&gt;30s: no endpoints available &lt;span class="k"&gt;for &lt;/span&gt;service &lt;span class="s2"&gt;"istiod"&lt;/span&gt;
2020-05-23T15:31:03.008138Z     error   installer       failed to create &lt;span class="s2"&gt;"EnvoyFilter/istio-system/stackdriver-filter-1.6-v160-2"&lt;/span&gt;: Internal error occurred: failed calling webhook &lt;span class="s2"&gt;"validation.istio.io"&lt;/span&gt;: Post https://istiod.istio-system.svc:443/validate?timeout&lt;span class="o"&gt;=&lt;/span&gt;30s: no endpoints available &lt;span class="k"&gt;for &lt;/span&gt;service &lt;span class="s2"&gt;"istiod"&lt;/span&gt;
2020-05-23T15:31:03.164115Z     error   installer       failed to create &lt;span class="s2"&gt;"EnvoyFilter/istio-system/tcp-metadata-exchange-1.6-v160-2"&lt;/span&gt;: Internal error occurred: failed calling webhook &lt;span class="s2"&gt;"validation.istio.io"&lt;/span&gt;: Post https://istiod.istio-system.svc:443/validate?timeout&lt;span class="o"&gt;=&lt;/span&gt;30s: no endpoints available &lt;span class="k"&gt;for &lt;/span&gt;service &lt;span class="s2"&gt;"istiod"&lt;/span&gt;
✘ Istiod encountered an error: failed to create &lt;span class="s2"&gt;"EnvoyFilter/istio-system/metadata-exchange-1.6-v160-2"&lt;/span&gt;: Internal error occurred: failed calling webhook &lt;span class="s2"&gt;"validation.istio.io"&lt;/span&gt;: Post https://istiod.istio-system.svc:443/validate?timeout&lt;span class="o"&gt;=&lt;/span&gt;30s: no endpoints available &lt;span class="k"&gt;for &lt;/span&gt;service &lt;span class="s2"&gt;"istiod"&lt;/span&gt;
failed to create &lt;span class="s2"&gt;"EnvoyFilter/istio-system/stackdriver-filter-1.6-v160-2"&lt;/span&gt;: Internal error occurred: failed calling webhook &lt;span class="s2"&gt;"validation.istio.io"&lt;/span&gt;: Post https://istiod.istio-system.svc:443/validate?timeout&lt;span class="o"&gt;=&lt;/span&gt;30s: no endpoints available &lt;span class="k"&gt;for &lt;/span&gt;service &lt;span class="s2"&gt;"istiod"&lt;/span&gt;
failed to create &lt;span class="s2"&gt;"EnvoyFilter/istio-system/tcp-metadata-exchange-1.6-v160-2"&lt;/span&gt;: Internal error occurred: failed calling webhook &lt;span class="s2"&gt;"validation.istio.io"&lt;/span&gt;: Post https://istiod.istio-system.svc:443/validate?timeout&lt;span class="o"&gt;=&lt;/span&gt;30s: no endpoints available &lt;span class="k"&gt;for &lt;/span&gt;service &lt;span class="s2"&gt;"istiod"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  (2) Should I keep using the name "canary"?
&lt;/h3&gt;

&lt;p&gt;I used "canary" for the revision name following the tutorial. But it seems I need to keep using the name "canary" for this version.&lt;/p&gt;

&lt;p&gt;So I feel I should use a name which I can keep using it for the version such as &lt;code&gt;v160&lt;/code&gt; etc?&lt;/p&gt;

&lt;h3&gt;
  
  
  (3) The unit isn't pod but namespace
&lt;/h3&gt;

&lt;p&gt;Currently, it only supports to change namespace label for the canary upgrade. I thought it would be convenient if I can upgrade pods one by one, but hm... it might be enough good.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It is a good direction that we can deploy multiple versions of istiod and gradually change to use the new version.&lt;/li&gt;
&lt;li&gt;I need to remember IngressGateway is upgraded at once without having multiple versions.&lt;/li&gt;
&lt;li&gt;I'm looking forward to seeing new information about cleanup. I hope it is added in 1.7.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And I started to subscribe this issue:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/istio/istio/issues/23889"&gt;https://github.com/istio/istio/issues/23889&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was fun!&lt;/p&gt;

</description>
      <category>istio</category>
    </item>
    <item>
      <title>Tried k8s + Istio on my laptop with k3d</title>
      <dc:creator>Mitz</dc:creator>
      <pubDate>Sun, 17 Nov 2019 03:59:40 +0000</pubDate>
      <link>https://dev.to/bufferings/tried-k8s-istio-in-my-local-machine-with-k3d-52gg</link>
      <guid>https://dev.to/bufferings/tried-k8s-istio-in-my-local-machine-with-k3d-52gg</guid>
      <description>&lt;h2&gt;
  
  
  ## k8s on local
&lt;/h2&gt;

&lt;p&gt;Sometimes I want to run k8s on my local machine to check something. So far I've used Minikube and one bound to Docker Desktop, but I wondered there might be newer ways to do it. Then I found this thread:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.reddit.com/r/kubernetes/comments/be0415/k3s_minikube_or_microk8s/" rel="noopener noreferrer"&gt;https://www.reddit.com/r/kubernetes/comments/be0415/k3s_minikube_or_microk8s/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The following tools are introduced there:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Minikube&lt;/li&gt;
&lt;li&gt;Microk8s&lt;/li&gt;
&lt;li&gt;K3s&lt;/li&gt;
&lt;li&gt;Kind&lt;/li&gt;
&lt;li&gt;Desktop Docker&lt;/li&gt;
&lt;li&gt;K3d&lt;/li&gt;
&lt;li&gt;Kubeadm&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I tried k3d, just because I felt I like it.&lt;/p&gt;

&lt;h2&gt;
  
  
  ## k3d
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/rancher/k3d" rel="noopener noreferrer"&gt;https://github.com/rancher/k3d&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It seems k3d runs k3s on Docker, which is also introduced in the thread above. I was confused a little bit when I thought Docker container which is for running Docker containers... but anyway I tried it. &lt;/p&gt;

&lt;p&gt;My laptop is Ubuntu, but it should work (I hope) on Windows &amp;amp; Mac because it's Docker.&lt;/p&gt;

&lt;p&gt;Firstly, I installed it reading the README (it supports brew as well):&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="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://raw.githubusercontent.com/rancher/k3d/master/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, I created cluster and set configuration for kubectl:&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="nv"&gt;$ &lt;/span&gt;k3d create
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;k3d get-kubeconfig&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It really worked!&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="nv"&gt;$ &lt;/span&gt;kubectl get pods &lt;span class="nt"&gt;-A&lt;/span&gt;
NAMESPACE     NAME                                      READY   STATUS      RESTARTS   AGE
kube-system   local-path-provisioner-58fb86bdfd-kvmdh   1/1     Running     0          3m40s
kube-system   coredns-57d8bbb86-grbbr                   1/1     Running     0          3m40s
kube-system   helm-install-traefik-4qr7t                0/1     Completed   0          3m40s
kube-system   svclb-traefik-j8c49                       3/3     Running     0          3m5s
kube-system   traefik-65bccdc4bd-vtk9r                  1/1     Running     0          3m5s

&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get svc &lt;span class="nt"&gt;-A&lt;/span&gt;                                                                                                                                                                                   
NAMESPACE     NAME         TYPE           CLUSTER-IP     EXTERNAL-IP    PORT&lt;span class="o"&gt;(&lt;/span&gt;S&lt;span class="o"&gt;)&lt;/span&gt;                                     AGE                                                                                
default       kubernetes   ClusterIP      10.43.0.1      &amp;lt;none&amp;gt;         443/TCP                                     5m57s                                                                              
kube-system   kube-dns     ClusterIP      10.43.0.10     &amp;lt;none&amp;gt;         53/UDP,53/TCP,9153/TCP                      5m56s                                                                              
kube-system   traefik      LoadBalancer   10.43.80.235   192.168.48.2   80:30107/TCP,443:31822/TCP,8080:31373/TCP   5m5s   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It seems to use traefik for a LoadBalancer service.&lt;/p&gt;

&lt;h2&gt;
  
  
  ## Istio?
&lt;/h2&gt;

&lt;p&gt;I hit upon an idea whether Istio could run on it. Then I found this issue:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/rancher/k3d/issues/104" rel="noopener noreferrer"&gt;https://github.com/rancher/k3d/issues/104&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It seems he successfully ran Istio on it after he turned off traefik to avoid port conflict.&lt;/p&gt;

&lt;p&gt;Let's try it.&lt;/p&gt;

&lt;h3&gt;
  
  
  ### Create k3d cluster without traefik
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Delete the previous cluster&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;k3d delete

&lt;span class="c"&gt;# Create a cluster without traefik&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;k3d create &lt;span class="nt"&gt;--server-arg&lt;/span&gt; &lt;span class="nt"&gt;--no-deploy&lt;/span&gt; &lt;span class="nt"&gt;--server-arg&lt;/span&gt; traefik

&lt;span class="c"&gt;# Generate config&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;k3d get-kubeconfig&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Check&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get pod,svc &lt;span class="nt"&gt;-A&lt;/span&gt;
NAMESPACE     NAME                                          READY   STATUS    RESTARTS   AGE
kube-system   pod/local-path-provisioner-58fb86bdfd-h6npn   1/1     Running   0          13m
kube-system   pod/coredns-57d8bbb86-zkjkq                   1/1     Running   0          13m

NAMESPACE     NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT&lt;span class="o"&gt;(&lt;/span&gt;S&lt;span class="o"&gt;)&lt;/span&gt;                  AGE
default       service/kubernetes   ClusterIP   10.43.0.1    &amp;lt;none&amp;gt;        443/TCP                  13m
kube-system   service/kube-dns     ClusterIP   10.43.0.10   &amp;lt;none&amp;gt;        53/UDP,53/TCP,9153/TCP   13m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I'm ready for installing Istio on it.&lt;/p&gt;

&lt;h3&gt;
  
  
  ### Install Istio
&lt;/h3&gt;

&lt;p&gt;I found the latest version was already 1.4, but I felt I would like to try 1.3 because 1.4 was released just in this month.&lt;/p&gt;

&lt;p&gt;I downloaded Istio from here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/istio/istio/releases/tag/1.3.5" rel="noopener noreferrer"&gt;https://github.com/istio/istio/releases/tag/1.3.5&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and I installed Istio following the steps in this page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://istio.io/docs/setup/install/helm/" rel="noopener noreferrer"&gt;https://istio.io/docs/setup/install/helm/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've already installed Helm on my laptop, and I chose the option of using &lt;code&gt;helm template&lt;/code&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="c"&gt;# Create a namespace for Istio&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl create namespace istio-system

&lt;span class="c"&gt;# Install CRDs&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;helm template &lt;span class="nb"&gt;install&lt;/span&gt;/kubernetes/helm/istio-init &lt;span class="nt"&gt;--name&lt;/span&gt; istio-init &lt;span class="nt"&gt;--namespace&lt;/span&gt; istio-system | kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; -

&lt;span class="c"&gt;# Wait for the generation of the CRDs&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; istio-system &lt;span class="nb"&gt;wait&lt;/span&gt; &lt;span class="nt"&gt;--for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;condition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;complete &lt;/span&gt;job &lt;span class="nt"&gt;--all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oh, I found the command has been changed. Previously, it was &lt;code&gt;wc&lt;/code&gt; to check there're 23 CRDs created, but now it uses &lt;code&gt;kubectl wait --for&lt;/code&gt;. Nice!&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="nv"&gt;$ &lt;/span&gt;helm template &lt;span class="nb"&gt;install&lt;/span&gt;/kubernetes/helm/istio &lt;span class="nt"&gt;--name&lt;/span&gt; istio &lt;span class="nt"&gt;--namespace&lt;/span&gt; istio-system | kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I couldn't believe there's no error... This might be the first time for me to be able to install Istio without any troubles lol&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get svc,pod &lt;span class="nt"&gt;-n&lt;/span&gt; istio-system
NAME                             TYPE           CLUSTER-IP      EXTERNAL-IP    PORT&lt;span class="o"&gt;(&lt;/span&gt;S&lt;span class="o"&gt;)&lt;/span&gt;                                                                                                                                      AGE
service/istio-galley             ClusterIP      10.43.10.191    &amp;lt;none&amp;gt;         443/TCP,15014/TCP,9901/TCP                                                                                                                   2m21s
service/istio-policy             ClusterIP      10.43.86.131    &amp;lt;none&amp;gt;         9091/TCP,15004/TCP,15014/TCP                                                                                                                 2m21s
service/istio-telemetry          ClusterIP      10.43.11.107    &amp;lt;none&amp;gt;         9091/TCP,15004/TCP,15014/TCP,42422/TCP                                                                                                       2m21s
service/istio-pilot              ClusterIP      10.43.126.19    &amp;lt;none&amp;gt;         15010/TCP,15011/TCP,8080/TCP,15014/TCP                                                                                                       2m21s
service/prometheus               ClusterIP      10.43.41.148    &amp;lt;none&amp;gt;         9090/TCP                                                                                                                                     2m21s
service/istio-citadel            ClusterIP      10.43.91.217    &amp;lt;none&amp;gt;         8060/TCP,15014/TCP                                                                                                                           2m21s
service/istio-sidecar-injector   ClusterIP      10.43.117.133   &amp;lt;none&amp;gt;         443/TCP,15014/TCP                                                                                                                            2m21s
service/istio-ingressgateway     LoadBalancer   10.43.69.0      192.168.96.2   15020:30845/TCP,80:31380/TCP,443:31390/TCP,31400:31400/TCP,15029:31842/TCP,15030:32247/TCP,15031:32685/TCP,15032:31093/TCP,15443:30499/TCP   2m21s

NAME                                          READY   STATUS      RESTARTS   AGE
pod/istio-init-crd-10-1.3.5-28hj7             0/1     Completed   0          5m40s
pod/istio-init-crd-11-1.3.5-vmwmw             0/1     Completed   0          5m40s
pod/istio-init-crd-12-1.3.5-84q77             0/1     Completed   0          5m40s
pod/istio-security-post-install-1.3.5-jb66j   0/1     Completed   0          2m21s
pod/svclb-istio-ingressgateway-ww22d          9/9     Running     0          2m21s
pod/istio-citadel-5c67db5cb-hmhvb             1/1     Running     0          2m20s
pod/prometheus-6f74d6f76d-tpjpc               1/1     Running     0          2m20s
pod/istio-policy-66d87c756b-hf4wx             2/2     Running     3          2m21s
pod/istio-galley-56b9fb859d-7jmsq             1/1     Running     0          2m21s
pod/istio-sidecar-injector-5d65cfcd79-lhh6k   1/1     Running     0          2m20s
pod/istio-pilot-64478c6886-9xm7b              2/2     Running     0          2m20s
pod/istio-telemetry-5d4c4bfbbf-g4ccz          2/2     Running     4          2m20s
pod/istio-ingressgateway-7b766b6685-5vwg5     1/1     Running     0          2m21s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, I tried to run a sample application on the Istio.&lt;/p&gt;

&lt;h3&gt;
  
  
  ### Deploy bookinfo sample application
&lt;/h3&gt;

&lt;p&gt;To check it actually works, I deployed bookinfo sample application included in Istio:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://istio.io/docs/examples/bookinfo/" rel="noopener noreferrer"&gt;https://istio.io/docs/examples/bookinfo/&lt;/a&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="c"&gt;# Enable automatic sidecar injection&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl label namespace default istio-injection&lt;span class="o"&gt;=&lt;/span&gt;enabled

&lt;span class="c"&gt;# Deploy apps&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; samples/bookinfo/platform/kube/bookinfo.yaml

&lt;span class="c"&gt;# Wait for the deployment finished for example using watch&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get pods &lt;span class="nt"&gt;-w&lt;/span&gt;
NAME                              READY   STATUS            RESTARTS   AGE
details-v1-78d78fbddf-5db8b       0/2     PodInitializing   0          37s
reviews-v1-7bb8ffd9b6-rdgjc       0/2     PodInitializing   0          37s
ratings-v1-6c9dbf6b45-p7567       0/2     PodInitializing   0          36s
productpage-v1-596598f447-nj6wx   0/2     PodInitializing   0          36s
reviews-v3-68964bc4c8-qrhc4       0/2     PodInitializing   0          37s
reviews-v2-d7d75fff8-65f4q        0/2     PodInitializing   0          37s

&lt;span class="c"&gt;# Create ingress gateway for bookinfo&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; samples/bookinfo/networking/bookinfo-gateway.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, I confirmed External IP of LoadBalaner service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get svc  -n istio-system istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
192.168.96.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and opened the following URL with the IP:&lt;/p&gt;

&lt;p&gt;http://{The IP Address}/productpage&lt;/p&gt;

&lt;p&gt;I was surprised again that it worked!&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fd09b8j6pg3qkpvqkeefj.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fd09b8j6pg3qkpvqkeefj.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The memory usage of the container with bookinfo was around 2GiB:&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="nv"&gt;$ &lt;/span&gt;docker stats &lt;span class="nt"&gt;--no-stream&lt;/span&gt;
CONTAINER ID        NAME                     CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
598bd6d07c85        k3d-k3s-default-server   52.24%              1.909GiB / 15.4GiB   12.40%              819MB / 21.7MB      1.41MB / 818MB      899
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thought it wouldn't be easier to solve problems if something happens somewhere, it seems very convenient to run k8s on local with k3d.&lt;/p&gt;

</description>
      <category>istio</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Micronaut PetClinic with GraalVM &gt; 19</title>
      <dc:creator>Mitz</dc:creator>
      <pubDate>Sat, 15 Jun 2019 12:29:17 +0000</pubDate>
      <link>https://dev.to/bufferings/micronaut-petclinic-with-graalvm-19-2dih</link>
      <guid>https://dev.to/bufferings/micronaut-petclinic-with-graalvm-19-2dih</guid>
      <description>&lt;p&gt;Now you can run Micronaut PetClinic with the (kinda) latest GraalVM Native Image. I will explain the meaning later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build &amp;amp; Run
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git clone https://github.com/bufferings/micronaut-petclinic.git
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;micronaut-petclinic

&lt;span class="c"&gt;# Build Native Image. Please wait for 10-15 minutes.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;./mvnw package &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; docker build &lt;span class="nt"&gt;-t&lt;/span&gt; micronaut-petclinic &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# Start Database&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt; db

&lt;span class="c"&gt;# Run separately to see the log easily&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;docker-compose up app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Start up time
&lt;/h2&gt;

&lt;p&gt;It starts in a few hundreds of millis.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RUn5pnxR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/qn4zxe51bsy9i4niufl8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RUn5pnxR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/qn4zxe51bsy9i4niufl8.png" alt="" width="880" height="440"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Docker Information
&lt;/h2&gt;

&lt;p&gt;The image size is 130MB.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ docker images micronaut-petclinic
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
micronaut-petclinic   latest              40834e227e19        About an hour ago   130MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;and the memory usage is 125MB after using for a while&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ docker ps &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;micronaut-petclinic_app&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; | xargs docker stats &lt;span class="nt"&gt;--no-stream&lt;/span&gt;
CONTAINER ID        NAME                                     CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
5c4c627ee81d        micronaut-petclinic_app_1_1350df269f2b   0.07%               124.3MiB / 15.4GiB   0.79%               158kB / 121kB       0B / 0B             11

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;I created Micronaut PetClinic last month and it worked as Native Image with GraalVM 1.0 RC16 to start surprisingly fast speed in a few hundreds of millis.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/bufferings" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EzRUEGnY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--S4URUfHU--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/42684/e65785f0-09e0-464b-91d4-ceb3f6b7346f.jpg" alt="bufferings"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/bufferings/micronaut-petclinic-58id" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Micronaut PetClinic&lt;/h2&gt;
      &lt;h3&gt;Mitz ・ May 6 '19 ・ 1 min read&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#micronautfw&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#graalvm&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#java&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;p&gt;A few days later, GraalVM released a production version 19.0.0.&lt;br&gt;
&lt;a href="https://medium.com/graalvm/announcing-graalvm-19-4590cf354df8"&gt;https://medium.com/graalvm/announcing-graalvm-19-4590cf354df8&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But unfortunately, my PetClinic doesn't work with GraalVM 19 Native Image. (´・ω・｀)&lt;/p&gt;

&lt;p&gt;The cause is this issue:&lt;br&gt;
&lt;a href="https://github.com/oracle/graal/issues/1295"&gt;https://github.com/oracle/graal/issues/1295&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and we need this commit:&lt;br&gt;
&lt;a href="https://github.com/oracle/graal/commit/c6237d219a91c82b1954dfbfa0898ed917db09eb"&gt;https://github.com/oracle/graal/commit/c6237d219a91c82b1954dfbfa0898ed917db09eb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The commit hasn't been included in the latest version 19.0.2 released yesterday.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker Image with the latest GraalVM
&lt;/h2&gt;

&lt;p&gt;Then I found it works when I build GraalVM from its master branch. So I created a Docker image with the master branch:&lt;br&gt;
&lt;a href="https://hub.docker.com/r/bufferings/build-graalvm-docker"&gt;https://hub.docker.com/r/bufferings/build-graalvm-docker&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I would like to use it for a while until the commit is included in the GraalVM official release.&lt;/p&gt;

&lt;p&gt;With Micronaut, it's so easy to create an application for Native Image, but I would like to talk about it another time (๑•̀ㅂ•́)و✧&lt;/p&gt;

</description>
      <category>micronaut</category>
      <category>graalvm</category>
      <category>java</category>
    </item>
    <item>
      <title>Micronaut PetClinic</title>
      <dc:creator>Mitz</dc:creator>
      <pubDate>Mon, 06 May 2019 18:14:22 +0000</pubDate>
      <link>https://dev.to/bufferings/micronaut-petclinic-58id</link>
      <guid>https://dev.to/bufferings/micronaut-petclinic-58id</guid>
      <description>&lt;p&gt;I tried implementing &lt;a href="https://github.com/spring-projects/spring-petclinic" rel="noopener noreferrer"&gt;Spring PetClinic&lt;/a&gt; with &lt;a href="https://docs.micronaut.io" rel="noopener noreferrer"&gt;Micronaut&lt;/a&gt; instead of using Spring.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/bufferings/micronaut-petclinic" rel="noopener noreferrer"&gt;https://github.com/bufferings/micronaut-petclinic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The application uses Thymeleaf, JPA(Hibernate) and DI. But it starts in a few hundreds of millis with &lt;a href="https://www.graalvm.org/" rel="noopener noreferrer"&gt;GraalVM&lt;/a&gt; native image. It's so fast!&lt;/p&gt;

&lt;p&gt;In this picture, it started in 324ms:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5i6lyf1dinqp3p5dsv32.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5i6lyf1dinqp3p5dsv32.png" alt="Screen Capture" width="800" height="661"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I haven't yet implemented all the features and it's still very dirty, but basic features work.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to try (not native image)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Clone the Project
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/bufferings/micronaut-petclinic.git
&lt;span class="nb"&gt;cd &lt;/span&gt;micronaut-petclinic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Start PostgreSQL
&lt;/h3&gt;

&lt;p&gt;This Petclinic uses PostgreSQL. You could start PostgreSQL with docker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Run Application
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./mvnw compile &lt;span class="nb"&gt;exec&lt;/span&gt;:exec
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3-2. Or you can run it from JAR
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./mvnw package
java -jar target/micronaut-*.jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Access PetClinic
&lt;/h3&gt;

&lt;p&gt;You can then access petclinic here: &lt;a href="http://localhost:8080/" rel="noopener noreferrer"&gt;http://localhost:8080/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With JAR file, it takes around 5s to start the app on my laptop.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to try native image
&lt;/h2&gt;

&lt;p&gt;Micronaut supports GraalVM native image. So I made this PetClinic run as native image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./mvnw package &amp;amp;&amp;amp; docker build -t micronaut-petclinic .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I usually have ☕ (around 10 mins on my laptop) to wait for the build finishes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Docker for Mac or Windows
export HOST_NAME=host.docker.internal
# Linux
export HOST_NAME=172.17.0.1

docker run --rm -p 8080:8080 -e JDBC_URL=jdbc:postgresql://${HOST_NAME}:5432/petclinic micronaut-petclinic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then it takes around 300ms to start. (๑•̀ㅂ•́)و✧&lt;/p&gt;

</description>
      <category>micronautfw</category>
      <category>graalvm</category>
      <category>java</category>
    </item>
    <item>
      <title>Let's make SpringBoot app start faster</title>
      <dc:creator>Mitz</dc:creator>
      <pubDate>Sat, 17 Nov 2018 01:36:32 +0000</pubDate>
      <link>https://dev.to/bufferings/lets-make-springboot-app-start-faster-k9m</link>
      <guid>https://dev.to/bufferings/lets-make-springboot-app-start-faster-k9m</guid>
      <description>&lt;h2&gt;
  
  
  "How Fast is Spring?"
&lt;/h2&gt;

&lt;p&gt;is a session at Spring One Platform 2018. I watched the video and tried it by myself. So I introduce here what I did and the results.&lt;/p&gt;

&lt;p&gt;I recommend you to watch this session video if you haven't yet. It's so interesting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://springoneplatform.io/2018/sessions/how-fast-is-spring-" rel="noopener noreferrer"&gt;https://springoneplatform.io/2018/sessions/how-fast-is-spring-&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Today's source code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/bufferings/spring-boot-startup-mybench" rel="noopener noreferrer"&gt;https://github.com/bufferings/spring-boot-startup-mybench&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;↓I used OpenJDK 11.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ java &lt;span class="nt"&gt;--version&lt;/span&gt;
openjdk 11.0.1 2018-10-16
OpenJDK Runtime Environment 18.9 &lt;span class="o"&gt;(&lt;/span&gt;build 11.0.1+13&lt;span class="o"&gt;)&lt;/span&gt;
OpenJDK 64-Bit Server VM 18.9 &lt;span class="o"&gt;(&lt;/span&gt;build 11.0.1+13, mixed mode&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;↓You can run all the benchmarks like this. It will take a while because it runs all the benchmarks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ ./mvnw clean package
❯ &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;benchmarks/&lt;span class="p"&gt;;&lt;/span&gt; java &lt;span class="nt"&gt;-jar&lt;/span&gt; target/benchmarks.jar&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  1. FluxBaseline
&lt;/h2&gt;

&lt;p&gt;↓I created a project using SpringInitializr only with Reactive Web. Then, I wrote a tiny controller with WebMVC style.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@SpringBootApplication&lt;/span&gt;
&lt;span class="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DemoApplication&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;home&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;SpringApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;DemoApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;↓The version of Spring Boot was 2.1.0.RELEASE.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;parent&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-parent&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.1.0.RELEASE&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;relativePath/&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- lookup parent from repository --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/parent&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;↓It took 2.938 ± 0.287 s/op to start.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I got a baseline to check the startup time. Let's start from here.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. WebMVC
&lt;/h2&gt;

&lt;p&gt;↓I wondered what about WebMVC, not WebFlux? So I tried it. Maybe does it just mean the comparison of Tomcat and Netty?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case02_Web                               ss   10  3.281 ± 0.342   s/op
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WebFlux is a bit faster, isn't it?&lt;/p&gt;

&lt;h2&gt;
  
  
  3. spring-context-indexer
&lt;/h2&gt;

&lt;p&gt;Next, I tried spring-context-indexer which seems to create component index.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-context-indexer&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;optional&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/optional&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;↓Um... a little slower?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case03_WithContextIndexer                ss   10  3.063 ± 0.102   s/op
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;↓I checked &lt;code&gt;spring.components&lt;/code&gt;, and found it contained only 1 component. I see... I should try with a bigger project to know the effect.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#
#Sun Nov 04 18:42:59 JST 2018
com.example.DemoApplication=org.springframework.stereotype.Component
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Lazy Initialization
&lt;/h2&gt;

&lt;p&gt;Tried Lazy Init.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LazyInitBeanFactoryPostProcessor&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;BeanFactoryPostProcessor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;postProcessBeanFactory&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ConfigurableListableBeanFactory&lt;/span&gt; &lt;span class="n"&gt;beanFactory&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;BeansException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;beanName&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;beanFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBeanDefinitionNames&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;beanFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBeanDefinition&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;beanName&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;setLazyInit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;↓Here's the result. It became just a little bit faster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case04_WithLazyInit                      ss   10  2.844 ± 0.129   s/op
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. NoVerify
&lt;/h2&gt;

&lt;p&gt;Ran with &lt;code&gt;-noverify&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case05_WithNoVerifyOption                ss   10  2.582 ± 0.060   s/op
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It became a little faster. I don't know what it means, so I need to check it later sometime.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. TieredStopAtLevel
&lt;/h2&gt;

&lt;p&gt;Ran with &lt;code&gt;-XX:TieredStopAtLevel=1&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case06_WithTieredStopAtLevel1Option      ss   10  1.980 ± 0.037   s/op
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uh, much faster! It took less than 2 seconds. But I don't know this flag, too. So I will check it later.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Specify SpringConfigLocation explicitly
&lt;/h2&gt;

&lt;p&gt;Ran with &lt;code&gt;-Dspring.config.location=classpath:/application.properties&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case07_WithSpringConfigLocationOption    ss   10  3.026 ± 0.139   s/op
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Um, it became slower.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Turn off JMX
&lt;/h2&gt;

&lt;p&gt;Ran with &lt;code&gt;-Dspring.jmx.enabled=false&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case08_WithJmxDisabledOption             ss   10  2.877 ± 0.097   s/op
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It became a little bit faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Exclude Logback
&lt;/h2&gt;

&lt;p&gt;From here, I try to exclude libraries. At first, excluding Logback:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-webflux&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;exclusions&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;exclusion&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-logging&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/exclusion&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/exclusions&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.slf4j&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;slf4j-jdk14&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case09_WithoutLogback                    ss   10  2.904 ± 0.096   s/op
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;mm... slightly improved?&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Exclude Jackson
&lt;/h2&gt;

&lt;p&gt;Next is Jackson&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-webflux&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;exclusions&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;exclusion&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-json&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/exclusion&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/exclusions&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case10_WithoutJackson                    ss   10  2.789 ± 0.093   s/op
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It became a little bit faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Exclude HibernateValidator
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-webflux&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;exclusions&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;exclusion&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;hibernate-validator&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.hibernate.validator&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/exclusion&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/exclusions&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case11_WithoutHibernateValidator         ss   10  2.857 ± 0.084   s/op
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Slightly improved, too.&lt;/p&gt;

&lt;p&gt;This is the end of library exclusion.&lt;/p&gt;

&lt;h2&gt;
  
  
  12. AppCDS
&lt;/h2&gt;

&lt;p&gt;AppCDS (Application Class Data Sharing) was included in Oracle JDK as a commercial feature. But it became available from OpenJDK 10.&lt;/p&gt;

&lt;p&gt;It seems AppCDS dumps information into a shared archive, so startup time becomes shorter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case12_WithAppCds                        ss   10  2.957 ± 0.079   s/op
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;mm... it wasn't faster... then I checked articles about CDS, and found the reason.&lt;/p&gt;

&lt;p&gt;With SpringBoot FatJAR, the libraries are out of the scope of CDS.&lt;/p&gt;

&lt;h2&gt;
  
  
  13. Flux with Thin Launcher
&lt;/h2&gt;

&lt;p&gt;Uh, I'm sorry, but the benchmark name "Exploded" is wrong. Once I tried to explode the FatJAR, but I couldn't use CDS with the exploded JAR after all. So I switched to use Thin Launcher. Please take the benchmark name "Exploded" as "Thin Launcher".&lt;/p&gt;

&lt;p&gt;Before using CDS, I would like to check the speed of JAR file packaged with Thin Launcher.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;        &lt;span class="nt"&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-maven-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot.experimental&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-thin-layout&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0.15.RELEASE&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/plugins&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although I used Thin Launcher to package the app, I didn't use the launch class of Thin Launcher, but specified Main class to make the startup time as fast as possible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case13_Exploded                          ss   10  2.476 ± 0.091   s/op
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;hum, a bit faster, isn't it?&lt;/p&gt;

&lt;h2&gt;
  
  
  14. Thin Launcher + CDS
&lt;/h2&gt;

&lt;p&gt;Now I would like to apply AppCDS to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case14_ExplodedWithAppCds                ss   10  1.535 ± 0.036   s/op
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wow! It became much faster!&lt;/p&gt;

&lt;h2&gt;
  
  
  15. All applied
&lt;/h2&gt;

&lt;p&gt;Finally, I applied everything.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case15_AllApplied                        ss   10  0.801 ± 0.037   s/op
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Less than 1 second! (∩´∀｀)∩yay&lt;/p&gt;

&lt;h2&gt;
  
  
  One more step
&lt;/h2&gt;

&lt;p&gt;In the Dave's session, he mentioned "Functional Bean Definitions", tried improvements with Spring without SpringBoot and the app became much faster. I need to learn more to understand them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result list
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case02_Web                               ss   10  3.281 ± 0.342   s/op
MyBenchmark.case03_WithContextIndexer                ss   10  3.063 ± 0.102   s/op
MyBenchmark.case04_WithLazyInit                      ss   10  2.844 ± 0.129   s/op
MyBenchmark.case05_WithNoVerifyOption                ss   10  2.582 ± 0.060   s/op
MyBenchmark.case06_WithTieredStopAtLevel1Option      ss   10  1.980 ± 0.037   s/op
MyBenchmark.case07_WithSpringConfigLocationOption    ss   10  3.026 ± 0.139   s/op
MyBenchmark.case08_WithJmxDisabledOption             ss   10  2.877 ± 0.097   s/op
MyBenchmark.case09_WithoutLogback                    ss   10  2.904 ± 0.096   s/op
MyBenchmark.case10_WithoutJackson                    ss   10  2.789 ± 0.093   s/op
MyBenchmark.case11_WithoutHibernateValidator         ss   10  2.857 ± 0.084   s/op
MyBenchmark.case12_WithAppCds                        ss   10  2.957 ± 0.079   s/op
MyBenchmark.case13_Exploded                          ss   10  2.476 ± 0.091   s/op
MyBenchmark.case14_ExplodedWithAppCds                ss   10  1.535 ± 0.036   s/op
MyBenchmark.case15_AllApplied                        ss   10  0.801 ± 0.037   s/op
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It was really interesting. Thank you!&lt;/p&gt;

</description>
      <category>java</category>
      <category>springboot</category>
    </item>
    <item>
      <title>Spring Boot Thin Launcher and Docker</title>
      <dc:creator>Mitz</dc:creator>
      <pubDate>Tue, 02 Oct 2018 12:44:32 +0000</pubDate>
      <link>https://dev.to/bufferings/spring-boot-thin-launcher-anddocker-2oa7</link>
      <guid>https://dev.to/bufferings/spring-boot-thin-launcher-anddocker-2oa7</guid>
      <description>&lt;h2&gt;
  
  
  Spring Boot Thin Launcher
&lt;/h2&gt;

&lt;p&gt;Yesterday, I played with the Spring Boot Startup Bench.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/bufferings" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EzRUEGnY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--S4URUfHU--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/42684/e65785f0-09e0-464b-91d4-ceb3f6b7346f.jpg" alt="bufferings"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/bufferings/started-enjoying-spring-boot-startup-bench-1ahj" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Started enjoying spring-boot-startup-bench&lt;/h2&gt;
      &lt;h3&gt;Mitz ・ Oct 1 '18 ・ 2 min read&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#springboot&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#java&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;and noticed it uses Spring Boot Thin Launcher. So today, I played with the Thin Launcher, which enables to create a thin jar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/dsyer/spring-boot-thin-launcher"&gt;https://github.com/dsyer/spring-boot-thin-launcher&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My Source Code
&lt;/h2&gt;

&lt;p&gt;is here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/bufferings/spring-boot-thin-sandbox"&gt;https://github.com/bufferings/spring-boot-thin-sandbox&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are 3 directories.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;demo-fat: Normal SpringBoot app.&lt;/li&gt;
&lt;li&gt;demo-thin: Thin app.&lt;/li&gt;
&lt;li&gt;demo-thin-docker: Thin app with docker.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  demo-fat
&lt;/h2&gt;

&lt;p&gt;This is just a simple spring boot app with web, though it has no page.&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;cd &lt;/span&gt;demo-fat
❯ ./mvnw clean package
❯ &lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-ahl&lt;/span&gt; target/demo-fat-0.0.1-SNAPSHOT.jar
&lt;span class="nt"&gt;-rw-rw-r&lt;/span&gt; - 1 bufferings bufferings 16M Sep 30 22:16 target/demo-fat-0.0.1-SNAPSHOT.jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The size is 16MB.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ java &lt;span class="nt"&gt;-jar&lt;/span&gt; target/demo-fat-0.0.1-SNAPSHOT.jar
…
2018–09–30 22:29:04.617 INFO 32639 - - &lt;span class="o"&gt;[&lt;/span&gt; main] com.example.demo.DemoApplication : Started DemoApplication &lt;span class="k"&gt;in &lt;/span&gt;3.852 seconds &lt;span class="o"&gt;(&lt;/span&gt;JVM running &lt;span class="k"&gt;for &lt;/span&gt;4.464&lt;span class="o"&gt;)&lt;/span&gt;
…
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  demo-thin
&lt;/h2&gt;

&lt;p&gt;This is also a simple spring boot app, but with Spring Boot Thin Launcher.&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;cd &lt;/span&gt;demo-thin
❯ ./mvnw clean package
❯ &lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-ahl&lt;/span&gt; target/demo-thin-0.0.1-SNAPSHOT.jar
&lt;span class="nt"&gt;-rw-rw-r&lt;/span&gt; - 1 bufferings bufferings 11K Sep 30 22:24 target/demo-thin-0.0.1-SNAPSHOT.jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's only 11KB. It downloads a launcher and libraries on startup, but actually it uses .m2 directory so it doesn't take so long.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ java &lt;span class="nt"&gt;-jar&lt;/span&gt; target/demo-thin-0.0.1-SNAPSHOT.jar
…
2018–09–30 22:30:51.689 INFO 1303 - - &lt;span class="o"&gt;[&lt;/span&gt; main] com.example.demo.DemoApplication : Started DemoApplication &lt;span class="k"&gt;in &lt;/span&gt;3.012 seconds &lt;span class="o"&gt;(&lt;/span&gt;JVM running &lt;span class="k"&gt;for &lt;/span&gt;4.987&lt;span class="o"&gt;)&lt;/span&gt;
…
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  demo-thin-docker
&lt;/h2&gt;

&lt;p&gt;This is a thin app with Docker.&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;cd &lt;/span&gt;demo-thin-docker
❯ ./mvnw clean package
❯ docker build &lt;span class="nt"&gt;-t&lt;/span&gt; demo-thin-docker &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This takes time to download all the dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080 demo-thin-docker - thin.debug&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; - thin.offline&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
…
2018–09–30 13:42:32.978 INFO 1 - - &lt;span class="o"&gt;[&lt;/span&gt; main] com.example.demo.DemoApplication : Started DemoApplication &lt;span class="k"&gt;in &lt;/span&gt;3.437 seconds &lt;span class="o"&gt;(&lt;/span&gt;JVM running &lt;span class="k"&gt;for &lt;/span&gt;5.804&lt;span class="o"&gt;)&lt;/span&gt;
…
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Dockerfile
&lt;/h2&gt;

&lt;p&gt;is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;FROM openjdk:11-jdk-slim
COPY docker/spring-boot-thin-wrapper-1.0.15.RELEASE.jar /thin/wrapper.jar
COPY pom.xml /thin/pom.xml
WORKDIR /thin
RUN jar cvf pom.jar pom.xml
RUN java &lt;span class="nt"&gt;-jar&lt;/span&gt; wrapper.jar &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--thin&lt;/span&gt;.archive&lt;span class="o"&gt;=&lt;/span&gt;/thin/pom.jar &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--thin&lt;/span&gt;.dryrun&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--thin&lt;/span&gt;.debug&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true

&lt;/span&gt;FROM openjdk:11-jre-slim
COPY &lt;span class="nt"&gt;--from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0 /root/.m2 /root/.m2
COPY target/demo-thin-docker-0.0.1-SNAPSHOT.jar /app.jar
ENTRYPOINT &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"java"&lt;/span&gt;,&lt;span class="s2"&gt;"-Djava.security.egd=file:/dev/./urandom"&lt;/span&gt;,&lt;span class="s2"&gt;"-jar"&lt;/span&gt;,&lt;span class="s2"&gt;"/app.jar"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  FROM
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;FROM openjdk:11-jdk-slim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's no reason to use Java 11, we can use the older version :)&lt;/p&gt;

&lt;h3&gt;
  
  
  COPY wrapper.jar
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;COPY docker/spring-boot-thin-wrapper-1.0.15.RELEASE.jar /thin/wrapper.jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I wanted to create a docker layer for the libraries. So I downloaded the wrapper.jar and put it in the repository.&lt;/p&gt;

&lt;p&gt;It has a feature of dry-run which doesn't run the main class but just download the libraries into .m2 repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  COPY pom.xml
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;COPY pom.xml /thin/pom.xml
WORKDIR /thin
RUN jar cvf pom.jar pom.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create the docker layer, copy the project pom.xml. The wrapper.jar can load a pom.xml in jar file. So I create a jar file which has only the pom file.&lt;/p&gt;

&lt;h3&gt;
  
  
  dry-run
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;RUN java &lt;span class="nt"&gt;-jar&lt;/span&gt; wrapper.jar &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--thin&lt;/span&gt;.archive&lt;span class="o"&gt;=&lt;/span&gt;/thin/pom.jar &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--thin&lt;/span&gt;.dryrun&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--thin&lt;/span&gt;.debug&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, execute wrapper jar with the pom.jar in a dry-run mode. If you want to know more detail, you can set &lt;code&gt;--thin.trace=true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then all the dependencies of the pom.xml are downloaded into the &lt;code&gt;/root/.m2&lt;/code&gt; directory.&lt;/p&gt;

&lt;h3&gt;
  
  
  COPY .m2
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;FROM openjdk:11-jre-slim
COPY &lt;span class="nt"&gt;--from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0 /root/.m2 /root/.m2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I used the multi stage build, because I don't need other files except for .m2 . So I copied the .m2 directory into the new image.&lt;/p&gt;

&lt;h3&gt;
  
  
  COPY app.jar and run
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;COPY target/demo-thin-docker-0.0.1-SNAPSHOT.jar /app.jar
ENTRYPOINT &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"java"&lt;/span&gt;,&lt;span class="s2"&gt;"-Djava.security.egd=file:/dev/./urandom"&lt;/span&gt;,&lt;span class="s2"&gt;"-jar"&lt;/span&gt;,&lt;span class="s2"&gt;"/app.jar"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then as usual, copy the jar and run it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Offline Mode
&lt;/h3&gt;

&lt;p&gt;To check there's no download on runtime, I used the - thin.offline=true to run docker with offline mode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080 demo-thin-docker - thin.debug&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; - thin.offline&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The good parts with docker
&lt;/h2&gt;

&lt;p&gt;As long as we don't change the dependencies, the library layer is reused. So the build finishes in no time.&lt;/p&gt;

&lt;p&gt;That's all for today's fun. And I'm thinking what kind of usage fits to Thin Jar and Fat Jar.&lt;/p&gt;

</description>
      <category>springboot</category>
      <category>docker</category>
      <category>java</category>
    </item>
    <item>
      <title>Started enjoying spring-boot-startup-bench</title>
      <dc:creator>Mitz</dc:creator>
      <pubDate>Mon, 01 Oct 2018 14:47:50 +0000</pubDate>
      <link>https://dev.to/bufferings/started-enjoying-spring-boot-startup-bench-1ahj</link>
      <guid>https://dev.to/bufferings/started-enjoying-spring-boot-startup-bench-1ahj</guid>
      <description>&lt;p&gt;Following s1p tweets, I found an interesting one this morning.&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;
      &lt;div class="ltag__twitter-tweet__media"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZPEqJDgt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/DoHFFv9XUAEencX.jpg" alt="unknown tweet media content"&gt;
      &lt;/div&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s---6tzQ9za--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/999949960232820736/80IG-cP__normal.jpg" alt="Marcin Grzejszczak profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Marcin Grzejszczak
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @mgrzejszczak
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Wat?! &lt;a href="https://twitter.com/david_syer"&gt;@david_syer&lt;/a&gt; shows that you can run a &lt;a href="https://twitter.com/springframework"&gt;@springframework&lt;/a&gt; app with Netty in less 0.2 seconds!!!😱😱😱 
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      15:24 PM - 27 Sep 2018
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1045333296555732992" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1045333296555732992" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1045333296555732992" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;That’s why I enjoyed this repository today.&lt;br&gt;
&lt;a href="https://github.com/dsyer/spring-boot-startup-bench"&gt;https://github.com/dsyer/spring-boot-startup-bench&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Build failed
&lt;/h2&gt;

&lt;p&gt;When I tried to build it with &lt;code&gt;$ ./mvnw clean install&lt;/code&gt;, it failed. Reading the error message, I modified one line and the build succeeded.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/bufferings/spring-boot-startup-bench/commit/4218301f4139274abe489ddaeb09058039184da7"&gt;https://github.com/bufferings/spring-boot-startup-bench/commit/4218301f4139274abe489ddaeb09058039184da7&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Uen5BSZO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/5h00ihnlfsdi9t8wkqs7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Uen5BSZO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/5h00ihnlfsdi9t8wkqs7.png" alt="" width="880" height="261"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Strange Result
&lt;/h2&gt;

&lt;p&gt;Then I ran the benchmark with &lt;code&gt;$ (cd benchmarks/; java -jar target/benchmarks.jar)&lt;/code&gt;. But it showed a strange result.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8cMJpUM4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ye67dpui9lki23or1wgb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8cMJpUM4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ye67dpui9lki23or1wgb.png" alt="" width="880" height="967"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;petclinicLatest(Precompute)Thin&lt;/code&gt; results were too slow.&lt;/p&gt;
&lt;h2&gt;
  
  
  Thin?
&lt;/h2&gt;

&lt;p&gt;I didn’t know what the &lt;code&gt;Thin&lt;/code&gt; means. Then I reached to &lt;a href="https://github.com/dsyer/spring-boot-thin-launcher"&gt;https://github.com/dsyer/spring-boot-thin-launcher&lt;/a&gt; and understood it’s an experimental library to make the jar file thin and download jars when it starts for the first time.&lt;/p&gt;

&lt;p&gt;I read the source code of the benchmark module to know how it runs the target, and added &lt;code&gt;--thin.debug=true&lt;/code&gt; to see the debug output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java &lt;span class="nt"&gt;-Xmx128m&lt;/span&gt; &lt;span class="nt"&gt;-Djava&lt;/span&gt;.security.egd&lt;span class="o"&gt;=&lt;/span&gt;file:/dev/./urandom &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-XX&lt;/span&gt;:TieredStopAtLevel&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-jar&lt;/span&gt; petclinic-latest/target/petclinic-latest-1.4.2-thin.jar &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--thin&lt;/span&gt;.debug&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--server&lt;/span&gt;.port&lt;span class="o"&gt;=&lt;/span&gt;0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  SNAPSHOT?
&lt;/h2&gt;

&lt;p&gt;I forgot to take a memo, but it showed jar resolution log. I noticed the petclinic-latest loaded some SNAPSHOT version libraries.&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--gfInXD62--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/720594596040876034/4hIP_pcI_normal.jpg" alt="Mitsuyuki Shiiba profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Mitsuyuki Shiiba
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="mentioned-user" href="https://dev.to/bufferings"&gt;@bufferings&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      ah, ThinJarWrapper might be slower if the app depends on SNAPSHOT version?
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      16:35 PM - 29 Sep 2018
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1046075993134444549" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1046075993134444549" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1046075993134444549" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;I guess every time it would check the SNAPSHOT version of the maven repository. So I modified the pom file to use RELEASE version.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/bufferings/spring-boot-startup-bench/commit/17fb6be5511a928ebf26cc49d6044ce6ffdcd73d"&gt;https://github.com/bufferings/spring-boot-startup-bench/commit/17fb6be5511a928ebf26cc49d6044ce6ffdcd73d&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--c6tfJrjI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/i85av2lyzmjy9xpch7ho.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--c6tfJrjI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/i85av2lyzmjy9xpch7ho.png" alt="" width="880" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Then…
&lt;/h2&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--gfInXD62--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/720594596040876034/4hIP_pcI_normal.jpg" alt="Mitsuyuki Shiiba profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Mitsuyuki Shiiba
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="mentioned-user" href="https://dev.to/bufferings"&gt;@bufferings&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      It became underatandable speed after I changed the SNAPSHOT to RELEASE version (∩´∀`∩)
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      16:57 PM - 29 Sep 2018
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1046081515870965760" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1046081515870965760" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1046081515870965760" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F2rC6sqI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/8ld8241ii8jsh1u7y3ui.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F2rC6sqI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/8ld8241ii8jsh1u7y3ui.png" alt="" width="880" height="986"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Though it would be different from the original aim to compare the SNAPSHOT version speed, I enjoyed the repository, and I would like to understand the details of this repository especially Flux benchmarks which is on the tweet picture.&lt;/p&gt;

</description>
      <category>springboot</category>
      <category>java</category>
    </item>
    <item>
      <title>Tried Zalenium to run Selenium tests on scalable containers</title>
      <dc:creator>Mitz</dc:creator>
      <pubDate>Wed, 04 Apr 2018 15:09:43 +0000</pubDate>
      <link>https://dev.to/bufferings/tried-zalenium-to-run-selenium-tests-on-scalable-containers-2n7c</link>
      <guid>https://dev.to/bufferings/tried-zalenium-to-run-selenium-tests-on-scalable-containers-2n7c</guid>
      <description>&lt;p&gt;My friend, who is a great test engineer, mentioned Zalenium yesterday and I was interested in it. So I tried it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zalenium?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://zalando.github.io/zalenium/" rel="noopener noreferrer"&gt;https://zalando.github.io/zalenium/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After a few hours trial, I've come to like it because&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1) it's very easy to try in my local machine,&lt;/li&gt;
&lt;li&gt;2) it dynamically starts containers to run Selenium tests,&lt;/li&gt;
&lt;li&gt;3) and provides video recording of the tests&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1) it's very easy to try in my local machine
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Start Zaleinum
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Pull 2 docker images&lt;/span&gt;
docker pull elgalu/selenium
docker pull dosel/zalenium

&lt;span class="c"&gt;# Run it!&lt;/span&gt;
docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-ti&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; zalenium &lt;span class="nt"&gt;-p&lt;/span&gt; 4444:4444 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; /tmp/videos:/home/seluser/videos &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--privileged&lt;/span&gt; dosel/zalenium start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(You may want to take care when you mount docker.sock, though it isn't a main topic here.)&lt;/p&gt;

&lt;p&gt;Then you can access Live Preview page &lt;a href="http://localhost:4444/grid/admin/live" rel="noopener noreferrer"&gt;http://localhost:4444/grid/admin/live&lt;/a&gt; and find 2 machines are running.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fyzahzecr9idpsdsuxic9.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fyzahzecr9idpsdsuxic9.png" alt="Live Preview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Run your tests
&lt;/h3&gt;

&lt;p&gt;Now you are ready to run your Selenium tests on Zalenium.&lt;/p&gt;

&lt;p&gt;I parepared Geb script here since I like it, but you can use whatever you like.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.gebish.org/" rel="noopener noreferrer"&gt;http://www.gebish.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HelloZelenium.groovy&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;Browser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;drive&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;go&lt;/span&gt; &lt;span class="s2"&gt;"http://gebish.org"&lt;/span&gt;

  &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"Geb - Very Groovy Browser Automation"&lt;/span&gt;

  &lt;span class="n"&gt;$&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"div.menu a.manuals"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;click&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;waitFor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;$&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"#manuals-menu"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;hasClass&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"animating"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;$&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"#manuals-menu a"&lt;/span&gt;&lt;span class="o"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="na"&gt;click&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;

  &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startsWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"The Book Of Geb"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is from Geb document. I skip the explanation of this script, because I think you can easily imagine what it does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GebConfig.groovy&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="n"&gt;capabilities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DesiredCapabilities&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;capabilities&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setCapability&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CapabilityType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;BROWSER_NAME&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BrowserType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CHROME&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;capabilities&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setCapability&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CapabilityType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;PLATFORM_NAME&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Platform&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LINUX&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="n"&gt;remoteWebDriverUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:4444/wd/hub"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RemoteWebDriver&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;remoteWebDriverUrl&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;capabilities&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can set configuration with GebConfig. We use RemoteWebDriver with the Zelenium Hub URL.&lt;/p&gt;

&lt;p&gt;Full source code including &lt;code&gt;import&lt;/code&gt; is here: &lt;a href="https://gist.github.com/bufferings/a8980ea515a893e21a3a95955ace5dc9" rel="noopener noreferrer"&gt;https://gist.github.com/bufferings/a8980ea515a893e21a3a95955ace5dc9&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run the test&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;groovy HelloZalenium
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you can see the tests are executed on the live preview page.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3sjj8eqddbfqp25q7ts5.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3sjj8eqddbfqp25q7ts5.png" alt="Live Preview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So easy!!&lt;/p&gt;

&lt;h2&gt;
  
  
  2) it dynamically starts containers to run Selenium tests,
&lt;/h2&gt;

&lt;p&gt;Then I would like to run multiple tests simultaneously.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for i in {1..8};do groovy HelloZalenium &amp;amp; done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, 8 machines are up and testing! After the tests, it automatically shutdown the containers.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F4mnjn4erdt7wsduq7tw7.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F4mnjn4erdt7wsduq7tw7.png" alt="Live Preview3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3) and provides video recording of the tests
&lt;/h2&gt;

&lt;p&gt;By default, all the tests are recorded. We can check them on &lt;a href="http://localhost:4444/dashboard/#" rel="noopener noreferrer"&gt;http://localhost:4444/dashboard/#&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fodim68hse2g8fxvtfy14.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fodim68hse2g8fxvtfy14.png" alt="Recorded Video"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration Options
&lt;/h2&gt;

&lt;p&gt;In addition, we can ask Zelenium to do something by configuration for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;driver = {
  def capabilities = new DesiredCapabilities();
  capabilities.setCapability(CapabilityType.BROWSER_NAME, BrowserType.FIREFOX);
  capabilities.setCapability(CapabilityType.PLATFORM_NAME, Platform.LINUX);
  capabilities.setCapability("screenResolution", "1280x720");
  capabilities.setCapability("tz", "Asia/Tokyo");

  def remoteWebDriverUrl = new URL("http://localhost:4444/wd/hub")
  new RemoteWebDriver(remoteWebDriverUrl, capabilities)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this time, we can see FireFox is used with 1280x720 and Asiz/Tokyo timezone.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7krp9rt8w3sjkh6wy1b7.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7krp9rt8w3sjkh6wy1b7.png" alt="Live Preview4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  and more!
&lt;/h2&gt;

&lt;p&gt;I haven't tried yet, but Zalenium has nice features more:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SauceLabs/BrowserStack/TestingBot integration&lt;/li&gt;
&lt;li&gt;Support Kubernetes environment&lt;/li&gt;
&lt;li&gt;etc...&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Zelenium is so convenient and easy to run Selenium Grid with Docker. I would like to keep trying and learning it!&lt;/p&gt;

</description>
      <category>zalenium</category>
      <category>selenium</category>
      <category>geb</category>
      <category>groovy</category>
    </item>
    <item>
      <title>Access host from a docker container</title>
      <dc:creator>Mitz</dc:creator>
      <pubDate>Sat, 31 Mar 2018 00:20:38 +0000</pubDate>
      <link>https://dev.to/bufferings/access-host-from-a-docker-container-4099</link>
      <guid>https://dev.to/bufferings/access-host-from-a-docker-container-4099</guid>
      <description>&lt;p&gt;This information is as of 2018-03-31 with Docker 18.03.0-ce&lt;/p&gt;

&lt;p&gt;I wanted to access host port from a docker container. &lt;/p&gt;

&lt;p&gt;For example, an nginx process is running on the host machine with port 8888 open, then I would like to create a container which can curl host:8888.&lt;/p&gt;

&lt;p&gt;I know how to discover container-to-container, but don't know how to get host IP address from a container.&lt;/p&gt;

&lt;p&gt;Therefore, I wandered the internet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Precondition
&lt;/h2&gt;

&lt;p&gt;I mainly use &lt;strong&gt;Docker for Mac&lt;/strong&gt;, but sometimes use &lt;strong&gt;Linux&lt;/strong&gt;. So I want my containers to run on both platform.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/bufferings/docker-access-host"&gt;https://github.com/bufferings/docker-access-host&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Host networking mode?
&lt;/h2&gt;

&lt;p&gt;I found Docker has "host networking mode".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/network/host/"&gt;https://docs.docker.com/network/host/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this mode, the container seems to be able access to the host with "127.0.0.1". How easy! I found it!&lt;/p&gt;

&lt;p&gt;So I tried it and it works on my Linux machine, but it didn't work on my Mac. Then I found:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/network/network-tutorial-host/#prerequisites"&gt;https://docs.docker.com/network/network-tutorial-host/#prerequisites&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The host networking driver only works on Linux hosts, and is not supported on Docker for Mac, Docker for Windows, or Docker EE for Windows Server.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(´・ω・｀) ok... let me find another way please.&lt;/p&gt;

&lt;h2&gt;
  
  
  host.docker.internal?
&lt;/h2&gt;

&lt;p&gt;I found I can resolve &lt;code&gt;host.docker.internal&lt;/code&gt; as the host IP address in the container on Docker for Mac. Great! That's what I wanted to know! But... where's Linux version of it...?&lt;/p&gt;

&lt;p&gt;(´・ω・｀) NotFound...&lt;/p&gt;

&lt;p&gt;In addition, I was a little bit confused there're several names:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;docker.for.mac.localhost &amp;lt;- from 17.06.0 but now deprecated&lt;/li&gt;
&lt;li&gt;docker.for.mac.host.internal &amp;lt;- from 17.12.0-ce-mac46 but now deprecated&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;host.docker.internal&lt;/strong&gt; &amp;lt;- from 18.03.0-ce-mac59&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/docker-for-mac/release-notes"&gt;https://docs.docker.com/docker-for-mac/release-notes&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Finally, my solution is like this.
&lt;/h2&gt;

&lt;p&gt;I created &lt;code&gt;docker-entrypoint.sh&lt;/code&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="nv"&gt;HOST_DOMAIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"host.docker.internal"&lt;/span&gt;
ping &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;-c1&lt;/span&gt; &lt;span class="nv"&gt;$HOST_DOMAIN&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null 2&amp;gt;&amp;amp;1
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt; &lt;span class="nt"&gt;-ne&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nv"&gt;HOST_IP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;ip route | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'NR==1 {print $3}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOST_IP&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="nv"&gt;$HOST_DOMAIN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/hosts
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="o"&gt;(&lt;/span&gt;main entrypoint&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and create Dockerfile call this file as an entry point.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;COPY docker-entrypoint.sh /usr/local/bin/

ENTRYPOINT &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"/usr/local/bin/docker-entrypoint.sh"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As a result, Docker for Mac do nothing because it has "host.docker.internal" and Linux version add it into hosts file.&lt;/p&gt;

&lt;p&gt;(๑•̀ㅂ•́)و✧&lt;/p&gt;

&lt;p&gt;The sample code is here:&lt;br&gt;
&lt;a href="https://github.com/bufferings/docker-access-host"&gt;https://github.com/bufferings/docker-access-host&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope host.docker.internal will be added for Linux near future.&lt;/p&gt;

&lt;p&gt;If you know better solution, please let me know.&lt;/p&gt;

</description>
      <category>docker</category>
    </item>
  </channel>
</rss>
