<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Tanin Srivaraphong on Medium]]></title>
        <description><![CDATA[Stories by Tanin Srivaraphong on Medium]]></description>
        <link>https://medium.com/@zrevig?source=rss-150824165a6------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*JFmdvdwEf_nnUi7i.jpg</url>
            <title>Stories by Tanin Srivaraphong on Medium</title>
            <link>https://medium.com/@zrevig?source=rss-150824165a6------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 19:15:18 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@zrevig/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[The repository ‘http://dl.google.com/linux/chrome/deb stable InRelease’ is not signed.]]></title>
            <link>https://giver.in.th/the-repository-http-dl-google-com-linux-chrome-deb-stable-inrelease-is-not-signed-234a353150e5?source=rss-150824165a6------2</link>
            <guid isPermaLink="false">https://medium.com/p/234a353150e5</guid>
            <category><![CDATA[linux]]></category>
            <category><![CDATA[apt]]></category>
            <dc:creator><![CDATA[Tanin Srivaraphong]]></dc:creator>
            <pubDate>Fri, 31 Jul 2026 06:26:35 GMT</pubDate>
            <atom:updated>2026-07-31T06:33:36.957Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*sNt3ffr7G_zaqk9k" /><figcaption>Photo by <a href="https://unsplash.com/@moneyphotos?utm_source=medium&amp;utm_medium=referral">rc.xyz NFT gallery</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Recently, I’ve encountered a challenge with my aging CircleCI pipeline used for deploying our legacy application. The issue arises whenever I make modifications to a pipeline step: the cache invalidates, forcing the entire process to start from scratch. This has led to complications, particularly with the use of an outdated image that has surfaced during builds.</p><blockquote>The repository ‘<a href="http://dl.google.com/linux/chrome/deb">http://dl.google.com/linux/chrome/deb</a> stable InRelease’ is not signed.</blockquote><h4>How to Fix</h4><p>Just add the step `<strong>Linux Package Signing Keys</strong>` as mentioned in <a href="https://www.google.com/linuxrepositories/">https://www.google.com/linuxrepositories/</a> before apt update or apt-get update</p><p>Since I’m using new debian version then I can use the following command (copy from instruction in the link above)</p><pre>wget -q -O — https://dl.google.com/linux/linux_signing_key.pub | sudo tee /etc/apt/trusted.gpg.d/google.asc &gt;/dev/null`</pre><p>Done.</p><h4>References</h4><ol><li><a href="https://support.google.com/chromebook/thread/257688390/the-repository-http-dl-google-com-linux-chrome-deb-stable-inrelease-is-not-signed">https://support.google.com/chromebook/thread/257688390/the-repository-http-dl-google-com-linux-chrome-deb-stable-inrelease-is-not-signed</a></li><li><a href="https://www.google.com/linuxrepositories/">https://www.google.com/linuxrepositories/</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=234a353150e5" width="1" height="1" alt=""><hr><p><a href="https://giver.in.th/the-repository-http-dl-google-com-linux-chrome-deb-stable-inrelease-is-not-signed-234a353150e5">The repository ‘http://dl.google.com/linux/chrome/deb stable InRelease’ is not signed.</a> was originally published in <a href="https://giver.in.th/">GiVeR</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[gpg: Note: database_open 134217901 waiting for lock (held by 30991) …]]></title>
            <link>https://giver.in.th/gpg-note-database-open-134217901-waiting-for-lock-held-by-30991-7ef593e19662?source=rss-150824165a6------2</link>
            <guid isPermaLink="false">https://medium.com/p/7ef593e19662</guid>
            <category><![CDATA[gpg]]></category>
            <category><![CDATA[git]]></category>
            <dc:creator><![CDATA[Tanin Srivaraphong]]></dc:creator>
            <pubDate>Fri, 19 Sep 2025 00:24:45 GMT</pubDate>
            <atom:updated>2025-09-19T00:24:45.700Z</atom:updated>
            <content:encoded><![CDATA[<h3>gpg: Note: database_open 134217901 waiting for lock (held by 30991) …</h3><h4>What’s Locking Your GPG Signature? A Simple Fix</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*hObsvGsIu-Z2CFqY" /><figcaption>Photo by <a href="https://unsplash.com/@flyd2069?utm_source=medium&amp;utm_medium=referral">FlyD</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Use ps aux | grep gpg to find the process locking GPG. If no process is found, a dangling .lockfile is often the culprit. Simply find and delete the lock file to resolve the issue.</p><pre>$ gpg --list-secret-keys --keyid-format LONG<br>gpg: Note: database_open 134217901 waiting for lock (held by 30991) ...<br>gpg: Note: database_open 134217901 waiting for lock (held by 30991) ...<br>gpg: Note: database_open 134217901 waiting for lock (held by 30991) ...<br>gpg: Note: database_open 134217901 waiting for lock (held by 30991) ...<br>gpg: Note: database_open 134217901 waiting for lock (held by 30991) ...<br>gpg: keydb_search_first failed: Operation timed out<br><br>$ cd ~/.gnupg/public-keys.d<br>$ ls -al<br><br>.rw-------@ 82k tanin 19 Aug 17:23 pubring.db<br>.rw-r--r--@  38 tanin 12 Sep 16:09 pubring.db.lock<br><br>$ rm pubring.db.lock</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7ef593e19662" width="1" height="1" alt=""><hr><p><a href="https://giver.in.th/gpg-note-database-open-134217901-waiting-for-lock-held-by-30991-7ef593e19662">gpg: Note: database_open 134217901 waiting for lock (held by 30991) …</a> was originally published in <a href="https://giver.in.th/">GiVeR</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Git Stash: push vs save — เลิกสับสน แล้วเลือกใช้ให้ถูกในปี 2025]]></title>
            <link>https://giver.in.th/git-stash-push-vs-save-%E0%B9%80%E0%B8%A5%E0%B8%B4%E0%B8%81%E0%B8%AA%E0%B8%B1%E0%B8%9A%E0%B8%AA%E0%B8%99-%E0%B9%81%E0%B8%A5%E0%B9%89%E0%B8%A7%E0%B9%80%E0%B8%A5%E0%B8%B7%E0%B8%AD%E0%B8%81%E0%B9%83%E0%B8%8A%E0%B9%89%E0%B9%83%E0%B8%AB%E0%B9%89%E0%B8%96%E0%B8%B9%E0%B8%81%E0%B9%83%E0%B8%99%E0%B8%9B%E0%B8%B5-2025-79067db2a75e?source=rss-150824165a6------2</link>
            <guid isPermaLink="false">https://medium.com/p/79067db2a75e</guid>
            <category><![CDATA[productivity]]></category>
            <category><![CDATA[developer-tools]]></category>
            <category><![CDATA[git]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Tanin Srivaraphong]]></dc:creator>
            <pubDate>Sat, 21 Jun 2025 08:23:45 GMT</pubDate>
            <atom:updated>2025-06-21T08:23:45.806Z</atom:updated>
            <content:encoded><![CDATA[<h3>Git Stash: push vs save — เลิกสับสน แล้วเลือกใช้ให้ถูกในปี 2025</h3><p>คำสั่งไหนที่ควรใช้? คำสั่งไหนที่เลิกใช้แล้ว? บทความนี้มีคำตอบพร้อมตารางเปรียบเทียบชัดๆ สำหรับนักพัฒนาทุกคน</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*wG691kOw5wzebzno" /><figcaption>Photo by <a href="https://unsplash.com/@yancymin?utm_source=medium&amp;utm_medium=referral">Yancy Min</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>สำหรับนักพัฒนาที่ใช้ Git เป็นประจำ คำสั่ง git stash ถือเป็นเครื่องมือช่วยชีวิตในยามที่ต้องสลับ Branch กะทันหัน แต่ยังไม่พร้อมที่จะ commit โค้ดที่ทำค้างไว้ แต่คุณเคยสงสัยไหมว่าระหว่าง git stash save กับ git stash push ที่หน้าตาคล้ายกัน มันต่างกันอย่างไร และเราควรจะเลือกใช้อันไหนกันแน่?</p><p>บทความนี้จะไขข้อข้องใจทั้งหมด เปรียบเทียบให้เห็นภาพชัดๆ และฟันธงไปเลยว่าคำสั่งไหนคือตัวเลือกที่ดีที่สุดสำหรับคุณในปัจจุบัน</p><h3>git stash save: คำสั่งดั้งเดิมที่ถึงเวลาต้องปล่อยวาง</h3><p>git stash save คือคำสั่งดั้งเดิมที่หลายคนอาจจะคุ้นเคยกันดี มันทำหน้าที่ของมันได้ตรงไปตรงมา นั่นคือการบันทึกการเปลี่ยนแปลงทั้งหมดใน Working Directory ของคุณเข้าไปเก็บไว้ใน Stash</p><pre># ตัวอย่างการใช้งานแบบดั้งเดิมพร้อมข้อความ<br>git stash save &quot;WIP: กำลังทำฟีเจอร์หน้าแรก&quot;</pre><p>แม้จะยังใช้งานได้ แต่ใน Git เวอร์ชันใหม่ๆ คำสั่งนี้ถูกจัดว่าเป็น <strong>Deprecated</strong> หรือ <strong>“ไม่แนะนำให้ใช้งานแล้ว”</strong></p><p><strong>ข้อจำกัดสำคัญของ </strong><strong>save คือ:</strong> มันขาดความยืดหยุ่น คุณไม่สามารถเลือกได้ว่าจะ stash เฉพาะบางไฟล์หรือบางโฟลเดอร์ เมื่อสั่ง save มันจะกวาดทุกการเปลี่ยนแปลงที่คุณยังไม่ได้ commit ไปเก็บไว้ทั้งหมด ซึ่งบางครั้งก็ไม่ใช่สิ่งที่เราต้องการ</p><h3>git stash push: คำสั่งใหม่ที่ทรงพลังและยืดหยุ่นกว่า</h3><p>git stash push คือคำสั่งที่ถูกพัฒนาขึ้นมาใหม่เพื่อแทนที่ save และเป็นคำสั่งที่ <strong>แนะนำให้ใช้เป็นมาตรฐานในปัจจุบัน</strong> มันไม่ได้แค่ทำทุกอย่างที่ save ทำได้ แต่ยังมาพร้อมความสามารถที่สำคัญอย่างยิ่ง</p><blockquote><em>ความสามารถเด่นที่สุดของ </em><em>git stash push คือการรองรับ </em><strong><em>Pathspec</em></strong><em> ซึ่งทำให้เราสามารถระบุได้ว่าจะ stash เฉพาะไฟล์หรือโฟลเดอร์ที่ต้องการเท่านั้น</em></blockquote><p>ลองดูตัวอย่างการใช้งาน:</p><pre># Stash เฉพาะการเปลี่ยนแปลงในไฟล์ main.js และโฟลเดอร์ components/<br>git stash push -m &quot;Update main logic and components&quot; -- src/main.js src/components/# Stash เฉพาะการเปลี่ยนแปลงในไฟล์ main.js และโฟลเดอร์ components/  </pre><p>การใช้ flag -m เพื่อใส่ข้อความก็เป็นรูปแบบที่สอดคล้องกับคำสั่งยอดนิยมอย่าง git commit -m &quot;...&quot; ทำให้ไวยากรณ์ของ Git มีความสอดคล้องกันมากขึ้น</p><h3>ตารางเปรียบเทียบชัดๆ: save vs push</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/720/1*UC5qjkAK1aJ_5_58wCZVQQ@2x.png" /></figure><h3>บทสรุป: ฟันธงให้เลยว่าควรใช้อะไร</h3><p>คำตอบนั้นชัดเจนมากครับ: <strong>คุณควรใช้ </strong><strong>git stash push เสมอ</strong></p><p>ในเมื่อ git stash push สามารถทำทุกอย่างที่ save ทำได้ แถมยังมอบความยืดหยุ่นที่เหนือกว่าด้วยฟีเจอร์ Pathspec จึงไม่มีเหตุผลที่จะย้อนกลับไปใช้คำสั่งที่เก่ากว่าและมีความสามารถน้อยกว่าอีกต่อไป</p><p>การเปลี่ยนนิสัยมาใช้ git stash push ตั้งแต่วันนี้ จะช่วยให้คุณจัดการกับโค้ดที่พักไว้ได้อย่างมีประสิทธิภาพและแม่นยำมากขึ้นแน่นอนครับ</p><p><em>หากคุณชอบบทความนี้ อย่าลืมกด “Clap” 👏 และกดติดตามเพื่อไม่พลาดเนื้อหาดีๆ เกี่ยวกับการพัฒนาซอฟต์แวร์นะครับ!</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=79067db2a75e" width="1" height="1" alt=""><hr><p><a href="https://giver.in.th/git-stash-push-vs-save-%E0%B9%80%E0%B8%A5%E0%B8%B4%E0%B8%81%E0%B8%AA%E0%B8%B1%E0%B8%9A%E0%B8%AA%E0%B8%99-%E0%B9%81%E0%B8%A5%E0%B9%89%E0%B8%A7%E0%B9%80%E0%B8%A5%E0%B8%B7%E0%B8%AD%E0%B8%81%E0%B9%83%E0%B8%8A%E0%B9%89%E0%B9%83%E0%B8%AB%E0%B9%89%E0%B8%96%E0%B8%B9%E0%B8%81%E0%B9%83%E0%B8%99%E0%B8%9B%E0%B8%B5-2025-79067db2a75e">Git Stash: push vs save — เลิกสับสน แล้วเลือกใช้ให้ถูกในปี 2025</a> was originally published in <a href="https://giver.in.th/">GiVeR</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Update the author name and email for a previously pushed Git commit]]></title>
            <link>https://giver.in.th/update-the-author-name-and-email-for-a-previously-pushed-git-commit-7b6560ae6aba?source=rss-150824165a6------2</link>
            <guid isPermaLink="false">https://medium.com/p/7b6560ae6aba</guid>
            <category><![CDATA[git]]></category>
            <dc:creator><![CDATA[Tanin Srivaraphong]]></dc:creator>
            <pubDate>Thu, 21 Nov 2024 04:36:46 GMT</pubDate>
            <atom:updated>2025-09-10T11:50:56.027Z</atom:updated>
            <content:encoded><![CDATA[<h3>Change user &amp; email in the previously pushed git commit</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*hqWUxrnR2xW3OGXJ" /><figcaption>Photo by <a href="https://unsplash.com/@pankajpatel?utm_source=medium&amp;utm_medium=referral">Pankaj Patel</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h3>TL;DR</h3><pre>git rebase -i HEAD~&lt;number-of-commits&gt;<br><br># Mark the commit you want to edit by changing pick to edit in the list of commits that appears.<br><br>git commit --amend --author=&quot;Your Name &lt;email@domain.com&gt;&quot;</pre><h3>Long Story</h3><p>Lately, I realized that I have multiple credentials on my computer, requiring me to alternate between personal and company projects. I noticed that my personal email was unintentionally used in my pushed commits when opening the PR. Subsequently, I had to investigate the issue. Upon inspection, I discovered the necessity of configuring my git to local settings instead of global settings.</p><p>It also have several ways to do like below</p><h4>1. Using git local config</h4><p>ref: <a href="https://stackoverflow.com/a/73658922/1890430">https://stackoverflow.com/a/73658922/1890430</a></p><pre>git config --local credential.helper &quot;&quot;<br>git push origin master<br># It asks for username and password for current repo.</pre><p>Or specific user/e-mail on the local repo manually</p><pre># Using text editor to put user and e-mail<br>git config --local -e<br><br># OR <br><br>git config user.name &quot;Your Name&quot;<br>git config user.email your@domain.com</pre><h4>2. Using git specific configuration</h4><pre>[includeIf &quot;gitdir:~/Documents/projects/my-company-repo&quot;]<br>  path = ~/.gitconfig-work<br><br># The contents of this file are included only for GitLab.com URLs<br>[includeIf &quot;hasconfig:remote.*.url:https://gitlab.com/**&quot;]<br>  path = ~/.gitconfig-work</pre><pre># .gitconfig-work<br>[user]<br>name = Your Name<br>email = name@domain.com</pre><h3>In case you missed to commit already</h3><p>Using the follow method in the link</p><p><a href="https://serhii.net/dtb/250215-1716-git-change-name-or-email-in-commit-history/">Git change name or email in commit history</a></p><pre>git config alias.change-commits &#39;!&#39;&quot;f() { VAR=\$1; OLD=\$2; NEW=\$3; shift 3; git filter-branch --env-filter \&quot;if  \\\&quot;\$\`echo \$VAR\`\\\&quot; = &#39;\$OLD&#39; ; then export \$VAR=&#39;\$NEW&#39;; fi\&quot; \$@; }; f &quot;<br>git change-commits GIT_AUTHOR_NAME &quot;&lt;Old Name&gt;&quot; &quot;&lt;New Name&gt;&quot; -f<br>git change-commits GIT_AUTHOR_EMAIL &lt;old@email.com&gt; &lt;new@email.com&gt; -f<br>git change-commits GIT_COMMITTER_NAME &quot;&lt;Old Name&gt;&quot; &quot;&lt;New Name&gt;&quot; -f<br>git change-commits GIT_COMMITTER_EMAIL &lt;old@email.com&gt; &lt;new@email.com&gt; -f</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7b6560ae6aba" width="1" height="1" alt=""><hr><p><a href="https://giver.in.th/update-the-author-name-and-email-for-a-previously-pushed-git-commit-7b6560ae6aba">Update the author name and email for a previously pushed Git commit</a> was originally published in <a href="https://giver.in.th/">GiVeR</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[สรุป] The Cloud Camp 2024 — Audition Round 2 (Day 3/ 3)]]></title>
            <link>https://giver.in.th/%E0%B8%AA%E0%B8%A3%E0%B8%B8%E0%B8%9B-the-cloud-camp-2024-audition-round-2-day-3-3-bba88d81968a?source=rss-150824165a6------2</link>
            <guid isPermaLink="false">https://medium.com/p/bba88d81968a</guid>
            <category><![CDATA[docker]]></category>
            <category><![CDATA[ci-cd-pipeline]]></category>
            <category><![CDATA[containerization]]></category>
            <dc:creator><![CDATA[Tanin Srivaraphong]]></dc:creator>
            <pubDate>Sat, 08 Jun 2024 13:01:15 GMT</pubDate>
            <atom:updated>2024-06-09T01:53:54.846Z</atom:updated>
            <content:encoded><![CDATA[<h3><a href="https://medium.com/giver-in-th/%E0%B8%AA%E0%B8%A3%E0%B8%B8%E0%B8%9B-the-cloud-camp-2024-audition-round-2-day-2-3-bfaf082b21a3?source=your_stories_page-------------------------------------">[สรุป] The Cloud Camp 2024 — Audition Round 2 (Day 3/ 3)</a></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*tgUP0rU4R4NDf21k" /><figcaption>Photo by <a href="https://unsplash.com/@carrier_lost?utm_source=medium&amp;utm_medium=referral">Ian Taylor</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>วันนี้เราจะมาอยู่กับ Basic Container และ Docker กันต่อเนื่องจากสัปดาห์ที่แล้วนะครับ ส่วนตอนก่อนหน้า อ่านตาม Link ข้างล่างได้เลยครับ</p><ul><li><a href="https://giver.in.th/%E0%B8%AA%E0%B8%A3%E0%B8%B8%E0%B8%9B-the-cloud-camp-2024-audition-round-2-day-2-3-bfaf082b21a3">[สรุป] The Cloud Camp 2024 — Audition Round 2 (Day 2/ 3)</a></li><li><a href="https://giver.in.th/%E0%B8%AA%E0%B8%A3%E0%B8%B8%E0%B8%9B-the-cloud-camp-2024-audition-round-2-day-1-3-40caa6cccda7">[สรุป] The Cloud Camp 2024 — Audition Round 2 (Day 1/ 3)</a></li></ul><h3>Container Origin</h3><ul><li>Concept มันก็มาจาก Container จริงๆ นั่นแหละอย่างที่เราเห็นตามรูปเรือที่มีตู้ Container วางอยู่แบบนั้นเลย</li><li>ของที่เราจัด (Pack) อยู่ในตู้ Container มันจะเพิ่ม เปลี่ยน หรือเอาของข้างในตู้ออกไม่ง่าย เพราะว่ามันถูกจัดให้พอดีสุดๆ ให้ขนสินค้าไปได้มากที่สุด โดยหลักการแล้ว การเอา Container มาอีกอัน แล้วย้ายเอาของข้างในไปใส่อีกตู้ดูท่าจะเหมาะสมและเร็วกว่า ก็เลยเป็นที่มาว่าการสร้าง Container ใหม่ทุกครั้งที่มีการเปลี่ยนแปลงย่อมสะดวกและง่ายกว่าแก้ไขของเดิม ซึ่งก็ตรงกับที่ว่า ถ้าเรามีการปรับเปลี่ยนอะไรใน Container Image เดิมก็จะเกิด Container Image ID ใหม่ทุกครั้ง</li></ul><h3>Application Deployment Process (Recap.)</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*A20XEq9a4XeHtGF8TeRgDA@2x.png" /><figcaption>Deployment Process (Jumpbox)</figcaption></figure><h3>Containerize and Application</h3><p>หลักการคือ การเอา Application ที่พร้อมรัน เอาไปใช้บน Server พร้อมใช้ ตามรูปนี้เลย</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/938/1*LzahX2CleYf9HVTPKahDLg@2x.png" /><figcaption>การนำ Container ไปใช้ (รูปจาก Jumpbox)</figcaption></figure><h3>ทบทวนความเข้าใจกับ Docker กันหน่อย</h3><ul><li>Docker คือ <strong>Platform</strong> ที่ทำให้เราใช้งาน Application ในลักษณะของ Conainer ได้ สรุปได้ว่า <strong>Docker = Container Platform</strong></li><li>Docker ประกอบด้วย <strong>containerd</strong> กับ <strong>runc</strong></li><li>Docker != Container Runtime แต่ใช้ <strong>containerd</strong> ในการรัน Container</li><li><strong>containerd</strong> ใช้ <strong>runc</strong> ในการรัน Container จริงๆ</li></ul><blockquote>สรุปได้ว่าในการทำงาน Docker จะใช้ containerd เป็น backend ในการจัดการคอนเทนเนอร์ และ containerd จะใช้ runc เพื่อรันคอนเทนเนอร์แต่ละตัว</blockquote><h3>คำถามจากทางบ้าน</h3><h4><strong>🙋 Portrainer คืออะไร</strong></h4><p>เป็น Container Management Software โดยจากคำนิยมจากตัว Software Portainer เอง เขาบอกว่า <em>“Portainer is your container management software to deploy, troubleshoot, and secure applications across cloud, datacenter, and Industrial IoT use cases.”</em></p><h4><strong>🙋</strong>Kubernetes (<strong>K8s) ใช้ทำอะไร จำเป็นต้องใช้ Docker หรือเปล่า</strong></h4><p>K8s ไม่จำเป็นต้องใช้คู่กับ Docker เสมอไป แต่เนื่องจากแต่ก่อน Docker เคยถูกใช้เป็น Container Runtime (containerd + runc) คู่กับ K8s มาอย่างช้านาน แต่สุดท้ายทาง K8s ก็เข้าร่วมมาตรฐาน CRI (Container Runtime Interface) และเลือกใช้ <strong>containerd</strong> เป็นตัวเริ่มต้น โดย<strong>ไม่ได้พึ่งพา Docker Ecosystem อีกต่อไป</strong> โดยเริ่มตั้งแต่ <strong>K8s v1.2.0</strong></p><h4><strong>🙋Helm คืออะไร</strong></h4><p>Helm <strong>เป็นเครื่องมือจัดการแพ็กเกจ (package manager</strong>) สำหรับ K8s ซึ่งมีบทบาทสำคัญในการทำให้การจัดการแอปพลิเคชันบน K8s ง่ายและมีประสิทธิภาพมากขึ้น โดย Helm ช่วยในการติดตั้ง, อัปเดต, และจัดการ lifecycle ของแอปพลิเคชันที่ทำงานบน k8s มองง่ายๆ ก็เหมือนคนใช้ NodeJS แล้วมี npm หรือ yarn ให้ใช้ประมาณนั้นเลย</p><blockquote>Helm is a tool for managing Charts. Charts are packages of pre-configured Kubernetes resources. — <a href="https://github.com/helm/helm">Helm</a></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5QMpFrSbbXsMv6u9TLFHgQ@2x.png" /><figcaption>Containerize an Application (รูปจาก Jumpbox Slide)</figcaption></figure><p>จากรูปบน เราทำการ Build ทั้ง Software Package ให้อยู่ในรูปแบบของ Container Image เพื่อเป็นแม่แบบให้ Container Runtime ไป Deploy ในรูปแบบของ Container Instance</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xYcMlNLbpIfqox8mBrCpOw@2x.png" /><figcaption>Container Image Building (Jumpbox)</figcaption></figure><h4>Container Deployment</h4><p>จากที่กล่าวข้างต้นคือ หลังจากที่เราได้ Container Image แล้ว เราก็จะนำส่งเจ้าตัว Container Image (เรียกสั้นๆ ว่า “Image”) ไปยัง Server ที่มีเจ้าตัว Container Runtimes อยู่ เพื่อนำไปปรับแต่งต่อเพื่อทำการรันเจ้าตัว Image ของเราที่เป็นแม่แบบ ออกไปอยู่ในรูปแบบ Instance</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8sWdVKZPApEAcQs1GZco1w@2x.png" /><figcaption>Container Deployment (Jumpbox)</figcaption></figure><h3><strong>Check Point #1</strong></h3><blockquote>1. เข้าใจที่มา ที่ไปของตู้ Container และ Container Technology<br>2. เข้าใจว่า Container เข้ามาแก้ปัญหาอะไร<br>3. รู้จักกระบวนการ Containerization<br>4. เข้าใจและสามารถอธิบายพื้นฐานของ Container ได้<br>4.1 เข้าใจและสามารถอธิบาย Container Runtime ได้<br>4.2 เข้าใจและสามารถอธิบาย Container Image ได้<br>4.3 เข้าใจและสามารถอธิบาย Container Instance ได้</blockquote><h4>Containerization Characteristic</h4><ol><li><strong>Isolation — </strong>ตัว Container จะทำการแยกตัว environment ออกจากตัว Application เพื่อให้แน่ใจว่าแต่ละ Container ทำงานได้อย่างอิสระ</li><li><strong>Portability</strong> — ทำงานได้ทุกที่ที่มี Container Runtime มาตรฐาน Container R</li><li><strong>Consistency</strong> — รันทุกที่ได้ผลแบบเดียวกันภายใต้เงื่อนไขตัว Container ตัวเดียวกัน</li><li><strong>Efficiency</strong> — ตัว Container จะเบากว่าการใช้ VM แบบดั้งเดิมมาก เพราะว่าใช้แค่ระดับ Kernel แทนที่จะใช้แบบ Full OS</li><li><strong>Scalability</strong> — เพราะว่าเล็กและ Portable ดังนั้นมันจะสามารถ Scale up/down ได้งานและรวดเร็วบน Cloud Native Application</li></ol><h3>Docker Components</h3><h4><strong>Docker Host</strong></h4><p>คือระบบหรือเครื่องที่รัน Docker Engine และจัดการทุกอย่างที่เกี่ยวข้องกับคอนเทนเนอร์ ตั้งแต่การสร้าง การจัดการ จนถึงการรันคอนเทนเนอร์ทั้งหมด เป็นสภาพแวดล้อมที่ Docker components อื่น ๆ ทำงานอยู่ โดย Docker Engine และ Docker Containers ถูกติดตั้งและดำเนินการภายใน Docker Host</p><h4><strong>Docker Daemon (dockerd)</strong></h4><p>Docker Daemon หรือ dockerd เป็นส่วนประกอบสำคัญของ Docker Engine ที่ทำงานอยู่บน Docker Host มีหน้าที่รับคำสั่งจาก Docker Client และ API เพื่อจัดการการสร้าง, การรัน, การหยุด และการลบคอนเทนเนอร์ รวมถึงการจัดการ Docker images, networks และ volumes.</p><h4><strong>Docker Registries</strong></h4><p>คือสถานที่ใช้เก็บ แชร์ และดาวน์โหลดเจ้าตัว docker image ซึ่งสามารถเป็นได้ทั้ง public หรือ private (ใช้ username/password)โดย default จะชี้ไปยัง <a href="https://hub.docker.com/">hub.docker.com</a></p><blockquote><strong>Check Point #2</strong></blockquote><blockquote>1. เข้าใจส่วนประกอบต่างๆ ของ docker architecture ได้เป็นอย่างดี<br>1.1 Docker Client / Docker CLI ทำหน้าที่อย่างไร<br>1.2 เข้าใจความหมายของคำว่า Host<br>1.3. Docker image ทำหน้าที่อย่างไร<br>2. รู้จัก Container Registry<br>2.1 Local Registry <br>2.2 Cloud Registry -&gt; Public / Private<br>3. Docker Daemon / Docker Server ทำหน้าที่อย่างไร</blockquote><h4><strong>Docker Client</strong> และ <strong>Docker CLI</strong></h4><p>เป็นคำที่บางครั้งใช้แทนกันได้ แต่ในบริบท (Context) ของ Docker นั้นมีหน้าที่ที่ค่อนข้างเหมือนกันและมักจะถูกใช้ร่วมกันเพื่ออธิบายการสื่อสารระหว่างผู้ใช้งานกับ Docker Daemon โดยส่วนใหญ่คนมักเข้าใจว่า Docker Client คือ GUI และ Docker CLI ก็คือ CLI Command-line ตรงตัว</p><h4>Docker Daemon กับ Docker Server ทำหน้าที่อย่างไร</h4><p>ต้องบอกก่อนว่า บางคนก็เรียก Docker Daemon ว่า Docker Server ซึ่งก็คือสิ่งเดียวกันนั่นแหละ ไปอ่านได้ในหัวข้อด้านบน “Docker Daemon (dockerd)”</p><h3>Docker Management</h3><p>หัวข้อนี้ไม่มีอะไรมาก ลองเล่นดูแล้วจะรู้</p><h4>Container Instance Managements</h4><ul><li>docker run</li><li>docker start</li><li>docker stop</li><li>docker kill</li></ul><h4>Monitoring &amp; Troubleshooting</h4><ul><li>docker ps, docker exec, docker logs</li><li>docker pull, docker images</li></ul><h4>Container Images Managements</h4><ul><li>docker rm, docker rmi, docker system prune</li><li>docker login, docker build, docker push</li></ul><h3>Basic CI/CD</h3><h4>Continuous Integration (CI)</h4><blockquote>CI is all about verifying your code!</blockquote><ul><li>Continuous + Integration</li><li>รวมความเปลี่ยนแปลงบ่อยๆ</li><li>เราต้องมีการตรวจสอบ (verify) ว่าโค้ดอันนั้นทำงานได้อย่างถูกต้อง</li></ul><h4>Continuous Delivery (CD)</h4><ul><li>เป็นการนำกระบวนการ (process) หลายๆ ตัวเข้ามาใช้เพื่อ “ทำให้ Software Engineer” หลายๆ คนพัฒนา Software ได้มีคุณภาพมากขึ้น และได้สร้างสรรค์ผลงานได้อย่างที่ต้องการ</li><li>เพื่อทำให้ทีมสามารถ release การเปลี่ยนแปลงได้อย่างปลอดภัย (Safely) รวดเร็ว (Quickly) และยั่งยืน (Systainably)</li><li>เพื่อพิสูจน์ว่าการเปลี่ยนแปลงนั้นสามารถถูก Deploy ได้หลายครั้ง</li><li>เพื่อทำการให้เกิดกระบวนการอัตโนมัติในการนำส่ง Software ออกไปใช้งาน (Automating Release Processes)</li></ul><p><strong>ส่วนประกอบของ CD มีอะไรบ้าง</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mYTfUPFZykNPR7Dwy05CaQ@2x.png" /><figcaption>CD Pipeline (From Jumpbox Slide)</figcaption></figure><h4>Lining (ได้ Verifed Source Code)</h4><ul><li>Source Code → <strong>Check / Lint → Source Code (verified)</strong></li></ul><h4>Testing (Quality Gate) (ได้ Tested Source Code)</h4><ul><li>Source Code → Check / Lint → Source Code (verified) → <strong>Test → Source Code (tested)</strong></li></ul><h4>Building (ได้ Executable File)</h4><ul><li>Source Code → Check / Lint → Source Code (verified) → Test → Source Code (tested)<strong> </strong>→<strong> Compile / Interpret → Executable File</strong></li></ul><h4>Publishing (ได้ Container Image)</h4><ul><li>Source Code → Check / Lint → Source Code (verified) → Test → Source Code (tested)<strong> </strong>→ Compile / Interpret → Executable File →<strong> Build → Container Image</strong></li></ul><h4>Deploying (ได้ Container Instance)</h4><ul><li>Source Code → Check / Lint → Source Code (verified) → Test → Source Code (tested)<strong> </strong>→ Compile / Interpret → Executable File →<strong> </strong>Build → Container Image →<strong> Run → Container Instance</strong></li></ul><blockquote><strong>Checkpoint #1</strong></blockquote><blockquote>1. เข้าใจกระบวนการของ CD<br>2. เข้าใจกระบวนการของ CI</blockquote><blockquote><strong>Checkpoint #2</strong></blockquote><blockquote>1. เห็นภาพรวมทั้งหมดของ CD<br>2. สามารถ Mapping แต่ละขั้นตอนในการสร้าง Apllication ออกมาเป็น Pipeline ได้<br>3. เข้าใจความแตกต่างระหว่าง CI/CD</blockquote><p>จบแล้วจร้ากับ Basic Concept ที่เรียนมาตลอด 3 วัน</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bba88d81968a" width="1" height="1" alt=""><hr><p><a href="https://giver.in.th/%E0%B8%AA%E0%B8%A3%E0%B8%B8%E0%B8%9B-the-cloud-camp-2024-audition-round-2-day-3-3-bba88d81968a">[สรุป] The Cloud Camp 2024 — Audition Round 2 (Day 3/ 3)</a> was originally published in <a href="https://giver.in.th/">GiVeR</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[สรุป] The Cloud Camp 2024 — Audition Round 2 (Day 2/ 3)]]></title>
            <link>https://giver.in.th/%E0%B8%AA%E0%B8%A3%E0%B8%B8%E0%B8%9B-the-cloud-camp-2024-audition-round-2-day-2-3-bfaf082b21a3?source=rss-150824165a6------2</link>
            <guid isPermaLink="false">https://medium.com/p/bfaf082b21a3</guid>
            <category><![CDATA[cnpf]]></category>
            <category><![CDATA[vi]]></category>
            <category><![CDATA[linux]]></category>
            <category><![CDATA[application]]></category>
            <dc:creator><![CDATA[Tanin Srivaraphong]]></dc:creator>
            <pubDate>Sun, 02 Jun 2024 11:07:34 GMT</pubDate>
            <atom:updated>2024-06-02T11:07:34.793Z</atom:updated>
            <content:encoded><![CDATA[<h3><a href="https://medium.com/giver-in-th/%E0%B8%AA%E0%B8%A3%E0%B8%B8%E0%B8%9B-the-cloud-camp-2024-audition-round-2-day-1-3-40caa6cccda7?source=your_stories_page-------------------------------------">[สรุป] The Cloud Camp 2024 — Audition Round 2 (Day 2/ 3)</a></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*__BsUSy_RmRiYdub" /><figcaption>Photo by <a href="https://unsplash.com/@hidd3n?utm_source=medium&amp;utm_medium=referral">Kevin Horvat</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>กลับมาต่อกันในวันที่ 2 นะครับ</p><p>ขอเกริ่นก่อนนะครับ พวก <strong>Basic Linux Command Fundamental</strong> และ <strong>VI Editor</strong> วันนี้ก็มีสอนเหมือนกัน แต่ผมขออนุญาตข้ามนะครับ เพื่อความกระชับของเนื้อหา</p><blockquote>พวก Linux Command พื้นฐานก็ไปหาได้เยอะแยะ ตัวอย่างเช่น <a href="https://www.hostinger.com/tutorials/linux-commands">https://www.hostinger.com/tutorials/linux-commands</a></blockquote><blockquote><strong>Vi Cheatsheet</strong><br><a href="https://vim.rtorr.com/">https://vim.rtorr.com/</a></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/623/1*Fdwk4149NB2nnYIJu5fWrA@2x.png" /></figure><p>สำหรับคนที่พื้นฐาน Linux ไม่แน่น นอกจากที่เรียนใน Class แล้ว แนะนำลองหาจากที่อื่นดู และทบทวนมากขึ้นตามเทคนิค <strong>“Spaced Repetition”</strong> หรือ <strong>การทบทวนแบบเว้นระยะ </strong>ซึ่งก็คือ การอ่านหรือและเว้นช่วงพักอย่างสม่ำเสมอ แล้วค่อยกลับมาทบทวนใหม่ ช่วงพักเว้นนี้อาจหมายถึง จากครั้งแรกที่อ่าน เว้นหนึ่งวันกลับมาทบทวนใหม่ ไล่เป็นเว้นสองวัน เว้นสามวัน การทำแบบนี้ค้นพบว่าการเว้นระยะในการทบทวนช่วยลด “โค้งการลืม” ได้ ถ้ายกตัวอย่างก็</p><p>สมมติว่าเด็กคนหนึ่งเรียนรู้คำว่า “แอปเปิ้ล” ในวันนี้</p><ul><li><strong>วันนี้</strong>ทบทวนคำว่า “แอปเปิ้ล” สองสามครั้ง</li><li><strong>วันพรุ่งนี้</strong>หรืออีกสองวัน ทบทวนคำว่า “แอปเปิ้ล” อีกครั้ง</li><li><strong>อีกหนึ่งสัปดาห์</strong> ทบทวนคำว่า “แอปเปิ้ล” อีกครั้ง</li></ul><p>การทบทวนแบบนี้ช่วยให้เด็กจำคำว่า “แอปเปิ้ล” ได้ดีกว่าและนานกว่า</p><h3>Linux in General</h3><h4>Linux Kernel 4 Majors Task</h4><ol><li>Memory Management</li><li>Process Management</li><li>Device Drivers</li><li>System Calls and Security — คุยกับ Hardware ยังไง หรือมีสิทธิ์ในการใช้งานยังไง</li></ol><h4>Tips</h4><blockquote>เราสามารถใช้ <strong>strace -c ls</strong> เพื่อใช้ดูว่า คำสั่ง “ls” มี system call เป็น trace อะไรบ้าง</blockquote><h4>Kernel Space and User Space</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/756/1*p7gpN-u4YEc_ie_XKFjLVQ@2x.png" /><figcaption>Jumpbox Slide</figcaption></figure><h4>Working with Hardware</h4><p>ขอ note เฉพาะคำสั่งที่ปกติ user ทั่วไปไม่ค่อยได้ใช้ แล้วพูดถึงใน class เรียนเน้อ</p><ul><li>ใช้คำสั่ง <strong>lscpu</strong> ดู CPU spec</li><li>ใช้คำสั่ง <strong>lsmem</strong> ดู Memory spec</li></ul><h4>Linux Boot Sequence</h4><ol><li><strong>BIOS POST</strong> (Basic Input/Output System Power-On Self Test)<br>- เมื่อคอมพิวเตอร์เปิดขึ้น BIOS จะทำการตรวจสอบฮาร์ดแวร์พื้นฐาน เช่น RAM Harddisk และอุปกรณ์อื่นๆ<br>- หลังจากตรวจสอบแล้ว BIOS จะค้นหาอุปกรณ์บูต (เช่น ฮาร์ดดิสก์, USB, CD/DVD) เพื่อโหลด Boot Loader</li><li><strong>Boot Loader</strong> (GRUB2 — <strong>GR</strong>and <strong>U</strong>nified <strong>B</strong>ootloader 2)<br>จะทำการโหลดและแสดงเมนูบูตให้ผู้ใช้เลือกว่าต้องการบูตเข้าสู่ระบบปฏิบัติการใด (ถ้ามีหลายระบบปฏิบัติการ)</li><li><strong>Kernel Initialization</strong><br>- หลังจาก Kernel ถูกโหลดเข้าสู่หน่วยความจำ Kernel จะทำการตรวจสอบและติดตั้งไดรเวอร์ฮาร์ดแวร์ทั้งหมด<br>- Kernel จะตั้งค่าระบบไฟล์ root (root filesystem) และเปิดใช้งานกระบวนการแรกของระบบ (initial process) ซึ่งมักจะเป็น init หรือ systemd</li><li><strong>INIT Process (Systemd)</strong><br>- ระบบ <strong>systemd</strong> จะทำการจัดการกระบวนการบูตที่เหลือทั้งหมด<br>- <strong>systemd</strong> จะเริ่มการทำงานของบริการพื้นฐาน (services) ต่างๆ เช่น การตั้งค่าเครือข่าย การติดตั้งระบบไฟล์เพิ่มเติม และการเริ่มต้นการบริการระบบ (system services)<br>- หลังจากนั้น <strong>systemd</strong> จะเริ่มโปรแกรมการเข้าสู่ระบบ (login prompt) ทำให้ผู้ใช้สามารถเข้าสู่ระบบและเริ่มการใช้งานเครื่องคอมพิวเตอร์ได้</li></ol><h4>File Types in Linux</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/880/1*DCmvzYaMyErn5j-NWyJETA@2x.png" /><figcaption>Jumpbox Slide</figcaption></figure><blockquote>⚠️ <strong>ข้อควรระวัง</strong> ⚠️</blockquote><blockquote><strong>Hard Links</strong> เวลาลบร่างโคลน ตัว original หรือต้นทางก็หายด้วยนะ เพราะว่าชี้ไปที่ inode เดียวกัน (อันนี้ low-level หน่อยนะ คนที่เรียนวิชา Operating System น่าจะเข้าใจ)</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/498/1*w49QkFCIRCkqgr-6h4flsQ.png" /><figcaption><a href="https://www.hpe.com/psnow/resources/ebooks/a00110181en_us_v11/AdministratorGuide/Hardlinks.html">https://www.hpe.com/psnow/resources/ebooks/a00110181en_us_v11/AdministratorGuide/Hardlinks.html</a></figcaption></figure><h4>Package Manager</h4><ul><li><strong>APT</strong> (Advanced Package Tool) — พัฒนาโดย Debian Project สำหรับจัดการแพ็คเกจในระบบปฏิบัติการ Debian และ Ubuntu ตัวอย่าง<br>👉 <strong>apt search</strong><br>👉 <strong>apt-cache search<br></strong>👉 <strong>apt install search<br></strong>👉 <strong>apt list — upgradable</strong> เพื่อให้ดู package ไหนสามารถ upgrade ได้บ้าง</li><li><strong>YUM</strong> (Yellowdog Updater, Modified) — พัฒนาโดย Yellowdog Linux (YDL) และใช้เป็นหลักใน Red Hat-based distributions เช่น Red Hat Enterprise Linux (RHEL), CentOS, และ Fedora</li><li><strong>DNF</strong> (Dandified YUM) — ถูกพัฒนาขึ้นมาเป็นการปรับปรุง YUM โดย Red Hat</li><li><strong>APK</strong> (Alpine Package Keeper) — พัฒนาโดย Alpine Linux</li></ul><h3>Basic Observability</h3><p>Application Characteristic</p><ul><li>Program Process</li><li>Application Building</li><li>Application Output</li><li>Application Package Manager</li></ul><h4>Program Process</h4><ul><li>Programming = Coding + Problem Solving</li><li>Application Building — Source Code เขียนให้มนุษย์เข้าใจ ก่อนที่จะถูกแปลงไปเป็นภาษา computer และกลายเป็น executable file หรือ application</li><li>Program = Collection of Instructions — ชุดหรือกลุ่มของคำสั่ง</li><li>แบ่งออกเป็น 2 รูปแบบ <br>1) <strong>Batch Program</strong> — ทำงานให้เสร็จโดยไม่ต้องการ User Interaction หรือรอ External Event และทำงานเป็นลำดับขึ้นจนเสร็จ<br>2) <strong>Event-Driven or Interactive Program</strong> — รอรับการทำงานตลอดเวลาเมื่อมีเหตุการณ์ (Event) เกิดขึ้น เช่น API call, กดปุ่ม และจะหยุดการทำงานเมื่อได้รับทำสั่งให้หยุด</li></ul><h4>Program vs Application</h4><ul><li>(Computer) Program = ชุดคำสั่งที่ถูกนำไปทำงานโดยคอมพิวเตอร์</li><li>Application = ตัวโปรแกรม (Computer Program) ที่ถูกออกแบบมาให้สำหรับผู้ใช้ (End Users)</li></ul><h4>Application Building</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/772/1*2468_YR3LYwv_zA9nnQqJA@2x.png" /><figcaption>Jumpbox Slide</figcaption></figure><blockquote>JIT = Just in Time<br>AOT = Ahead of Time</blockquote><h3>Executable file</h3><h4>กลุ่ม OS Executable</h4><ul><li>เกิดจากกลุ่ม System Programming Language</li><li>พวก binary file ทั้งหลาย เช่น .exe บน Windows และไม่มีนามสกุลบน *nix เป็นต้น</li></ul><h4>กลุ่ม Application Package</h4><ul><li>เกิดจากกลุ่ม High-level Programming Language</li><li>ต้องการตัว Runtime เช่น .jar, .war ของ Java ที่ต้องการ JDK (JRE and JVM) ในการใช้งาน หรือฝั่ง Javascript (.js) ที่ต้องการ NodeJS (V8) ในการรันคำสั่ง</li></ul><h4>Trend Application Programming with OS Executable</h4><p><strong>Pros</strong></p><ul><li>ไม่ต้องการตัว Runtime</li><li>เบาสบาย</li><li>ประสิทธิภาพสูงเพราะว่า มันเป็นภาษาเครื่องเลยไม่ต้องผ่านตัวแปลภาษา</li></ul><p><strong>Cons</strong></p><ul><li>ต้อง compile ไปให้ใช้งานกับทุก platform และ architecture ทั้งหมดที่ใช้ทีละตัว</li></ul><p>ตัวอย่างของการพยายามแปลงพวก Runtime เป็น Executable file ก็</p><ul><li>NodeJS มี Node Single Executable</li><li>Java มี GraalVM</li></ul><h4>Application Output</h4><ul><li>Logs เช่น Grafana loki, Elasticsearch</li><li>Traces เช่น Grafana Tempo, Elastic APM</li><li>Metrics เช่น Grafana Mimir, Prometheus</li></ul><h4>Application Package Manager</h4><ul><li>Source Code</li><li>Code Translation</li><li>Executable file</li></ul><h4>Observability</h4><ul><li>Telemetry = Tele (ไกล) + Metron (การวัด) = กระบวนการส่งข้อมูลจากการวัดจากที่ห่างไกล</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/450/1*4Nxdm4n99kxYT4rRXjRVrQ@2x.png" /><figcaption>อะไรที่ไม่ทำให้เราถึงตายจะทำให้เราแข็งแกร่ง</figcaption></figure><p>สุดท้ายก่อนจบวัน มีการพูดถึงเรื่องที่มาของ Container Technology แต่ผมว่าจะเอาไปรวมกับสัปดาห์แทนละกันจะได้ไม่ครึ่งๆ กลางๆ</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bfaf082b21a3" width="1" height="1" alt=""><hr><p><a href="https://giver.in.th/%E0%B8%AA%E0%B8%A3%E0%B8%B8%E0%B8%9B-the-cloud-camp-2024-audition-round-2-day-2-3-bfaf082b21a3">[สรุป] The Cloud Camp 2024 — Audition Round 2 (Day 2/ 3)</a> was originally published in <a href="https://giver.in.th/">GiVeR</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[สรุป] The Cloud Camp 2024 — Audition Round 2 (Day 1/ 3)]]></title>
            <link>https://giver.in.th/%E0%B8%AA%E0%B8%A3%E0%B8%B8%E0%B8%9B-the-cloud-camp-2024-audition-round-2-day-1-3-40caa6cccda7?source=rss-150824165a6------2</link>
            <guid isPermaLink="false">https://medium.com/p/40caa6cccda7</guid>
            <category><![CDATA[cnpf]]></category>
            <category><![CDATA[cloud]]></category>
            <category><![CDATA[cloud-native]]></category>
            <dc:creator><![CDATA[Tanin Srivaraphong]]></dc:creator>
            <pubDate>Sat, 01 Jun 2024 13:39:19 GMT</pubDate>
            <atom:updated>2024-06-09T01:43:50.984Z</atom:updated>
            <content:encoded><![CDATA[<h3>[สรุป] The Cloud Camp 2024 — Audition Round 2 (Day 1/ 3)</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*sWRy3uBpjoMz_Evw" /></figure><h3>เกริ่นนำ</h3><p>เป้าหมายแรกเริ่มที่อยากเรียนคือ อยาก upskill และ reskill ของที่รู้เมื่อนานชาติมาแล้ว แต่ก็พอไม่ได้ใช้ทุกวัน มันก็ลืมไปแล้ว โดยเริ่มจากพื้นฐานก่อน ก็ได้มาคอส free ปูพื้นฐานของ CNPF โดย Jumpbox ซึ่งก็ได้ลงเรียน มีเวลา 3 วันแหล่ะ ก็พยายาม force ตัวเองให้มาจดโน้ตเนอะ input = output ได้รับเท่าไร ก็จดเท่านั้นแหละ รวมถึงหาข้อมูลเพิ่มเติมด้วย</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/685/1*K_n30hN79r-1gXY4N83_7g.png" /><figcaption>Cloud Native Maturity Matrix</figcaption></figure><blockquote>ยุคนี้คือยุคของ Cloud Native Era</blockquote><h3>วันแรกที่เรียนต้องปรับ Mindset ในการเรียนรู้ก่อน</h3><ol><li>ต้องให้กำลังใจตัวเอง อย่าใช้ประโยคแนว “อยาก” “จะ” “ต้อง” “ไม่” เพื่อเป็นการปลุกใจตัวเอง อย่าโทษตัวเอง มันไม่มีประโยชน์</li><li>อย่าไปว่าคนอื่นโง่หรือโทษว่าตัวเองโง่ มีแต่รู้กับไม่รู้ในการเรียนรู้</li><li>อย่างน้อยถ้าเราได้รู้อะไร ถึงรู้ไม่เท่าคนอื่น อย่างน้อยตัวเราเองก็รู้มากกว่าก่อนที่เราเรียนนั่นแหละ</li></ol><blockquote>“พร้อมยอมรับ<strong>ความอ่อนแอ </strong>และ <strong>เชื่อในตัวเอง</strong>หรือยัง” กล่าวคือ รู้ยังว่าตัวเองไม่รู้อะไรหรือมีจุดอ่อนอะไร แค่นั้นก็เพียงพอแล้ว</blockquote><blockquote>เราเชื่อว่าการเรียนรู้ทำให้ชีวิตคุณดีขึ้น — Jumpbox Team</blockquote><h3>เข้าเนื้อหา Cloud Native Practitioner Foundamental (CNPF) ต้องรู้อะไรบ้าง</h3><ol><li>Cloud Computing</li><li>Linux Foundamental</li><li>Observability</li><li>Container Foudnamental</li><li>CI &amp; CD</li><li>Problem Solving</li></ol><h3>Cloud Computing</h3><h4>Cloud คืออะไร ทำไมต้องใช้ Cloud</h4><ul><li>Cloud คือ Computer ที่อยู่บนโลกนี้สักที่หนึ่งบนโลก</li><li>มือถือเราเครื่อง powerful กว่าเครื่องบางเครื่องบน cloud เสียอีก</li><li>ถ้าพูดถึง Cloud มันต้องหมายถึงการใช้งานทรัพยากรคอมพิวเตอร์<strong>ผ่านทาง Internet</strong></li><li>Cloud ทำให้เราไม่จำเป็นต้องมี server หรือ hardware ที่เราต้องดูแลเอง ปล่อยให้ผู้ให้บริการ cloud (Cloud Provider) เป็นคนจัดการแทน</li><li>ถ้าเราใช้เครื่องแล้วทรัพยากรไม่พอ เราก็ Upgrade hardware จากการไปซื้อ hardware โน้นนั่นนี่ แล้วใช้คน upgrade แต่เรามายุคที่อยู่ที่เรียกว่า Cloud (Digital) Transformation ที่สามารถทำระบบ automation หรือ bot เพื่อให้ upgrade เครื่อง<strong>ผ่าน internet</strong> ได้</li><li>Cloud Computing — Pay as you go ใช้เท่าไร จ่ายเท่านั้น</li></ul><blockquote>Cloud is the <strong>on-demand</strong> delivery of infrastructure (handware/servers), storage, databases,, and all kinds of application services <strong>via the internet</strong></blockquote><h3>Cloud Characteristics</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/668/1*rFUFtW80VGORAdsAriQc-w.png" /><figcaption>Jumpbox Slide</figcaption></figure><ul><li><strong>Reduce Cost</strong> — Pay as you go ใช้เท่าไรจ่ายเท่านั้น</li><li><strong>Unlimited Storage</strong> — ในชีวิตอาจจะจำกัดแหละ แต่มันมากพอที่เราไม่ต้องสนใจ</li><li><strong>Scalable</strong> — ขยายได้ไม่จำกัด ตราบเท่าที่เรายอมจ่ายเพื่อให้ขยาย</li><li><strong>Security</strong> — มีความปลอดภัยตราบเท่าที่ผู้ให้บริการจะทำได้</li></ul><h3>Cloud Native</h3><p>“ใช้ความสามารถของ cloud ให้เกิดประโยชน์สูงสุด” — Use cloud in optimized way</p><ul><li>Cloud Native <strong>is not only</strong> for Application</li><li>Cloud Native มันคือ ERA หรือยุคสมัย</li><li>Cloud Native != Cloud ตัวของมันเองก็ไม่ใช่ cloud นะ</li><li>Cloud Native is more than a toolset</li><li>สามารถใช้เทคโนโลยีที่ใช้จำลองเสมือน Virtualization Technology (Hypervisor) เพื่อทำงานเป็น cloud ได้</li></ul><blockquote>ตัวอย่างสุดขำ ถ้าเอาตุ่ม (Jar) มาร่วมกับ Cloud Native มันก็จะออกมาแบบใน clip นี้เลย มีคุณสมบัติ unlimited storage และกันปอบลง (แบบไม่ตั้งใจ ฮ่าๆ)</blockquote><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FH0X-oN6Es74%3Fstart%3D149%26feature%3Doembed%26start%3D149&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DH0X-oN6Es74&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FH0X-oN6Es74%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/5b6f823165e2e8f41efeff0ab754efdf/href">https://medium.com/media/5b6f823165e2e8f41efeff0ab754efdf/href</a></iframe><h4>Cloud Native for XYZ</h4><blockquote>It is a complete architecture, a philosophical approach for <strong>XYZ</strong> that <strong>take full advantage of cloud computing</strong></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/605/1*gm6WpU6ZfubKOIt1pWTMRQ.png" /><figcaption>Jumpbox Slide</figcaption></figure><p>ถ้าใครอยากอ่านเพิ่มแนะนำหนังสือ Cloud Native Transformation by Pini Reznik, Jamie Dobson, Michelle Gienow หรือไปอ่านบนเวบ <a href="https://www.cnpatterns.org/">https://www.cnpatterns.org/</a></p><p><a href="https://www.oreilly.com/library/view/cloud-native-transformation/9781492048893/">Cloud Native Transformation</a></p><h3>Cloud Fundamental</h3><ul><li>Cloud Characteristics</li><li>Cloud Delivery Models =&gt; SaaS, PaaS, IaaS</li><li>Cloud Deployment Models</li></ul><h4>Cloud Characteristics</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/882/1*b-4aAEmcQ43wKHofhWbpww.png" /></figure><ol><li><strong>On Demand Usage </strong>— ใช้ตามที่ควรใช้ใจ</li><li><strong>Ubiquitous Access</strong> — คนที่เข้ามา จะไม่เห็น resource คนอื่นในเครื่องเดียวกัน แต่ทุกอย่างใช้พื้นที่เดียวกันแบบไม่รู้ตัว</li><li><strong>Multi-Tenant</strong> — ทุกคนใช้เครื่องร่วมกันทั้งหมด แล้ว Hypervisor จะมาแบ่ง resource ให้เอง</li><li><strong>Elasticity</strong> — การขยายเครื่องแบบ “Pre-Determined” ตัวอย่างเช่น สมมติว่าพรุ่งนี้จะมีขายตั๋วคอนสักรายการนึง แล้วเราประเมินว่าคนจะเข้ามาอย่างล้นหลามตอน 9:00 น. เราก็อาจจะ scale เครื่องรอตั้งแต่ 8 โมงนิดๆ เลยก็ได้สัก 100 เครื่อง แต่ถ้าเกิดแบบเป็น “Runtime” ก็คือเราจะตัดสินใจ scale เครื่องถ้ามันตรงเงื่อนไขที่เรากำหนด เช่น ถ้าสมมติเครื่อง server เรามี CPU Load 50% แล้วก็ค่อยให้เพิ่มเครื่องเข้ามาอีก 1 ตัวเรื่อยๆ จนกว่า CPU เฉลี่ยของเครื่องทั้งหมดต่ำกว่า 50% แบบนี้ ซึ่งเราจะทำได้ ก็ต้องมีตัววัด metrics ของบริการของเรา</li><li><strong>Measured Usage</strong> — เรามีที่ๆ ให้ monitor ปริมาณการใช้งานของระบบเรา ไม่ว่าจะ CPU, Memory ต่างๆ นานา ที่สำคัญควรมีระบบ automation แล้วก็การออก report ด้วย</li><li><strong>Resiliency</strong> — Multi Availabililty Zone (Across Physical Locations), Multi Cloud (ใช้ Cloud Service Provider คนละเจ้าเลย)</li></ol><h4>Checkpoint #1</h4><ul><li>Cloud Characteristic มีอะไรบ้าง แต่ละตัวมีความสามารถอย่างไร</li><li>ลักษณะแบบใดที่ทำให้เกิด Cost Optimization ได้</li><li>ลักษณะแบบใดที่ทำให้สามารถ track สิ่งต่างๆ ที่เกิดขึ้นได้</li><li>ลักษณะแบบใดที่ทำให้เกิด High Availability</li><li>ลักษณะแบบใดที่ทำให้เกิด Scalability</li></ul><h4>Shared Responsibility Model</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*FYPseiDyUumDDP7j.png" /><figcaption><a href="https://cloudfoundation.org/maturity-model/security-and-compliance/shared-responsibility-model-alignment.html#best-practices-for-aligning-a-shared-responsibility-model">https://cloudfoundation.org/maturity-model/security-and-compliance/shared-responsibility-model-alignment.html#best-practices-for-aligning-a-shared-responsibility-model</a></figcaption></figure><p>จากภาพเราจะดูง่ายเลยว่า ส่วนไหนที่ลูกค้ารับผิดชอบ และส่วนใหญ่ผู้ให้บริการ cloud (Cloud Service Provider) รับผิดชอบ</p><h4>Cloud Delivery Models</h4><ul><li>Infrastructure-as-a-Service (IaaS) — คิดว่าเป็น Digital Ocean ละกัน</li><li>Platform-as-a-Service (PaaS) — เรามี Application + Data แล้วใช้งานได้เลย</li><li>Software-as-a-Service (SaaS) — ไปแต่ตัว ทุกอย่างมีให้ใช้</li><li>Sub Models — พวก ABC-as-a-service ทั้งหลาย เช่น Database as a service, Storage as a service ซึ่ง พวกนี้จะให้บริการเป็นเรื่องๆ ไป</li><li>Combining Models — คือ พวกที่ให้บริการ IaaS, PaaS หรือ SaaS แต่ผู้ใช้ที่ต้องการความ Advance สามารถไปปรับแต่งระดับล่างได้</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vzJry3QGiB34cAghgXV1pA@2x.png" /><figcaption>เปรียบเทียบระหว่าง IaaS กับ PaaS และ Saas (Jumpbox)</figcaption></figure><p>จาก model ที่กล่าวมาด้านบน ปัจจุบันหลายบริการสามารถทำอะไรได้มากกว่า Single Models โดดๆ และมักจะมาในรูปแบบรวมหรือผสมกันมากกว่า 1 ตัวอย่างเช่น</p><h4><strong>ตัวอย่างที่ 1: IaaS + PaaS</strong></h4><p>ปล่อยให้ deploy app ของเราได้โดยไม่ต้องยุ่งกับ server เลย แต่สามารถปรับแต่ server config ได้นิดหน่อย</p><h4><strong>ตัวอย่างที่ 2: Saas + PaaS + IaaS</strong></h4><p>ตัวอย่างจากรูปข้างล่าง Software Dashboard ที่เราใช้งาน ต่อเข้ากับ PaaS ที่เป็น EKS (Elastic Kubernetes Service) โดยมี Virtual Server อยู่หลังบ้าน ซึ่ง อย่างที่เราทราบกันอยู่แล้ว ใน AWS เวลาเราจะใช้สัก service ที่มันต้อง depend กับ service อื่น เราสามารถหาได้ว่ามันไป setup ตัว service ข้างใต้ที่ไหน และเราสามารถปรับแต่งตัวข้างใต้ได้ด้วย</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/747/1*_uyMMeukF7YNeqtRUO3FBA.png" /><figcaption>Jumpbox Slide</figcaption></figure><h4>Checkpoint #2</h4><ul><li>Cloud Delivery Models ประกอบไปด้วยอะไรบ้าง</li><li>IaaS คืออะไร</li><li>PaaS คืออะไร</li><li>SaaS คืออะไร</li><li>Sub Models คืออะไร มีความเกี่ยวข้องกับ IaaS, PaaS, SaaS อย่างไร</li><li>ให้คิด Product และทำการวาดภาพให้ออกมาในรูปแบบ Combining Cloud Delivery Models: IaaS, PaaS, SaaS</li></ul><h4>Cloud Deployment Models</h4><ul><li><strong>Public Cloud</strong> — ผู้ในบริการ Cloud สาธารณะ เช่น AWS, Azure, Google Cloud, AKUITY (ให้บริการ ARGO CD), Atlas (ให้บริการ MongoDB) หรือ Redis เป็นต้น</li><li><strong>Private Cloud</strong> — On-Premise (ที่ไม่เรียก cloud เพราะว่าบางอย่างอาจจะไม่ได้คุณสมบัติของ cloud) or owned by a single organization</li><li><strong>Multi-Cloud</strong> — คือ User เจ้าเดียว ไปใช้ cloud provider หลายเจ้าพร้อมๆ กัน เช่น ใช้ AWS (Amazon Web Service) + GCP (Google Cloud Platform)</li><li><strong>Hybrid Cloud</strong> — ใช้ Private + Public Cloud พร้อมๆ กันเพื่อทำงานเฉพาะ เช่น ข้อมูลเก็บในรัฐบาลที่ข้อมูลบางส่วนเก็บต้องในประเทศเท่านั้นใน Private Cloud แต่ตัว application ไปใช้ Public Cloud อย่างนี้</li></ul><p>จริงๆ ครึ่งหลังมีเรื่อง Basic Linux Foundamental แต่เนื่องจากเป็นเรื่องที่ผมรู้อยู่แล้ว และอยากให้บทความไม่ยืดยาวเกินไป เลยของโฟกัสในเรื่อง Cloud Native Concept ก็พอ</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=40caa6cccda7" width="1" height="1" alt=""><hr><p><a href="https://giver.in.th/%E0%B8%AA%E0%B8%A3%E0%B8%B8%E0%B8%9B-the-cloud-camp-2024-audition-round-2-day-1-3-40caa6cccda7">[สรุป] The Cloud Camp 2024 — Audition Round 2 (Day 1/ 3)</a> was originally published in <a href="https://giver.in.th/">GiVeR</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[Solved] DNS-Error 1000 on connecting `medium.com` custom domain with Cloudflare]]></title>
            <link>https://giver.in.th/solved-dns-error-1000-on-connecting-medium-com-custom-domain-with-cloudflare-ccc31d1e6e72?source=rss-150824165a6------2</link>
            <guid isPermaLink="false">https://medium.com/p/ccc31d1e6e72</guid>
            <category><![CDATA[domains]]></category>
            <category><![CDATA[cloudflare]]></category>
            <category><![CDATA[medium]]></category>
            <dc:creator><![CDATA[Tanin Srivaraphong]]></dc:creator>
            <pubDate>Wed, 13 Mar 2024 07:49:41 GMT</pubDate>
            <atom:updated>2024-03-14T15:47:37.796Z</atom:updated>
            <content:encoded><![CDATA[<h3>[Solved] DNS-Error 1000 on connecting “medium.com” custom domain with Cloudflare</h3><h3>Step by Step</h3><ul><li><strong>On Cloudflare</strong>, make sure you configure your Cloudflare DNS to point to the right domain, as shown in the picture</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EEupPoo_SJKz25OvQF0y_g.png" /><figcaption>Cloudflare DNS Records</figcaption></figure><ul><li><strong>On Medium.com</strong>, please follow the <a href="https://help.medium.com/hc/en-us/articles/115003053487-Setting-up-a-custom-domain-for-your-profile-or-publication">support page</a> to get the correct IP addresses (as shown in the picture below)</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Nn8IDAZL7r1z-lmZO6dTrg.png" /><figcaption>Medium.com Settings Page</figcaption></figure><blockquote>If custom domain in Medium.com had already linked then we need to unlink and link it again after we done Cloudflare step properly</blockquote><ul><li>Done. Happy writer :)</li></ul><h3>TL;DR</h3><p>Actually, this solution is not originally mine, but I searched around the internet and saw people asking the same question again and again then I can conclude on the exact step to make it work on the custom domain in medium.com (paid user) specially for me.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ccc31d1e6e72" width="1" height="1" alt=""><hr><p><a href="https://giver.in.th/solved-dns-error-1000-on-connecting-medium-com-custom-domain-with-cloudflare-ccc31d1e6e72">[Solved] DNS-Error 1000 on connecting `medium.com` custom domain with Cloudflare</a> was originally published in <a href="https://giver.in.th/">GiVeR</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Typescript: Find The Different Between 2 Types of Properties]]></title>
            <link>https://zrevig.medium.com/typescript-find-the-different-between-2-types-of-properties-2e6e021c8ba0?source=rss-150824165a6------2</link>
            <guid isPermaLink="false">https://medium.com/p/2e6e021c8ba0</guid>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[react]]></category>
            <dc:creator><![CDATA[Tanin Srivaraphong]]></dc:creator>
            <pubDate>Tue, 06 Jun 2023 04:12:29 GMT</pubDate>
            <atom:updated>2023-06-06T04:24:20.372Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*PJVpBLoALbjScatb" /><figcaption>Photo by <a href="https://unsplash.com/ko/@flowforfrank?utm_source=medium&amp;utm_medium=referral">Ferenc Almasi</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>When we work on Typescript, especially when we work with React. Most of the time, it’s easy to get confused about which one to use to cover all the needed properties.</p><p>In my use case, I want to extend my custom link components from &lt;a&gt; attributes.</p><pre>interface ComponentProps1 extends React.DetailedHTMLProps&lt;React.HTMLAttributes&lt;HTMLAnchorElement&gt;, HTMLAnchorElement&gt; {}<br><br>interface ComponentProps2 extends React.HTMLAttributes&lt;HTMLAnchorElement&gt; {}<br><br>type Dif = Omit&lt;ComponentProps1, keyof ComponentProps2&gt;;<br>type Dif2 = Omit&lt;React.ComponentPropsWithRef&lt;&#39;a&#39;&gt;, keyof React.AnchorHTMLAttributes&lt;HTMLAnchorElement&gt;&gt;;</pre><p>If we mouse over the Dif or Dif2 in IDE (e.g. VSCode), we might see the difference between both props.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/483/1*4Pq5vWCR_LWxPZ31KT-V7w.png" /></figure><p><strong>Ref:</strong> <a href="https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgMIHsC2AHdILgAKU62AzgIzIQAekIAJmcgEoSJgB0AIhGHMAA2EBgAkAKgFkAMsVJkAPGw6cJMgIJgwUYACMArpEVrp6kAgAW6KAFFhmAmAB8AGmQmzl63YgPwT5ABvAF8AKFDQSFhEFAwcPEc5cgAmajoCJlZ2BC4PLR0DIwUPcytbe0cAkPCwAE9sFG5gGGQAXmQAeUxgMAU43HwiEnIKNwBrCFr0Fv6EoflkpwBuGvrG5tT2rp6lbK5ZwbAksgB1Hos2GAUAcjhr12QJqZblHM5PMrztPUMIYylTKVvBV-MsIuBoPAkMh1DlgHg4LphNJQGNjml6JkmjBUiEgA">Try it on Typescript Playground</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2e6e021c8ba0" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[Fixed] MacOS Universal Clipboard is not working (Monterey)]]></title>
            <link>https://zrevig.medium.com/fixed-macos-universal-clipboard-is-not-working-monterey-733db347ca2e?source=rss-150824165a6------2</link>
            <guid isPermaLink="false">https://medium.com/p/733db347ca2e</guid>
            <category><![CDATA[macos]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[apple]]></category>
            <dc:creator><![CDATA[Tanin Srivaraphong]]></dc:creator>
            <pubDate>Sat, 30 Apr 2022 04:50:18 GMT</pubDate>
            <atom:updated>2024-03-14T15:48:27.373Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*rSghowcuV0xur47h" /><figcaption>Photo by <a href="https://unsplash.com/@goian?utm_source=medium&amp;utm_medium=referral">Ian Schneider</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h3>TL; DR</h3><ul><li><strong>❌ NOT SAFE </strong>for non-geek user</li><li>❌ NOT ALWAYS WORKING</li><li>Make sure you’re logged in to your ✅ <strong>same iCloud account</strong> on every single device that needs to use the Universal Clipboard feature</li><li>Go to <strong>Terminal</strong>, and type the following command</li><li><em>(Optional)</em> To <strong>delete</strong> existing.</li></ul><pre>defaults delete ~/Library/Preferences/com.apple.coreservices.useractivityd.plist ClipboardSharingEnabled</pre><ul><li>✅ To <strong>enable</strong> clipboard sharing features</li></ul><pre>defaults write ~/Library/Preferences/com.apple.coreservices.useractivityd.plist ClipboardSharingEnabled 1</pre><p>5. Done. Enjoy</p><p>Long story that I have to spend a lot of time investigating the problem by doing the several user troubleshooting ways to solve this problem</p><h3>Option #1</h3><ul><li>Using the same iCloud account on every device</li><li>Restart Macs</li><li>Restart iOS devices</li><li>Turn on/off Bluetooth</li><li>Turn on/off Wifi</li><li>Disable and Enable the handoff feature on both macOS and iOS devices</li><li>etc.</li></ul><p>Above item, I did it already but never thrived. So I’m trying to figure out the most geek way to enable this feature.</p><p>Thx to one of the community contributions from the following thread</p><blockquote><a href="https://discussions.apple.com/thread/253274114">https://discussions.apple.com/thread/253274114</a></blockquote><p>😘 Thanks, <a href="https://discussions.apple.com/profile/msimpson81">msimpson81</a> that giving the geek way to solve this issue.</p><p>Final Output of com.apple.coreservices.useractivityd.plist file.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NRZOz_Q_nI5ahB7DaQ_JIQ.png" /><figcaption>No need to be the same as mine</figcaption></figure><h3>Option #2</h3><p>Most of the case I do not really need this to make it works</p><blockquote>Ref: <a href="https://forums.macrumors.com/threads/universal-clipboard-not-working-mac-iphone-iphone-mac.2231304/?post=28871143#post-28871143">https://forums.macrumors.com/threads/universal-clipboard-not-working-mac-iphone-iphone-mac.2231304/?post=28871143#post-28871143</a></blockquote><ol><li><strong>Disable Handoff</strong> in System Prefs</li><li><strong>Terminal</strong>: <br>rm ~/Library/Preferences/com.apple.coreservices.useractivityd.plist</li><li><strong>Keychain Access</strong> -&gt; delete “handoff-own-encryption-key” (this is the local device’s handoff key)</li><li>Restart in<strong> Safe Mode</strong></li><li>System Prefs -&gt; <strong>Enable Handoff</strong>.</li><li>Reboot.</li><li>Universal Clipboard working correctly!</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9fk-zEwtP974fjVUdMfJww@2x.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=733db347ca2e" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>