<?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: mixth</title>
    <description>The latest articles on DEV Community by mixth (@mixth).</description>
    <link>https://dev.to/mixth</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%2F123018%2F5314f41d-f9ce-4176-8569-859f9c5bb597.jpeg</url>
      <title>DEV Community: mixth</title>
      <link>https://dev.to/mixth</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mixth"/>
    <language>en</language>
    <item>
      <title>Ability to change configuration after build. For containerized Angular and more</title>
      <dc:creator>mixth</dc:creator>
      <pubDate>Tue, 23 Jul 2019 17:32:08 +0000</pubDate>
      <link>https://dev.to/zarewoft/change-configurations-after-build-for-angular-and-more-5g98</link>
      <guid>https://dev.to/zarewoft/change-configurations-after-build-for-angular-and-more-5g98</guid>
      <description>&lt;p&gt;It is pretty normal to encounter an application that requires multiple environment configurations. But when it comes to web, we tend to build a whole new app once again when we change just the environment configurations. And the process takes &lt;strong&gt;minutes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In the world of containerization, this strategy of building everything makes it difficult to achieve &lt;em&gt;one image, deploy everywhere&lt;/em&gt;, which I am such a fan of. And when someone tries to do so, it always makes a BIG image with building tools and so on. Plus, a long starting time for the containers too.&lt;/p&gt;

&lt;p&gt;So my goals here are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We can build once and deploy everywhere.&lt;/li&gt;
&lt;li&gt;We can have a small final product image.&lt;/li&gt;
&lt;li&gt;We can have the ability to change those environment configuration just at the deployment time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With a simple web concept, we can achieve that.&lt;/p&gt;

&lt;h2&gt;
  
  
  GLOBAL VARIABLES!!!!
&lt;/h2&gt;

&lt;p&gt;Yep... you heard it right.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I plan to put &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; in the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;. Inside this &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;, I want to declare a global variable which is a simple object contains configuration of the environment. &lt;strong&gt;But&lt;/strong&gt;, I am not going to put it in the &lt;code&gt;index.html&lt;/code&gt; yet. Let's put a placeholder, say &lt;code&gt;&amp;lt;!-- CONFIG --&amp;gt;&lt;/code&gt;, instead.&lt;/li&gt;
&lt;li&gt;In configuration file (such as what we have in typical Angular projects), I  implement it to read global variable first, or else, assign a default configuration.&lt;/li&gt;
&lt;li&gt;Add a new &lt;a href="https://linux.die.net/man/1/sed"&gt;&lt;code&gt;sed&lt;/code&gt;&lt;/a&gt; command for docker image. Which basically do just replace the placeholder with a config from &lt;a href="https://docs.docker.com/engine/reference/builder/#env"&gt;environment variables&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Just that. We are good to go! Here are gists just for an idea.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Cons?
&lt;/h2&gt;

&lt;p&gt;The config is plainly exposed.&lt;/p&gt;

&lt;p&gt;This might let some users making weird things to your web. But I guess, it gonna have just a minimal impact since if they look hard enough, they might find it in any scenarios. Anyway, please proceed with caution.&lt;/p&gt;




&lt;p&gt;That's it! Thanks for reading 😁&lt;br&gt;
If you have any questions or some kind of improvement, please let me know in the comment below.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>docker</category>
      <category>javascript</category>
    </item>
    <item>
      <title>[GitLab Runner] Build Docker Image in Docker Job on GitLab Runner Container</title>
      <dc:creator>mixth</dc:creator>
      <pubDate>Wed, 01 May 2019 10:23:05 +0000</pubDate>
      <link>https://dev.to/zarewoft/gitlab-runner-build-docker-image-in-docker-job-on-gitlab-runner-container-5g7g</link>
      <guid>https://dev.to/zarewoft/gitlab-runner-build-docker-image-in-docker-job-on-gitlab-runner-container-5g7g</guid>
      <description>&lt;p&gt;It would be really awesome if we can run each jobs in Gitlab Pipeline in containerized environments. Gitlab Runner &lt;a href="https://docs.gitlab.com/runner/executors/docker.html" rel="noopener noreferrer"&gt;enables that&lt;/a&gt; by having &lt;code&gt;image&lt;/code&gt; in targeted jobs accompanying with &lt;code&gt;docker&lt;/code&gt; executor.&lt;/p&gt;

