<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>nowcow의 개발일지</title>
    <link>https://nowcow.tistory.com/</link>
    <description>백엔드 개발자 </description>
    <language>ko</language>
    <pubDate>Fri, 22 May 2026 03:10:02 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>nowcow</managingEditor>
    <item>
      <title>Synology Nas에 Docker로 Node.js 서버 구축하기</title>
      <link>https://nowcow.tistory.com/3</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;내친김에 진행했던 Spirng 프로젝트들을 배포해보고 싶어서 찾아보다가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Synology로 배포가 가능하다는 것을 발견.... 완전 만능이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Synology 자체가 Linux 기반이라 그런지 확장성이 무궁무진하다.&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; React + Node.js로 토이프로젝트를 진행 중이었는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지난번에 구축했던 데이터서버도 성공적으로 적용 해보았고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Node.js 서버도 구축해보면 좋겠다 싶어서 시도해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;개발환경&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/playlist?list=PLRx0vPvlEmdD1pSqKZiTihy5rplxecNpz&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.youtube.com/playlist?list=PLRx0vPvlEmdD1pSqKZiTihy5rplxecNpz&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1728374688086&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;React와 Node.js를 활용한 고객 관리 시스템 개발 강의&quot; data-og-description=&quot; &quot; data-og-host=&quot;www.youtube.com&quot; data-og-source-url=&quot;https://www.youtube.com/playlist?list=PLRx0vPvlEmdD1pSqKZiTihy5rplxecNpz&quot; data-og-url=&quot;http://www.youtube.com/playlist?list=PLRx0vPvlEmdD1pSqKZiTihy5rplxecNpz&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cJQX8u/hyXeaYqOYI/KcAmWIVJYpOtkTWdX6TBP1/img.jpg?width=480&amp;amp;height=270&amp;amp;face=0_0_480_270,https://scrap.kakaocdn.net/dn/FB0Yl/hyXd8sL21b/Lhoj2kICyWXtyaCQuA7od1/img.jpg?width=480&amp;amp;height=270&amp;amp;face=0_0_480_270&quot;&gt;&lt;a href=&quot;https://www.youtube.com/playlist?list=PLRx0vPvlEmdD1pSqKZiTihy5rplxecNpz&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.youtube.com/playlist?list=PLRx0vPvlEmdD1pSqKZiTihy5rplxecNpz&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cJQX8u/hyXeaYqOYI/KcAmWIVJYpOtkTWdX6TBP1/img.jpg?width=480&amp;amp;height=270&amp;amp;face=0_0_480_270,https://scrap.kakaocdn.net/dn/FB0Yl/hyXd8sL21b/Lhoj2kICyWXtyaCQuA7od1/img.jpg?width=480&amp;amp;height=270&amp;amp;face=0_0_480_270');&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;React와 Node.js를 활용한 고객 관리 시스템 개발 강의&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;www.youtube.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;React 복습도 할 겸, Node.js도 간단하게 배워볼 겸 해서 이 강의를 모두 듣고 토이 프로젝트를 완성했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;24년 9월기준, 영상에 나오는 React와 Node.js의 버전에서는 현재 지원되지 않는 라이브러리들이 있어서&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React 최신 안정화 버전 18.3.1, Node.js는 22.9.0 버전으로 진행했다.&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;Node.js에 대한 이해가 전혀 없었는데, 강의를 수강하면서 조금은 이해가 됐기때문에 서버를 구축할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Node.js 설치하기&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;우선 Synology Nas 패키지 센터에서 Docker를 설치한다. Docker의 활용도가 정말 무궁무진하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;612&quot; data-origin-height=&quot;434&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d5RHOE/btsJXMdp4fp/iFlQ0LcRMbOhGSCJFCE4T0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d5RHOE/btsJXMdp4fp/iFlQ0LcRMbOhGSCJFCE4T0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d5RHOE/btsJXMdp4fp/iFlQ0LcRMbOhGSCJFCE4T0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd5RHOE%2FbtsJXMdp4fp%2FiFlQ0LcRMbOhGSCJFCE4T0%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;612&quot; height=&quot;434&quot; data-origin-width=&quot;612&quot; data-origin-height=&quot;434&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;그리고 node를 관리할 폴더 하나를 만들어야한다. docker 라는 최상위 디렉토리 안에 node 폴더를 생성해주었고, 현재 진행중인 프로젝트 이름인 management 폴더를 하나 더 만들어 주었다. 폴더 안에 있어야할 파일들은 이따가 자세히 설명할 것이기 때문에 &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;일단 빈 폴더들만 만들어주면 된다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&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;859&quot; data-origin-height=&quot;319&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcFGuu/btsJXY5JWDA/HYimifuBwY34QVb6rJ96SK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcFGuu/btsJXY5JWDA/HYimifuBwY34QVb6rJ96SK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcFGuu/btsJXY5JWDA/HYimifuBwY34QVb6rJ96SK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcFGuu%2FbtsJXY5JWDA%2FHYimifuBwY34QVb6rJ96SK%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;859&quot; height=&quot;319&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;859&quot; data-origin-height=&quot;319&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Dokcer 설치가 완료되었으면 Docker를 열고, 레지스트리에서 node를 검색하고 자신의 개발환경에 맞는 node 버전을 설치하면 된다. (cmd창에서 node -v 입력하고 node 버전 확인.)&lt;/li&gt;
&lt;li&gt;나는 22.9.0 버전에서 개발을 진행했기 때문에 같은 버전으로 설치해주었다. 최신버전이 필요하다면 latest로 설치.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1056&quot; data-origin-height=&quot;396&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pRolI/btsJZJMO53M/McXqdhBmju3NEY9I7Uc44k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pRolI/btsJZJMO53M/McXqdhBmju3NEY9I7Uc44k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pRolI/btsJZJMO53M/McXqdhBmju3NEY9I7Uc44k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpRolI%2FbtsJZJMO53M%2FMcXqdhBmju3NEY9I7Uc44k%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;1056&quot; height=&quot;396&quot; data-origin-width=&quot;1056&quot; data-origin-height=&quot;396&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;설정페이지가 열리면 일반 설정에서는 딱히 건드릴 것은 없는 것 같고, 포트설정도... 어차피 ssh로 Node.js를 빌드하는 과정에서 포트를 지정해주면 되기 때문에 그냥 빈 포트 1111로 막 설정해주었다. 볼륨설정이 가장 중요하다.&lt;/li&gt;
&lt;/ul&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;655&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/or80b/btsJYJfXp3n/ZaJOaIkkddmwqRjxscme2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/or80b/btsJYJfXp3n/ZaJOaIkkddmwqRjxscme2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/or80b/btsJYJfXp3n/ZaJOaIkkddmwqRjxscme2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2For80b%2FbtsJYJfXp3n%2FZaJOaIkkddmwqRjxscme2K%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;655&quot; height=&quot;384&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;648&quot; data-origin-height=&quot;290&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oEE2U/btsJZ8rZXFG/rTXQkvmtrl5kxqEMQbbK8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oEE2U/btsJZ8rZXFG/rTXQkvmtrl5kxqEMQbbK8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oEE2U/btsJZ8rZXFG/rTXQkvmtrl5kxqEMQbbK8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoEE2U%2FbtsJZ8rZXFG%2FrTXQkvmtrl5kxqEMQbbK8K%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;648&quot; height=&quot;290&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;648&quot; data-origin-height=&quot;290&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;폴더추가에서 아까 만든 디렉토리를 설정한다. 나는 /docker/node/management 였다. 그리고 마운트 경로에 Node.js와 매핑되는 /home/node/app 이라는 경로를 입력해주면 설치 단계는 끝난다.&lt;/li&gt;
&lt;/ul&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;655&quot; data-origin-height=&quot;274&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/R3iYZ/btsJYUnZJMt/SSekxJiSCNuT89KNcKwig1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/R3iYZ/btsJYUnZJMt/SSekxJiSCNuT89KNcKwig1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/R3iYZ/btsJYUnZJMt/SSekxJiSCNuT89KNcKwig1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FR3iYZ%2FbtsJYUnZJMt%2FSSekxJiSCNuT89KNcKwig1%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;655&quot; height=&quot;274&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;274&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;h3 data-ke-size=&quot;size23&quot;&gt;Node.js 서버 Build를 위한 준비&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 /docker/node/management 디렉토리 안에 Build를 위해 필요한 파일들을 넣고 Build를 진행하면 서버가 구축된다.&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;우선 Dockerfile 이라는 파일이 필요하다.&amp;nbsp;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;IntelliJ 기준, 프로젝트 제일 상위 디렉토리에 Dokcerfile 이라는 파일을 만들어줘야 한다.&lt;/li&gt;
&lt;li&gt;우클릭 - New - file에서 확장자는 따로 지정하지 않고 Dockerfile 이라는 이름의 파일을 만들어 준다.&lt;/li&gt;
&lt;li&gt;Dockerfile 안에&amp;nbsp; docker 명령어들을 입력해준다. 아래는 예시&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1728394212190&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Node.js 이미지 설정
FROM node:22.9.0

