<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Beaver Bridge</title>
    <description>The latest articles on Forem by Beaver Bridge (@__aa3e4bc832ba7032bfa3).</description>
    <link>https://forem.com/__aa3e4bc832ba7032bfa3</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%2F1110704%2F787da751-eb46-4255-8785-ec0707a9ba7e.png</url>
      <title>Forem: Beaver Bridge</title>
      <link>https://forem.com/__aa3e4bc832ba7032bfa3</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/__aa3e4bc832ba7032bfa3"/>
    <language>en</language>
    <item>
      <title>macOS에서 울트라 와이드 모니터 사용시 원하는 해상도를 고해상도(HiDPI) 로 사용하기</title>
      <dc:creator>Beaver Bridge</dc:creator>
      <pubDate>Sat, 12 Jul 2025 04:53:00 +0000</pubDate>
      <link>https://forem.com/__aa3e4bc832ba7032bfa3/macoseseo-ulteura-waideu-moniteo-sayongsi-weonhaneun-haesangdoreul-gohaesangdohidpi-ro-sayonghagi-3303</link>
      <guid>https://forem.com/__aa3e4bc832ba7032bfa3/macoseseo-ulteura-waideu-moniteo-sayongsi-weonhaneun-haesangdoreul-gohaesangdohidpi-ro-sayonghagi-3303</guid>
      <description>&lt;p&gt;울트라 와이드 모니터에 연결하면 선택할 수 있는 해상도는 많은데 옆에 &lt;code&gt;(저해상도)&lt;/code&gt; 라고 붙어있어서, 선택하면 글자가 흐릿하게 보이는 증상이 반드시 발생한다. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fm2npq8qvql5zemlpv7ic.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fm2npq8qvql5zemlpv7ic.png" alt=" " width="338" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;지금 사용하는 모니터는 크로스오버 40LGD5K인데 최대 해상도가 5120*2160이고, 내가 사용할 해상도는 3840*1620인데, 맥북에어에 연결했을 때 나오는 HiDPI 해상도는 5120*2160 다음이 3008*1269다.&lt;br&gt;
그래서 강제로 3840*1620을 고해상도로 만드는 작업이 필요하다.&lt;/p&gt;
&lt;h1&gt;
  
  
  방법1. OneKeyHiDPI 사용
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/xzhih/one-key-hidpi" rel="noopener noreferrer"&gt;https://github.com/xzhih/one-key-hidpi&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;bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/xzhih/one-key-hidpi/master/hidpi.sh&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;그러면 &lt;code&gt;/Library/Displays/Contents/Resources/Overrides&lt;/code&gt; 나 &lt;code&gt;~/Library/Displays/Contents/Resources/Overrides&lt;/code&gt; 에 제조사와 모델을 이용한 폴더가 만들어지고, 그 안에는 이런 식으로 해상도가 지정된다.&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="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;plist&lt;/span&gt; &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;"1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;DisplayProductID&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;integer&amp;gt;&lt;/span&gt;16384&lt;span class="nt"&gt;&amp;lt;/integer&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;DisplayVendorID&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;integer&amp;gt;&lt;/span&gt;8973&lt;span class="nt"&gt;&amp;lt;/integer&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;scale-resolutions&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;array&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAAeAAAADKgAAAAB&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAAeAAAADKgAAAABACAAAA==&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAAKoAAABfoAAAABACAAAA==&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAAKAAAABkAAAAABACAAAA==&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAAKAAAABaAAAAABACAAAA==&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAAHgAAABLAAAAABACAAAA==&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAAHgAAABDgAAAABACAAAA==&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAAFAAAAAtAAAAABACAAAA==&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAAGkAAAA7AAAAAB&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAAGQAAAA4QAAAAB&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAAFoAAAAyoAAAAB&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAAFAAAAAtAAAAAB&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAAEgAAAAogAAAAB&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAAEAAAAAkAAAAAB&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAADSAAAAdQAAAAB&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAADIAAAAcIAAAAB&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAACgAAAAWgAAAAB&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAANIAAAB2IAAAAJAKAAAA==&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAALQAAABlQAAAAJAKAAAA==&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAAKAAAABaAAAAAJAKAAAA==&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAAIAAAABIAAAAAJAKAAAA==&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAAHgAAABDgAAAAJAKAAAA==&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAAGkAAAA7AAAAAJAKAAAA==&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAAGQAAAA4QAAAAJAKAAAA==&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&amp;gt;&lt;/span&gt;AAAFAAAAAtAAAAAJAKAAAA==&lt;span class="nt"&gt;&amp;lt;/data&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/array&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;target-default-ppmm&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;real&amp;gt;&lt;/span&gt;10.0699301&lt;span class="nt"&gt;&amp;lt;/real&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plist&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;이거로 성공한다면 지정한 해상도가 고해상도로 바뀌어서 선택하고 사용하면 된다. &lt;/p&gt;