&lt;p&gt;But... what about running these jobs in Gitlab Runner that is also running inside its own container? And then, build, tag, push Docker images as a job too?&lt;/p&gt;

&lt;p&gt;Oh, yes! We can.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why?
&lt;/h1&gt;

&lt;p&gt;Because isolation each job to its container is sooooooo good. It creates a clean working space each time we run, we can also choose which environment we want to run each job simply by selecting a Docker image we want.&lt;/p&gt;

&lt;p&gt;And having Gitlab Runner runs as container is pretty cool, right? We can easily start and upgrade it.&lt;/p&gt;

&lt;p&gt;How about the part of building and pushing inside a container, you may ask. that part... I just want to try out making every job using container. That's all. 🤪 If you can think of any reason, please help me in the comment.&lt;/p&gt;

&lt;h1&gt;
  
  
  Steps
&lt;/h1&gt;

&lt;p&gt;Here are the steps we will be doing today:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Prepare How To Start the Runner&lt;/li&gt;
&lt;li&gt;Register the Runner&lt;/li&gt;
&lt;li&gt;Start It!&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Prepare How To Start the Runner
&lt;/h2&gt;

&lt;p&gt;I usually use docker-compose to run Docker container declaratively.&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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3"&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;runner&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;gitlab/gitlab-runner:alpine&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/Users/zarewoft/gitlab-runner/config:/etc/gitlab-runner&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/run/docker.sock:/var/run/docker.sock&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, I map my &lt;code&gt;config&lt;/code&gt; directory to consume &lt;code&gt;config.yoml&lt;/code&gt; that will be created later.&lt;/p&gt;

&lt;p&gt;Secondly, &lt;code&gt;docker.sock&lt;/code&gt; is mapped to accommodate Docker executor. This will make the executor interacts with host's Docker daemon, hence, its jobs will create containers that will be siblings of the Runner.&lt;/p&gt;

&lt;h2&gt;
  
  
  Register the Runner
&lt;/h2&gt;

&lt;p&gt;The Runner requires to be registered with Gitlab server. Here, we will start a short-lived Gitlab Runner container to do just that. It will register to Gitlab server and create &lt;code&gt;config.yoml&lt;/code&gt; to use in the future.&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;--rm&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; /Users/zarewoft/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner:alpine register &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--url&lt;/span&gt; https://gitlab.com/ &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--registration-token&lt;/span&gt; REGISTRATION_TOKEN &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--executor&lt;/span&gt; docker &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--description&lt;/span&gt; &lt;span class="s2"&gt;"My Docker Runner"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--docker-image&lt;/span&gt; &lt;span class="s2"&gt;"docker:stable"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
command to register our Runner





&lt;p&gt;From the example, I mount my &lt;code&gt;config&lt;/code&gt; directory to persistently store &lt;code&gt;config.yoml&lt;/code&gt;, same spot as what my earlier docker-compose will consume. I also provide &lt;code&gt;docker-image&lt;/code&gt; which tells the executor what the default image is.&lt;/p&gt;

&lt;h4&gt;
  
  
  Cache Image Layers
&lt;/h4&gt;

&lt;p&gt;Imagine define a job in Gitlab Pipeline. The job will build and push a Docker image which contains our app. It will definitely use image similar to &lt;code&gt;docker:stable&lt;/code&gt;. In the process, it will create many layers of Docker image which can be reused in the future, sadly, it would destroy along with the job's container.&lt;/p&gt;

&lt;p&gt;No. We shall not sacrifice minutes in each pipeline we run!!!&lt;br&gt;
It would be nice if we can persist those layers somewhere 🤔.&lt;/p&gt;