# 작업 디렉토리 생성
WORKDIR /usr/src/app

# 패키지 파일을 복사
COPY package*.json ./

# 의존성 설치
RUN yarn install
RUN npm install
RUN npm install -g nodemon

# 애플리케이션 소스 복사
COPY . .

# 포트 노출
EXPOSE 6000

# 애플리케이션 시작
CMD [&quot;yarn&quot;, &quot;run&quot;, &quot;server&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;여기서 확인할 것은 본인 환경과 맞는 Node.js 버전을 맞춰주는 것, yarn / npm 등, 프로젝트의 서버에서 필요한 의존성을 설치해 주는 것(동영상 강의에서 yarn을 사용해서 여기에도 yarn을 설치해주었다.), 사용할 포트를 지정하는 것, 세가지다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Synology Nas에서 기본적으로 5000포트를 사용하기 때문에 나는 편의상 6000번 포트를 Node.js 서버에 사용하려고 6000번 포트를 지정해서 Dockerfile을 성공적으로 생성했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다음으로 필요한 파일은 package.json 파일이다. 아마 프로젝트를 만들면서 작성했기 때문에 파일만 복사해서 가져오면 될 것 같다. 스크립트에 &quot;server&quot;: &quot;nodemon server.js&quot; 라고 작성해 두었기 때문에 CMD [&quot;yarn&quot;, &quot;run&quot;, &quot;server&quot;] 명령어를 통해 server.js라는 파일을 실행하게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1728395180868&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;name&quot;: &quot;management&quot;,
  &quot;version&quot;: &quot;1.0.0&quot;,
  &quot;scripts&quot;: {
    &quot;client&quot;: &quot;cd client &amp;amp;&amp;amp; yarn start&quot;,
    &quot;server&quot;: &quot;nodemon server.js&quot;,
    &quot;dev&quot;: &quot;concurrently --kill-others-on-fail \&quot;yarn server\&quot; \&quot;yarn client\&quot;&quot;,
    &quot;start&quot;: &quot;node server.js&quot;
  },
  &quot;dependencies&quot;: {
    &quot;@mui/icons-material&quot;: &quot;^6.1.1&quot;,
    &quot;basic-ftp&quot;: &quot;^5.0.5&quot;,
    &quot;body-parser&quot;: &quot;1.18.3&quot;,
    &quot;express&quot;: &quot;^4.21.0&quot;,
    &quot;http-proxy-middleware&quot;: &quot;^3.0.2&quot;,
    &quot;mariadb&quot;: &quot;^3.3.2&quot;,
    &quot;multer&quot;: &quot;^1.4.5-lts.1&quot;,
    &quot;mysql&quot;: &quot;^2.18.1&quot;,
    &quot;path&quot;: &quot;^0.12.7&quot;
  },
  &quot;devDependencies&quot;: {
    &quot;concurrently&quot;: &quot;^4.0.1&quot;
  },
  &quot;description&quot;: &quot;React와 node.js로 만든 고객 관리 시스템 입니다.&quot;,
  &quot;main&quot;: &quot;server.js&quot;,
  &quot;keywords&quot;: [],
  &quot;author&quot;: &quot;&quot;,
  &quot;license&quot;: &quot;ISC&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;그리고 database.json 파일도 필요하다. 로컬에서 Node.js 서버를 DataBase와 연결할 때 작성했던 파일을 그대로 가져오면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1728395144691&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;host&quot;: &quot;시놀로지id.synology.me&quot;,
  &quot;user&quot;: &quot;id&quot;,
  &quot;password&quot;: &quot;pw&quot;,
  &quot;port&quot;: &quot;3306&quot;,
  &quot;database&quot;: &quot;management&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;yarn.lock 혹은 package-lock.json 파일도 필요하다. 두 파일을 혼용해서 사용하면 충돌이 일어날 수 있기 때문에 npm대신 yarn을 썼으면 yarn.lock파일을, npm을 사용한다면 package-lock.json 파일을 가져오도록 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마지막은 제일 중요한 server.js 파일이다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1728395351331&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const fs = require('fs');
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const port = process.env.PORT || 6000;
const ftp = require('basic-ftp');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true}));

const data = fs.readFileSync('./database.json');
const conf = JSON.parse(data);
const mysql = require('mysql');