&lt;h1&gt;
  
  
  방법 2. BetterDisplay 사용
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/waydabber/BetterDisplay" rel="noopener noreferrer"&gt;https://github.com/waydabber/BetterDisplay&lt;/a&gt; 를 사용하는 방법이 있다. brew로 설치할 수도 있고, 무료모드로도 충분하다. 이 방법은 가상 디스플레이를 만들고 원래 모니터에서 가상 디스플레이로 미러링을 하는 방식이라 CPU가 조금 더 사용된다는 단점이 있다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--cask&lt;/span&gt; betterdisplay
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;프로그램을 설치하고 가상화면을 생성한다. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F5piov6gf9gr9uziqzlt2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F5piov6gf9gr9uziqzlt2.png" alt=" " width="696" height="1694"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fmlo36xv8vhjowyoin5cz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fmlo36xv8vhjowyoin5cz.png" alt=" " width="800" height="617"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;시스템 환경설정 -&amp;gt; 디스플레이로 이동해서 아래와 같이 설정한다.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;맥북 디스플레이: 확장 디스플레이&lt;/li&gt;
&lt;li&gt;가상 디스플레이: 메인 디스플레이&lt;/li&gt;
&lt;li&gt;울트라 와이드 모니터: 가상 디스플레이 미러링 + 가상 디스플레이에 최적화 &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F3l3799wco1rsetqkwjid.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F3l3799wco1rsetqkwjid.png" alt=" " width="800" height="874"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F1yfxncja129iwfoyfyc3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F1yfxncja129iwfoyfyc3.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F2k8du04v5w85mrlcgi2q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F2k8du04v5w85mrlcgi2q.png" alt=" " width="800" height="673"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;그리고 나서 가상 디스플레이에서 원하는 해상도를 선택하면 된다. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fnvsmf6q5f2cktgeeodh5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fnvsmf6q5f2cktgeeodh5.png" alt=" " width="800" height="880"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;재부팅할 때마다 자동으로 실행되도록 설정해준다. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fjl9tiebvjdiygq9cqdwl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fjl9tiebvjdiygq9cqdwl.png" alt=" " width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;디스플레이 정렬에 들어갔을 때 이렇게 나오면 된다. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F69uve1lp4j2bbhms861q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F69uve1lp4j2bbhms861q.png" alt=" " width="800" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>onekeyhidpi</category>
      <category>betterdisplay</category>
      <category>ultrawidemonitor</category>
    </item>
    <item>
      <title>개발용 샘플 이미지</title>
      <dc:creator>Beaver Bridge</dc:creator>
      <pubDate>Mon, 30 Jun 2025 06:39:05 +0000</pubDate>
      <link>https://forem.com/__aa3e4bc832ba7032bfa3/gaebalyong-saempeul-imiji-3d39</link>
      <guid>https://forem.com/__aa3e4bc832ba7032bfa3/gaebalyong-saempeul-imiji-3d39</guid>
      <description>&lt;p&gt;&lt;a href="https://mond-al.github.io/test-image-zip" rel="noopener noreferrer"&gt;https://mond-al.github.io/test-image-zip&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;용량도 작고, 다른 이미지와 구별하기 쉽게 숫자가 적혀있어서 개발용으로 좋다 &lt;/p&gt;

</description>
      <category>software</category>
      <category>resources</category>
      <category>productivity</category>
    </item>
    <item>
      <title>비밀번호 입력 없이 ssh로 서버 접속</title>
      <dc:creator>Beaver Bridge</dc:creator>
      <pubDate>Thu, 12 Jun 2025 04:16:47 +0000</pubDate>
      <link>https://forem.com/__aa3e4bc832ba7032bfa3/bimilbeonho-ibryeog-eobsi-sshro-seobeo-jeobsog-log</link>
      <guid>https://forem.com/__aa3e4bc832ba7032bfa3/bimilbeonho-ibryeog-eobsi-sshro-seobeo-jeobsog-log</guid>
      <description>&lt;h1&gt;
  
  
  ~/.ssh/id_rsa 파일이 없을 때