&lt;p&gt;Oh, or we can just make them use the host's Docker daemon!&lt;/p&gt;

&lt;p&gt;Here comes &lt;code&gt;docker-volumes&lt;/code&gt;. The option tells Docker daemon, which is the host's, to map &lt;code&gt;docker.sock&lt;/code&gt; of the host to each container it will create for any jobs.&lt;/p&gt;

&lt;p&gt;By adding this, our final register command look 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;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; /Users/zarewoft/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner:alpine register &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--url&lt;/span&gt; https://gitlab.com/ &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--registration-token&lt;/span&gt; REGISTRATION_TOKEN &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--executor&lt;/span&gt; docker &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--description&lt;/span&gt; &lt;span class="s2"&gt;"My Docker Runner"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--docker-image&lt;/span&gt; &lt;span class="s2"&gt;"docker:stable"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--docker-volumes&lt;/span&gt; /var/run/docker.sock:/var/run/docker.sock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Ffuo1wkkoc2ik1kxknk7k.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%2Ffuo1wkkoc2ik1kxknk7k.png" width="785" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
a diagram to make this article a bit more colorful



&lt;h2&gt;
  
  
  Start It!
&lt;/h2&gt;

&lt;p&gt;And then, just up the docker-compose.&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;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Hope you find this informative enough. If there are any mistakes, please let me know in the comment. Thanks! 😊&lt;/p&gt;

</description>
      <category>devops</category>
      <category>gitlab</category>
      <category>cicd</category>
      <category>docker</category>
    </item>
    <item>
      <title>สร้าง Docker Image ลีนๆ ด้วย Multi-stage Builds</title>
      <dc:creator>mixth</dc:creator>
      <pubDate>Wed, 01 May 2019 06:51:07 +0000</pubDate>
      <link>https://dev.to/zarewoft/docker-image-multi-stage-builds-13mk</link>
      <guid>https://dev.to/zarewoft/docker-image-multi-stage-builds-13mk</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Firstly published on 2018-01-18 in &lt;a href="https://medium.com/zarewoft/%E0%B8%AA%E0%B8%A3%E0%B9%89%E0%B8%B2%E0%B8%87-docker-image-%E0%B8%A5%E0%B8%B5%E0%B8%99%E0%B9%86-%E0%B8%94%E0%B9%89%E0%B8%A7%E0%B8%A2-multi-stage-builds-e786ba6d5102" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;สวัสดีครับ 😀&lt;br&gt;
บล็อกนี้เป็นบล็อกแรกสำหรับเรื่อง Docker เลยครับ โดยผมตั้งใจว่าจะมาเล่าผลลัพธ์จากประสบการณ์การฝึกใช้งาน Docker ทั้งเรื่องง่ายๆ เรื่องที่เสียเวลา เรื่องที่เจ็บมาเยอะๆ ให้ทุกท่านอ่านกันครับ&lt;/p&gt;



&lt;p&gt;"ขนาดไม่ใช่เรื่องสำคัญ" คงไม่จริงแน่ๆ สำหรับการใช้งาน Docker เพราะเมื่อขนาดใหญ่ขึ้น เราก็เสียค่า storage สำหรับเก็บ image ใน registry มากขึ้น ตอนรัน container ก็ต้องใช้ disk ของเครื่อง host มากขึ้นอีก&lt;/p&gt;

&lt;p&gt;การลดขนาดของ docker image มีหลากหลาย practice ที่เราควรทำครับ เช่น การไม่พยายามสร้าง layer ใหม่ที่ไม่จำเป็นด้วย &lt;code&gt;RUN&lt;/code&gt;, การจัดวาง sequence ของ command ใน Dockerfile&lt;br&gt;
วันนี้ผมจะพาท่านๆมารู้จักกับ multi-stage builds ซึ่งผมได้ความรู้มาจากการลองผิดลองถูก อ่านบทความต่างๆ แล้วทดลองใช้กับงานจริงครับ&lt;/p&gt;
&lt;h1&gt;
  
  
  Multi-stage Builds
