<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>차근차근</title>
    <link>https://normal-operating.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Thu, 25 Jun 2026 02:15:02 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Anything Doing OK</managingEditor>
    <item>
      <title>Ai 영상 어떻게 만드는 거야? Ai 영상 무료로 만들기 가이드(feat. 일론 머스크)</title>
      <link>https://normal-operating.tistory.com/51</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;요즘 유투브나 인스타 릴스 등에 ai 영상이 많이 올라온다. 이런 영상 어떻게 만드는 거야??&lt;/h4&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;클릭 10번안에 만드는 ai 영상 가이드 시작합니다!&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;891&quot; data-origin-height=&quot;551&quot;&gt;&lt;a href=&quot;https://grok.com/&quot; target=&quot;_blank&quot; title=&quot;https://grok.com/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZAUuI/dJMb87trSmA/89CsL8vhU2OXFsZOmWVoCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZAUuI%2FdJMb87trSmA%2F89CsL8vhU2OXFsZOmWVoCk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;537&quot; height=&quot;332&quot; data-origin-width=&quot;891&quot; data-origin-height=&quot;551&quot;/&gt;&lt;/a&gt;&lt;figcaption&gt;https://grok.com/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://grok.com/&quot;&gt;https://grok.com/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;으로 들어가줍니다. 이상한 사이트 아니고 Tesla 의 일론 머스크가 만든 사이트이니 괜찮습니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;들어가서 가입해줍니다. 간단한 이메일로 가입!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;787&quot; data-origin-height=&quot;435&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RZTGL/dJMb9WZJWti/i3WklfEB5AGbIp22zilweK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RZTGL/dJMb9WZJWti/i3WklfEB5AGbIp22zilweK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RZTGL/dJMb9WZJWti/i3WklfEB5AGbIp22zilweK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRZTGL%2FdJMb9WZJWti%2Fi3WklfEB5AGbIp22zilweK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;481&quot; height=&quot;266&quot; data-origin-width=&quot;787&quot; data-origin-height=&quot;435&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왼쪽의 상상 클릭! 클릭하면 여러 이미지가 나옵니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;430&quot; data-origin-height=&quot;70&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dLRw5o/dJMb9NPlBDq/DvdEnDyjxJXRAi2kujwZZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dLRw5o/dJMb9NPlBDq/DvdEnDyjxJXRAi2kujwZZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dLRw5o/dJMb9NPlBDq/DvdEnDyjxJXRAi2kujwZZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdLRw5o%2FdJMb9NPlBDq%2FDvdEnDyjxJXRAi2kujwZZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;430&quot; height=&quot;70&quot; data-origin-width=&quot;430&quot; data-origin-height=&quot;70&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하단의 입력창에 자신이 원하는 이미지 입력해주세요! 아니면 옆의 클립을 클릭해서 파일 업로드도 가능합니다.&lt;br /&gt;이미지를 한번 업로드 해볼까요?&amp;nbsp;&lt;br /&gt;이미지를 업로드 하자마자&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;452&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p6mQF/dJMb8XYFB1x/dVVmPpJXRwT8oEsYkXycO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p6mQF/dJMb8XYFB1x/dVVmPpJXRwT8oEsYkXycO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p6mQF/dJMb8XYFB1x/dVVmPpJXRwT8oEsYkXycO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp6mQF%2FdJMb8XYFB1x%2FdVVmPpJXRwT8oEsYkXycO0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;576&quot; height=&quot;452&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;452&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 동영상을 만들어주네요!&amp;nbsp;&lt;br /&gt;동영상을&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;182&quot; data-origin-height=&quot;66&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzP5xs/dJMb9P7sVit/OEkEvTj4FKk3UhjVYudp4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzP5xs/dJMb9P7sVit/OEkEvTj4FKk3UhjVYudp4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzP5xs/dJMb9P7sVit/OEkEvTj4FKk3UhjVYudp4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzP5xs%2FdJMb9P7sVit%2FOEkEvTj4FKk3UhjVYudp4K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;182&quot; height=&quot;66&quot; data-origin-width=&quot;182&quot; data-origin-height=&quot;66&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 버튼을 눌러서 다운로드해서 사용도 가능합니다!&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;생성된 영상이에요 더 재밌게 만들어볼까요??&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;607&quot; data-origin-height=&quot;407&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dD7zss/dJMb86Bi5Ic/LJBzx47sHvZ5QMGWECkB5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dD7zss/dJMb86Bi5Ic/LJBzx47sHvZ5QMGWECkB5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dD7zss/dJMb86Bi5Ic/LJBzx47sHvZ5QMGWECkB5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdD7zss%2FdJMb86Bi5Ic%2FLJBzx47sHvZ5QMGWECkB5k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;549&quot; height=&quot;368&quot; data-origin-width=&quot;607&quot; data-origin-height=&quot;407&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 입력창에 이미지와 같이 써주면~&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;더 신기한 영상도 만들 수 있으니 사용해보세요!&lt;br /&gt;모자가 귀여운 동물로 바뀌도록 변경해 &amp;lt;&amp;lt; 이런식으로 써주면~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;짜잔 생성완료!&amp;nbsp; GPT 나 Gemmin 를 따라잡기 위해서 테슬라가 열심히 하네요!&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;h3 data-ke-size=&quot;size23&quot;&gt;재밌고 무료니 다들 한번씩 사용해보세요! &lt;br /&gt;궁금한 건 댓글로 남겨주세요!&lt;/h3&gt;</description>
      <category>취미/프로그래밍</category>
      <category>ai 영상만들기</category>
      <author>Anything Doing OK</author>
      <guid isPermaLink="true">https://normal-operating.tistory.com/51</guid>
      <comments>https://normal-operating.tistory.com/51#entry51comment</comments>
      <pubDate>Mon, 10 Nov 2025 11:29:20 +0900</pubDate>
    </item>
    <item>
      <title>무료로 5분만에 React 배포하는 꿀팁 CI/CD 구축까지(feat.Cloudflare)</title>
      <link>https://normal-operating.tistory.com/50</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;저번 html, css, js 로 이루어진 간단한 사이트 Cloudflare Pages 로 간단하게 배포해봤습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 React 로 만들어진 웹을 배포합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;npx create-react-app my-react-app 등의 명령어로 react app 을 생성해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 코드수정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git diff 를 쳐보니 수정사항 목록이 나오네요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;555&quot; data-origin-height=&quot;330&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dcYgta/dJMb9ap9yiI/3gDVKjjtKESU70OSvg8xs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dcYgta/dJMb9ap9yiI/3gDVKjjtKESU70OSvg8xs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dcYgta/dJMb9ap9yiI/3gDVKjjtKESU70OSvg8xs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdcYgta%2FdJMb9ap9yiI%2F3gDVKjjtKESU70OSvg8xs0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;442&quot; height=&quot;263&quot; data-origin-width=&quot;555&quot; data-origin-height=&quot;330&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git&amp;nbsp;status &lt;br /&gt;On&amp;nbsp;branch&amp;nbsp;main &lt;br /&gt;Changes&amp;nbsp;not&amp;nbsp;staged&amp;nbsp;for&amp;nbsp;commit: &lt;br /&gt;&amp;nbsp;&amp;nbsp;(use&amp;nbsp;&quot;git&amp;nbsp;add&amp;nbsp;&amp;lt;file&amp;gt;...&quot;&amp;nbsp;to&amp;nbsp;update&amp;nbsp;what&amp;nbsp;will&amp;nbsp;be&amp;nbsp;committed) &lt;br /&gt;&amp;nbsp;&amp;nbsp;(use&amp;nbsp;&quot;git&amp;nbsp;restore&amp;nbsp;&amp;lt;file&amp;gt;...&quot;&amp;nbsp;to&amp;nbsp;discard&amp;nbsp;changes&amp;nbsp;in&amp;nbsp;working&amp;nbsp;directory) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modified:&amp;nbsp;&amp;nbsp;&amp;nbsp;src/App.js &lt;br /&gt;&lt;br /&gt;no&amp;nbsp;changes&amp;nbsp;added&amp;nbsp;to&amp;nbsp;commit&amp;nbsp;(use&amp;nbsp;&quot;git&amp;nbsp;add&quot;&amp;nbsp;and/or&amp;nbsp;&quot;git&amp;nbsp;commit&amp;nbsp;-a&quot;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 방법으로 react app 을 만드신 분들은 이미 git 으로 추적하고 있으니 다음과 같이 명령어 작성해서&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본인의 github와 연결해줍시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git&amp;nbsp;init &lt;br /&gt;git&amp;nbsp;add&amp;nbsp;. &lt;br /&gt;git&amp;nbsp;commit&amp;nbsp;-m&amp;nbsp;&quot;Initial&amp;nbsp;commit&quot; &lt;br /&gt;git&amp;nbsp;branch&amp;nbsp;-M&amp;nbsp;main &lt;br /&gt;git&amp;nbsp;remote&amp;nbsp;add&amp;nbsp;origin&amp;nbsp;https://github.com/your-username/your-repo-name.git &amp;lt;&amp;lt; 여기다가 자신의 reposiroty git&lt;br /&gt;git push -u origin main&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;으로 진행해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 Cloudflare 에 접속해서 진행&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1031&quot; data-origin-height=&quot;441&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3ZYVK/dJMb9NIx0eX/ECKm1rKziVstPp7ppTfrpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3ZYVK/dJMb9NIx0eX/ECKm1rKziVstPp7ppTfrpk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3ZYVK/dJMb9NIx0eX/ECKm1rKziVstPp7ppTfrpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3ZYVK%2FdJMb9NIx0eX%2FECKm1rKziVstPp7ppTfrpk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;654&quot; height=&quot;280&quot; data-origin-width=&quot;1031&quot; data-origin-height=&quot;441&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Account home -&amp;gt; Developer Platform -&amp;gt; + Create application&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pages -&amp;gt; Get started&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;502&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cEbj8w/dJMb9Om9shj/2Rts5XLWMIKxSwc9tXxJDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cEbj8w/dJMb9Om9shj/2Rts5XLWMIKxSwc9tXxJDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cEbj8w/dJMb9Om9shj/2Rts5XLWMIKxSwc9tXxJDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcEbj8w%2FdJMb9Om9shj%2F2Rts5XLWMIKxSwc9tXxJDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;497&quot; height=&quot;309&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;502&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자신이 만든 react repository 가 안 보일 경우 페이지 하단의 Cloudflare Pages 클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;75&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VCnwl/dJMb9OAGzel/Cy1Z10P28ubK6s8sMcJ40k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VCnwl/dJMb9OAGzel/Cy1Z10P28ubK6s8sMcJ40k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VCnwl/dJMb9OAGzel/Cy1Z10P28ubK6s8sMcJ40k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVCnwl%2FdJMb9OAGzel%2FCy1Z10P28ubK6s8sMcJ40k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;877&quot; height=&quot;75&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;75&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쭉 내려와서&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;326&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qk8Fe/dJMb862mgee/rkhmuKsKMkjtqI4jes7Ijk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qk8Fe/dJMb862mgee/rkhmuKsKMkjtqI4jes7Ijk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qk8Fe/dJMb862mgee/rkhmuKsKMkjtqI4jes7Ijk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqk8Fe%2FdJMb862mgee%2FrkhmuKsKMkjtqI4jes7Ijk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;912&quot; height=&quot;326&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;326&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Select repositories 선택해서 자신이 만든 react application 추가해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 Main 페이지로 돌아가게 되는데 동일하게 Account home -&amp;gt; Developer Platform -&amp;gt; +Create application -&amp;gt; Pages -&amp;gt; Get Started -&amp;gt; Select a repository 로 가서 만든 React application 선택후 하단의 Begin Setup 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 입력폼이 나타나는데 여기에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;798&quot; data-origin-height=&quot;737&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bh8Hal/dJMb9XRRBcx/hoAYw0OKPKulRrLMkryQTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bh8Hal/dJMb9XRRBcx/hoAYw0OKPKulRrLMkryQTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bh8Hal/dJMb9XRRBcx/hoAYw0OKPKulRrLMkryQTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbh8Hal%2FdJMb9XRRBcx%2FhoAYw0OKPKulRrLMkryQTK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;798&quot; height=&quot;737&quot; data-origin-width=&quot;798&quot; data-origin-height=&quot;737&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 입력해줍니다 Project name 은 자율 나머지 동일하게 Root directory 등 작성할 필요없습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 Save and Deploy 클릭 Framework preset 은 React 등 선택하지 마시고 None 선택해주세요.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드중 ....&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1101&quot; data-origin-height=&quot;548&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bc8ZZk/dJMb9WrSQDg/qDCjJfdPTEmLc3uf9WfZm1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bc8ZZk/dJMb9WrSQDg/qDCjJfdPTEmLc3uf9WfZm1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bc8ZZk/dJMb9WrSQDg/qDCjJfdPTEmLc3uf9WfZm1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbc8ZZk%2FdJMb9WrSQDg%2FqDCjJfdPTEmLc3uf9WfZm1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;504&quot; height=&quot;251&quot; data-origin-width=&quot;1101&quot; data-origin-height=&quot;548&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드 성공!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;990&quot; data-origin-height=&quot;276&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgQcqI/dJMb9NofjiY/n1S9MwGS0d8oCE08W1qU2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgQcqI/dJMb9NofjiY/n1S9MwGS0d8oCE08W1qU2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgQcqI/dJMb9NofjiY/n1S9MwGS0d8oCE08W1qU2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgQcqI%2FdJMb9NofjiY%2Fn1S9MwGS0d8oCE08W1qU2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;699&quot; height=&quot;195&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;990&quot; data-origin-height=&quot;276&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 도메인으로 들어가면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;817&quot; data-origin-height=&quot;627&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/x3Alo/dJMb9WrSQFa/u2fKaPaFLjphGi0dksmgB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/x3Alo/dJMb9WrSQFa/u2fKaPaFLjphGi0dksmgB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/x3Alo/dJMb9WrSQFa/u2fKaPaFLjphGi0dksmgB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fx3Alo%2FdJMb9WrSQFa%2Fu2fKaPaFLjphGi0dksmgB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;817&quot; height=&quot;627&quot; data-origin-width=&quot;817&quot; data-origin-height=&quot;627&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성공적으로 나오는 걸 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 로컬에서 작업 후 main 에 git push 만 하게되면 자동으로 적용되니 좀 더 편하게 개발할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cloudflare 등에서 이해안되는 부분이 있다면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://normal-operating.tistory.com/49&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://normal-operating.tistory.com/49&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1760601540532&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Vercel 말고 Cloudflare로 무료로 3분만에 배포하기(딸깍)&quot; data-og-description=&quot;요즘 맨날 Cloudflare 에서 사람임을 확인하세요. 뜨길래 뭐하는 데인지 싶어서 찾아보니무료 플랜이 있다. 진짜 딸깍 배포가 가능하니(CI/CD 구축 필요 X) 잘 따라와주시길... 준비물 : git / github 우선&quot; data-og-host=&quot;normal-operating.tistory.com&quot; data-og-source-url=&quot;https://normal-operating.tistory.com/49&quot; data-og-url=&quot;https://normal-operating.tistory.com/49&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cm1XSh/hyZKbO3q09/EKRYkdIia2ZxMWukPRW0L0/img.png?width=750&amp;amp;height=305&amp;amp;face=0_0_750_305,https://scrap.kakaocdn.net/dn/NvQ7f/hyZLuG4doz/pRSm5Fq1CdTqhvkophh8l1/img.png?width=750&amp;amp;height=305&amp;amp;face=0_0_750_305,https://scrap.kakaocdn.net/dn/bJmYdS/hyZLa8PGzs/HJ5YwkdAtOzd1dIKMRDDEK/img.png?width=1154&amp;amp;height=731&amp;amp;face=0_0_1154_731&quot;&gt;&lt;a href=&quot;https://normal-operating.tistory.com/49&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://normal-operating.tistory.com/49&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cm1XSh/hyZKbO3q09/EKRYkdIia2ZxMWukPRW0L0/img.png?width=750&amp;amp;height=305&amp;amp;face=0_0_750_305,https://scrap.kakaocdn.net/dn/NvQ7f/hyZLuG4doz/pRSm5Fq1CdTqhvkophh8l1/img.png?width=750&amp;amp;height=305&amp;amp;face=0_0_750_305,https://scrap.kakaocdn.net/dn/bJmYdS/hyZLa8PGzs/HJ5YwkdAtOzd1dIKMRDDEK/img.png?width=1154&amp;amp;height=731&amp;amp;face=0_0_1154_731');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Vercel 말고 Cloudflare로 무료로 3분만에 배포하기(딸깍)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;요즘 맨날 Cloudflare 에서 사람임을 확인하세요. 뜨길래 뭐하는 데인지 싶어서 찾아보니무료 플랜이 있다. 진짜 딸깍 배포가 가능하니(CI/CD 구축 필요 X) 잘 따라와주시길... 준비물 : git / github 우선&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;normal-operating.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 게시물 참고해주세요.&lt;/p&gt;</description>
      <category>취미/프로그래밍</category>
      <author>Anything Doing OK</author>
      <guid isPermaLink="true">https://normal-operating.tistory.com/50</guid>
      <comments>https://normal-operating.tistory.com/50#entry50comment</comments>
      <pubDate>Thu, 16 Oct 2025 17:00:08 +0900</pubDate>
    </item>
    <item>
      <title>Vercel 말고 Cloudflare로 무료로 3분만에 배포하기(딸깍)</title>
      <link>https://normal-operating.tistory.com/49</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 맨날 &lt;span style=&quot;background-color: #e9f7fb; color: #0b333e; text-align: start;&quot;&gt;Cloudflare&lt;/span&gt; 에서 사람임을 확인하세요. 뜨길래 뭐하는 데인지 싶어서 찾아보니&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무료 플랜이 있다. 진짜 딸깍 배포가 가능하니(CI/CD 구축 필요 X) 잘 따라와주시길...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;준비물 : git / github&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 개발자라면 당연히 있는 github 로 들어간다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;664&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cITQNe/btsQTzKS6XC/xFyGb49WwZP0JjLH9SzgD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cITQNe/btsQTzKS6XC/xFyGb49WwZP0JjLH9SzgD0/img.png&quot; data-alt=&quot;create repository 선택&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cITQNe/btsQTzKS6XC/xFyGb49WwZP0JjLH9SzgD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcITQNe%2FbtsQTzKS6XC%2FxFyGb49WwZP0JjLH9SzgD0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;473&quot; height=&quot;412&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;664&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;create repository 선택&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 repository 를 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성된 빈 repository clone&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;674&quot; data-origin-height=&quot;61&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnF2Uf/btsQTQTx0Jh/QNR95jj0XLeaRLahRFwshK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnF2Uf/btsQTQTx0Jh/QNR95jj0XLeaRLahRFwshK/img.png&quot; data-alt=&quot;clone 완료&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnF2Uf/btsQTQTx0Jh/QNR95jj0XLeaRLahRFwshK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnF2Uf%2FbtsQTQTx0Jh%2FQNR95jj0XLeaRLahRFwshK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;674&quot; height=&quot;61&quot; data-origin-width=&quot;674&quot; data-origin-height=&quot;61&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;clone 완료&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아... clone 까지 하고&amp;nbsp; 나서 posting 이라고 쓴다는 걸 잘못쓴 걸 발견.... 구냥 봐주시길....&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;windsurf / vscode 등의 에디터로 편집&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 코드작성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1819&quot; data-origin-height=&quot;159&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/T119i/btsQUZPKWBA/Rpkr6eyBiSZue53fAkgKfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/T119i/btsQUZPKWBA/Rpkr6eyBiSZue53fAkgKfk/img.png&quot; data-alt=&quot;windsurf 딸깍&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/T119i/btsQUZPKWBA/Rpkr6eyBiSZue53fAkgKfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FT119i%2FbtsQUZPKWBA%2FRpkr6eyBiSZue53fAkgKfk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1819&quot; height=&quot;159&quot; data-origin-width=&quot;1819&quot; data-origin-height=&quot;159&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;windsurf 딸깍&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 로컬에서 동작 확인(생략가능)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;750&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mmfgV/btsQVyqNStM/H2iD8KGa3fKcxPkNBeztk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mmfgV/btsQVyqNStM/H2iD8KGa3fKcxPkNBeztk1/img.png&quot; data-alt=&quot;딸깍 한 거 치곤 나쁘지 않다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mmfgV/btsQVyqNStM/H2iD8KGa3fKcxPkNBeztk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmmfgV%2FbtsQVyqNStM%2FH2iD8KGa3fKcxPkNBeztk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1256&quot; height=&quot;750&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;750&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;딸깍 한 거 치곤 나쁘지 않다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. git 으로 push 하기&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;305&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0lzDo/btsQSxNMI6g/PKAxuFCY5zr3MEEY7oJRd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0lzDo/btsQSxNMI6g/PKAxuFCY5zr3MEEY7oJRd0/img.png&quot; data-alt=&quot;git push 딸깍&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0lzDo/btsQSxNMI6g/PKAxuFCY5zr3MEEY7oJRd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0lzDo%2FbtsQSxNMI6g%2FPKAxuFCY5zr3MEEY7oJRd0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;750&quot; height=&quot;305&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;305&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;git push 딸깍&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. github repository 와 cloudflare 연결하기&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1053&quot; data-origin-height=&quot;317&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgqfAw/btsQVyK0obU/BosTGo0DF7klKCP0konOZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgqfAw/btsQVyK0obU/BosTGo0DF7klKCP0konOZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgqfAw/btsQVyK0obU/BosTGo0DF7klKCP0konOZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgqfAw%2FbtsQVyK0obU%2FBosTGo0DF7klKCP0konOZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1053&quot; height=&quot;317&quot; data-origin-width=&quot;1053&quot; data-origin-height=&quot;317&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Account home -&amp;gt; Developer platform&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;으로 가서&amp;nbsp; +Create application&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pages -&amp;gt; Get started&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cWIEAp/btsQTUBEYFM/ks21MWEIxHNOUiYZj3SNSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cWIEAp/btsQTUBEYFM/ks21MWEIxHNOUiYZj3SNSK/img.png&quot; data-alt=&quot;gogo&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cWIEAp/btsQTUBEYFM/ks21MWEIxHNOUiYZj3SNSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcWIEAp%2FbtsQTUBEYFM%2Fks21MWEIxHNOUiYZj3SNSK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;775&quot; height=&quot;540&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;540&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;gogo&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;들어가면 어쩌고 저쩌고 내 repository 가 안보일텐데 하단에 있는&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;863&quot; data-origin-height=&quot;96&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEFdZi/btsQVE5u1gm/ARJSazRqou0WRoZFzAjIW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEFdZi/btsQVE5u1gm/ARJSazRqou0WRoZFzAjIW1/img.png&quot; data-alt=&quot;Cloudflare Pages 클릭&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEFdZi/btsQVE5u1gm/ARJSazRqou0WRoZFzAjIW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEFdZi%2FbtsQVE5u1gm%2FARJSazRqou0WRoZFzAjIW1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;863&quot; height=&quot;96&quot; data-origin-width=&quot;863&quot; data-origin-height=&quot;96&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Cloudflare Pages 클릭&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #777777; text-align: center;&quot;&gt;Cloudflare Pages 클릭&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스크롤을 쭉 내리면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1201&quot; data-origin-height=&quot;649&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cyHjhS/btsQVmqwIN0/k9R6VrEqoOlNSHzs4DpMdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cyHjhS/btsQVmqwIN0/k9R6VrEqoOlNSHzs4DpMdk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cyHjhS/btsQVmqwIN0/k9R6VrEqoOlNSHzs4DpMdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcyHjhS%2FbtsQVmqwIN0%2Fk9R6VrEqoOlNSHzs4DpMdk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1201&quot; height=&quot;649&quot; data-origin-width=&quot;1201&quot; data-origin-height=&quot;649&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 있는데 select repository 에서 방금 git push 한 저장소 선택하고 Save&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 메인 화면으로 올텐데 다시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Account home -&amp;gt; Developer platform -&amp;gt;&amp;nbsp; Create application 클릭 -&amp;gt; Pages -&amp;lt; import an ~ 어쩌고 클릭(Get started) -&amp;gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1154&quot; data-origin-height=&quot;731&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmPEtz/btsQVMPUc3L/46ki0CyIcHajoDIOLNSRH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmPEtz/btsQVMPUc3L/46ki0CyIcHajoDIOLNSRH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmPEtz/btsQVMPUc3L/46ki0CyIcHajoDIOLNSRH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcmPEtz%2FbtsQVMPUc3L%2F46ki0CyIcHajoDIOLNSRH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1154&quot; height=&quot;731&quot; data-origin-width=&quot;1154&quot; data-origin-height=&quot;731&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방금 등록한 repository 선택하고 Begin setup&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무슨 입력창 뜰덴데 다 비우고 Save and Deploy 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #313131; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;Building and deploying&amp;nbsp; -&amp;gt; &lt;/span&gt;&lt;span&gt;Success! Your project is deployed to Region: Earth]&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;되면 완료&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;836&quot; data-origin-height=&quot;169&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4oSYL/btsQUzDPXFo/fR8y2UNsK9yhAx2eRSnnH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4oSYL/btsQUzDPXFo/fR8y2UNsK9yhAx2eRSnnH1/img.png&quot; data-alt=&quot;아래 하이퍼링크 접속 ㄱㄱ&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4oSYL/btsQUzDPXFo/fR8y2UNsK9yhAx2eRSnnH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4oSYL%2FbtsQUzDPXFo%2FfR8y2UNsK9yhAx2eRSnnH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;836&quot; height=&quot;169&quot; data-origin-width=&quot;836&quot; data-origin-height=&quot;169&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;아래 하이퍼링크 접속 ㄱㄱ&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;659&quot; data-origin-height=&quot;366&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qg8Ae/btsQVkzwsDA/7EAJ6KWVOgtKEMdnoI4s8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qg8Ae/btsQVkzwsDA/7EAJ6KWVOgtKEMdnoI4s8K/img.png&quot; data-alt=&quot;배포 완료&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qg8Ae/btsQVkzwsDA/7EAJ6KWVOgtKEMdnoI4s8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqg8Ae%2FbtsQVkzwsDA%2F7EAJ6KWVOgtKEMdnoI4s8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;659&quot; height=&quot;366&quot; data-origin-width=&quot;659&quot; data-origin-height=&quot;366&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;배포 완료&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 &lt;a href=&quot;https://blog-postion.pages.dev/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blog-postion.pages.dev/ &lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생기면서 배포 완료&amp;nbsp; 이렇게 해서 구글이 싫어하는 쓸모없는 사이트가 생성되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;심지어 무료 (카드 등록 안해도됨)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;git push 하면 자동으로 재배포됨&quot; &amp;lt;&amp;lt; 중요 ㄹㅇ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단점 : 디버깅 어려움 / 정적사이트만 가능 ㅠ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2부 : 도메인 연결하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3부 : 리액트 정적사이트 배포하기&lt;/p&gt;</description>
      <category>취미/프로그래밍</category>
      <category>cloudflare</category>
      <category>vercel</category>
      <author>Anything Doing OK</author>
      <guid isPermaLink="true">https://normal-operating.tistory.com/49</guid>
      <comments>https://normal-operating.tistory.com/49#entry49comment</comments>
      <pubDate>Mon, 29 Sep 2025 15:00:18 +0900</pubDate>
    </item>
    <item>
      <title>AWS Lightsail scale up</title>
      <link>https://normal-operating.tistory.com/48</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;527&quot; data-origin-height=&quot;231&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6NFIh/btsO0Ia9SH9/3Aie2GFlKZ6MzKY8cRVMFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6NFIh/btsO0Ia9SH9/3Aie2GFlKZ6MzKY8cRVMFk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6NFIh/btsO0Ia9SH9/3Aie2GFlKZ6MzKY8cRVMFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6NFIh%2FbtsO0Ia9SH9%2F3Aie2GFlKZ6MzKY8cRVMFk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;527&quot; height=&quot;231&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;527&quot; data-origin-height=&quot;231&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사양이 너무 낮아서 새로운 Lightsail 로 scale up 진행하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;920&quot; data-origin-height=&quot;569&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/et5wbh/btsO0XsptMD/uFWMcGVGGgJOvhdnOq21I0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/et5wbh/btsO0XsptMD/uFWMcGVGGgJOvhdnOq21I0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/et5wbh/btsO0XsptMD/uFWMcGVGGgJOvhdnOq21I0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fet5wbh%2FbtsO0XsptMD%2FuFWMcGVGGgJOvhdnOq21I0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;920&quot; height=&quot;569&quot; data-origin-width=&quot;920&quot; data-origin-height=&quot;569&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 인스턴스로 들어가서 Snapshot tab&amp;nbsp; =&amp;gt; Create snapshot =&amp;gt; 생성되기까지 대기 =&amp;gt; 점 3개 create new instance 선택&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;819&quot; data-origin-height=&quot;285&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r1vwl/btsO0cX0a4R/V1n4HgEPkr05O9GGc09n8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r1vwl/btsO0cX0a4R/V1n4HgEPkr05O9GGc09n8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r1vwl/btsO0cX0a4R/V1n4HgEPkr05O9GGc09n8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr1vwl%2FbtsO0cX0a4R%2FV1n4HgEPkr05O9GGc09n8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;819&quot; height=&quot;285&quot; data-origin-width=&quot;819&quot; data-origin-height=&quot;285&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;선택 후 맞는 사양을 선택하고 create instance 진행하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;108&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c1O6xg/btsO0a0mt1i/isXO0ibtAItypDQBaYyitK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c1O6xg/btsO0a0mt1i/isXO0ibtAItypDQBaYyitK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c1O6xg/btsO0a0mt1i/isXO0ibtAItypDQBaYyitK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc1O6xg%2FbtsO0a0mt1i%2FisXO0ibtAItypDQBaYyitK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;510&quot; height=&quot;108&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;108&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 사양으로 성공적으로 생성된 모습을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도메인 연결은 해당 글 참조&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://normal-operating.tistory.com/44&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://normal-operating.tistory.com/44&lt;/a&gt;&lt;/p&gt;</description>
      <category>취미/프로그래밍</category>
      <category>AWS</category>
      <category>lightsail</category>
      <author>Anything Doing OK</author>
      <guid isPermaLink="true">https://normal-operating.tistory.com/48</guid>
      <comments>https://normal-operating.tistory.com/48#entry48comment</comments>
      <pubDate>Tue, 1 Jul 2025 18:13:44 +0900</pubDate>
    </item>
    <item>
      <title>Andy Grammer - These Tears (가사/해석/번역/Lyrics/노래/추천)</title>
      <link>https://normal-operating.tistory.com/47</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;instagram 에서 좋은 노래 발견해서 가사 공유합니다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=c3qO96QK3QE&amp;amp;list=RDc3qO96QK3QE&amp;amp;start_radio=1&quot;&gt;https://www.youtube.com/watch?v=c3qO96QK3QE&amp;amp;list=RDc3qO96QK3QE&amp;amp;start_radio=1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;These tears mean I'm lettin' you go&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;이 눈물은 당신을 보내준다는 의미예요&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;I'm learnin' how to be alone&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;혼자서도 잘 지내는 법을 배우고 있어요&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;I'm broken, but give it time&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;몸과 마음이 다 망가졌지만, 시간이 지나면&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;I'm gon' be alright&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;괜찮아질 거예요&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;These tears mean it's settlin' in&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;이 눈물은 괜찮아지고 있다는 의미예요&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;That I'm not gon' see you again&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;다음 생에 우리 다시 만날 때까지&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;'Til one day in another life&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;다시는 당신을 못 보겠지만&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;But I'm gon' be al-, I'm gon' be alright&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;괜찮아질 거예요, 괜찮아지겠죠&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;I been missing you tonight&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;오늘 밤도 당신을 그리워할 거예요&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;I'll be missing you tomorrow&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;내일도 당신이 그립겠죠&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;It's the hardest pill to swallow&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;삼켜내기 힘든 이별이지만&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;But I'm starting to get it down&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;그래도 조금씩 괜찮아지고 있어요&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;I try to think of all the times&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;내가 도저히 못 이겨낼 거라 생각했던&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;I thought I wouldn't make it through&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;과거의 순간들을 떠올려보려고 해요&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;But somehow I always do&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;그때도 그랬듯이 어떻게든 이겨내겠죠&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;And I'll do the same for you&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;당신과의 이별도 그렇게 견뎌내 볼게요&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;it don't mean I'm good with goodbye-bye-bye&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;이별이 견딜만하다는 건 아니에요&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;But it ain't all that bad when I cry, cry, cry&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;하지만 너무 힘들 때 우는 것도 나쁘지 않아요&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;These tears mean I'm lettin' you go&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;이 눈물은 당신을 보내준다는 의미예요&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;I'm learnin' how to be alone&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;혼자서도 잘 지내는 법을 배우고 있어요&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;I'm broken, but give it time&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;몸과 마음이 다 망가졌지만, 시간이 지나면&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;I'm gon' be alright&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;괜찮아질 거예요&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;These tears mean it's settlin' in&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;이 눈물은 괜찮아지고 있다는 의미예요&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;That I'm not gon' see you again&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;다음 생에 우리 다시 만날 때까지&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;'Til one day in another life&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;다시는 당신을 못 보겠지만&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;But I'm gon' be al-, I'm gon' be alright&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;괜찮아질 거예요, 괜찮아지겠죠&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;I see you everywhere&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;꿈에서 걸을 때에도&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;On the sidewalks of my dreams&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;어디를 가든 당신이 보여요&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;Like a distant melody&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;저 멀리 들려오는 희미한 선율처럼&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;I hear you callin' and callin' to me&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;날 부르는 당신의 목소리가 들려요&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;And I love you, but I leave you&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;내가 살아가려면&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;In the past, baby, because I need to&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;당신을 너무 사랑하지만,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;To not go insane&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;당신을 추억 속에 묻어두고 떠나야만 해요&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;I know I love you the same&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;당신을 사랑하는 내 마음은 변함이 없단 걸 알아요&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;it don't mean I'm good with goodbye-bye-bye&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;이별이 견딜만한 건 아니에요&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;(It don't mean I'm good with goodbye)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;(이별이 견딜만한 건 아니에요)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;But ain't all that bad when I cry, cry, cry&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;하지만 너무 힘들 때 우는 것도 나쁘지 않아요&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;These tears mean I'm lettin' you go&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;이 눈물은 당신을 보내준다는 의미예요&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;I'm learnin' how to be alone&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;혼자서도 잘 지내는 법을 배우고 있어요&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;I'm broken, but give it time&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;몸과 마음이 다 망가졌지만, 시간이 지나면&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;I'm gon' be alright 괜찮아질 거예요&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;These tears mean it's settlin' in&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;이 눈물은 괜찮아지고 있다는 의미예요&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;That I'm not gon' see you again&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;다음 생에 우리 다시 만날 때까지&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;'Til one day in another life&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;다시는 당신을 못 보겠지만&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;But I'm gon' be al-, I'm gon' be alright&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;괜찮아질 거예요, 괜찮아지겠죠&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;I'm gon' be al-, I'm gon' be alright&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;괜찮아질 거예요, 괜찮아지겠죠&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;I'm gon' be al-, I'm gon' be alright&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;괜찮아질 거예요, 괜찮아지겠죠&lt;/span&gt;&lt;/p&gt;</description>
      <category>기타</category>
      <author>Anything Doing OK</author>
      <guid isPermaLink="true">https://normal-operating.tistory.com/47</guid>
      <comments>https://normal-operating.tistory.com/47#entry47comment</comments>
      <pubDate>Wed, 25 Jun 2025 11:08:57 +0900</pubDate>
    </item>
    <item>
      <title>Postgres MCP 연결해서 데이터 뽑기</title>
      <link>https://normal-operating.tistory.com/46</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. MCP 기초&lt;/b&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=fkqXQOjj8cA&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/33zOu/hyY47q86IU/HegeW2OtziifzpZaVFk4Z1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=1054_200_1224_386,https://scrap.kakaocdn.net/dn/blLD9n/hyY32KndID/jVtSEKWWSjmbk1p8DFLgZk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=1054_200_1224_386&quot; data-video-width=&quot;400&quot; data-video-height=&quot;225&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;MCP써야 진짜 Claude다! 500% 활용 튜토리얼 (개념부터 활용까지)&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/fkqXQOjj8cA&quot; width=&quot;400&quot; height=&quot;225&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;https://www.youtube.com/watch?v=fkqXQOjj8cA &amp;nbsp;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;12분 정도까지 보면서 MCP 기초 학습하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2.MCP 설정 JSON 만들기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://smithery.ai/server/@smithery-ai/postgres&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://smithery.ai/server/@smithery-ai/postgres&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1749014322320&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;PostgreSQL MCP Server | Smithery&quot; data-og-description=&quot;&quot; data-og-host=&quot;smithery.ai&quot; data-og-source-url=&quot;https://smithery.ai/server/@smithery-ai/postgres&quot; data-og-url=&quot;https://smithery.ai/server/@smithery-ai/postgres&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://smithery.ai/server/@smithery-ai/postgres&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://smithery.ai/server/@smithery-ai/postgres&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;PostgreSQL MCP Server | Smithery&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;smithery.ai&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;으로 접속하여 우측의 JSON 클릭&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;643&quot; data-origin-height=&quot;457&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wSegK/btsOp6ce8yK/5yDMUGo02yhgfpQo5wvbG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wSegK/btsOp6ce8yK/5yDMUGo02yhgfpQo5wvbG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wSegK/btsOp6ce8yK/5yDMUGo02yhgfpQo5wvbG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwSegK%2FbtsOp6ce8yK%2F5yDMUGo02yhgfpQo5wvbG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;477&quot; height=&quot;339&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;643&quot; data-origin-height=&quot;457&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 정보를 작성해주고 첫번째 모자이크에 DB 비밀번호 맨뒤 '/'뒤에 에 접속하고자하는 DB명&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex ) postgresql://postgres:password@localhost:5432/databasename &amp;lt; 해당형식이된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot; style=&quot;background-color: #1d2021; color: #ebdbb2; text-align: start;&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;&quot;postgres&quot;: {
      &quot;command&quot;: &quot;cmd&quot;,
      &quot;args&quot;: [
        &quot;/c&quot;,
        &quot;npx&quot;,
        &quot;-y&quot;,
        &quot;@smithery/cli@latest&quot;,
        &quot;run&quot;,
        &quot;@smithery-ai/postgres&quot;,
        &quot;--key&quot;,
        &quot;**************&quot;,
        &quot;--profile&quot;,
        &quot;**************&quot;
      ]
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제공받은 JSON 파일을&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;claude_desktop_config.json 에 붙여준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*** 에는 실제 제공받은 key 가 있을 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 클로드 데스크탑 재실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. 프롬프트 작성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프롬프트로&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;color: #141413; text-align: start;&quot;&gt;
&lt;div data-testid=&quot;user-message&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;' DB 에서 user 중에 john 이라는 이름을 포함한 사용자를 찾아줘 ' 라고 요청을 작성하면&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #faf9f5; color: #383a42; text-align: left;&quot;&gt;&lt;span style=&quot;color: #383a42;&quot;&gt;{&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #faf9f5; color: #383a42; text-align: left;&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;span style=&quot;color: #50a14f;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color: #50a14f;&quot;&gt;sql&lt;/span&gt;&lt;span style=&quot;color: #50a14f;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color: #4078f2;&quot;&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span style=&quot;color: #50a14f;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color: #50a14f;&quot;&gt;SELECT * FROM users WHERE name ILIKE '%john%'&lt;/span&gt;&lt;span style=&quot;color: #50a14f;&quot;&gt;`&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #faf9f5; color: #383a42; text-align: left;&quot;&gt;&lt;span style=&quot;color: #383a42;&quot;&gt;}&amp;nbsp;&lt;br /&gt;이런식으로 스스로 쿼리를 DB 에 날린다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;269&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rmyfb/btsOouePJaN/ugo81DkvYOPpmybK0aeS1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rmyfb/btsOouePJaN/ugo81DkvYOPpmybK0aeS1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rmyfb/btsOouePJaN/ugo81DkvYOPpmybK0aeS1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frmyfb%2FbtsOouePJaN%2Fugo81DkvYOPpmybK0aeS1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;732&quot; height=&quot;269&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;269&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령어를 잘못날려서 name 이 없는 상황&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;330&quot; data-origin-height=&quot;322&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wbjBT/btsOo8oKFfT/sipMo3wgdT9z1E2VcFemW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wbjBT/btsOo8oKFfT/sipMo3wgdT9z1E2VcFemW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wbjBT/btsOo8oKFfT/sipMo3wgdT9z1E2VcFemW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwbjBT%2FbtsOo8oKFfT%2FsipMo3wgdT9z1E2VcFemW0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;330&quot; height=&quot;322&quot; data-origin-width=&quot;330&quot; data-origin-height=&quot;322&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 알아서 클로드가&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;724&quot; data-origin-height=&quot;389&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OSXpq/btsOof25Hk4/vicmAwsIV323KoJOCI7QCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OSXpq/btsOof25Hk4/vicmAwsIV323KoJOCI7QCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OSXpq/btsOof25Hk4/vicmAwsIV323KoJOCI7QCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOSXpq%2FbtsOof25Hk4%2FvicmAwsIV323KoJOCI7QCk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;724&quot; height=&quot;389&quot; data-origin-width=&quot;724&quot; data-origin-height=&quot;389&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블의 구조를 분석하고 쿼리를 재생성해서&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1749015227882&quot; class=&quot;actionscript&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;&quot;user_id&quot;: 1,
    &quot;username&quot;: &quot;john_doe&quot;,
    &quot;email&quot;: &quot;john.doe@example.com&quot;,
    &quot;first_name&quot;: &quot;John&quot;,
    &quot;last_name&quot;: &quot;Doe&quot;,
    &quot;phone&quot;: &quot;010-1234-5678&quot;,
    &quot;created_at&quot;: &quot;2025-06-04T04:20:11.211Z&quot;,
    &quot;is_active&quot;: true,
    &quot;role&quot;: &quot;customer&quot;
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의 데이터를 찾아준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 DB 에서 쿼리를 날린 데이터와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;168&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c99M3F/btsOphTnmXg/4OSoxkqLz034TAY4Sa1cek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c99M3F/btsOphTnmXg/4OSoxkqLz034TAY4Sa1cek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c99M3F/btsOphTnmXg/4OSoxkqLz034TAY4Sa1cek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc99M3F%2FbtsOphTnmXg%2F4OSoxkqLz034TAY4Sa1cek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;661&quot; height=&quot;168&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;168&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;4.사용후기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클로드처럼&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿼리 이렇게 날리면 DBA 한테 한대 맞을 거 같다. ILIKE '%john%' 라니.. 음...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도메인 지식이 중요하고 프롬프트의 중요성이 더욱 커질 것 같다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아마 프롬프트로 Table 의 구조 와 DB 구조를 분석 시킨 후 데이터를 뽑도록하여 성능을 높여야겠다.&lt;/p&gt;</description>
      <category>취미/프로그래밍</category>
      <author>Anything Doing OK</author>
      <guid isPermaLink="true">https://normal-operating.tistory.com/46</guid>
      <comments>https://normal-operating.tistory.com/46#entry46comment</comments>
      <pubDate>Wed, 4 Jun 2025 14:47:43 +0900</pubDate>
    </item>
    <item>
      <title>React with Nest.js Architecture</title>
      <link>https://normal-operating.tistory.com/45</link>
      <description>&lt;h2 style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;신규 CRM 구축을 위한 NestJS &amp;amp; React 아키텍처 설계 제안&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;부제 : 단일 서버 통합구성과 서버분리 독립구성을 기반으로&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;1. 서론&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;본 문서는 신규 CRM(Customer Relationship Management) 시스템 구축을 위해 NestJS(백엔드)와 React(프론트엔드)를 기반으로 하는 두 가지 주요 아키텍처 접근 방식, 즉&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span&gt;1. 단일 서버 통합 구성(배포)&lt;/span&gt;&lt;/b&gt;&lt;span&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span&gt;2. 서버 분리 독립 배포&lt;/span&gt;&lt;/b&gt;&lt;span&gt;를 비교 분석하고, 각 방식의 장단점, 적합한 시나리오, 그리고 구체적인 구현 고려 사항을 제시합니다. 이를 통해 프로젝트의 특성, 팀 구성, 확장성 요구사항 등을 종합적으로 고려하여 최적의 아키텍처를 선택하는 데 도움을 드리고자 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;참고 자료:&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;NestJS 공식 문서:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://docs.nestjs.com/&quot;&gt;https://docs.nestjs.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Awesome NestJS (다양한 예제 및 보일러플레이트):&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://github.com/nestjs/awesome-nestjs&quot;&gt;https://github.com/nestjs/awesome-nestjs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;2. 아키텍처 옵션 상세 분석&lt;/span&gt;&lt;/h3&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;2.1. 옵션 1: 단일 서버 - 통합 배포 (Monolithic Frontend &amp;amp; Backend)&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;개념:&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;NestJS 애플리케이션이 React 애플리케이션의 빌드된 정적 파일(HTML, CSS, JavaScript 번들)을 직접 서빙하거나, NestJS가 서버 사이드 렌더링(SSR) 또는 정적 사이트 생성(SSG)을 통해 React 컴포넌트를 렌더링하여 완성된 HTML을 클라이언트에게 전달합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;주요 구현 방식: &lt;/span&gt;&lt;/b&gt;&lt;span&gt;React 빌드 결과물을 특정 경로(예:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;/&lt;/span&gt;&lt;span&gt;)에서 서빙하고, API 요청은 특정 접두사(예:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;/api&lt;/span&gt;&lt;span&gt;)를 통해 처리합니다.&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #edeef1; color: #1a1c1e;&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;gradle&quot;&gt;&lt;code&gt;// Nest.JS main.ts 또는 app.module.ts