&lt;/h1&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; ~/.ssh

ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; rsa &lt;span class="nt"&gt;-b&lt;/span&gt; 4096 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"my_name.home"&lt;/span&gt;
Enter file &lt;span class="k"&gt;in &lt;/span&gt;which to save the key &lt;span class="o"&gt;(&lt;/span&gt;/Users/mac/.ssh/id_rsa&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="c"&gt;# 비워두기. 그냥 Enter 치기&lt;/span&gt;
Enter passphrase &lt;span class="o"&gt;(&lt;/span&gt;empty &lt;span class="k"&gt;for &lt;/span&gt;no passphrase&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="c"&gt;# 비워두기. 그냥 Enter 치기&lt;/span&gt;
Enter same passphrase again: &lt;span class="c"&gt;# 비워두기. 그냥 Enter 치기&lt;/span&gt;

&lt;span class="c"&gt;# remote의 ~/.ssh/authorized_keys에 저장(초기 설정인 경우, 비밀번호 입력해야할 수 있음)&lt;/span&gt;
ssh-copy-id &lt;span class="nt"&gt;-i&lt;/span&gt; ~/.ssh/id_rsa.pub &lt;span class="o"&gt;[&lt;/span&gt;remote-host]
&lt;span class="c"&gt;# ssh-copy-id -i ~/.ssh/id_rsa.pub my-account@192.168.1.205 &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  새로운 ~/.ssh/id_rsa 파일을 사용하고 싶을 때
&lt;/h1&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; ~/.ssh

ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; rsa &lt;span class="nt"&gt;-b&lt;/span&gt; 4096 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"my_name.home"&lt;/span&gt;
Enter file &lt;span class="k"&gt;in &lt;/span&gt;which to save the key &lt;span class="o"&gt;(&lt;/span&gt;/Users/mac/.ssh/id_rsa&lt;span class="o"&gt;)&lt;/span&gt;: ./id_rsa_qa_rocky
Enter passphrase &lt;span class="o"&gt;(&lt;/span&gt;empty &lt;span class="k"&gt;for &lt;/span&gt;no passphrase&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="c"&gt;# 비워두기. 그냥 Enter 치기&lt;/span&gt;
Enter same passphrase again: &lt;span class="c"&gt;# 비워두기. 그냥 Enter 치기&lt;/span&gt;

&lt;span class="c"&gt;# remote의 ~/.ssh/authorized_keys에 저장(초기 설정인 경우, 비밀번호 입력해야할 수 있음)&lt;/span&gt;
ssh-copy-id &lt;span class="nt"&gt;-i&lt;/span&gt; ~/.ssh/id_rsa_qa_rocky.pub &lt;span class="o"&gt;[&lt;/span&gt;remote-host]
&lt;span class="c"&gt;# ssh-copy-id -i ~/.ssh/id_rsa.pub my-account@192.168.1.205&lt;/span&gt;

&lt;span class="c"&gt;# ./ssh/config 에 지정&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  .ssh/config 에 새로 만든 id_rsa 파일 지정
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;host qa_rocky
    user my_account
    identityfile ~/.ssh/id_rsa_qa_rocky
    &lt;span class="nb"&gt;hostname &lt;/span&gt;192.168.1.205
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  접속하기
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh qa_rocky
&lt;span class="c"&gt;# ssh my-account@192.168.1.205 로 접속하면 비밀번호 물어봄&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Docker + MariaDB 에서 ERROR: (conn:4, no: 45009, SQLState: 08S01) socket has unexpectedly been closed</title>
      <dc:creator>Beaver Bridge</dc:creator>
      <pubDate>Tue, 05 Nov 2024 06:49:35 +0000</pubDate>
      <link>https://forem.com/__aa3e4bc832ba7032bfa3/docker-mariadb-eseo-error-conn4-no-45009-sqlstate-08s01-socket-has-unexpectedly-been-closed-2ln3</link>
      <guid>https://forem.com/__aa3e4bc832ba7032bfa3/docker-mariadb-eseo-error-conn4-no-45009-sqlstate-08s01-socket-has-unexpectedly-been-closed-2ln3</guid>
      <description>&lt;p&gt;OS: macOS 15.1&lt;br&gt;
Docker desktop: 4.35.1&lt;br&gt;
MariaDB: lts-noble&lt;/p&gt;

&lt;p&gt;sequelize로 마이그레이션을 하려했더니 이런 에러가 발생한다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ERROR: (conn:4, no: 45009, SQLState: 08S01) socket has unexpectedly been closed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;검색해봐도 원인을 못 찾았는데, 혹시나 Docker Desktop 4.35부터인가 들어온 Virtual Machine Options - Docker VMM 이 문제인가 싶어서 Apple Virtualization framework로 바꿔보니 이상없이 잘 된다. &lt;/p&gt;

</description>
      <category>docker</category>
      <category>mariadb</category>
      <category>sequelize</category>
    </item>
    <item>
      <title>Sveltekit + TypeScript + TypeORM + ESM</title>
      <dc:creator>Beaver Bridge</dc:creator>
      <pubDate>Mon, 21 Oct 2024 12:53:00 +0000</pubDate>
      <link>https://forem.com/__aa3e4bc832ba7032bfa3/sveltekit-typescript-typeorm-esmodule-40f</link>
      <guid>https://forem.com/__aa3e4bc832ba7032bfa3/sveltekit-typescript-typeorm-esmodule-40f</guid>
      <description>&lt;h2&gt;
  
  
  SvelteKit Project 생성
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm create svelte@latest test1
&lt;span class="c"&gt;# Skeleton project&lt;/span&gt;
&lt;span class="c"&gt;# using TypeScript&lt;/span&gt;
&lt;span class="c"&gt;# check ESLint, Prettier, Playwright, Vitest&lt;/span&gt;

&lt;span class="nb"&gt;cd &lt;/span&gt;test1 

bun i
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  TypeORM 설정
&lt;/h2&gt;

&lt;p&gt;참조: &lt;a href="https://typeorm.io/#installation" rel="noopener noreferrer"&gt;https://typeorm.io/#installation&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;bun add typeorm reflect-metadata pg

bun add @types/node tsx &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;tsconfig.json&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"emitDecoratorMetadata"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"experimentalDecorators"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;package.json&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"typeorm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsx ./node_modules/typeorm/cli.js --dataSource src/lib/typeorm/config.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"migration:create"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsx ./node_modules/typeorm/cli.js migration:create src/lib/typeorm/migrations/Migration"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"migration:generate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run typeorm migration:generate src/lib/typeorm/migrations/Migration"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"migration:run"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run typeorm migration:run"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;src/lib/typeorm/config.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DataSource&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;typeorm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AppDataSource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DataSource&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;postgres&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;localhost&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5432&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;postgres&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;default_password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;postgres&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;synchronize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;entities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/lib/typeorm/entity/*.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;subscribers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="na"&gt;migrations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/lib/typeorm/migrations/*.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  테스트
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run migration:create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;이렇게하니 TypeORM 에서 migration이나 CRUD에서 &lt;code&gt;Unknown file extension ".ts"&lt;/code&gt; 가 발생한다. &lt;/p&gt;

&lt;p&gt;아무리 찾아봐도 해답은 없는 것 같고, 이렇게 하는게 최선인 것 같다. &lt;/p&gt;

&lt;p&gt;src/lib/typeorm/config.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./entity/User&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Company&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./entity/Company&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nx"&gt;entities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Company&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="nx"&gt;migrations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dist/lib/typeorm/migrations/*.{ts, js}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;결국은 해결하지 못했다. 다른 Prisma, Sequelize, MikroORM, DrizzleORM 을 모두 확인해봤지만, TypeORM만큼 마이그레이션용으로 괜찮은 건 없는 것 같고(그나마 MikroORM이 가장 근접했다), 결국 마이그레이션은 TypeORM으로, 그후에 Drizzle의 &lt;code&gt;db:pull&lt;/code&gt;로 가져온 후 CRUD는 Drizzle을 사용하기로 했다. &lt;/p&gt;




&lt;p&gt;&lt;code&gt;migrations: ['src/lib/typeorm/migrations/*.ts']&lt;/code&gt; 이 부분은 평소에는 주석처리를 해놓고 마이그레이션 할 때만 해제해서 사용하는 걸로 사용 중이다. drizzle은 제거 했다. &lt;/p&gt;




&lt;p&gt;&lt;code&gt;config.ts&lt;/code&gt;와 &lt;code&gt;config.migration.ts&lt;/code&gt; 로 나눠서, &lt;code&gt;package.json&lt;/code&gt; 넣는 정보는 마이그레이션에서만 사용하니 &lt;code&gt;config.migration.ts&lt;/code&gt; 로 등록하고, 실제 코드는 &lt;code&gt;config.ts&lt;/code&gt;  를 사용하고 있다. &lt;/p&gt;

</description>
      <category>sveltekit</category>
      <category>typescript</category>
      <category>typeorm</category>
    </item>
    <item>
      <title>아이폰 단축어에서 POST API 호출해서 텔레그램으로 인증코드 공유하기</title>
      <dc:creator>Beaver Bridge</dc:creator>
      <pubDate>Thu, 22 Aug 2024 13:35:36 +0000</pubDate>
      <link>https://forem.com/__aa3e4bc832ba7032bfa3/aipon-dancugeoeseo-post-api-hoculhaeseo-telregeuraemeuro-injeungkodeu-gongyuhagi-1hj0</link>
      <guid>https://forem.com/__aa3e4bc832ba7032bfa3/aipon-dancugeoeseo-post-api-hoculhaeseo-telregeuraemeuro-injeungkodeu-gongyuhagi-1hj0</guid>
      <description>&lt;p&gt;밤에 OTT 보려고 들어갔더니 인증을 받으라고 하는데, 대표 계정인 사람이 자고 있어서 인증코드를 볼 수 없을 때를 위함.&lt;/p&gt;

&lt;h2&gt;
  
  
  준비
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;인증코드를 보내는 전화번호를 연락처에 등록한다. 그래야 보낸 사람 선택할 때 편하다.(넷플릭스는 번호가 달라지는건지, 그냥 내용에 &lt;code&gt;넷플릭스&lt;/code&gt;가 있으면 보내게 변경했다)&lt;/li&gt;
&lt;li&gt;텔레그램에 가입한다.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  텔레그램 봇
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;텔레그램 BotFather(&lt;a href="https://t.me/BotFather" rel="noopener noreferrer"&gt;https://t.me/BotFather&lt;/a&gt;) 에서 봇을 만들어야 한다. POST API를 전송하는 봇이다.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/newbot&lt;/code&gt; 을 입력하면 봇의 이름을 입력하라고 나오고, 이름을 입력하면 토큰을 알려준다.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  텔레그램 채널
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;공개&lt;/code&gt; 채널을 만든다. 채널의 고유id를 쉽게 알기위해 공개로 만들어야 한다. 채널 링크에 사용될 이름을 적당히 넣으면 된다.&lt;/li&gt;
&lt;li&gt;채널의 관리자로 위에서 만든 봇을 관리자로 추가한다. 메시지 전송 권한은 끄면 안된다.&lt;/li&gt;
&lt;li&gt;api를 호출한다. 사용하는 프로그램있으면 쓰고, 없으면 &lt;a href="https://reqbin.com" rel="noopener noreferrer"&gt;https://reqbin.com&lt;/a&gt; 이런 거 사용한다. 
url은 &lt;code&gt;https://api.telegram.org/bot토큰/sendMessage?text=내용&amp;amp;chat_id=@봇이름&lt;/code&gt; 이다. 실제로는 &lt;code&gt;https://api.telegram.org/bot661928238:AEoidd_eidjab/sendMessage?text=내용&amp;amp;chat_id=@my_channel_name&lt;/code&gt; 이런 느낌이다. &lt;/li&gt;
&lt;li&gt;텔레그램 채널에 메시지가 오면 성공&lt;/li&gt;
&lt;li&gt;호출 결과를 보면 &lt;code&gt;id&lt;/code&gt; 에 &lt;code&gt;-&lt;/code&gt;가 붙은 숫자가 있는데, 이게 채널의 고유id다. 위의 url의 chat_id에 &lt;code&gt;-&lt;/code&gt;가 붙은 저 숫자를 넣으면되니 채널은 비공개로 변경한다.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  아이폰 단축어
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;단축어 앱에서 자동화 조건으로 &lt;code&gt;다음 조건으로 메시지를 받을 때: [발신자 xxxx]&lt;/code&gt; 가 되게 한다. (혹은 특정 OTT의 제목을 적어도 된다)&lt;/li&gt;
&lt;li&gt;동작에는 &lt;code&gt;메시지를 입력으로 받기&lt;/code&gt; -&amp;gt; &lt;code&gt;단축어입력을 url 인코딩&lt;/code&gt; -&amp;gt; &lt;code&gt;https://api.telegram.org/~~~~?chat_id=-28237381&amp;amp;text=URL인코딩된 텍스트&lt;/code&gt;   로 설정하고 &lt;code&gt;&amp;gt;&lt;/code&gt; 를 눌러서 메소드를 &lt;code&gt;POST&lt;/code&gt; 로 선택한다. &lt;/li&gt;
&lt;li&gt;테스트할 때는 &lt;code&gt;메시지를 입력으로 받기&lt;/code&gt; 대신에 텍스트를 직접 입력하고 수동으로 실행하면 편하다. &lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>iphone</category>
      <category>telegram</category>
      <category>restapi</category>
    </item>
    <item>
      <title>docker에서 supabase self-hosting으로 사용 중 폴더 위치 변경 시 파일 다시 업로드하기</title>
      <dc:creator>Beaver Bridge</dc:creator>
      <pubDate>Tue, 13 Aug 2024 14:51:04 +0000</pubDate>
      <link>https://forem.com/__aa3e4bc832ba7032bfa3/dockereseo-supabase-self-hostingeuro-sayong-jung-poldeo-wici-byeongyeong-si-pail-dasi-eobrodeuhagi-1l0d</link>
      <guid>https://forem.com/__aa3e4bc832ba7032bfa3/dockereseo-supabase-self-hostingeuro-sayong-jung-poldeo-wici-byeongyeong-si-pail-dasi-eobrodeuhagi-1l0d</guid>
      <description>&lt;p&gt;참고 &lt;a href="https://supabase.com/docs/guides/platform/migrating-and-upgrading-projects#migrate-storage-objects" rel="noopener noreferrer"&gt;https://supabase.com/docs/guides/platform/migrating-and-upgrading-projects#migrate-storage-objects&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// storage_restore.js&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@supabase/supabase-js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PROJECT_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:8100&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PROJECT_SERVICE_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;service_role_key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;started at: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;supabaseRestClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PROJECT_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PROJECT_SERVICE_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;storage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;supabaseClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PROJECT_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PROJECT_SERVICE_KEY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// make sure you update max_rows in postgrest settings if you have a lot of objects or paginate here&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabaseRestClient&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;objects&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;//    .eq("bucket_id", "manuals");&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error getting objects from old bucket&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;objectData&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`moving &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;objectData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s2"&gt;`./storage/stub/stub/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;objectData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucket_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;objectData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;objectData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;uploadObjectError&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabaseClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;storage&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;objectData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucket_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;objectData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;upsert&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;contentType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;objectData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mimetype&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;cacheControl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;objectData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cacheControl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uploadObjectError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;uploadObjectError&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error moving &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;objectData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;finished at: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;이 파일을 supabase studio 컨테이너로 이동시킨다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;cp &lt;/span&gt;storage_restore.js container_id:/app/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;기존 폴더에서 supabase studio 컨테이너로 파일을 이동시킨다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;cp &lt;/span&gt;storage container_id:/app/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;컨테이너 안으로 진입해서 스크립트를 실행한다&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; container_id bash
&lt;span class="nb"&gt;cd &lt;/span&gt;app
node store_restore.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>supabase</category>
      <category>docker</category>
    </item>
    <item>
      <title>dockerd &amp; 실행 시 iptables not found 오류</title>
      <dc:creator>Beaver Bridge</dc:creator>
      <pubDate>Fri, 07 Jun 2024 02:01:22 +0000</pubDate>
      <link>https://forem.com/__aa3e4bc832ba7032bfa3/dockerd-silhaeng-si-iptables-not-found-oryu-2ja8</link>
      <guid>https://forem.com/__aa3e4bc832ba7032bfa3/dockerd-silhaeng-si-iptables-not-found-oryu-2ja8</guid>
      <description>&lt;p&gt;rocky linux 8.10에서&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dockerd &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;실행 시&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;failed to start daemon: Error initializing network controller: error obtaining controller instance: failed to register "bridge" driver: failed to create NAT chain DOCKER: iptables not found
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;같은 에러가 뜨면&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dockerd &lt;span class="nt"&gt;--iptables&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt; &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;로 실행하면 된다.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;근데 이러면 나중에 문제가 생기니 dnf로 iptable 관련 프로그램을 설치하는게 낫다. *&lt;/em&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>iptables</category>
    </item>
    <item>
      <title>[Sequelize + mariaDB] index 걸린 컬럼 삭제하기</title>
      <dc:creator>Beaver Bridge</dc:creator>
      <pubDate>Sun, 28 Apr 2024 04:24:14 +0000</pubDate>
      <link>https://forem.com/__aa3e4bc832ba7032bfa3/sequelize-mariadb-index-geolrin-keolreom-sagjehagi-2nf0</link>
      <guid>https://forem.com/__aa3e4bc832ba7032bfa3/sequelize-mariadb-index-geolrin-keolreom-sagjehagi-2nf0</guid>
      <description>&lt;p&gt;index가 걸린 필드를 삭제할 때 &lt;code&gt;Cannot drop index 'notices_approval_id_foreign_idx': needed in a foreign key constraint&lt;/code&gt; 에러가 뜬다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;down&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;queryInterface&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Sequelize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;queryInterface&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sequelize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ALTER TABLE notices DROP CONSTRAINT if exists notices_approval_id_foreign_idx&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;queryInterface&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sequelize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ALTER TABLE notices DROP COLUMN if exists approval_id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;원래는 &lt;a href="https://sequelize.org/api/v6/class/src/dialects/abstract/query-interface.js~queryinterface#instance-method-removeConstraint"&gt;removeConstraint&lt;/a&gt;, &lt;a href="https://sequelize.org/api/v6/class/src/dialects/abstract/query-interface.js~queryinterface#instance-method-removeColumn"&gt;removeColumn&lt;/a&gt; 을 사용해야하는데, 안돼서 쿼리를 직접 사용해야 한다.&lt;/p&gt;

</description>
      <category>sequelize</category>
      <category>mariadb</category>
    </item>
    <item>
      <title>local.properties의 값 가져오기</title>
      <dc:creator>Beaver Bridge</dc:creator>
      <pubDate>Thu, 25 Apr 2024 17:17:28 +0000</pubDate>
      <link>https://forem.com/__aa3e4bc832ba7032bfa3/localpropertiesyi-gabs-gajyeoogi-81h</link>
      <guid>https://forem.com/__aa3e4bc832ba7032bfa3/localpropertiesyi-gabs-gajyeoogi-81h</guid>
      <description>&lt;p&gt;kts 기준&lt;/p&gt;

&lt;h3&gt;
  
  
  local.properties
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"akldfjjasdfualksjdfalsdhfulaskjhd"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  app/build.gradle.kts
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.android.build.gradle.internal.cxx.configure.gradleLocalProperties&lt;/span&gt;

&lt;span class="nf"&gt;android&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;defaultConfig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;buildConfigField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"String"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"API_KEY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;readProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"API_KEY"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;readProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;  &lt;span class="nf"&gt;gradleLocalProperties&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rootDir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;getProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  사용법
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nc"&gt;BuildConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;API_KEY&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>kts</category>
      <category>android</category>
    </item>
    <item>
      <title>Sequelize의 include 안에서 order 적용하기</title>
      <dc:creator>Beaver Bridge</dc:creator>
      <pubDate>Wed, 17 Apr 2024 02:26:41 +0000</pubDate>
      <link>https://forem.com/__aa3e4bc832ba7032bfa3/sequelizeyi-include-aneseo-order-jeogyonghagi-5113</link>
      <guid>https://forem.com/__aa3e4bc832ba7032bfa3/sequelizeyi-include-aneseo-order-jeogyonghagi-5113</guid>
      <description>&lt;p&gt;팀의 사용자를 불러올 때 이렇게 했는데, 결과도 로그에 찍히는 sql에도 &lt;code&gt;order by&lt;/code&gt; 가 없다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;teams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;as&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sort_weight&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;찾아보니 이렇게 &lt;code&gt;include&lt;/code&gt; 안쪽이 아닌 같은 레벨에서 처리하는 거였다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;teams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;as&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sort_weight&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;asc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;만약 더 깊이 들어간다면, 다른 방법을 써야한다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;teams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="na"&gt;as&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;teams&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="na"&gt;as&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;child_teams&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="na"&gt;as&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sort_weight&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;asc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sequelize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;col&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;child_teams.users.sort_weight&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;asc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;이런 식으로 &lt;code&gt;sequelize.col&lt;/code&gt; 을 사용해서 컬럼에 직접 접근해서 사용해줘야 했다.&lt;/p&gt;

</description>
      <category>sequelize</category>
      <category>orderby</category>
    </item>
    <item>
      <title>nvm으로 node 버전 관리하기</title>
      <dc:creator>Beaver Bridge</dc:creator>
      <pubDate>Fri, 08 Mar 2024 11:09:53 +0000</pubDate>
      <link>https://forem.com/__aa3e4bc832ba7032bfa3/nvmeuro-node-beojeon-gwanrihagi-378k</link>
      <guid>https://forem.com/__aa3e4bc832ba7032bfa3/nvmeuro-node-beojeon-gwanrihagi-378k</guid>
      <description>&lt;p&gt;node를 brew로 설치해서 사용하고, &lt;code&gt;brew upgrade&lt;/code&gt; 를 자주 실행해서 node가 항상 최신 버전이다. 근데 개발한 프로그램이 나한테서만 로그인이 안되는 문제가 발생해서 찾아보니 내 node 버전이 너무 높은게 원인이었다.&lt;/p&gt;

&lt;p&gt;안그래도 &lt;code&gt;node 버전은 lts를 써야한다&lt;/code&gt; 라는 얘기는 들었지만, 이렇게 문제가 발생할 줄은 몰랐다. 이참에 nvm으로 갈아탄다. &lt;/p&gt;

&lt;h2&gt;
  
  
  nvm 설치
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/nvm-sh/nvm"&gt;https://github.com/nvm-sh/nvm&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="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;arch&lt;/span&gt; &lt;span class="nt"&gt;-arm64&lt;/span&gt; brew &lt;span class="nb"&gt;install &lt;/span&gt;nvm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&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;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; ~/.nvm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  .zshrc에 추가
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;NVM_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.nvm"&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"/opt/homebrew/opt/nvm/nvm.sh"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\.&lt;/span&gt; &lt;span class="s2"&gt;"/opt/homebrew/opt/nvm/nvm.sh"&lt;/span&gt;  &lt;span class="c"&gt;# This loads nvm&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\.&lt;/span&gt; &lt;span class="s2"&gt;"/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm"&lt;/span&gt;  &lt;span class="c"&gt;# This loads nvm bash_completion&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  설치가능한 목록 보기
&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;nvm list
-&amp;gt;     v18.19.1
default -&amp;gt; v18.19.1
iojs -&amp;gt; N/A &lt;span class="o"&gt;(&lt;/span&gt;default&lt;span class="o"&gt;)&lt;/span&gt;
unstable -&amp;gt; N/A &lt;span class="o"&gt;(&lt;/span&gt;default&lt;span class="o"&gt;)&lt;/span&gt;
node -&amp;gt; stable &lt;span class="o"&gt;(&lt;/span&gt;-&amp;gt; v18.19.1&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;default&lt;span class="o"&gt;)&lt;/span&gt;
stable -&amp;gt; 18.19 &lt;span class="o"&gt;(&lt;/span&gt;-&amp;gt; v18.19.1&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;default&lt;span class="o"&gt;)&lt;/span&gt;
lts/&lt;span class="k"&gt;*&lt;/span&gt; -&amp;gt; lts/iron &lt;span class="o"&gt;(&lt;/span&gt;-&amp;gt; N/A&lt;span class="o"&gt;)&lt;/span&gt;
lts/argon -&amp;gt; v4.9.1 &lt;span class="o"&gt;(&lt;/span&gt;-&amp;gt; N/A&lt;span class="o"&gt;)&lt;/span&gt;
lts/boron -&amp;gt; v6.17.1 &lt;span class="o"&gt;(&lt;/span&gt;-&amp;gt; N/A&lt;span class="o"&gt;)&lt;/span&gt;
lts/carbon -&amp;gt; v8.17.0 &lt;span class="o"&gt;(&lt;/span&gt;-&amp;gt; N/A&lt;span class="o"&gt;)&lt;/span&gt;
lts/dubnium -&amp;gt; v10.24.1 &lt;span class="o"&gt;(&lt;/span&gt;-&amp;gt; N/A&lt;span class="o"&gt;)&lt;/span&gt;
lts/erbium -&amp;gt; v12.22.12 &lt;span class="o"&gt;(&lt;/span&gt;-&amp;gt; N/A&lt;span class="o"&gt;)&lt;/span&gt;
lts/fermium -&amp;gt; v14.21.3 &lt;span class="o"&gt;(&lt;/span&gt;-&amp;gt; N/A&lt;span class="o"&gt;)&lt;/span&gt;
lts/gallium -&amp;gt; v16.20.2 &lt;span class="o"&gt;(&lt;/span&gt;-&amp;gt; N/A&lt;span class="o"&gt;)&lt;/span&gt;
lts/hydrogen -&amp;gt; v18.19.1
lts/iron -&amp;gt; v20.11.1 &lt;span class="o"&gt;(&lt;/span&gt;-&amp;gt; N/A&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  node 설치
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/nvm-sh/nvm?tab=readme-ov-file#long-term-support"&gt;https://github.com/nvm-sh/nvm?tab=readme-ov-file#long-term-support&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="nv"&gt;$ &lt;/span&gt;nvm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--lts&lt;/span&gt; &lt;span class="c"&gt;# or nvm install v20.11.1&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;nvm use &lt;span class="nt"&gt;--lts&lt;/span&gt; &lt;span class="c"&gt;# or nvm use v20.11.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  기본 버전 지정
&lt;/h2&gt;

&lt;p&gt;이걸 안하면 터미널이 새로 실행되면 &lt;code&gt;node -v&lt;/code&gt; 를 해도 &lt;code&gt;command not found&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;$ &lt;/span&gt;nvm &lt;span class="nb"&gt;alias &lt;/span&gt;default node &lt;span class="c"&gt;# or nvm alias default 20.11.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>nvm</category>
      <category>node</category>
    </item>
  </channel>
</rss>