const connection = mysql.createConnection({
    host: conf.host,
    user: conf.user,
    password: conf.password,
    port: conf.port,
    database: conf.database
});
connection.connect();&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;이런식으로 쭉 작성된 server.js파일인데, Dockerfile에서 지정해준 6000번 포트를 잘 확인해주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;const port = process.env.PORT || 6000;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;database.json 파일을 이용해 DataBase에도 성공적으로 연결 해주었다면 이제 Build를 위한 준비는 끝났다.&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;470&quot; data-origin-height=&quot;275&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxzndK/btsJ0cH3Dy1/NQbzN4l4ll513KK2rssDlK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxzndK/btsJ0cH3Dy1/NQbzN4l4ll513KK2rssDlK/img.png&quot; data-alt=&quot;Node.js 서버 빌드를 위한 필수파일들&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxzndK/btsJ0cH3Dy1/NQbzN4l4ll513KK2rssDlK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxzndK%2FbtsJ0cH3Dy1%2FNQbzN4l4ll513KK2rssDlK%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;470&quot; height=&quot;275&quot; data-origin-width=&quot;470&quot; data-origin-height=&quot;275&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Node.js 서버 빌드를 위한 필수파일들&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;여기까지 준비가 끝났으면 ssh에 접속해서, node 이미지를 만들고, build를 해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Node.js 서버 Build 후 Run하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cmd의 ssh 명령어를 통해 Synology Nas 내부에 접근해야 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;우선 제어판 - 터미널 및 SNMP - 터미널 - SSH 서비스 활성화 체크 - 포트 : 22 이렇게 설정해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;628&quot; data-origin-height=&quot;503&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/orTUV/btsJY6Wp1QG/lcT45hiEY8O9DoLAFuDgG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/orTUV/btsJY6Wp1QG/lcT45hiEY8O9DoLAFuDgG0/img.png&quot; data-alt=&quot;제어판 - 터미널 및 SNMP - 터미널&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/orTUV/btsJY6Wp1QG/lcT45hiEY8O9DoLAFuDgG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2ForTUV%2FbtsJY6Wp1QG%2FlcT45hiEY8O9DoLAFuDgG0%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;628&quot; height=&quot;503&quot; data-origin-width=&quot;628&quot; data-origin-height=&quot;503&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;제어판 - 터미널 및 SNMP - 터미널&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이제 명령프롬프트(cmd)를 켜고, Synology에 접속한다.&amp;nbsp;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;명령어는 ssh 시놀로지id@192.168.x.x (시놀로지 내부ip)&lt;/li&gt;
&lt;li&gt;시놀로지 내부ip 확인하는 방법은 &lt;a href=&quot;https://nowcow.tistory.com/1&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://nowcow.tistory.com/1&lt;/a&gt; 이 포스트에 있다.&lt;/li&gt;
&lt;li&gt;패스워드까지 입력하고 나면 시놀로지id@시놀로지id : ~$ 이렇게 접속된걸 확인할 수 있다.&lt;/li&gt;
&lt;li&gt;패스워드 입력할때는 화면에 아무런 반응이 없지만 그냥 입력후 엔터를 치면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1135&quot; data-origin-height=&quot;466&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uOIyj/btsJZvnZce0/xXCKLkTJ6WxiRaMLxYzHAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uOIyj/btsJZvnZce0/xXCKLkTJ6WxiRaMLxYzHAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uOIyj/btsJZvnZce0/xXCKLkTJ6WxiRaMLxYzHAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuOIyj%2FbtsJZvnZce0%2FxXCKLkTJ6WxiRaMLxYzHAK%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;1135&quot; height=&quot;466&quot; data-origin-width=&quot;1135&quot; data-origin-height=&quot;466&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;접속이 완료됐다면 /dokcer/node/management/ 라는 디렉토리로 찾아가보자.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;바로 cd /docker/~~ 입력하면 안되고 최상단에 /volume1/ 이라는 디렉토리를 거쳐야 한다.&lt;/li&gt;
&lt;li&gt;cd /volume1/docker/node/management/&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1416&quot; data-origin-height=&quot;142&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqqiuE/btsJZWrVdOI/kLgKybIUYwWGsmJGwGId4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqqiuE/btsJZWrVdOI/kLgKybIUYwWGsmJGwGId4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqqiuE/btsJZWrVdOI/kLgKybIUYwWGsmJGwGId4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqqiuE%2FbtsJZWrVdOI%2FkLgKybIUYwWGsmJGwGId4K%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;1416&quot; height=&quot;142&quot; data-origin-width=&quot;1416&quot; data-origin-height=&quot;142&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;명령어를 입력해서 ~~/management/ 디렉토리 안에 있는 파일들을 Build 해보자.&lt;/li&gt;
&lt;li&gt;원래는 docker ~~ 명령어를 통해서 진행하지만, ssh 접속할 때 admin계정으로 접속하지 않아서 권한이 없다. docker 명령어 앞에 sudo를 붙여 해결한다.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;
&lt;div&gt;
&lt;div&gt;sudo docker build -t 식별가능한이름 . ex) sudo doceker build -t management-server .&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;691&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzj1YP/btsJYcXhq87/Weq7gAyYFHK48SKK1LVcWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzj1YP/btsJYcXhq87/Weq7gAyYFHK48SKK1LVcWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzj1YP/btsJYcXhq87/Weq7gAyYFHK48SKK1LVcWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbzj1YP%2FbtsJYcXhq87%2FWeq7gAyYFHK48SKK1LVcWk%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;810&quot; height=&quot;691&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;691&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;Dockerfile을 읽어서 안에 설정해둔 값으로 Build가 잘 된것을 확인할 수 있다. 나는 여러가지 의존성을 더 추가해주었기 때문에 약간의 시간도 소모되었고, Build 과정은 각자 다를 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이제 Build된 이미지를 Run 해줄 차례이다.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;sudo docker run -d -p 6000:6000 이름 ex) sudo&amp;nbsp;docker&amp;nbsp;run&amp;nbsp;-d&amp;nbsp;-p&amp;nbsp;6000:6000&amp;nbsp;management-server&lt;/li&gt;
&lt;li&gt;6000:6000의 뜻은 외부 6000번 포트로 들어온 요청을 내부 컨테이너 6000번 포트로 매핑한다는 뜻이다.&lt;/li&gt;
&lt;li&gt;(외부6000):(내부6000) 이렇게 이해하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1098&quot; data-origin-height=&quot;83&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OBWML/btsJYIn5gtV/l0XXihTDrRuLOOM9vQ0lKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OBWML/btsJYIn5gtV/l0XXihTDrRuLOOM9vQ0lKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OBWML/btsJYIn5gtV/l0XXihTDrRuLOOM9vQ0lKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOBWML%2FbtsJYIn5gtV%2Fl0XXihTDrRuLOOM9vQ0lKK%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;1098&quot; height=&quot;83&quot; data-origin-width=&quot;1098&quot; data-origin-height=&quot;83&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;이제 Docker - 컨테이너 에서 방금 Run 한 management-server가 실행되고 있다면 성공!!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1197&quot; data-origin-height=&quot;383&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ddXJrd/btsJYIawaSx/RX7Yt1qz8KPdnySzMmgnV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ddXJrd/btsJYIawaSx/RX7Yt1qz8KPdnySzMmgnV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ddXJrd/btsJYIawaSx/RX7Yt1qz8KPdnySzMmgnV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FddXJrd%2FbtsJYIawaSx%2FRX7Yt1qz8KPdnySzMmgnV0%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;1197&quot; height=&quot;383&quot; data-origin-width=&quot;1197&quot; data-origin-height=&quot;383&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;management-server를 더블클릭해서 로그탭을 보면 제대로 실행되었는지 로그 확인도 가능하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;918&quot; data-origin-height=&quot;374&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPFiSy/btsJ0cnJ9BG/KCUKP4QHvVQ9qcVXZHlGEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPFiSy/btsJ0cnJ9BG/KCUKP4QHvVQ9qcVXZHlGEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPFiSy/btsJ0cnJ9BG/KCUKP4QHvVQ9qcVXZHlGEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPFiSy%2FbtsJ0cnJ9BG%2FKCUKP4QHvVQ9qcVXZHlGEK%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;918&quot; height=&quot;374&quot; data-origin-width=&quot;918&quot; data-origin-height=&quot;374&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;나는 server.js 파일에 테스트를 위한 api를 하나 만들어두었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1728400975757&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// test용 get요청
app.get('/api/test', (req, res) =&amp;gt; {
    res.send('Hello World! Welcome to the API!');
});&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;curl http://시놀로지id.synology.me:6000/api/test 명령어를 입력했을 때 정상적으로 출력되는 것을 볼 수 있다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;854&quot; data-origin-height=&quot;42&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p6pyA/btsJY5pKI70/CdL98KXZQTGMOXZJQAozM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p6pyA/btsJY5pKI70/CdL98KXZQTGMOXZJQAozM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p6pyA/btsJY5pKI70/CdL98KXZQTGMOXZJQAozM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp6pyA%2FbtsJY5pKI70%2FCdL98KXZQTGMOXZJQAozM1%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;854&quot; height=&quot;42&quot; data-origin-width=&quot;854&quot; data-origin-height=&quot;42&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 Synology Nas에 24시간 구동되는 Node.js 서버를 구축했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨테이너를 실행하는 동안은 서버가 계속 구동되기 때문에 yarn server 등의 실행 명령어가 필요없어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 client 단에서 proxy 설정을 통해 우리가 만든 서버와 매핑해주면 정상적으로 데이터를 불러올 수 있게 된다.&lt;/p&gt;</description>
      <category>웹서버</category>
      <category>docker</category>
      <category>Nas</category>
      <category>node</category>
      <category>Node.js</category>
      <category>node서버</category>
      <category>React</category>
      <category>synology</category>
      <author>nowcow</author>
      <guid isPermaLink="true">https://nowcow.tistory.com/3</guid>
      <comments>https://nowcow.tistory.com/3#entry3comment</comments>
      <pubDate>Wed, 9 Oct 2024 00:32:27 +0900</pubDate>
    </item>
    <item>
      <title>Synology Nas로 Spring Boot 프로젝트 파일 업로드 기능 로컬에서 웹서버로 전환하기</title>
      <link>https://nowcow.tistory.com/2</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;DataBase&amp;nbsp;서버를&amp;nbsp;성공적으로&amp;nbsp;구축하여&amp;nbsp;팀&amp;nbsp;프로젝트에서&amp;nbsp;잘&amp;nbsp;사용중이었다. &lt;br /&gt;문득&amp;nbsp;파일&amp;nbsp;업로드&amp;nbsp;기능도&amp;nbsp;웹서버를&amp;nbsp;구축하여&amp;nbsp;입/출력&amp;nbsp;하면&amp;nbsp;어떨까&amp;nbsp;생각이&amp;nbsp;들었다. &lt;br /&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;Mark Ⅲ에서 파일을 FTP 서버에 입력(업로드) 하는 것을 성공했고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mark Ⅳ에서 파일을 출력(다운로드) 하는 것을 성공했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 Mark Ⅰ~ Ⅳ 까지의 해결 과정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;프로젝트의 기능 중에 파일을 업로드를 담당하는 class&lt;/h4&gt;
&lt;pre id=&quot;code_1728064557806&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Configuration
public class WebConfig implements WebMvcConfigurer {