import { Module } from '@nestjs/common';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';
import { YourApiModule } from './api/your-api.module'; // API 라우팅 모듈

@Module({
  imports: [
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', '..', 'client', 'dist'), // React 빌드 결과물 경로 (Vite는 dist, CRA는 build)
      exclude: ['/api/(.*)'], // API 경로는 제외하여 NestJS 컨트롤러가 처리하도록 함
      // serveRoot: '/', // 기본값. 특정 경로로 서빙하고 싶다면 변경 (예: '/app')
    }),
    YourApiModule, // CRM API 모듈 등록
    // ... other NestJS modules
  ],
})
export class AppModule {}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;상세 흐름도:&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #edeef1; color: #1a1c1e;&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;gherkin&quot;&gt;&lt;code&gt;[ 사용자 브라우저 ]
       |
       | (HTTPS 요청: www.example.com/dashboard 또는 www.example.com/api/users)
       V
[ 통합 서버 (Nginx/Apache 등 리버스 프록시 - 선택 사항) ]
       |
       V
[ Nest.JS 애플리케이션 서버 (Node.js 환경) ]
       |
       |-- (요청 경로 분석) --&amp;gt; [ ServeStaticModule ] -- (경로가 '/' 또는 React 라우트인 경우)
       |      |                                            |
       |      |                                            V
       |      |                                     [ React 빌드 산출물 (index.html, main.js, main.css) ]
       |      |                                            |
       |      |                                            V (클라이언트로 전송)
       |      |
       |      `-- (경로가 '/api/*' 인 경우) --&amp;gt; [ Nest.JS API 라우터/컨트롤러 ]
       |                                             |
       |                                             V
       |                                          [ 서비스 로직, 데이터베이스 연동 등 ]
       |                                             |
       |                                             V
       |                                          [ 데이터베이스 / 캐시 / 외부 API ]
       |                                             |
       |                                             V
       |                                          [ API 응답 (JSON 등) ]
       |                                             |
       |                                             V (클라이언트로 전송)
       V
[ 사용자 브라우저에 결과 표시 / React 앱에서 API 응답 처리 ]&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;장점:&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;단순화된 배포 및 인프라:&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;하나의 애플리케이션(NestJS)만 배포 및 관리.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;단일 서버 인스턴스, 도메인, SSL 인증서로 인프라 관리 단순화.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;초기 설정 및 배포 자동화(CI/CD) 파이프라인 구성이 상대적으로 용이.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;인증/세션 관리 용이성:&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;동일 출처(Same-Origin)이므로 쿠키 기반 세션 관리(예:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;HttpOnly&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;Secure&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;플래그 쿠키)가 자연스럽고 보안적으로 유리.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;참고:&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;NestJS Passport 세션 인증:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://docs.nestjs.com/security/authentication#session-authentication&quot;&gt;https://docs.nestjs.com/security/authentication#session-authentication&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;CORS 문제 없음:&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;프론트엔드와 백엔드가 동일 출처에서 서비스되므로 CORS(Cross-Origin Resource Sharing) 정책 설정이 불필요.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;초기 개발 속도:&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;작은 팀이나 풀스택 개발자 중심의 환경에서는 단일 코드베이스 및 컨텍스트로 인해 초기 개발 속도가 빠를 수 있음.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;단점:&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;강한 결합도:&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;프론트엔드와 백엔드가 하나의 프로세스 및 배포 단위로 묶여, 한쪽의 문제(예: NestJS 서버 다운)가 전체 서비스 중단으로 이어짐.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;한쪽의 리소스 사용량 급증(예: API 요청 폭주)이 다른 쪽(정적 파일 서빙) 성능에 영향을 줄 수 있음.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;개발 및 빌드 복잡성 증가 가능성:&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;React 빌드 결과물을 NestJS 프로젝트 내 특정 위치로 복사하거나, NestJS 빌드 프로세스에 React 빌드 단계를 통합해야 함. (예:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;package.json&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;스크립트 관리)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;기술 스택 및 팀 분리 어려움:&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;프론트엔드와 백엔드 라이브러리/프레임워크 버전 충돌 가능성.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;각 팀의 독립적인 기술 결정 및 작업 흐름에 제약.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;서버 부하 증가 (특히 SSR 시):&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;SSR은 각 요청마다 서버에서 React 컴포넌트를 렌더링하므로 CPU 사용량 증가 및 응답 시간 지연 가능성. (캐싱 전략 필수)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;정적 파일 서빙 자체도 Node.js의 주 스레드를 일부 사용할 수 있으므로, 고 트래픽 상황에서는 전용 웹 서버(Nginx 등)보다 비효율적일 수 있음.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;확장성 제약:&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;프론트엔드 서빙과 백엔드 API 로직이 분리되지 않아, 특정 부분만 독립적으로 확장하기 어려움. (예: API 서버만 스케일 아웃)&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;적합한 경우:&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;프로토타입 또는 MVP(Minimum Viable Product) 개발.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;개발팀 규모가 작고, 풀스택 개발자 중심으로 구성된 경우.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;인프라 관리 복잡성을 최소화하고 빠른 초기 배포를 목표로 하는 경우.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;내부용 소규모 애플리케이션.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;2.2. 옵션 2: 서버 분리 - 독립 배포 (Decoupled Frontend &amp;amp; Backend)&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;개념:&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;React 프론트엔드 애플리케이션과 NestJS 백엔드 API가 서로 다른 서버 또는 동일 서버 내 다른 포트에서 독립적으로 실행되고 배포됩니다. 이들은 네트워크를 통해 API를 호출하여 통신합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;주요 구현 방식:&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;React 프론트엔드:&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;개발: Vite 또는 Create React App 등의 개발 서버 사용 (예:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;localhost:5173&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;배포: 빌드된 정적 파일(HTML, CSS, JS)을 CDN(AWS CloudFront, Cloudflare), 정적 웹 호스팅 서비스(Vercel, Netlify, AWS S3 + CloudFront, GitHub Pages) 또는 Nginx/Apache와 같은 웹 서버를 통해 배포.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;NestJS 백엔드 API:&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;개발: 독립적인 Node.js 서버로 실행 (예:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;localhost:3000&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;배포: Docker 컨테이너, PaaS(AWS Elastic Beanstalk, Google Cloud Run), IaaS(AWS EC2) 등에 배포.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;API 엔드포인트:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;api.example.com&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;또는 리버스 프록시를 통해&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;www.example.com/api&lt;/span&gt;&lt;span&gt;로 구성.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;CORS 설정 필수.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;background-color: #edeef1; color: #1a1c1e;&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;// Nest.JS main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // CORS 설정
  app.enableCors({
    origin: [
        'http://localhost:5173', // 로컬 React 개발 서버 (Vite 기본 포트)
        'http://localhost:3000', // 로컬 React 개발 서버 (CRA 기본 포트)
        'https://crm-app.yourdomain.com', // 실제 배포될 프론트엔드 도메인
        // 필요한 경우 추가 도메인/출처 등록
    ],
    methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
    credentials: true, // 인증 정보(쿠키 등)를 주고받아야 할 경우 true
  });
  // 참고: NestJS CORS 문서: https://docs.nestjs.com/security/cors

  // API 경로 접두사 설정 (선택 사항이지만 권장)
  app.setGlobalPrefix('api/v1');
  // 참고: NestJS 접두사 설정: https://docs.nestjs.com/faq/global-prefix

  // 전역 ValidationPipe 적용 (DTO 유효성 검사)
  app.useGlobalPipes(new ValidationPipe({
    whitelist: true, // DTO에 정의되지 않은 속성 제거
    forbidNonWhitelisted: true, // DTO에 정의되지 않은 속성 요청 시 에러 발생
    transform: true, // 요청 데이터를 DTO 타입으로 자동 변환
  }));
  // 참고: NestJS Validation: https://docs.nestjs.com/techniques/validation

  await app.listen(process.env.PORT || 3001); // 백엔드 서버 포트
  console.log(`Application is running on: ${await app.getUrl()}`);
}
bootstrap();&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;상세 흐름도:&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #edeef1; color: #1a1c1e;&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;gherkin&quot;&gt;&lt;code&gt;[ 사용자 브라우저 ]
       |
       | (HTTPS 웹 페이지 요청: https://crm-app.yourdomain.com)
       V
[ 프론트엔드 서버 / CDN (예: Vercel, Netlify, AWS S3 + CloudFront) ]
       |  (React 정적 파일: index.html, main.js, main.css 등 서빙)
       V
[ 사용자 브라우저 - React 앱 로드 및 실행 ]
       |
       | (데이터 필요시 HTTPS API 요청: https://api.yourdomain.com/v1/users 또는 https://crm-app.yourdomain.com/api/v1/users (리버스 프록시 사용 시))
       V
[ (선택) API Gateway (예: AWS API Gateway, Nginx 등) ]
       |  (라우팅, 로드밸런싱, 인증, 요청 제한 등 역할 수행)
       V
[ (선택) 로드 밸런서 (예: AWS ALB/NLB) ]
       |
       V
[ Nest.JS 백엔드 API 서버 인스턴스들 (Node.js 환경) ]
       |  (API 로직 실행)
       |    |
       |    V
       |  [ 서비스 로직, 데이터베이스 연동 등 ]
       |    |
       |    V
       |  [ 데이터베이스 / 캐시 / 외부 API ]
       |    |
       |    V
       |  (API 응답 - JSON 등)
       V
[ 사용자 브라우저 - React 앱에서 API 응답 수신, 데이터 사용 및 UI 업데이트 ]&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;장점:&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;높은 유연성 및 확장성 :&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;프론트엔드와 백엔드를 독립적으로 확장(scale out/up) 가능. 프론트엔드는 CDN으로 글로벌 배포, 백엔드는 API 트래픽에 맞춰 유연하게 조정.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;각 부분의 리소스(CPU, 메모리, 네트워크) 요구사항에 최적화된 인프라 구성.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;관심사의 명확한 분리 :&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;프론트엔드는 UI/UX, 백엔드는 비즈니스 로직/데이터 처리에 집중. 코드베이스 관리 용이.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;명확한 API 계약(예: OpenAPI/Swagger 명세)을 통해 팀 간 협업 원활.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;독립적인 개발 및 배포 주기:&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;프론트엔드팀과 백엔드팀이 각자의 기술 스택, 개발 도구, 배포 파이프라인, 릴리스 주기를 가질 수 있음.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;API 계약이 유지되는 한, 한쪽의 변경이 다른 쪽에 즉각적인 배포 문제를 일으키지 않음.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;기술 스택 선택의 자유:&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;각 영역에 가장 적합한 기술, 라이브러리, 프레임워크 선택 가능.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;향후 특정 부분(예: 모바일 앱용 API, 특정 마이크로서비스) 추가 시 유연하게 대응.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;마이크로서비스 아키텍처로의 전환 용이성:&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;백엔드가 이미 분리되어 있으므로, 필요에 따라 API를 여러 마이크로서비스로 분할하고 확장하기 용이.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;최적화된 프론트엔드 제공:&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;정적 파일은 CDN을 통해 사용자에게 가장 가까운 엣지 로케이션에서 제공되므로 로딩 속도 극대화.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;단점:&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;CORS 설정 필수:&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;다른 출처(Origin)에서 서비스되므로 브라우저의 동일 출처 정책(Same-Origin Policy)으로 인해 API 요청 시 CORS 설정이 백엔드에 반드시 필요.()&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;인프라 복잡성 증가:&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;프론트엔드 호스팅, 백엔드 서버, (선택적) API Gateway, CDN 등 여러 구성 요소 관리 필요.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;별도의 도메인/서브도메인, SSL 인증서 관리.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;인증/인가 처리의 복잡성 증가 가능성:&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;주로 토큰 기반 인증(JWT, OAuth2) 사용.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;쿠키 기반 세션을 사용하려면 서드파티 쿠키 문제, 도메인 및 경로 설정(예:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;SameSite=None; Secure&lt;/span&gt;&lt;span&gt;, 부모 도메인 설정)에 대한 깊은 이해 필요. CSRF 방어 전략 추가 고려.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;참고:&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;JWT 와 NestJS:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://docs.nestjs.com/security/authentication#jwt-functionality&quot;&gt;https://docs.nestjs.com/security/authentication#jwt-functionality&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;개발 환경 설정의 복잡성:&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;로컬 개발 시 프론트엔드 개발 서버(예: Vite)와 백엔드 API 서버(NestJS)를 각각 실행.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;프론트엔드 개발 서버에서 API 요청 시 CORS 문제를 해결하기 위한 프록시 설정 필요.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;네트워크 지연 약간 증가:&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;API 요청이 별도 서버로 가므로 동일 서버 내 통신보다 미세한 네트워크 지연 추가 (대부분의 경우 무시 가능).&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;엔드투엔드(E2E) 테스트 복잡성 증가:&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;여러 시스템을 연동하여 테스트 환경을 구성해야 함.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;적합한 경우:&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;중대규모 이상의 프로젝트, 서비스 지향 아키텍처(SOA)를 지향하는 경우.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;프론트엔드와 백엔드 팀이 분리되어 있거나, 독립적인 개발/배포/확장이 중요한 경우.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;높은 가용성, 확장성, 트래픽 처리 능력이 요구되는 서비스.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;CDN을 통한 프론트엔드 성능 최적화가 매우 중요한 경우.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;향후 마이크로서비스 아키텍처로의 전환 가능성을 열어두고 싶은 경우.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;현대적인 웹 애플리케이션 개발에서 일반적으로 권장되는 방식.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;3. 아키텍처 비교 요약&lt;/span&gt;&lt;/h3&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot;&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 403px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;span&gt;특징&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;span&gt;1서버 (통합 배포)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;span&gt;2서버 (분리 배포)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;&lt;span&gt;배포 단위&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;span&gt;단일 (NestJS 앱 + React 빌드 결과물)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;span&gt;다중 (NestJS 앱 따로, React 빌드 결과물 따로)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 43px;&quot;&gt;
&lt;td style=&quot;height: 43px;&quot;&gt;&lt;b&gt;&lt;span&gt;출처(Origin)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 43px;&quot;&gt;&lt;span&gt;동일 (CORS 불필요)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 43px;&quot;&gt;&lt;span&gt;분리 (백엔드 CORS 설정 필수, 로컬 개발 시 프론트엔드 프록시 설정 권장)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;&lt;span&gt;코드 공유 방식&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;span&gt;내부적 (상대 경로, 모듈 임포트 등)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;span&gt;외부적 (API 호출)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 43px;&quot;&gt;
&lt;td style=&quot;height: 43px;&quot;&gt;&lt;b&gt;&lt;span&gt;빌드 의존성&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 43px;&quot;&gt;&lt;span&gt;높음 (프론트 빌드 -&amp;gt; 백엔드 패키징에 포함)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 43px;&quot;&gt;&lt;span&gt;낮음 (API 계약만 준수)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 43px;&quot;&gt;
&lt;td style=&quot;height: 43px;&quot;&gt;&lt;b&gt;&lt;span&gt;CI/CD 파이프라인&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 43px;&quot;&gt;&lt;span&gt;통합 또는 순차적 (FE 빌드 후 BE 빌드/배포)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 43px;&quot;&gt;&lt;span&gt;완전 분리 또는 독립적&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;&lt;span&gt;결합도(Coupling)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;span&gt;높음 (Tight Coupling)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;span&gt;낮음 (Loose Coupling - API 계약 기반)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;&lt;span&gt;인프라 복잡성&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;span&gt;낮음&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;span&gt;중간 ~ 높음&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;&lt;span&gt;확장성 유연성&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;span&gt;낮음&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;span&gt;높음&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;&lt;span&gt;팀 독립성&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;span&gt;낮음&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;span&gt;높음&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;&lt;span&gt;인증 (쿠키 기반)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;span&gt;간단&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;span&gt;복잡 (토큰 기반 권장, 쿠키 사용 시 추가 설정 필요)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;&lt;span&gt;초기 개발 속도&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;span&gt;빠를 수 있음&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;span&gt;상대적으로 느릴 수 있음 (초기 설정)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;&lt;span&gt;장기적 유지보수성&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;span&gt;낮아질 수 있음&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;span&gt;높아질 수 있음&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;4. 추가 고려 사항 및 권장 사항&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;4.1. 프로젝트 초기 단계 vs. 장기적 관점&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;span&gt;프로젝트 초기에는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span&gt;옵션 1 (통합 배포)&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;이 빠른 프로토타이핑과 시장 검증에 유리할 수 있습니다. 그러나 CRM 시스템은 일반적으로 기능이 복잡해지고 데이터가 누적되며 사용자 수가 증가하는 경향이 있으므로, 장기적인 확장성, 유지보수성, 팀 분업 등을 고려할 때&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span&gt;옵션 2 (분리 배포)&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;가 더 적합한 선택이 될 가능성이 높습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;4.2. 개발팀 구성 및 전문성&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;span&gt;팀이 풀스택 개발자 위주이고 규모가 작다면 옵션 1로 시작할 수 있습니다. 프론트엔드와 백엔드 전문 팀이 분리되어 있다면 옵션 2가 자연스럽습니다. 옵션 2는 각 팀이 자신의 전문 분야에 집중하여 개발 생산성을 높일 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;4.3. 인증 및 보안&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;옵션 1(통합 배포):&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;HttpOnly&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;Secure&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;SameSite=Lax&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(또는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;Strict&lt;/span&gt;&lt;span&gt;) 쿠키를 사용하여 세션 관리가 비교적 간단하고 CSRF 공격에 대해 상대적으로 안전합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;옵션 2(분리 배포):&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;JWT(JSON Web Token)를 사용하는 것이 일반적입니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;4.4. 개발 환경 (DX - Developer Experience)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;옵션 1:&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;단일 프로젝트 설정, 하나의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;npm start&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;명령으로 실행 가능 (단, 빌드 스크립트 통합 필요).&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;옵션 2:&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;프론트엔드, 백엔드 각각 개발 서버 실행.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;4.5. 코드 구조 (Monorepo vs. Polyrepo)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;옵션 1:&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;자연스럽게 단일 레포지토리(Monorepo의 한 형태)가 됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;옵션 2:&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;프론트엔드와 백엔드를 별도의 레포지토리(Polyrepo)로 관리하거나, Nx, Lerna, Turborepo 같은 도구를 사용하여 Monorepo로 관리할 수 있습니다. Monorepo는 코드 공유, 통합 테스트, 버전 관리 등에서 이점이 있을 수 있지만, 초기 설정과 빌드/CI 복잡성이 증가할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;4.6. CI/CD (지속적 통합/배포)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;옵션 1:&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;단일 파이프라인. React 빌드 후 NestJS 애플리케이션에 통합하여 배포.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;옵션 2:&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;프론트엔드와 백엔드 각각 독립적인 CI/CD 파이프라인 구성. 프론트엔드는 정적 호스팅/CDN으로, 백엔드는 서버/컨테이너 환경으로 배포.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;4.6. 폴더 구조의 차이점&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;주요 폴더 구조 차이점 비교&lt;/span&gt;&lt;/h3&gt;
&lt;div style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot;&gt;
&lt;table style=&quot;border-collapse: collapse; width: 97.5577%; height: 659px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;width: 12.093%; height: 23px;&quot;&gt;&lt;span&gt;특징&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 29.7674%; height: 23px;&quot;&gt;&lt;span&gt;옵션 1: 단일 서버 - 통합 배포&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.7442%; height: 23px;&quot;&gt;&lt;span&gt;옵션 2: 서버 분리 - 독립 배포 (Polyrepo 기준)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 41px;&quot;&gt;
&lt;td style=&quot;width: 12.093%; height: 41px;&quot;&gt;&lt;b&gt;&lt;span&gt;프로젝트 루트&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 29.7674%; height: 41px;&quot;&gt;&lt;span&gt;단일 루트 (&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;crm-integrated-app/&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.7442%; height: 41px;&quot;&gt;&lt;span&gt;프론트엔드, 백엔드 각각 독립된 루트 (&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;crm-frontend/&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;crm-backend/&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 45px;&quot;&gt;
&lt;td style=&quot;width: 12.093%; height: 45px;&quot;&gt;&lt;b&gt;&lt;span&gt;프론트엔드 위치&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 29.7674%; height: 45px;&quot;&gt;&lt;span&gt;백엔드 프로젝트의 하위 디렉토리 (&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;client/&lt;/span&gt;&lt;span&gt;) 또는 빌드 결과물만 특정 위치에 복사&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.7442%; height: 45px;&quot;&gt;&lt;span&gt;독립적인 프로젝트 폴더 (&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;crm-frontend/&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;width: 12.093%; height: 23px;&quot;&gt;&lt;b&gt;&lt;span&gt;백엔드 위치&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 29.7674%; height: 23px;&quot;&gt;&lt;span&gt;프로젝트의 주축 (&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;server/&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;또는 프로젝트 루트)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.7442%; height: 23px;&quot;&gt;&lt;span&gt;독립적인 프로젝트 폴더 (&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;crm-backend/&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 68px;&quot;&gt;
&lt;td style=&quot;width: 12.093%; height: 68px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;node_modules&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 29.7674%; height: 68px;&quot;&gt;&lt;span&gt;- React용, NestJS용 각각 존재 가능 (모노레포 도구 없이는 분리)&lt;/span&gt;&lt;span&gt;&amp;lt;br/&amp;gt;&lt;/span&gt;&lt;span&gt;- 모노레포 도구 사용 시 최상위&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;node_modules&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;공유 가능&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.7442%; height: 68px;&quot;&gt;&lt;span&gt;프론트엔드, 백엔드 각각 완전히 독립된&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;node_modules/&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 45px;&quot;&gt;
&lt;td style=&quot;width: 12.093%; height: 45px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;package.json&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 29.7674%; height: 45px;&quot;&gt;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;client/package.json&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;server/package.json&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;각각 존재&lt;/span&gt;&lt;span&gt;&amp;lt;br/&amp;gt;&lt;/span&gt;&lt;span&gt;- (선택) 최상위&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;package.json&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(모노레포 도구 사용 시)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.7442%; height: 45px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;crm-frontend/package.json&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;crm-backend/package.json&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;각각 존재&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 68px;&quot;&gt;
&lt;td style=&quot;width: 12.093%; height: 68px;&quot;&gt;&lt;b&gt;&lt;span&gt;빌드 결과물 처리&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 29.7674%; height: 68px;&quot;&gt;&lt;span&gt;React 빌드 결과물이 NestJS 프로젝트 내 특정 폴더(&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;server/dist/client&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;등)로 복사되거나, NestJS가 직접 참조하여 서빙&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.7442%; height: 68px;&quot;&gt;&lt;span&gt;- React: 독립적인 빌드 결과물 (&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;dist/&lt;/span&gt;&lt;span&gt;)을 정적 호스팅/CDN에 배포&lt;/span&gt;&lt;span&gt;&amp;lt;br/&amp;gt;&lt;/span&gt;&lt;span&gt;- NestJS: 독립적인 빌드 결과물 (&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;dist/&lt;/span&gt;&lt;span&gt;)을 서버에 배포&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 68px;&quot;&gt;
&lt;td style=&quot;width: 12.093%; height: 68px;&quot;&gt;&lt;b&gt;&lt;span&gt;코드 공유 방식&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 29.7674%; height: 68px;&quot;&gt;&lt;span&gt;- React -&amp;gt; NestJS: 불가능 (API 호출)&lt;/span&gt;&lt;span&gt;&amp;lt;br/&amp;gt;&lt;/span&gt;&lt;span&gt;- NestJS -&amp;gt; React: 불가능 (API 응답)&lt;/span&gt;&lt;span&gt;&amp;lt;br/&amp;gt;&lt;/span&gt;&lt;span&gt;- 동일 프로젝트 내 타입/유틸리티 공유는 상대 경로로 가능하나 권장되지 않음.&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.7442%; height: 68px;&quot;&gt;&lt;span&gt;API 계약(명세)을 통한 완전한 분리. 코드 직접 공유 없음 (단, 타입 정의 등은 별도 패키지로 만들어 공유 가능)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 41px;&quot;&gt;
&lt;td style=&quot;width: 12.093%; height: 41px;&quot;&gt;&lt;b&gt;&lt;span&gt;설정 파일 (예:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;tsconfig.json&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;.eslintrc.js&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 29.7674%; height: 41px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;client/&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;server/&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;각각 존재&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.7442%; height: 41px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;crm-frontend/&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;crm-backend/&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;각각 존재&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 68px;&quot;&gt;
&lt;td style=&quot;width: 12.093%; height: 68px;&quot;&gt;&lt;b&gt;&lt;span&gt;개발 환경 실행&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 29.7674%; height: 68px;&quot;&gt;&lt;span&gt;단일&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;npm start&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(내부적으로 React, NestJS 서버 동시 실행 스크립트 구성) 또는 NestJS 서버만 실행 (React는 빌드 후 서빙)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.7442%; height: 68px;&quot;&gt;&lt;span&gt;프론트엔드 서버, 백엔드 서버 각각 별도 터미널에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;npm start&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;핵심 차이점 요약&lt;/span&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;프로젝트 결합도 및 독립성:&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;옵션 1 (통합):&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;프론트엔드와 백엔드가 하나의 프로젝트 단위로 강하게 결합되어 있습니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;client&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;폴더는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;server&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;폴더의 일부처럼 취급될 수 있습니다. 배포도 하나의 단위로 이루어집니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;옵션 2 (분리):&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;프론트엔드와 백엔드가 완전히 독립된 프로젝트입니다. 각자의 생명주기(개발, 빌드, 배포)를 가집니다. API를 통해 통신하며 서로의 내부 구현에 대해 알 필요가 없습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;관리 단위:&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;옵션 1 (통합):&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;단일 저장소(repository)에서 관리되는 경우가 많습니다. 빌드 및 배포 파이프라인도 통합될 가능성이 높습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;옵션 2 (분리 - Polyrepo):&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;프론트엔드와 백엔드가 각각 별도의 저장소에서 관리될 수 있습니다. CI/CD 파이프라인도 분리됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;옵션 2 (분리 - Monorepo):&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;단일 저장소 내에 여러 독립적인 프로젝트(&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;apps/&lt;/span&gt;&lt;span&gt;)를 두고, 공유 가능한 코드(&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;libs/&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;또는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;packages/&lt;/span&gt;&lt;span&gt;)도 함께 관리합니다. 모노레포 도구(Nx, Turborepo 등)가 이를 효율적으로 관리하도록 돕습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;코드 공유:&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;옵션 1 (통합):&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;직접적인 코드 공유는 어렵고 권장되지 않지만, 이론적으로는 같은 파일 시스템 내에 있으므로 가능성은 열려 있습니다. (주로 타입 공유 정도)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;옵션 2 (분리 - Polyrepo):&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;코드 직접 공유는 불가능합니다. API 명세를 통해 상호작용합니다. 만약 공통 로직이나 타입이 필요하다면, 별도의 npm 패키지로 만들어 각 프로젝트에서 의존성으로 추가해야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;옵션 2 (분리 - Monorepo):&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;모노레포의 가장 큰 장점 중 하나로,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;libs/&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(또는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;packages/&lt;/span&gt;&lt;span&gt;) 디렉토리를 통해 프론트엔드와 백엔드 간에 타입 정의(DTOs), 유틸리티 함수, 심지어 UI 컴포넌트까지 손쉽게 공유할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;5. 최종 권고안&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;신규 CRM 시스템은 일반적으로 지속적인 기능 추가와 사용자 증가가 예상되는 서비스입니다. 따라서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span&gt;장기적인 확장성, 유지보수성, 팀 간 협업 효율성, 기술적 유연성&lt;/span&gt;&lt;/b&gt;&lt;span&gt;을 고려할 때,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span&gt;옵션 2: 서버 분리 - 독립 배포 아키텍처&lt;/span&gt;&lt;/b&gt;&lt;span&gt;를 채택하는 것을 강력히 권장합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;주요 사유:&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;확장성:&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;프론트엔드와 백엔드의 트래픽 및 리소스 요구사항이 다를 수 있으므로, 각각 독립적으로 확장하여 비용 효율성과 성능을 최적화할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;팀 생산성:&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;프론트엔드팀과 백엔드팀이 각자의 전문 영역에 집중하고, 독립적인 개발 및 배포 주기를 가져갈 수 있어 개발 속도와 품질을 높일 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;기술 선택의 유연성:&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;향후 특정 기술 스택의 업그레이드나 변경 시, 다른 부분에 미치는 영향을 최소화할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span&gt;견고성(Resilience):&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;한쪽 시스템의 장애가 다른 쪽 시스템에 직접적인 영향을 미치는 것을 방지할 수 있습니다 (예: 백엔드 API 서버 점검 중에도 캐시된 프론트엔드는 계속 서비스 가능).&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;물론, 옵션 2는 초기 설정의 복잡성(CORS, 인증, 다중 배포 파이프라인 등)이 존재하지만, 이는 잘 정립된 패턴과 도구(Docker, CI/CD 서비스, API Gateway 등)를 통해 관리 가능하며, 장기적인 이점을 고려할 때 충분히 감수할 만한 수준입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1a1c1e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>취미/프로그래밍</category>
      <author>Anything Doing OK</author>
      <guid isPermaLink="true">https://normal-operating.tistory.com/45</guid>
      <comments>https://normal-operating.tistory.com/45#entry45comment</comments>
      <pubDate>Thu, 22 May 2025 17:13:40 +0900</pubDate>
    </item>
    <item>
      <title>AWS LightSail 도메인 연결 후 웹 서버 띄우기(1)(2025ver.)</title>
      <link>https://normal-operating.tistory.com/44</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;995&quot; data-origin-height=&quot;367&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QmWH7/btsMjK4xYzg/Z3gDY5fd7g9vCPWBB2LTzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QmWH7/btsMjK4xYzg/Z3gDY5fd7g9vCPWBB2LTzK/img.png&quot; data-alt=&quot;최종적으로 띄울 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QmWH7/btsMjK4xYzg/Z3gDY5fd7g9vCPWBB2LTzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQmWH7%2FbtsMjK4xYzg%2FZ3gDY5fd7g9vCPWBB2LTzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;995&quot; height=&quot;367&quot; data-origin-width=&quot;995&quot; data-origin-height=&quot;367&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;최종적으로 띄울 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EC2 가 요금문제 또는 해킹 문제가 많아 가벼운 토이프로젝트는 Lightsail 을 선택하는 경우가 왕왕있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 AWS 에 가입 후&amp;nbsp;&lt;br /&gt;&lt;a href=&quot;https://lightsail.aws.amazon.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://lightsail.aws.amazon.com/&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1739542401319&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;https://lightsail.aws.amazon.com/ls/webapp&quot; data-og-description=&quot;&quot; data-og-host=&quot;lightsail.aws.amazon.com&quot; data-og-source-url=&quot;https://lightsail.aws.amazon.com/&quot; data-og-url=&quot;https://lightsail.aws.amazon.com/ls/webapp&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://lightsail.aws.amazon.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://lightsail.aws.amazon.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;https://lightsail.aws.amazon.com/ls/webapp&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;lightsail.aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이동&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;251&quot; data-origin-height=&quot;175&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oAQuB/btsMjRvF7bg/ocDfz6sFZMshbhKadcNnD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oAQuB/btsMjRvF7bg/ocDfz6sFZMshbhKadcNnD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oAQuB/btsMjRvF7bg/ocDfz6sFZMshbhKadcNnD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoAQuB%2FbtsMjRvF7bg%2FocDfz6sFZMshbhKadcNnD1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;251&quot; height=&quot;175&quot; data-origin-width=&quot;251&quot; data-origin-height=&quot;175&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;872&quot; data-origin-height=&quot;787&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cEoON5/btsMj5HaaEO/IpWKkWKp6qwLAss1H3rbwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cEoON5/btsMj5HaaEO/IpWKkWKp6qwLAss1H3rbwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cEoON5/btsMj5HaaEO/IpWKkWKp6qwLAss1H3rbwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcEoON5%2FbtsMj5HaaEO%2FIpWKkWKp6qwLAss1H3rbwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;872&quot; height=&quot;787&quot; data-origin-width=&quot;872&quot; data-origin-height=&quot;787&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 선택지들 선택&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지역은 잘못선택하면 접속 속도가 너무 느려지니 꼭 한국으로 선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;719&quot; data-origin-height=&quot;857&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beyJBh/btsMiYWOY6O/SQJWwq1rNh7qKXMRKfzQIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beyJBh/btsMiYWOY6O/SQJWwq1rNh7qKXMRKfzQIk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beyJBh/btsMiYWOY6O/SQJWwq1rNh7qKXMRKfzQIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeyJBh%2FbtsMiYWOY6O%2FSQJWwq1rNh7qKXMRKfzQIk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;719&quot; height=&quot;857&quot; data-origin-width=&quot;719&quot; data-origin-height=&quot;857&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;순서대로 선택한후 create instance 클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인스턴스는 삭제하고 만들일이 많다...인스턴스 만들 때 너무 공들이지 마시길....&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Select a Network type 에는 IPv6-only 로 가면 3.5 달러짜리 사용할 수 있는데 관련 문서가 적어서 패스...&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정하다가 머리털 다 빠질거같아서 그냥 6천원 더쓰고 건강지켰다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;358&quot; data-origin-height=&quot;242&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYoBiF/btsMkYUTkrL/tHQckD3mxFDo3IEmaxMdv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYoBiF/btsMkYUTkrL/tHQckD3mxFDo3IEmaxMdv1/img.png&quot; data-alt=&quot;아직 만들어지기전&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYoBiF/btsMkYUTkrL/tHQckD3mxFDo3IEmaxMdv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYoBiF%2FbtsMkYUTkrL%2FtHQckD3mxFDo3IEmaxMdv1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;358&quot; height=&quot;242&quot; data-origin-width=&quot;358&quot; data-origin-height=&quot;242&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;아직 만들어지기전&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;327&quot; data-origin-height=&quot;164&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dIlvWB/btsMj7SAJ7y/aX85ckG0kmxWnttInA9DOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dIlvWB/btsMj7SAJ7y/aX85ckG0kmxWnttInA9DOK/img.png&quot; data-alt=&quot;생성 완료!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dIlvWB/btsMj7SAJ7y/aX85ckG0kmxWnttInA9DOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdIlvWB%2FbtsMj7SAJ7y%2FaX85ckG0kmxWnttInA9DOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;327&quot; height=&quot;164&quot; data-origin-width=&quot;327&quot; data-origin-height=&quot;164&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;생성 완료!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;698&quot; data-origin-height=&quot;599&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYvsen/btsMkDi7cDa/40s2KmZAkXQgSbHtJOkuL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYvsen/btsMkDi7cDa/40s2KmZAkXQgSbHtJOkuL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYvsen/btsMkDi7cDa/40s2KmZAkXQgSbHtJOkuL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYvsen%2FbtsMkDi7cDa%2F40s2KmZAkXQgSbHtJOkuL0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;698&quot; height=&quot;599&quot; data-origin-width=&quot;698&quot; data-origin-height=&quot;599&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ssh key 다운해준다 (추후 vscode 에서 연결할 때 필요)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;685&quot; data-origin-height=&quot;283&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tJ49X/btsMkxwC72x/lrOWjps3LZbRxqAeUBnRj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tJ49X/btsMkxwC72x/lrOWjps3LZbRxqAeUBnRj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tJ49X/btsMkxwC72x/lrOWjps3LZbRxqAeUBnRj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtJ49X%2FbtsMkxwC72x%2FlrOWjps3LZbRxqAeUBnRj0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;685&quot; height=&quot;283&quot; data-origin-width=&quot;685&quot; data-origin-height=&quot;283&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Attach static IP 클릭( 고정 아이피 생성)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;649&quot; data-origin-height=&quot;211&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czCbQf/btsMi1stMsX/8nWhwe4h8LVC87CxKkpMj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czCbQf/btsMi1stMsX/8nWhwe4h8LVC87CxKkpMj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czCbQf/btsMi1stMsX/8nWhwe4h8LVC87CxKkpMj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FczCbQf%2FbtsMi1stMsX%2F8nWhwe4h8LVC87CxKkpMj0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;649&quot; height=&quot;211&quot; data-origin-width=&quot;649&quot; data-origin-height=&quot;211&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 이렇게 고정 아이픽 ㅏ생성이된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 도메인을 구입하면 되는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://aws.amazon.com/ko/route53/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://aws.amazon.com/ko/route53/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1739548325271&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;company&quot; data-og-title=&quot;Amazon Route 53 - DNS 서비스 - AWS&quot; data-og-description=&quot;Amazon Virtual Private Cloud(VPC)에 사용자 지정 도메인 이름을 할당하고 액세스합니다. DNS 데이터를 퍼블릭 인터넷에 노출하지 않고 내부 AWS 리소스 및 서버를 사용합니다.&quot; data-og-host=&quot;aws.amazon.com&quot; data-og-source-url=&quot;https://aws.amazon.com/ko/route53/&quot; data-og-url=&quot;https://aws.amazon.com/ko/route53/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/l1Zto/hyYf0NAhNK/9szbUcmNMibZWMkXUDzRek/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/kV5lr/hyYfVMgOqd/IqKf4sMkeDigWTPqwO55K0/img.png?width=179&amp;amp;height=109&amp;amp;face=0_0_179_109,https://scrap.kakaocdn.net/dn/Mqt1O/hyYcUuf1XE/3m4B2MxIXOfikQglnSxH1k/img.png?width=2360&amp;amp;height=1320&amp;amp;face=0_0_2360_1320&quot;&gt;&lt;a href=&quot;https://aws.amazon.com/ko/route53/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://aws.amazon.com/ko/route53/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/l1Zto/hyYf0NAhNK/9szbUcmNMibZWMkXUDzRek/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/kV5lr/hyYfVMgOqd/IqKf4sMkeDigWTPqwO55K0/img.png?width=179&amp;amp;height=109&amp;amp;face=0_0_179_109,https://scrap.kakaocdn.net/dn/Mqt1O/hyYcUuf1XE/3m4B2MxIXOfikQglnSxH1k/img.png?width=2360&amp;amp;height=1320&amp;amp;face=0_0_2360_1320');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Amazon Route 53 - DNS 서비스 - AWS&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Amazon Virtual Private Cloud(VPC)에 사용자 지정 도메인 이름을 할당하고 액세스합니다. DNS 데이터를 퍼블릭 인터넷에 노출하지 않고 내부 AWS 리소스 및 서버를 사용합니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로 이동후&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1951&quot; data-origin-height=&quot;727&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3fxFy/btsMkauX3xM/NWVaDUohoblzdutAkjckvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3fxFy/btsMkauX3xM/NWVaDUohoblzdutAkjckvk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3fxFy/btsMkauX3xM/NWVaDUohoblzdutAkjckvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3fxFy%2FbtsMkauX3xM%2FNWVaDUohoblzdutAkjckvk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1951&quot; height=&quot;727&quot; data-origin-width=&quot;1951&quot; data-origin-height=&quot;727&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메인 페이지 -&amp;gt; Rout53 시작하기 -&amp;gt; 좌측 Side menu 에서 등록된 도메인 도메인 등록 클릭&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;747&quot; data-origin-height=&quot;798&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7PdSS/btsMj9XaIW2/5sldN47JIq61JowUKcLfEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7PdSS/btsMj9XaIW2/5sldN47JIq61JowUKcLfEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7PdSS/btsMj9XaIW2/5sldN47JIq61JowUKcLfEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7PdSS%2FbtsMj9XaIW2%2F5sldN47JIq61JowUKcLfEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;747&quot; height=&quot;798&quot; data-origin-width=&quot;747&quot; data-origin-height=&quot;798&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검색 후 마음에 드는 도메인 클릭 여기는 비싼 거 밖에 안나왔지만&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czPAOA/btsMjBmziqy/ZD6DHhvHQBhPnOEmSvI0h1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czPAOA/btsMjBmziqy/ZD6DHhvHQBhPnOEmSvI0h1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czPAOA/btsMjBmziqy/ZD6DHhvHQBhPnOEmSvI0h1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FczPAOA%2FbtsMjBmziqy%2FZD6DHhvHQBhPnOEmSvI0h1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;756&quot; height=&quot;456&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;456&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 .link 형식의 도메인은 싸니까 부담없이 구매할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1284&quot; data-origin-height=&quot;393&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FjzAp/btsMjLoRXBC/NmnLnSG0tAzMtzAJbw8ST0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FjzAp/btsMjLoRXBC/NmnLnSG0tAzMtzAJbw8ST0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FjzAp/btsMjLoRXBC/NmnLnSG0tAzMtzAJbw8ST0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFjzAp%2FbtsMjLoRXBC%2FNmnLnSG0tAzMtzAJbw8ST0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1284&quot; height=&quot;393&quot; data-origin-width=&quot;1284&quot; data-origin-height=&quot;393&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;선택하고 자동갱신 비활성화 또는 활성화 (요금이 갱신되면서 많이 나올 수 있음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 -&amp;gt; 다음 하고 나서 결제 하면된다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1634&quot; data-origin-height=&quot;121&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c8TVC4/btsMjKwQrd3/jpuiecT8TIN8Z2MjlaKsT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c8TVC4/btsMjKwQrd3/jpuiecT8TIN8Z2MjlaKsT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c8TVC4/btsMjKwQrd3/jpuiecT8TIN8Z2MjlaKsT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc8TVC4%2FbtsMjKwQrd3%2FjpuiecT8TIN8Z2MjlaKsT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1634&quot; height=&quot;121&quot; data-origin-width=&quot;1634&quot; data-origin-height=&quot;121&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 aws 가입할 때 등록한 이메일로 등록완료 이메일이 온다.(이미지 미첨부)&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1655&quot; data-origin-height=&quot;193&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bChTWE/btsMkt2bxVg/n8142iRbtSXfrF1o2OG8oK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bChTWE/btsMkt2bxVg/n8142iRbtSXfrF1o2OG8oK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bChTWE/btsMkt2bxVg/n8142iRbtSXfrF1o2OG8oK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbChTWE%2FbtsMkt2bxVg%2Fn8142iRbtSXfrF1o2OG8oK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1655&quot; height=&quot;193&quot; data-origin-width=&quot;1655&quot; data-origin-height=&quot;193&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존걸로 보니까 몇시간 걸리는듯...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에 있는 도메인으로 진행합니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;256&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V9fG7/btsMkMf38tT/ORw0v7qOZlzbf7CiUP2RDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V9fG7/btsMkMf38tT/ORw0v7qOZlzbf7CiUP2RDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V9fG7/btsMkMf38tT/ORw0v7qOZlzbf7CiUP2RDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV9fG7%2FbtsMkMf38tT%2FORw0v7qOZlzbf7CiUP2RDk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;830&quot; height=&quot;256&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;256&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 이름 서버까지 업데이트 되면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;698&quot; data-origin-height=&quot;564&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8VB4W/btsMiYWQ1GO/UN0gQOmsi43kHAKXeBp3X1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8VB4W/btsMiYWQ1GO/UN0gQOmsi43kHAKXeBp3X1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8VB4W/btsMiYWQ1GO/UN0gQOmsi43kHAKXeBp3X1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8VB4W%2FbtsMiYWQ1GO%2FUN0gQOmsi43kHAKXeBp3X1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;698&quot; height=&quot;564&quot; data-origin-width=&quot;698&quot; data-origin-height=&quot;564&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인스턴스 -&amp;gt; Domains 가서 순서대로 설정해주면 된다 하고 하단의 Save 누르기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;All subdomains ~ 는 www.구매한도메인. 으로 가도되고 ww.&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;구매한도메인.&lt;span&gt;&amp;nbsp; 으로가도된다. 해당 고정 IP에 연결된 서버를 띄워준다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;인스턴스에서 nginx 관련해서 따로 설정해줄 건 없다. 기존에 설치되어있다. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;496&quot; data-origin-height=&quot;456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRri7B/btsMiFXnVk7/7kuZxYegyLGBmTBpkf8HZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRri7B/btsMiFXnVk7/7kuZxYegyLGBmTBpkf8HZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRri7B/btsMiFXnVk7/7kuZxYegyLGBmTBpkf8HZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRri7B%2FbtsMiFXnVk7%2F7kuZxYegyLGBmTBpkf8HZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;496&quot; height=&quot;456&quot; data-origin-width=&quot;496&quot; data-origin-height=&quot;456&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 이렇게 생김 Apache는 안깔려있는듯...?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 ssh 접속 하나도 안하고 웹 페이지에서만 딸깍 딸깍으로 설정 완료했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ 3줄 요약(주의사항)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 인스턴스는 한국으로 설정하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 도메인 등록후 이름서버 등록까지는 시간이 걸림(5시간 정도)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 포스팅은 인스턴스 vscode 연결하기로 오겠습니다.&lt;/p&gt;</description>
      <category>취미/프로그래밍</category>
      <author>Anything Doing OK</author>
      <guid isPermaLink="true">https://normal-operating.tistory.com/44</guid>
      <comments>https://normal-operating.tistory.com/44#entry44comment</comments>
      <pubDate>Sat, 15 Feb 2025 01:46:16 +0900</pubDate>
    </item>
    <item>
      <title>Laravel Sail을 활용한 MySQL 설정과 개발환경 구축</title>
      <link>https://normal-operating.tistory.com/42</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://normal-operating.tistory.com/5&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://normal-operating.tistory.com/5&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1735881219001&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;WSL2 와 Docker를 이용한 Laravel 개발환경 구축하기&quot; data-og-description=&quot;https://laravel.kr/docs/9.x/installation&amp;nbsp;라라벨 9.x - 설치하기라라벨 한글 메뉴얼 9.x - 설치하기laravel.kr공식문서가 굉장히 잘되어있다 그럼에도 설치하는 구축하는 도중 몇가지 실수할 수 있는 점이 있&quot; data-og-host=&quot;normal-operating.tistory.com&quot; data-og-source-url=&quot;https://normal-operating.tistory.com/5&quot; data-og-url=&quot;https://normal-operating.tistory.com/5&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/HiWvd/hyXWvNOR79/VEjX8F2MYE5PWs2IJvWO31/img.png?width=800&amp;amp;height=486&amp;amp;face=0_0_800_486,https://scrap.kakaocdn.net/dn/cMXozV/hyXSwt32nV/iewjqKnYxvUO0iEsbrK4Uk/img.png?width=800&amp;amp;height=486&amp;amp;face=0_0_800_486,https://scrap.kakaocdn.net/dn/cTdzqf/hyXWscuWlX/N2PXyDmrsIE77UgNnz3Lc1/img.png?width=1507&amp;amp;height=916&amp;amp;face=0_0_1507_916&quot;&gt;&lt;a href=&quot;https://normal-operating.tistory.com/5&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://normal-operating.tistory.com/5&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/HiWvd/hyXWvNOR79/VEjX8F2MYE5PWs2IJvWO31/img.png?width=800&amp;amp;height=486&amp;amp;face=0_0_800_486,https://scrap.kakaocdn.net/dn/cMXozV/hyXSwt32nV/iewjqKnYxvUO0iEsbrK4Uk/img.png?width=800&amp;amp;height=486&amp;amp;face=0_0_800_486,https://scrap.kakaocdn.net/dn/cTdzqf/hyXWscuWlX/N2PXyDmrsIE77UgNnz3Lc1/img.png?width=1507&amp;amp;height=916&amp;amp;face=0_0_1507_916');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;WSL2 와 Docker를 이용한 Laravel 개발환경 구축하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;https://laravel.kr/docs/9.x/installation&amp;nbsp;라라벨 9.x - 설치하기라라벨 한글 메뉴얼 9.x - 설치하기laravel.kr공식문서가 굉장히 잘되어있다 그럼에도 설치하는 구축하는 도중 몇가지 실수할 수 있는 점이 있&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;normal-operating.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 게시글에서 이어지는 내용입니다. 해당 프로젝트를 git 으로 관리하고,&lt;br /&gt;다른 컴퓨터에 git clone 을 받은 후 실행하기까지 설정 사항과 에러 해결 방법을 작성한 게시글입니다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1267&quot; data-origin-height=&quot;426&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dAVsmH/btsLB2FIEDc/VhvIM07oBbNJGz7UQbSot1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dAVsmH/btsLB2FIEDc/VhvIM07oBbNJGz7UQbSot1/img.png&quot; data-alt=&quot;git clone 후 sail up 명령어를 실행하여 해당 화면 띄워야한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dAVsmH/btsLB2FIEDc/VhvIM07oBbNJGz7UQbSot1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdAVsmH%2FbtsLB2FIEDc%2FVhvIM07oBbNJGz7UQbSot1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1267&quot; height=&quot;426&quot; data-origin-width=&quot;1267&quot; data-origin-height=&quot;426&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;git clone 후 sail up 명령어를 실행하여 해당 화면 띄워야한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기초되는 환경은 다음과 같다. &lt;br /&gt;1. WSL2 환경 구축이 되어있을 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Docker&amp;nbsp; Desktop 설치가 되고 환경 설정이 되어있을 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git clone 을 받게되면 해당 폴더 구조로 이루어져 있다. (cd 해당폴더)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;567&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/R16rY/btsLDv03daw/ILZi4nxHvbShJRcy6YxWR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/R16rY/btsLDv03daw/ILZi4nxHvbShJRcy6YxWR1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/R16rY/btsLDv03daw/ILZi4nxHvbShJRcy6YxWR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FR16rY%2FbtsLDv03daw%2FILZi4nxHvbShJRcy6YxWR1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;712&quot; height=&quot;567&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;567&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1735882376523&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cp .env.example .env&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령어 실행 .env 가 없을 경우&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 .env 파일을 열어서 해당 속성으로 변경&lt;/p&gt;
&lt;pre id=&quot;code_1735882475193&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=root&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.env 파일이 있는 경우는 실행하지 않아도 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;552&quot; data-origin-height=&quot;52&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TMibR/btsLEGAAHfX/CoRuH6qsUcNO8YSFXYx1C0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TMibR/btsLEGAAHfX/CoRuH6qsUcNO8YSFXYx1C0/img.png&quot; data-alt=&quot;sail up 명령어가 실패할 경우&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TMibR/btsLEGAAHfX/CoRuH6qsUcNO8YSFXYx1C0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTMibR%2FbtsLEGAAHfX%2FCoRuH6qsUcNO8YSFXYx1C0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;552&quot; height=&quot;52&quot; data-origin-width=&quot;552&quot; data-origin-height=&quot;52&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;sail up 명령어가 실패할 경우&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-bash: ./vendor/bin/sail: No such file or directory 로 명령어가 실패할 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 프로젝트 directory 에서 composer require laravel/sail --dev 명령어를 실행해준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;647&quot; data-origin-height=&quot;397&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFZcuX/btsLDZm4u35/Cj3YOePc3w9IdYdmXwxZwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFZcuX/btsLDZm4u35/Cj3YOePc3w9IdYdmXwxZwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFZcuX/btsLDZm4u35/Cj3YOePc3w9IdYdmXwxZwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFZcuX%2FbtsLDZm4u35%2FCj3YOePc3w9IdYdmXwxZwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;647&quot; height=&quot;397&quot; data-origin-width=&quot;647&quot; data-origin-height=&quot;397&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대강 이런 식으로 설치가 완료된다.&lt;/p&gt;
&lt;pre id=&quot;code_1735883117287&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Error response from daemon: Ports are not available: exposing port TCP 0.0.0.0:3306 -&amp;gt; 0.0.0.0:0: 
listen tcp 0.0.0.0:3306: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에러가 뜰 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docker ps 로 해당 포트를 사용중인 container를 찾아서 종료시키거나&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.env 파일과 docker-compose.yml 파일에서 포트를 변경해준다. (추천)&lt;/p&gt;
&lt;pre id=&quot;code_1735883385668&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;   mysql:
        image: 'mysql/mysql-server:8.0'
        ports:
            - '${FORWARD_DB_PORT:-3308}:3308'
        environment:
            MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
            MYSQL_ROOT_HOST: '%'
            MYSQL_DATABASE: '${DB_DATABASE}'
            MYSQL_USER: '${DB_USERNAME}'
            MYSQL_PASSWORD: '${DB_PASSWORD}'
            MYSQL_ALLOW_EMPTY_PASSWORD: 1
        volumes:&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 변경&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 ./vendor/bin/sail up 명령어를 써주면&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;403&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tBFDw/btsLEHM3bre/zCtHDKcjFIQOiXMBdzDlik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tBFDw/btsLEHM3bre/zCtHDKcjFIQOiXMBdzDlik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tBFDw/btsLEHM3bre/zCtHDKcjFIQOiXMBdzDlik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtBFDw%2FbtsLEHM3bre%2FzCtHDKcjFIQOiXMBdzDlik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;403&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;403&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동작은 잘되지만&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #111827; text-align: start;&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;No application encryption key has been specified.&lt;/div&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;에러가 발생한다.&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;해결방법은 해당 Laravel application 을 실행한 후&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;./vendor/bin/sail artisan key:generate 명령어를 쳐서 APP_KEY 를 생성&lt;/div&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;&amp;nbsp;INFO&amp;nbsp;&amp;nbsp;Application key set successfully.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;텍스트가 뜨면서 성공이 뜬다.&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;확인하고 싶으면 .env 파일 가면 확인가능하다.&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SQLSTATE[HY000] [2002] Connection refused (Connection: mysql, SQL: select * from `sessions` where `id` = RLR6XGlxGaJRG6AKFXqVBQtGYAmLK9cYJRcnVEOX limit 1) 웹 페이지에서 해당 에러가 뜰 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mysql image 삭제 후 재설치하고 다시 sail up 명령어를 실행하면 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #111827; text-align: right;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #111827; text-align: right;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #111827; text-align: right;&quot;&gt;&amp;nbsp;&lt;/div&gt;</description>
      <category>취미/프로그래밍</category>
      <author>Anything Doing OK</author>
      <guid isPermaLink="true">https://normal-operating.tistory.com/42</guid>
      <comments>https://normal-operating.tistory.com/42#entry42comment</comments>
      <pubDate>Fri, 3 Jan 2025 17:55:49 +0900</pubDate>
    </item>
    <item>
      <title>Spring Boot &amp;amp; Redis 사용한 이메일 인증코드 구현</title>
      <link>https://normal-operating.tistory.com/41</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;저번에 Laravel 로 이메일 인증코드를 구현하는 방법을 알아보았다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://normal-operating.tistory.com/37&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://normal-operating.tistory.com/37&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1732720653866&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Laravel 이메일 인증코드 구현&quot; data-og-description=&quot;https://normal-operating.tistory.com/36&amp;nbsp;&amp;nbsp;Laravel 이메일 인증 연동 구현하기회사에서 레거시만 사용하다보니 기능을 간단하게 구현할 수 있는 laravel 을 통해서 구현해보았다.&amp;nbsp;&amp;nbsp;진행하면서 발생한 오류 &quot; data-og-host=&quot;normal-operating.tistory.com&quot; data-og-source-url=&quot;https://normal-operating.tistory.com/37&quot; data-og-url=&quot;https://normal-operating.tistory.com/37&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cw5xeY/hyXGHf6VFN/UhC3HG44ly7JT6D3ubUzbk/img.png?width=481&amp;amp;height=577&amp;amp;face=0_0_481_577,https://scrap.kakaocdn.net/dn/fbXCO/hyXC8Gq23s/iL0xXWyx1QK4tkRD6g8t81/img.png?width=481&amp;amp;height=577&amp;amp;face=0_0_481_577,https://scrap.kakaocdn.net/dn/dk8ZN9/hyXGHf6VHl/9mzgAO6AO8XYw3YxGukYk0/img.png?width=481&amp;amp;height=577&amp;amp;face=0_0_481_577&quot;&gt;&lt;a href=&quot;https://normal-operating.tistory.com/37&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://normal-operating.tistory.com/37&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cw5xeY/hyXGHf6VFN/UhC3HG44ly7JT6D3ubUzbk/img.png?width=481&amp;amp;height=577&amp;amp;face=0_0_481_577,https://scrap.kakaocdn.net/dn/fbXCO/hyXC8Gq23s/iL0xXWyx1QK4tkRD6g8t81/img.png?width=481&amp;amp;height=577&amp;amp;face=0_0_481_577,https://scrap.kakaocdn.net/dn/dk8ZN9/hyXGHf6VHl/9mzgAO6AO8XYw3YxGukYk0/img.png?width=481&amp;amp;height=577&amp;amp;face=0_0_481_577');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Laravel 이메일 인증코드 구현&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;https://normal-operating.tistory.com/36&amp;nbsp;&amp;nbsp;Laravel 이메일 인증 연동 구현하기회사에서 레거시만 사용하다보니 기능을 간단하게 구현할 수 있는 laravel 을 통해서 구현해보았다.&amp;nbsp;&amp;nbsp;진행하면서 발생한 오류&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;normal-operating.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;244&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwoLDB/btsKZNt2kQj/s4F3ZFnuiHYLHsMlat3In1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwoLDB/btsKZNt2kQj/s4F3ZFnuiHYLHsMlat3In1/img.png&quot; data-alt=&quot;동작이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwoLDB/btsKZNt2kQj/s4F3ZFnuiHYLHsMlat3In1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwoLDB%2FbtsKZNt2kQj%2Fs4F3ZFnuiHYLHsMlat3In1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;636&quot; height=&quot;244&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;244&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;동작이미지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기능은 거의 비슷하다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Redis 설치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jaey0ng.tistory.com/54&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://jaey0ng.tistory.com/54&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1732721743853&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Redis] 윈도우 환경에서 redis 설치/실행하기&quot; data-og-description=&quot;윈도우 설치 Redis 공식문서입니다. https://redis.io/docs/install/install-redis/install-redis-on-windows/ Install Redis on Windows Use Redis on Windows for development redis.io 레디스 공식문서에는 위처럼 사용하면 된다라고 써&quot; data-og-host=&quot;jaey0ng.tistory.com&quot; data-og-source-url=&quot;https://jaey0ng.tistory.com/54&quot; data-og-url=&quot;https://jaey0ng.tistory.com/54&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/N9skV/hyXDcB06uL/PY50bO0OB8rw8NUxlyghv1/img.png?width=512&amp;amp;height=175&amp;amp;face=0_0_512_175,https://scrap.kakaocdn.net/dn/fZgjj/hyXC78AETZ/rMaAXr2Le1QVWtT6KnXYz0/img.png?width=512&amp;amp;height=175&amp;amp;face=0_0_512_175,https://scrap.kakaocdn.net/dn/FXfMT/hyXDmkno7z/dkNsx97tZMh7PUAOCk5k7k/img.png?width=773&amp;amp;height=760&amp;amp;face=0_0_773_760&quot;&gt;&lt;a href=&quot;https://jaey0ng.tistory.com/54&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jaey0ng.tistory.com/54&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/N9skV/hyXDcB06uL/PY50bO0OB8rw8NUxlyghv1/img.png?width=512&amp;amp;height=175&amp;amp;face=0_0_512_175,https://scrap.kakaocdn.net/dn/fZgjj/hyXC78AETZ/rMaAXr2Le1QVWtT6KnXYz0/img.png?width=512&amp;amp;height=175&amp;amp;face=0_0_512_175,https://scrap.kakaocdn.net/dn/FXfMT/hyXDmkno7z/dkNsx97tZMh7PUAOCk5k7k/img.png?width=773&amp;amp;height=760&amp;amp;face=0_0_773_760');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Redis] 윈도우 환경에서 redis 설치/실행하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;윈도우 설치 Redis 공식문서입니다. https://redis.io/docs/install/install-redis/install-redis-on-windows/ Install Redis on Windows Use Redis on Windows for development redis.io 레디스 공식문서에는 위처럼 사용하면 된다라고 써&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jaey0ng.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 점은 Redis 를 사용해서 인증번호를 저장하고 인증번호를 이메일로 전송해준다는 점&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정사항&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. SecurityConfig 에 인증 관련 경로인&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;&quot;/api/email/send&quot;,&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;를 추가해준다&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;.requestMatchers(&quot;/login&quot;, &quot;/register&quot;,&quot;/api/register&quot;, &quot;/api/email/send&quot;, &quot;/verify&quot;).permitAll() // 인증 관련 경로는 누구나 접근 가능&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. application.properties 에 다음과 같이 설정 추가&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=인증받은gmail
spring.mail.password=16자리-없이
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=5000
spring.mail.properties.mail.smtp.writetimeout=5000
spring.mail.transport.protocol=smtp&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.build.gradle의 dependencies에 다음과 같이 설정 추가&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;clean&quot;&gt;&lt;code&gt;implementation 'org.springframework.boot:spring-boot-starter-mail'&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. MailConfig 생성 후&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;package com.application.member.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;

import java.util.Properties;

@Configuration
public class MailConfig {

    @Bean
    public JavaMailSender getJavaMailSender() {
        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
        mailSender.setHost(&quot;smtp.gmail.com&quot;);
        mailSender.setPort(587);

        mailSender.setUsername(&quot;이메일&quot;);
        mailSender.setPassword(&quot;인증코드16자리-없이&quot;);

        Properties props = mailSender.getJavaMailProperties();
        props.put(&quot;mail.transport.protocol&quot;, &quot;smtp&quot;);
        props.put(&quot;mail.smtp.auth&quot;, &quot;true&quot;);
        props.put(&quot;mail.smtp.starttls.enable&quot;, &quot;true&quot;);
        props.put(&quot;mail.debug&quot;, &quot;true&quot;);

//      SSL 설정 추가
        props.put(&quot;mail.smtp.ssl.trust&quot;, &quot;smtp.gmail.com&quot;);
        props.put(&quot;mail.smtp.ssl.protocols&quot;, &quot;TLSv1.2&quot;);

        return mailSender;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 코드 작성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. RedisConfig 에&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;crystal&quot;&gt;&lt;code&gt;package com.application.member.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;

@Configuration
public class RedisConfig {

    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory connectionFactory) {
        return new StringRedisTemplate(connectionFactory);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 코드 작성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6.&amp;nbsp; EmailService에&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;@Service
public class EmailService {

    private final JavaMailSender mailSender;
    private final StringRedisTemplate redisTemplate;

    public EmailService(JavaMailSender mailSender, StringRedisTemplate redisTemplate) {
        this.mailSender = mailSender;
        this.redisTemplate = redisTemplate;
    }

    // 인증번호 생성
    public String generateVerificationCode() {
        Random random = new Random();
        int code = 100000 + random.nextInt(900000); // 6자리 랜덤 숫자
        return String.valueOf(code);
    }

    // 인증번호 Redis에 저장 (5분 유효기간 설정)
    public void saveVerificationCode(String email, String verificationCode) {
        ValueOperations&amp;lt;String, String&amp;gt; ops = redisTemplate.opsForValue();
        ops.set(email, verificationCode, 5, TimeUnit.MINUTES); // 5분 TTL
    }

    // 인증번호 검증
    public boolean verifyCode(String email, String code) {
        ValueOperations&amp;lt;String, String&amp;gt; ops = redisTemplate.opsForValue();
        String storedCode = ops.get(email);

        if (storedCode != null &amp;amp;&amp;amp; storedCode.equals(code)) {
            redisTemplate.delete(email); // 인증 성공 시 Redis에서 제거
            return true;
        }
        return false;
    }
    // 이메일 발송
    public void sendVerificationEmail(String toEmail, String verificationCode) {
        MimeMessage message = mailSender.createMimeMessage();
        try {
            message.setFrom(toEmail);
            message.setRecipients(MimeMessage.RecipientType.TO, toEmail);
            String body = &quot;&quot;;
            body += &quot;&amp;lt;h3&amp;gt;&quot; + &quot;요청하신 인증 번호입니다.&quot; + &quot;&amp;lt;/h3&amp;gt;&quot;;
            body += &quot;&amp;lt;h1&amp;gt;&quot; + verificationCode + &quot;&amp;lt;/h1&amp;gt;&quot;;
            body += &quot;&amp;lt;h3&amp;gt;&quot; + &quot;감사합니다.&quot; + &quot;&amp;lt;/h3&amp;gt;&quot;;
            message.setText(body,&quot;UTF-8&quot;, &quot;html&quot;);
            mailSender.send(message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 코드작성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7.&amp;nbsp; EmailController 에&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;kotlin&quot;&gt;&lt;code&gt;@RestController
@RequestMapping(&quot;/api/email&quot;)
public class EmailController {

    private final EmailService emailService;

    public EmailController(EmailService emailService) {
        this.emailService = emailService;
    }

    @PostMapping(&quot;/send&quot;)
    public String sendVerificationCode(@RequestParam String email) {
        System.out.println(&quot;Received email: &quot; + email);
        String verificationCode = emailService.generateVerificationCode();
        System.out.println(&quot;Generated Verification Code: &quot; + verificationCode);
        emailService.saveVerificationCode(email, verificationCode); // Redis에 저장
        emailService.sendVerificationEmail(email, verificationCode); // 이메일 발송
        return &quot;인증번호가 발송되었습니다.&quot;;

    }
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 코드작성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프론트 코드&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;  const email = document.getElementById(&quot;email&quot;).value;
  const response = await fetch('/api/email/send', {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({ email })
  });&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring Security 때문에 고생좀 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2일에 걸쳐서 구현하게 되어 빠져있는 부분이 있을 수 있습니다.&amp;nbsp;&lt;/p&gt;</description>
      <category>취미/프로그래밍</category>
      <category>이메일 인증 구현</category>
      <author>Anything Doing OK</author>
      <guid isPermaLink="true">https://normal-operating.tistory.com/41</guid>
      <comments>https://normal-operating.tistory.com/41#entry41comment</comments>
      <pubDate>Thu, 28 Nov 2024 00:40:47 +0900</pubDate>
    </item>
  </channel>
</rss>