최근 진행 중인 프로젝트는 NAS로 구축한 개인 서버에서 돌리고 있습니다.
서버를 띄우는 데는 Docker를 이용했고, 도메인 연결이나 네트워크 설정 등등 전체적으로 어떻게 서버를 구성했는지 기록해두면 좋을 것 같아 정리해보도록 하겠습니다.
NAS (Network Attached Storage)는 네트워크에 연결된 스토리지 장치로, 네트워크를 통해 데이터에 접근할 수 있어 여러 사용자가 파일을 저장하고 공유할 수 있게 해줍니다. 사실 저는 거의 안 썼지만 원래 집에서도 주로 파일 저장, 백업 용도로 쓰이고 있었습니다.
그러다 팀 프로젝트를 진행하면서 NAS에 Docker 컨테이너를 띄울 수 있다는 걸 알게 됐습니다.
진행 중인 다른 프로젝트에서는 AWS를 쓰고 있었는데, 아무래도 이런 외부 클라우드 서비스는 비용이 꽤나 부담됐고... 💸
따라서 비용 절감(초기 비용은 있지만) + 직접 서버를 구축하고 운영하는 경험을 쌓을 수 있다는 장점이 있어 NAS를 개인 서버로 만들기로 결정했습니다.
참고로 쓰고 있는 모델은 Synology DS920+ 이고, Spring Boot, MySQL, Redis 컨테이너를 띄워 사용하고 있습니다.
간편한 설정과 배포를 위해 Docker와 Docker Compose를 이용했습니다.
패키지 센터에서 Container Manager를 설치합니다.

Docker의 컨테이너와 이미지를 GUI로 쉽게 관리할 수 있습니다.
레지스트리 탭에서는 Docker Hub에 올라온 이미지들을 다운받을 수 있고, 네트워크 탭에서는 컨테이너들이 연결된 네트워크를 확인할 수 있습니다.
Docker Compose 설정을 위해서는 docker-compose.yml 파일이 필요합니다.
따로 docker-compose.yml을 작성해서 업로드해도 되고, 직접 NAS의 터미널에 접속해서 새로 파일을 생성해도 됩니다.
참고로 Synology NAS에서 터미널을 사용하려면 제어판 > 터미널 및 SNMP > 터미널 > SSH 활성화를 해야 합니다. 그 후 터미널에서 ssh 사용자_ID@IP 주소로 접속할 수 있습니다.
아무튼 저는 Spring Boot, MySQL, Redis의 설정을 담은 docker-compose.yml을 인텔리제이에서 작성한 후 업로드해줬습니다.
내용은 사용할 이미지 이름, 컨테이너 이름, 포트, 각종 환경변수 등을 적었습니다.
간단한 명령어로 컨테이너를 띄울 수 있습니다.
docker-compose.yml 파일이 있는 곳으로 폴더를 변경하고 필요한 명령어를 실행합니다.
자주 사용하는 메서드는 아래와 같은 것들이 있습니다.
docker-compose up -ddocker-compose downdocker pull 사용자 이름/이미지 이름그리고 컨테이너에 직접 접속해서 명령어를 실행해야 할 경우
docker exec -it 컨테이너_이름 /bin/bash를 실행해서 설정했습니다.
이렇게 띄운 서버에 누구나 접속할 수 있게 하려면 여러 설정이 필요합니다.
공유기에 접속해서 포트포워딩을 해줘야합니다.
공유기 설정은 다 다르긴하지만 보통 WAN > 포트 포워딩 > 규칙 추가를 해주면 됩니다.
Spring, MySQL 컨테이너가 띄워진 포트, HTTP의 기본 포트인 80, HTTPS의 기본 포트인 443을 열어줬습니다.
시놀로지의 경우 자체적으로 제공해주는 도메인이 있어 구매할 필요는 없지만,
저는 서비스를 운영해야하기 때문에 가비아에서 따로 구매했습니다.
그리고 처음에는 가비아에서 제공하는 네임 서버를 사용하다가, 이후 프론트엔드가 Cloudflare에 배포하면서 네임 서버를 이전했습니다.
서버 도메인은 api.XXX.XXX 형태, 서비스 도메인은 www.XXX.XXX 형태로 저장해주기 위해 Cloudflare의 레코드에는 아래와 같이 추가해줬습니다.
| 유형 | 이름 | 콘텐츠 |
|---|---|---|
| A | api | NAS의 퍼블릭 IP 주소 |
| CNAME | www | 프론트엔드 배포 주소 |
그리고 NAS에서는 제어판 > 외부 액세스 > DDNS에 들어가서 Cloudflare로 공급자를 설정해 도메인을 추가해줬습니다.
이렇게만 하면 같은 HTTP 환경에서는 통신할 수 있지만, 클라이언트 배포 페이지와 같은 HTTPS 환경과는 통신할 수 없습니다.
통신을 요청하면 아래와 같은 에러가 뜹니다.
Mixed Content: The page at '<URL>' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint '<URL>'. This request has been blocked; the content must be served over HTTPS.
그리고 서버 주소에 접속하면 안전하지 않음이라고 뜨기도 합니다.
HTTPS 설정을 위해서는 인증서 발급을 해줘야 합니다.
제어판 > 보안 > 인증서에서 추가 > 새 인증서 추가 > Let's Encrypt에서 인증서 얻기로 발급받을 수 있습니다. 도메인 이름, 이메일, 서브도메인 리스트를 입력해주고 적용합니다.
이 때 80번 포트가 열려있지 않다는 오류 메시지가 뜰 수 있는데, 공유기와 NAS의 방화벽 설정에서 열려있는지 확인해줘야 합니다.
다 생성했다면 설정을 클릭한 후 원하는 서비스에 인증서를 설정해주면 됩니다.
이 과정을 꼭 해야 인증서가 제대로 연결됩니다.
제어판 > 로그인 포털 > 고급 > 역방향 프록시에서 설정해줄 수 있습니다.
HTTPS:443로 들어오는 요청을 컨테이너가 돌아가고 있는 HTTP:8080로 전달할 수 있게 설정했습니다.
그럼 이제 클라이언트 측에서도 서버의 baseURL을 http://api.XXX.XXX:8080이 아닌 https://api.XXX.XXX로 설정해줄 수 있습니다!
당분간 리팩토링, 테스트 코드 관련 포스팅을 계속 이어갈 예정입니다.