&lt;/h1&gt;

&lt;p&gt;ผมมักชอบที่จะรัน test และ build บน docker เลย เพื่อการันตีว่าแอพผ่านการ test ก่อนจะ build บน environment ที่เหมือนกันครับ แต่ในบางครั้งการ build บน docker ก็ทำให้มี file ที่ไม่จำเป็นมากมายเกิดขึ้นใน image เรา ถ้าเราเอาตัวนี้ไปใช้จริงก็คงจะเป็น image ที่หนาเกินไป&lt;/p&gt;

&lt;p&gt;ยกตัวอย่างเช่น build gulp สำหรับ frontend แอพ ถ้าเอาแบบเอี่ยมๆเลย เราก็ต้องใช้ &lt;code&gt;FROM node&lt;/code&gt; แล้วมา &lt;code&gt;npm install&lt;/code&gt; แล้วค่อยใช้ gulp อีกที&lt;/p&gt;

&lt;p&gt;ซึ่งมันไม่จำเป็นมากๆเลยที่จะเอาทั้งหมดนี้ไปไว้ใน image ใช่ไหมครับ เพราะสุดท้ายแล้วเราแค่จะ serve static file เอง มันคงจะดีไม่น้อย ถ้าเราใช้ image หนึ่งอันมารันทั้งหมดนี้ แล้วเอาผลลัพธ์ไปใส่อีก image ใช่มะ?&lt;/p&gt;

&lt;p&gt;Multi-stage builds คือ concept แบบที่เราว่าเลยครับ กล่าวคือ การสร้าง stage นึง แล้วใช้เป็นแค่ทางผ่านแล้วเอาไฟล์ไปใช้อีก stage นึงครับ&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%2Fjslgy2rh0bdoep1mpcji.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%2Fjslgy2rh0bdoep1mpcji.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  วิธีการใช้งาน
&lt;/h1&gt;

&lt;p&gt;ระบุ name ให้กับ image ที่เราสร้างในกระบวนการในบรรทัด FROM&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM &amp;lt;IMAGE&amp;gt; AS &amp;lt;NAME&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;เวลาเราจะ &lt;code&gt;COPY&lt;/code&gt; file จาก stage เดิม ให้ใส่ parameter ชื่อ from เพิ่มเข้าไป&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;COPY --from=&amp;lt;NAME&amp;gt; &amp;lt;ORIGIN_PATH&amp;gt; &amp;lt;DEST_PATH&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
ตัวอย่าง multi-stages builds โดยการ npm install, run build แอพ ก่อนจะสร้าง image nginx สำหรับ serve





&lt;p&gt;ในตัวอย่างข้างต้นคือเราใช้ image node มา build app เสร็จแล้ว serve ด้วย nginx ครับ ถ้าอยาก validate ดูว่าถูกต้องไหม ลองสั่ง &lt;code&gt;docker history &amp;lt;IMAGE_HASH&amp;gt;&lt;/code&gt; ดูได้ครับ&lt;br&gt;
แต่หากเราไม่อยากตั้งชื่อให้มันจริงๆ ก็ใส่เป็น index ก็ได้นะ (0, 1, 2, …) โดยเรียงจาก &lt;code&gt;FROM&lt;/code&gt; ด้านบนสุดมาเรื่อยๆครับ (แต่… มันตั้งชื่อได้ก็ตั้งให้มันเถิด)&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;ลองดูนะครับว่าเราสามารถใช้เทคนิคนี้ในการทำให้ image ของเราเล็กลง หรือใช้งานได้สะดวกขึ้นอย่างไงบ้าง&lt;/p&gt;

&lt;p&gt;หากมีส่วนใดผิดพลาด ไม่ถูกต้อง แจ้งได้เลยครับ :)&lt;/p&gt;

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