    private String resourcePath = &quot;/upload/**&quot;;
    private String savePath = &quot;file:///c:/image/&quot;;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry){
        registry.addResourceHandler(resourcePath)
                .addResourceLocations(savePath);
    }
}&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;식으로&amp;nbsp;Webconfig&amp;nbsp;class를&amp;nbsp;이용해서&amp;nbsp;c:/image라는&amp;nbsp;로컬&amp;nbsp;경로에서&amp;nbsp;업로드된&amp;nbsp;파일을&amp;nbsp;관리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 단순하게 Synology Nas에서 제공하는 WebDav나 FTP를 네트워크 드라이브로 연결해서 사용하면 되겠지 했다.&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;h3 data-ke-size=&quot;size23&quot;&gt;Mark Ⅰ&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RaiDrive 등의 FTP 연결 프로그램을 설치해서, FTP서버를 로컬 z드라이브로 할당하고, 위의 경로만 z://image로 바꿔서 사용하면 다른 설정은 건드릴 필요 없이 간단하게 FTP서버를 이용할 수 있다.&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;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;프로그램을 설치해서 z드라이브를 할당해야하기 때문에 z드라이브를 사용중인 컴퓨터에서는 환경을 또 바꾸어주어야 한다.&lt;/li&gt;
&lt;li&gt;팀원 모두가 RaiDrive같은 프로그램을 따로 설치해야하기 때문에 번거롭다.. (이런 과정이귀찮은 사람이 생길 수 있음)&lt;/li&gt;
&lt;li&gt;추후에 만약 완성된 프로젝트를 배포한다고 했을 때... 그때는 어떻게 해야할 것인가에 대한 문제점.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 이 방법으로 프로젝트를 완성하긴 했다. 다만 3번 문제가 제일 신경쓰여서 나 혼자 develop 해보기로 결정했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Mark Ⅱ&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FTP를 쓰면 어쨌든 네트워크 드라이브를 할당 해주어야 하기 때문에 이거 말고 WebDav 서비스를 이용해서 c:/ , z:/ 이런 경로 말고 http 프로토콜을 이용해보려고 했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;994&quot; data-origin-height=&quot;557&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ujgRz/btsJVHbnkFg/x88sKDDLz3oVVclhtJRC21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ujgRz/btsJVHbnkFg/x88sKDDLz3oVVclhtJRC21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ujgRz/btsJVHbnkFg/x88sKDDLz3oVVclhtJRC21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FujgRz%2FbtsJVHbnkFg%2Fx88sKDDLz3oVVclhtJRC21%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;668&quot; height=&quot;374&quot; data-origin-width=&quot;994&quot; data-origin-height=&quot;557&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;이렇게 기본 5005, 5006 포트를 개방하고,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://시놀로지id.synology.me:5005/&quot;&gt;http://시놀로지id.synology.me:5005/&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;문제점&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;이 방법은 출력(다운로드)은 가능한데 입력(업로드)이 안되는 것 같다...
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;FTP서버처럼 네트워크 드라이브를 할당해서 업로드를 하는 방식임..&lt;/li&gt;
&lt;li&gt;image.jpg라는 파일을 출력할 때 &lt;a href=&quot;http://시놀로지id.synology.me:5005/&quot;&gt;http://시놀로지id.synology.me:5005/image.jpg&lt;/a&gt; 이렇게 하면 출력이 돼야하는데 익멱 WebDav를 활성화 해도 자꾸 로그인을 하라고 나온다... 아이디에 anonymous를 입력해야 정상 출력됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://시놀로지id.synology.me:5005/image.jpg&quot;&gt;http://anonymous@시놀로지id.synology.me:5005/image.jpg&lt;/a&gt; 이런식으로 아이디 값을 지정해주면 출력은 가능한데 입력은 불가능하고, 익명에 대한 폴더와 권한을 지정해주긴 했지만 인증 정보를 포함하는 HTTP Basic Authentication은 보안상의 이유로 권장되지 않는다고 한다.&amp;nbsp;&lt;/li&gt;
&lt;/ol&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;h3 data-ke-size=&quot;size23&quot;&gt;Mark Ⅲ (파일 업로드 성공)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring Boot에 FTP를 사용할 수 있는 라이브러리가 있다는 것... 그러면 네트워크 드라이브를 따로 할당하지 않고 FTP 서버로 접근이 가능하다.&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;버전은 각자 맞게 최신 버전으로 검색해서 [Apache Commons Net] 라이브러리를 dependencies에 추가해준다.&lt;/p&gt;
&lt;pre id=&quot;code_1728109768154&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;implementation 'commons-net:commons-net:3.8.0'&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;pre id=&quot;code_1728109940396&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;implementation 'commons-io:commons-io:2.11.0&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;위의 라이브러리를 사용하면 FTP, SMTP, POP3, IMAP, Telnet, NTP와 같은 네트워크 프로토콜을 쉽게 구현할 수 있게 해준다고 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일단 Synology에서 FTP 기능을 활성화 시킨다.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;기본포트 21을 사용해도 무방하지만, 랜덤 공격에 당할 수 있다고 하니 임의로 2200포트를 사용했다.&lt;/li&gt;
&lt;li&gt;기본 포트 범위 사용으로 하면 라우터구성 할 때 자꾸 에러나서 그냥 55555포트를 임의로 설정.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;962&quot; data-origin-height=&quot;431&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQGI1w/btsJV5XfS4k/pYQuKCl1rnIVoQXq8pZho1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQGI1w/btsJV5XfS4k/pYQuKCl1rnIVoQXq8pZho1/img.png&quot; data-alt=&quot;제어판 - 파일서비스 - FTP&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQGI1w/btsJV5XfS4k/pYQuKCl1rnIVoQXq8pZho1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQGI1w%2FbtsJV5XfS4k%2FpYQuKCl1rnIVoQXq8pZho1%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;962&quot; height=&quot;431&quot; data-origin-width=&quot;962&quot; data-origin-height=&quot;431&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;제어판 - 파일서비스 - FTP&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;그리고 조금 아래로 내려보면 '고급 설정'이 있다.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;익명 FTP 활성화 체크&lt;/li&gt;
&lt;li&gt;익명 루트 변경 체크&lt;/li&gt;
&lt;li&gt;업로드된 파일을 관리할 폴더 하나를 지정해준다 (나는 web 이라는 폴더 만들어서 지정.)&lt;/li&gt;
&lt;li&gt;이렇게 되면 FTP를 anonymous(익명)으로 접속하면 web 폴더에만 읽기/쓰기가 가능해진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;842&quot; data-origin-height=&quot;622&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Q43ZX/btsJV6hzwfu/vusXJzTPqRNDhpKmxSmiHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Q43ZX/btsJV6hzwfu/vusXJzTPqRNDhpKmxSmiHk/img.png&quot; data-alt=&quot;web이라는 공유폴더를 사용중이다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Q43ZX/btsJV6hzwfu/vusXJzTPqRNDhpKmxSmiHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQ43ZX%2FbtsJV6hzwfu%2FvusXJzTPqRNDhpKmxSmiHk%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;842&quot; height=&quot;622&quot; data-origin-width=&quot;842&quot; data-origin-height=&quot;622&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;web이라는 공유폴더를 사용중이다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이제 라우터 구성, 방화벽, 포트폴리오 설정을 해주어야 한다.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;제어판 - 외부 액세스 - 생성 -&amp;nbsp; 내장 응용 프로그램 - FTP 파일 서버 선택 - 적용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1140&quot; data-origin-height=&quot;663&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwwOkA/btsJVarGyz6/ENiUnYFSnvPtimc4LYQZzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwwOkA/btsJVarGyz6/ENiUnYFSnvPtimc4LYQZzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwwOkA/btsJVarGyz6/ENiUnYFSnvPtimc4LYQZzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwwOkA%2FbtsJVarGyz6%2FENiUnYFSnvPtimc4LYQZzK%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;1140&quot; height=&quot;663&quot; data-origin-width=&quot;1140&quot; data-origin-height=&quot;663&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용중인 공유기 설정 페이지에서 2200포트도 포트포워딩 해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;98&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dCDcbh/btsJWACrmyV/KSQCOYhNKTKRW4NSpHONk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dCDcbh/btsJWACrmyV/KSQCOYhNKTKRW4NSpHONk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dCDcbh/btsJWACrmyV/KSQCOYhNKTKRW4NSpHONk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdCDcbh%2FbtsJWACrmyV%2FKSQCOYhNKTKRW4NSpHONk0%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;536&quot; height=&quot;98&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;98&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;내부 ip 등 자세한 포트포워딩 정보는 (&lt;a href=&quot;https://nowcow.tistory.com/1&quot;&gt;https://nowcow.tistory.com/1&lt;/a&gt;) 이곳에 포스팅 해두었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 FTP 서버를 구축하고, 외부 접속이 가능하게 하는 설정은 모두 끝났고 이제 프로젝트에 적용해보자.&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;h4 data-ke-size=&quot;size20&quot;&gt;이제 Spring 프로젝트에서 FTP 클래스를 하나 만든다. 나는 그냥 FtpUtil 이렇게 이름 지었다.&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;나는 의존성 주입 없이 Java 클래스를 객체로 생성하여 사용하는 방식으로 했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1728120844214&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class FtpUtil {
    private static final String FTP_SERVER = &quot;시놀로지ip.synology.me&quot;; // FTP 서버 주소
    private static final int FTP_PORT = 2200; // FTP 포트 번호
    private static final String FTP_USER = &quot;anonymous&quot;;    // FTP 사용자명
    private static final String FTP_PASS = &quot;&quot;;    // FTP 비밀번호

    private FTPClient ftpClient;

    public FtpUtil() {
        ftpClient = new FTPClient();
    }

    // FTP 서버에 연결
    public void connect() throws IOException {
        ftpClient.connect(FTP_SERVER, FTP_PORT); // 서버 주소와 포트
        boolean success = ftpClient.login(FTP_USER, FTP_PASS);
        if (!success) {
            throw new IOException(&quot;FTP 서버 로그인 실패&quot;);
        }
        ftpClient.enterLocalPassiveMode();  // Passive 모드 사용
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);  // 바이너리 파일 타입 설정
    }

    // 파일 업로드
    public boolean uploadFile(String remoteFilePath, File localFile) throws IOException {
        try (InputStream inputStream = new FileInputStream(localFile)) {
            boolean done = ftpClient.storeFile(remoteFilePath, inputStream);
            if (!done) {
                throw new IOException(&quot;파일 업로드 실패&quot;);
            }
            return true;
        }
    }

    // 파일 다운로드
    public void downloadFile(String remoteFilePath, String localFilePath) throws IOException {
        try (FileOutputStream fos = new FileOutputStream(localFilePath)) {
            boolean success = ftpClient.retrieveFile(remoteFilePath, fos);
            if (!success) {
                throw new IOException(&quot;파일 다운로드 실패&quot;);
            }
        }
    }

    // 파일 삭제
    public boolean deleteFile(String remoteFilePath) {
        try {
            // FTP 서버에서 파일 삭제 로직
            ftpClient.deleteFile(remoteFilePath);
            return true; // 삭제 성공 시 true 반환
        } catch (IOException e) {
            e.printStackTrace();
            return false; // 삭제 실패 시 false 반환
        }
    }


    // FTP 연결 종료
    public void disconnect() {
        if (ftpClient.isConnected()) {
            try {
                ftpClient.logout();
                ftpClient.disconnect();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}&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;익명 로그온을 활성화 해두었기 때문에 사용자명에 anonymous만 입력해주어도 접근이 가능해진다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 이렇게 contoller 혹은 service 에서 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;newFtpUtil()&lt;/span&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;darr;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Contoller&lt;/p&gt;
&lt;pre id=&quot;code_1728140732863&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    @PostMapping(&quot;/post/save&quot;)
    public String save(@ModelAttribute PostDTO postDTO, HttpSession session) throws IOException {

        // 게시물 저장
        postService.save(postDTO);

        // 세이브 된 글 번호로 리다이렉트
        int firstPostNum = postService.findFirstPostNum(); // 첫 번째 게시물 번호 가져오기
        System.out.println(&quot;firstPostNum = &quot; + firstPostNum);
        return &quot;redirect:/post/&quot; + firstPostNum;
    }&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;Service&lt;/p&gt;
&lt;pre id=&quot;code_1728140797292&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public void save(PostDTO postDTO) throws IOException {
        if (postDTO.getPost_upLoadFile().isEmpty()) {
            PostEntity postEntity = PostEntity.toSaveEntity(postDTO);
            postRepository.save(postEntity);
        } else {
            PostEntity postEntity = PostEntity.toSaveFileEntity(postDTO);
            Integer postNum = postRepository.save(postEntity).getPostNum();
            PostEntity post = postRepository.findById(postNum).get();

            FtpUtil ftpUtil = new FtpUtil();
            try {
                ftpUtil.connect(); // FTP 서버 연결
                for (MultipartFile postFile : postDTO.getPost_upLoadFile()) {
                    String originalFilename = postFile.getOriginalFilename();

                    if (originalFilename != null &amp;amp;&amp;amp; !originalFilename.isEmpty()) {
                        // 확장자 추출
                        String fileExtension = originalFilename.substring(originalFilename.lastIndexOf(&quot;.&quot;));
                        // 랜덤 파일 이름 생성
                        String randomFileName = UUID.randomUUID().toString() + fileExtension;

                        // 임시 파일로 서버에 저장
                        File tempFile = new File(System.getProperty(&quot;java.io.tmpdir&quot;) + &quot;/&quot; + randomFileName);
                        postFile.transferTo(tempFile);

                        // FTP 서버에 파일 업로드
                        ftpUtil.uploadFile(&quot;/marketFile/&quot; + randomFileName, tempFile);

                        // FileEntity 생성 및 저장
                        FileEntity fileEntity = FileEntity.toFileEntity(post, randomFileName);
                        fileRepository.save(fileEntity);

                        // 업로드 후 임시 파일 삭제
                        if (tempFile.exists()) {
                            tempFile.delete();
                        }
                    } else {
                        System.out.println(&quot;파일이 입력되지 않았습니다! 파일명: &quot; + originalFilename);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                // 파일 업로드 중 발생한 오류 처리
            } finally {
                ftpUtil.disconnect(); // FTP 서버 연결 해제
            }
        }
    }&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;Contoller는 Service를 불러오는 부분이고, 실제로 Service의 public void save 메소드에서 FtpUtil을 불러온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 혹시나 파일명이 겹치게 될까봐 UUID 라는 라이브러리를 사용해서 파일의 이름을 랜덤하게 지정하고&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;FtpUitl 초기화 - FTP서버 연결 - 파일이 업로드 되면 랜덤으로 이름 생성 - 임시파일을 로컬 저장소에 저장 - FTP로 업로드 - 임시파일 삭제 - FTP 연결해제&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;이 로직으로 돌아가는데, 중간에 괜히 임시파일을 로컬에 저장하는 이유는 FTP로 파일을 전송할 때 파일의 경로가 필요하기 때문이라고 한다. 또 에러 관리 및 유지보수를 위해서 라고도 하는데 이 부분은 조금 더 서치가 필요할 것 같다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각자의 프로젝트에 맞게 코드를 알맞게 수정 및 적용하면 될 것 같고,&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1728142631311&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// FTP 서버에 파일 업로드
ftpUtil.uploadFile(&quot;/marketFile/&quot; + randomFileName, tempFile);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 /web/ 디렉토리 안에 /markerFile/ 이라는 폴더에 저장하고싶어서 저렇게 디렉토리 경로를 추가했다.&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;h3 data-ke-size=&quot;size23&quot;&gt;Mark Ⅳ (파일 업로드/다운로드 모두 가능)&lt;/h3&gt;
&lt;pre id=&quot;code_1728143136019&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;div style=&quot;width: 700px; display: flex; justify-content: center&quot;&amp;gt;
	&amp;lt;div th:each=&quot;index : ${#numbers.sequence(0, detail.file_url.size() - 1)}&quot;&amp;gt;
		&amp;lt;img th:id=&quot;'thumbnail_' + ${index}&quot; th:src=&quot;@{|/upload/${detail.file_url[__${index}__]}|}&quot;
			style=&quot;width: 80px; height: 80px; margin: 15px; box-shadow: 0px 0px 8px -1px;
			border-radius: 8px; cursor: pointer&quot; th:onclick=&quot;'extend('+ ${index} +')'&quot; th:onmouseover=&quot;'extend('+ ${index} +')'&quot;&amp;gt;
	&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&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;원래는 이 글 맨 위에 보여준 WebConfig 클래스를 만들고, 이런식으로 /upload/ 경로로 요청되는 것들을 c:/image/로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대치해서 로컬의 c:/image 디렉토리 안에 있는 파일을 불러왔었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇게 되면 &lt;span style=&quot;color: #e3e3e3; text-align: left;&quot;&gt;&lt;a href=&quot;http://hhjnn92.synology.me/marketFile/1710906607795_239935090_2_1708954300_w856.jpg&quot;&gt;http://localhost:8080/image/사진.jpg&lt;/a&gt;&lt;/span&gt; 이런 식의 경로가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 로컬환경을 쓰지 않으려고 했던 것이기 때문에 FTP를 이용해 Synology에 업로드했던 파일을 가져와야한다.&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;어떻게.....?&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;진짜 이 부분에서 애를 많이 먹었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;u&gt;http://localhost:8080/&lt;/u&gt;&lt;/span&gt; 부분을 내 WebDav 경로로 대치했을때 사용자 정보가 없어서 아무 이미지도 로드되지 않았다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a href=&quot;http://anonymous@시놀로지id.synology.me:5005/&quot;&gt;http://anonymous@시놀로지id.synology.me:5005/image.jpg&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 이 url로 접속하면 사진이 불러와 졌던걸 생각해서&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://anonymous@시놀로지id.synology.me:5005/&quot;&gt;http://anonymous@시놀로지id.synology.me:5005/&lt;/a&gt; 이 경로 대치를 했는데도 계속 이미지가 로드되지 않았다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Thymeleaf에서 anonymous@ 이 부분을 인식하지 못하는 것 같기도 하고 고민이 참 많았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FTP에선 익명 로그인을 지원하는데 WebDav에서는 익명 로그인을 사용하지 못하는건지...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Thymeleaf 탬플릿에서 WebDav 연결하는 유틸리티 클래스를 연결해줘야하는건지.... 도무지 감이 잡히지 않다가&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국&amp;nbsp;&lt;a href=&quot;https://digitalogia.tistory.com/367&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://digitalogia.tistory.com/367&lt;/a&gt; 이 블로그에서 해답을 찾았다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자세한 세팅법은 위의 블로그를 참고하시면 된다.&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Web Staion&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 정확히 뭔지도 모르는 Web Staion이 이미 세팅되어있었고, 방화벽 규칙에 추가해주고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iptime 설정에서 80포트를 포트포워딩 해주었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 /web/marketFile/ 이라는 디렉토리 경로를 사용하는것에 대한 의문이 풀렸을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://시놀로지id.synology.me/image.jpg&quot;&gt;http://시놀로지id.synology.me/image.jpg&lt;/a&gt; 경로를 주소창에 입력하면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시놀로지 파일스테이션에 있는 /web/ 이라는 공유폴더가 Root 디렉토리로 설정되어서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/web/image.jpg 라는 파일이 출력되는걸 알 수 있다.. 정말 이렇게 간단한 일일 줄이야...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/web/ 폴더 안에 모든 파일이 계속 업로드 된다면 관리가 쉽지 않을 것 같아서 진행중인 프로젝트의 이름을 따서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/marketFile/ 이라는 디렉토리를 이 프로젝트 전용 디렉토리로 사용했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;594&quot; data-origin-height=&quot;502&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5LRju/btsJWoCdt9M/DtpR4QUGelqL0GpK2qAbK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5LRju/btsJWoCdt9M/DtpR4QUGelqL0GpK2qAbK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5LRju/btsJWoCdt9M/DtpR4QUGelqL0GpK2qAbK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5LRju%2FbtsJWoCdt9M%2FDtpR4QUGelqL0GpK2qAbK1%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;594&quot; height=&quot;502&quot; data-origin-width=&quot;594&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;&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;pre id=&quot;code_1728145540385&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;div style=&quot;width: 700px; display: flex; justify-content: center&quot;&amp;gt;
	&amp;lt;div th:each=&quot;index : ${#numbers.sequence(0, detail.file_url.size() - 1)}&quot;&amp;gt;
		&amp;lt;img th:id=&quot;'thumbnail_' + ${index}&quot; th:src=&quot;@{|http://시놀로지id.synology.me/marketFiles/${detail.file_url[__${index}__]}|}&quot;
			style=&quot;width: 80px; height: 80px; margin: 15px; box-shadow: 0px 0px 8px -1px;
			border-radius: 8px; cursor: pointer&quot; th:onclick=&quot;'extend('+ ${index} +')'&quot; th:onmouseover=&quot;'extend('+ ${index} +')'&quot;&amp;gt;
	&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&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;그리고 코드를 바꿔서 Mark Ⅳ 단계에서 프로젝트의 DataBase와, 파일 입/출력 기능을 로컬에서 웹서버로 전환 완료했다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 테스트 목적으로 진행된 작업이라 보안에 크게 신경쓰지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;anonymous 계정에 지정된 폴더만 접근할 수 있게 권한을 주는 정도로만 진행했는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안을 생각한다면 익명이 아니라 프로젝트에 맞는 계정을 새로 생성하고 접근 권한도 따로 부여하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitHub에 공개되지 않게 ignore에 추가도 해야할 것이다.&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;이제 이렇게 완성된 프로젝트를 Synology를 이용해서 배포까지 해 볼것이다!&lt;/p&gt;</description>
      <category>웹서버</category>
      <category>FTP</category>
      <category>Nas</category>
      <category>Spring</category>
      <category>spring boot</category>
      <category>synology</category>
      <category>웹서버</category>
      <category>파일서버</category>
      <author>nowcow</author>
      <guid isPermaLink="true">https://nowcow.tistory.com/2</guid>
      <comments>https://nowcow.tistory.com/2#entry2comment</comments>
      <pubDate>Mon, 7 Oct 2024 13:23:53 +0900</pubDate>
    </item>
    <item>
      <title>Synology Nas로 MariaDB(MySQL) DataBase 서버 구축하기</title>
      <link>https://nowcow.tistory.com/1</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;팀&amp;nbsp;프로젝트를&amp;nbsp;진행하면서&amp;nbsp;제일&amp;nbsp;답답했던&amp;nbsp;부분중에&amp;nbsp;하나가&amp;nbsp;데이터베이스&amp;nbsp;관리였다. &lt;br /&gt;팀원&amp;nbsp;4명이&amp;nbsp;모두&amp;nbsp;로컬에서&amp;nbsp;작업하다&amp;nbsp;보니&amp;nbsp;각자&amp;nbsp;기능테스를&amp;nbsp;하며&amp;nbsp;불필요한&amp;nbsp;데이터들이&amp;nbsp;많이&amp;nbsp;쌓였고, &lt;br /&gt;데이터를&amp;nbsp;합쳐야&amp;nbsp;할&amp;nbsp;때에는&amp;nbsp;각자&amp;nbsp;데이터가&amp;nbsp;다르기때문에&amp;nbsp;dump&amp;nbsp;하기도&amp;nbsp;너무&amp;nbsp;힘들었다. &lt;br /&gt;그래서&amp;nbsp;데이터베이스를&amp;nbsp;로컬&amp;nbsp;-&amp;gt;&amp;nbsp;서버로&amp;nbsp;이전해보기로&amp;nbsp;결정. &lt;br /&gt;검색해보니&amp;nbsp;synology에&amp;nbsp;mariaDB&amp;nbsp;서버&amp;nbsp;구축이&amp;nbsp;가능하다고&amp;nbsp;해서&amp;nbsp;도전&amp;nbsp;해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Synology에 MariaDB설치하기&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;우선&amp;nbsp;패키지센터에서&amp;nbsp;mariadb를&amp;nbsp;검색하여&amp;nbsp;설치한다.&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 때 PHP 8.0과 phpMyAdmin도 같이 설치된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;452&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bywVHQ/btsJUGLbKlr/XwQkrNQlxgSAYtQTKkMnR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bywVHQ/btsJUGLbKlr/XwQkrNQlxgSAYtQTKkMnR1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bywVHQ/btsJUGLbKlr/XwQkrNQlxgSAYtQTKkMnR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbywVHQ%2FbtsJUGLbKlr%2FXwQkrNQlxgSAYtQTKkMnR1%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;626&quot; height=&quot;452&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;452&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8k3HV/btsJVB3pg3B/yvih3wuWaZHNQr2Tae9QWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8k3HV/btsJVB3pg3B/yvih3wuWaZHNQr2Tae9QWK/img.png&quot; data-alt=&quot;혹시 설치가 안된다면 각각 검색하여 설치하도록 한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8k3HV/btsJVB3pg3B/yvih3wuWaZHNQr2Tae9QWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8k3HV%2FbtsJVB3pg3B%2Fyvih3wuWaZHNQr2Tae9QWK%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;755&quot; height=&quot;250&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;250&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;패스워드 / 포트 설정하는 창이 나오는데, 패스워드는 root 계정에서 사용하게 될 패스워드.&lt;br /&gt;나는 3306 포트를 사용하기로 했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;695&quot; data-origin-height=&quot;495&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lTzAI/btsJUUCscXC/uk7SS12HClKo2xFp8k2871/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lTzAI/btsJUUCscXC/uk7SS12HClKo2xFp8k2871/img.png&quot; data-alt=&quot;나중에 mysql 서버도 구축하려고 했는데 포트가 충돌하여 애먹었다. 결론은 3306 사용해도 된다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lTzAI/btsJUUCscXC/uk7SS12HClKo2xFp8k2871/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlTzAI%2FbtsJUUCscXC%2Fuk7SS12HClKo2xFp8k2871%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;695&quot; height=&quot;495&quot; data-origin-width=&quot;695&quot; data-origin-height=&quot;495&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;나중에 mysql 서버도 구축하려고 했는데 포트가 충돌하여 애먹었다. 결론은 3306 사용해도 된다.&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;다음화면으로&amp;nbsp;쭉&amp;nbsp;넘겨서&amp;nbsp;설치를&amp;nbsp;완료한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실행하여&amp;nbsp;TCP/IP&amp;nbsp;연결&amp;nbsp;활성화&amp;nbsp;체크&amp;nbsp;후&amp;nbsp;적용&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이렇게 되면 mariadb 세팅은 끝.&lt;/li&gt;
&lt;/ul&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;505&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lTwGk/btsJV2MJPiy/0Jk1THOx0UoFsVYlpZwY9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lTwGk/btsJV2MJPiy/0Jk1THOx0UoFsVYlpZwY9K/img.png&quot; data-alt=&quot;이렇게 끝이면 좋겠지만 외부접속을 위해 포트포워딩 / 방화벽 설정을 해주어야 한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lTwGk/btsJV2MJPiy/0Jk1THOx0UoFsVYlpZwY9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlTwGk%2FbtsJV2MJPiy%2F0Jk1THOx0UoFsVYlpZwY9K%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;607&quot; height=&quot;505&quot; data-origin-width=&quot;607&quot; data-origin-height=&quot;505&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;h3 data-ke-size=&quot;size23&quot;&gt;외부&amp;nbsp;접속을&amp;nbsp;위해&amp;nbsp;포트&amp;nbsp;개방하기.&amp;nbsp;(포트포워딩)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;우선 사용중인 nas의 내부ip를 확인한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;193&quot; data-origin-height=&quot;65&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8wlnI/btsJVTJiceO/ynSMscZ92oykwyfxB5xwYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8wlnI/btsJVTJiceO/ynSMscZ92oykwyfxB5xwYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8wlnI/btsJVTJiceO/ynSMscZ92oykwyfxB5xwYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8wlnI%2FbtsJVTJiceO%2FynSMscZ92oykwyfxB5xwYk%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;193&quot; height=&quot;65&quot; data-origin-width=&quot;193&quot; data-origin-height=&quot;65&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;328&quot; data-origin-height=&quot;295&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8SPI2/btsJVZWZp7g/v1M39e8yTefOKywUVCYqh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8SPI2/btsJVZWZp7g/v1M39e8yTefOKywUVCYqh0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8SPI2/btsJVZWZp7g/v1M39e8yTefOKywUVCYqh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8SPI2%2FbtsJVZWZp7g%2Fv1M39e8yTefOKywUVCYqh0%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;328&quot; height=&quot;295&quot; data-origin-width=&quot;328&quot; data-origin-height=&quot;295&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;시놀로지&amp;nbsp;상단에&amp;nbsp;위젯버튼을&amp;nbsp;누르면&amp;nbsp;위젯&amp;nbsp;창이&amp;nbsp;뜨는데&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;+ 버튼을 눌러서 시스템 상태 위젯을 활성화 시키고 내부 ip 확인한다. (192.168.0.xxx)&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;br /&gt;이제 각자 사용중인 공유기의 설정 페이지로 이동한다. http://192.168.0.1&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는&amp;nbsp;iptime을&amp;nbsp;이용중이라&amp;nbsp;iptime&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;198&quot; data-origin-height=&quot;125&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mhJ1s/btsJUW72mrG/hnfZlCSSXU9Xyl4Qcyr3g0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mhJ1s/btsJUW72mrG/hnfZlCSSXU9Xyl4Qcyr3g0/img.png&quot; data-alt=&quot;고급설정&amp;amp;nbsp;-&amp;amp;nbsp;NAT/라우터&amp;amp;nbsp;관리&amp;amp;nbsp;-&amp;amp;nbsp;포트포워드&amp;amp;nbsp;설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mhJ1s/btsJUW72mrG/hnfZlCSSXU9Xyl4Qcyr3g0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmhJ1s%2FbtsJUW72mrG%2FhnfZlCSSXU9Xyl4Qcyr3g0%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;198&quot; height=&quot;125&quot; data-origin-width=&quot;198&quot; data-origin-height=&quot;125&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;고급설정&amp;nbsp;-&amp;nbsp;NAT/라우터&amp;nbsp;관리&amp;nbsp;-&amp;nbsp;포트포워드&amp;nbsp;설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;664&quot; data-origin-height=&quot;156&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2ah0n/btsJUPH5iar/E5mQPuxKQ5RZQ507TpBZKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2ah0n/btsJUPH5iar/E5mQPuxKQ5RZQ507TpBZKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2ah0n/btsJUPH5iar/E5mQPuxKQ5RZQ507TpBZKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2ah0n%2FbtsJUPH5iar%2FE5mQPuxKQ5RZQ507TpBZKK%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;664&quot; height=&quot;156&quot; data-origin-width=&quot;664&quot; data-origin-height=&quot;156&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;새&amp;nbsp;규칙을&amp;nbsp;하나&amp;nbsp;추가해준다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;규칙 이름 - 그냥 알아보기 쉽게 알아서 지정해준다. &lt;br /&gt;내부&amp;nbsp;ip주소&amp;nbsp;-&amp;nbsp;마지막&amp;nbsp;파란네모에&amp;nbsp;synology에서&amp;nbsp;확인한&amp;nbsp;내부&amp;nbsp;ip&amp;nbsp;입력. &lt;br /&gt;외부 포트 / 내부 포트 - 처음에 설정했던 3306포트 입력하고 적용.&lt;/blockquote&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;h3 data-ke-size=&quot;size23&quot;&gt;그&amp;nbsp;다음은&amp;nbsp;다시&amp;nbsp;synology로&amp;nbsp;돌아와서&amp;nbsp;방화벽&amp;nbsp;규칙을&amp;nbsp;생성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제어판&amp;nbsp;-&amp;nbsp;보안&amp;nbsp;-&amp;nbsp;방화벽&amp;nbsp;-&amp;nbsp;규칙편집&amp;nbsp;-&amp;nbsp;생성&amp;nbsp;-&amp;nbsp;내장된&amp;nbsp;응용&amp;nbsp;프로그램&amp;nbsp;목록에서&amp;nbsp;선택&amp;nbsp;-&amp;nbsp;MariaDB&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;1166&quot; data-origin-height=&quot;679&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xvhrD/btsJUEmgf8R/M3rgtphHslDhos7Y1kqiTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xvhrD/btsJUEmgf8R/M3rgtphHslDhos7Y1kqiTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xvhrD/btsJUEmgf8R/M3rgtphHslDhos7Y1kqiTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxvhrD%2FbtsJUEmgf8R%2FM3rgtphHslDhos7Y1kqiTK%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;1166&quot; height=&quot;679&quot; data-origin-width=&quot;1166&quot; data-origin-height=&quot;679&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;618&quot; data-origin-height=&quot;536&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uG9D7/btsJUXsqyIC/nFH6p6wfEF6NEltoQHpiq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uG9D7/btsJUXsqyIC/nFH6p6wfEF6NEltoQHpiq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uG9D7/btsJUXsqyIC/nFH6p6wfEF6NEltoQHpiq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuG9D7%2FbtsJUXsqyIC%2FnFH6p6wfEF6NEltoQHpiq0%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;618&quot; height=&quot;536&quot; data-origin-width=&quot;618&quot; data-origin-height=&quot;536&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;583&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GQ99U/btsJUXePyUs/CQRdhTbGeVA1OxKk3QTn2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GQ99U/btsJUXePyUs/CQRdhTbGeVA1OxKk3QTn2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GQ99U/btsJUXePyUs/CQRdhTbGeVA1OxKk3QTn2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGQ99U%2FbtsJUXePyUs%2FCQRdhTbGeVA1OxKk3QTn2k%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;805&quot; height=&quot;583&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;583&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;되면&amp;nbsp;외부에서&amp;nbsp;접속할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;세팅은&amp;nbsp;끝난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;이제 MariaDB 관리자 페이지에 접속해서 확인해보자.&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아까 설치된 phpMyAdmin 접속. &lt;a href=&quot;http://시놀로지id.synology.me/phpmyadmin/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;http://시놀로지id.synology.me/phpmyadmin/&lt;/a&gt;&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;117&quot; data-origin-height=&quot;94&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3f0Z6/btsJUDHFJdE/QmImkxNK8qKZHVGYvvBhQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3f0Z6/btsJUDHFJdE/QmImkxNK8qKZHVGYvvBhQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3f0Z6/btsJUDHFJdE/QmImkxNK8qKZHVGYvvBhQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3f0Z6%2FbtsJUDHFJdE%2FQmImkxNK8qKZHVGYvvBhQk%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;117&quot; height=&quot;94&quot; data-origin-width=&quot;117&quot; data-origin-height=&quot;94&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;485&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HxtjJ/btsJVZWZvdT/AHbJeRRGPsKupktJAddkb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HxtjJ/btsJVZWZvdT/AHbJeRRGPsKupktJAddkb1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HxtjJ/btsJVZWZvdT/AHbJeRRGPsKupktJAddkb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHxtjJ%2FbtsJVZWZvdT%2FAHbJeRRGPsKupktJAddkb1%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;485&quot; height=&quot;480&quot; data-origin-width=&quot;485&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와&amp;nbsp;같은&amp;nbsp;페이지가&amp;nbsp;뜰텐데,&amp;nbsp;암호에&amp;nbsp;처음&amp;nbsp;설정했던&amp;nbsp;root계정&amp;nbsp;패스워드를&amp;nbsp;입력하고&amp;nbsp;접속한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;혹시나&amp;nbsp;phpMyAdmin&amp;nbsp;접속이&amp;nbsp;안된다면&amp;nbsp;80&amp;nbsp;포트도&amp;nbsp;포트포워딩을&amp;nbsp;해준다. &lt;br /&gt;mariadb&amp;nbsp;포트포워딩&amp;nbsp;했던&amp;nbsp;것처럼&amp;nbsp;이름은&amp;nbsp;대충&amp;nbsp;php로&amp;nbsp;지어주고, &lt;br /&gt;내부&amp;nbsp;ip주소에&amp;nbsp;시놀로지&amp;nbsp;내부ip&amp;nbsp;입력,&amp;nbsp;외부포트&amp;nbsp;/&amp;nbsp;내부포트는&amp;nbsp;각각&amp;nbsp;80~80&amp;nbsp;/&amp;nbsp;80~80&lt;/blockquote&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;1280&quot; data-origin-height=&quot;538&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LG25o/btsJV9E5DhK/dWwApleYQc5qXFjl4k99O0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LG25o/btsJV9E5DhK/dWwApleYQc5qXFjl4k99O0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LG25o/btsJV9E5DhK/dWwApleYQc5qXFjl4k99O0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLG25o%2FbtsJV9E5DhK%2FdWwApleYQc5qXFjl4k99O0%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;1280&quot; height=&quot;538&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;538&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;화면이&amp;nbsp;떴다면&amp;nbsp;대성공.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;하나&amp;nbsp;추가로&amp;nbsp;설정해주어야&amp;nbsp;할&amp;nbsp;것이&amp;nbsp;있다면&amp;nbsp;root계정을&amp;nbsp;사용하지&amp;nbsp;말고&amp;nbsp;사용자&amp;nbsp;계정을&amp;nbsp;추가해주기.&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;421&quot; data-origin-height=&quot;81&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nnCUu/btsJVNP58Dq/IkQZ8jtxdtcFFj17wwfaCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nnCUu/btsJVNP58Dq/IkQZ8jtxdtcFFj17wwfaCK/img.png&quot; data-alt=&quot;상단의 사용자 계정 페이지로 가서&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nnCUu/btsJVNP58Dq/IkQZ8jtxdtcFFj17wwfaCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnnCUu%2FbtsJVNP58Dq%2FIkQZ8jtxdtcFFj17wwfaCK%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;421&quot; height=&quot;81&quot; data-origin-width=&quot;421&quot; data-origin-height=&quot;81&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;254&quot; data-origin-height=&quot;211&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CV9B7/btsJUVafGbQ/TvGlyTq4PhIVIBA00DXdc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CV9B7/btsJUVafGbQ/TvGlyTq4PhIVIBA00DXdc1/img.png&quot; data-alt=&quot;사용자&amp;amp;nbsp;추가를&amp;amp;nbsp;눌러준다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CV9B7/btsJUVafGbQ/TvGlyTq4PhIVIBA00DXdc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCV9B7%2FbtsJUVafGbQ%2FTvGlyTq4PhIVIBA00DXdc1%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;254&quot; height=&quot;211&quot; data-origin-width=&quot;254&quot; data-origin-height=&quot;211&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사용자&amp;nbsp;추가를&amp;nbsp;눌러준다.&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;570&quot; data-origin-height=&quot;619&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/D9wap/btsJV8TF1pm/KJwqnupfXPc4XwaIMs3CGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/D9wap/btsJV8TF1pm/KJwqnupfXPc4XwaIMs3CGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/D9wap/btsJV8TF1pm/KJwqnupfXPc4XwaIMs3CGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FD9wap%2FbtsJV8TF1pm%2FKJwqnupfXPc4XwaIMs3CGk%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;570&quot; height=&quot;619&quot; data-origin-width=&quot;570&quot; data-origin-height=&quot;619&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;root계정&amp;nbsp;대신&amp;nbsp;사용하는&amp;nbsp;것이기&amp;nbsp;때문에&amp;nbsp;전체적&amp;nbsp;권한을&amp;nbsp;모두체크&amp;nbsp;하고&amp;nbsp;계정을&amp;nbsp;생성한다. &lt;br /&gt;호스트명에&amp;nbsp;있는&amp;nbsp;%의&amp;nbsp;의미는&amp;nbsp;모든&amp;nbsp;ip에&amp;nbsp;대한&amp;nbsp;접속을&amp;nbsp;허용한다는&amp;nbsp;것이다. &lt;br /&gt;ip를&amp;nbsp;제한하고&amp;nbsp;싶다면&amp;nbsp;192.168.x.x&amp;nbsp;등의&amp;nbsp;ip를&amp;nbsp;설정해주면&amp;nbsp;되는데,&amp;nbsp;팀원&amp;nbsp;모두가&amp;nbsp;사용할&amp;nbsp;것이니&amp;nbsp;%로&amp;nbsp;설정.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;이렇게&amp;nbsp;모든&amp;nbsp;설정을&amp;nbsp;마쳤고,&amp;nbsp;DB&amp;nbsp;서버가&amp;nbsp;제대로&amp;nbsp;구축되었는지&amp;nbsp;확인하기&amp;nbsp;위해&amp;nbsp;DBeaver&amp;nbsp;툴을&amp;nbsp;사용했다.&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;927&quot; data-origin-height=&quot;636&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wTObS/btsJVaZkr3z/oekKYhKrb5tCj2ctqkMZV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wTObS/btsJVaZkr3z/oekKYhKrb5tCj2ctqkMZV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wTObS/btsJVaZkr3z/oekKYhKrb5tCj2ctqkMZV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwTObS%2FbtsJVaZkr3z%2FoekKYhKrb5tCj2ctqkMZV1%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;927&quot; height=&quot;636&quot; data-origin-width=&quot;927&quot; data-origin-height=&quot;636&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;연결에서&amp;nbsp;MariaDB&amp;nbsp;선택하고&amp;nbsp;우리가&amp;nbsp;설정해둔&amp;nbsp;값을&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;47&quot; data-origin-height=&quot;26&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKFpfs/btsJWu25ty5/vnaDi40M59rpuUJgDv12fK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKFpfs/btsJWu25ty5/vnaDi40M59rpuUJgDv12fK/img.png&quot; data-alt=&quot;연결 성공!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKFpfs/btsJWu25ty5/vnaDi40M59rpuUJgDv12fK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKFpfs%2FbtsJWu25ty5%2FvnaDi40M59rpuUJgDv12fK%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;47&quot; height=&quot;26&quot; data-origin-width=&quot;47&quot; data-origin-height=&quot;26&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;하나&amp;nbsp;재밌는&amp;nbsp;것은&amp;nbsp;MariaDB가&amp;nbsp;MySql&amp;nbsp;계열(?)이라서&amp;nbsp;그런지 &lt;br /&gt;별다른&amp;nbsp;설정&amp;nbsp;없이&amp;nbsp;MySql를&amp;nbsp;사용하는&amp;nbsp;환경에서도&amp;nbsp;DB서버가&amp;nbsp;잘&amp;nbsp;작동했다. &lt;br /&gt;팀프로젝트&amp;nbsp;환경설정이&amp;nbsp;MySql로&amp;nbsp;되어있었는데&amp;nbsp;MariaDB에&amp;nbsp;대한&amp;nbsp;dependencies&amp;nbsp;추가&amp;nbsp;없이&amp;nbsp;사용&amp;nbsp;가능했다. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;이제&amp;nbsp;로컬&amp;nbsp;말고&amp;nbsp;서버로&amp;nbsp;구축한&amp;nbsp;데이터베이스를&amp;nbsp;사용하면&amp;nbsp;된다!&lt;/p&gt;</description>
      <category>DATABASE</category>
      <category>Database</category>
      <category>database서버</category>
      <category>mariadb</category>
      <category>MYSQL</category>
      <category>Nas</category>
      <category>synology</category>
      <author>nowcow</author>
      <guid isPermaLink="true">https://nowcow.tistory.com/1</guid>
      <comments>https://nowcow.tistory.com/1#entry1comment</comments>
      <pubDate>Sat, 5 Oct 2024 00:48:34 +0900</pubDate>
    </item>
  </channel>
</rss>