개요
저는 디스플레이가 박살이 나버린 맥북으로 홈 서버를 구축해서 사이드 프로젝트를 배포했고, 개발용 서버로도 사용 중입니다.
비싼 돈 주고 산 16인치 맥북을 카페에서 실수로 떨어트렸는데, 모서리 부분이 아작이 나버렸습니다. 디스플레이 교체 비용 견적을 내보았는데 너무 비싸서, 차라리 새 맥북을 한대 더 사는 게 나을 것 같더라구요. 그래서 예정에 없던 새 맥북을 구매했습니다. 기분이 좋은데 안 좋네요.. 그런데 디스플레이만 망가졌지, 다른 건 멀쩡하게 작동하는 맥북을 그냥 썩히기에는 너무 아깝다는 생각이 들어, 클라우드 임대료도 아낄 겸 이 맥북을 홈 서버로 구축해서 써먹어보기로 했습니다.
결과적으로 최근에 진행했던 팀 프로젝트를 그 맥북에 성공적으로 배포해서 운영 중입니다. NCP 기준으로 4코어 16GB 인스턴스 월 예상 임대료가 17만 원 정도라고 나오던데, 이걸 맥북 충전 전기료만으로 퉁 쳤으니 매우 이득이라고 생각하고 있습니다. (맥북 값은 더 이상 생각하지 않기로 했습니다.) 개인적인 개발용 서버나 파일 서버로도 활용할 수 있으니, 최대한 끝까지 뽑아먹고 보내줄 생각입니다.
서버 운영을 위한 환경 설정
맥북을 서버로 운용하기 위해서 필요한 기본적인 환경 설정 방법을 정리해보겠습니다.
설정해주어야 하는 항목은 크게 사설 IP 고정과 포트포워딩, 방화벽 설정, 절전 모드 해제가 있습니다.
설명은 macOS 세콰이어 기준입니다.
사설 IP 고정
주기적으로 사설 IP가 변경되는 DHCP(유동 IP)를 비활성화하고, IP를 수동으로 고정시켜야 합니다. 그렇지 않으면 IP가 변경될 때마다 포트포워딩을 새로 해줘야 하니까요. 그리고 저는 안정적인 네트워크 환경을 위해서 유선 랜을 연결해서 사용 중입니다. 벽에서 나오는 이더넷 포트에 다이렉트로 랜선을 연결해, 집에 굴러다니는 허브에 연결해서 아래 사진과 같이 연결시켜 사용중입니다.

먼저, [시스템 설정] 앱을 실행해서 [네트워크] 탭에 들어갑니다. 언급한 대로 저는 유선랜 환경이기 때문에, 다음과 같이 네트워크 프로파일이 유선랜 하나만 활성화되어있는 상태입니다. 유선/무선 구분은 맨 앞의 아이콘 모양으로 판단할 수 있습니다.

네트워크 프로파일을 클릭하면 다음과 같이 현재 설정값이 표시됩니다. 저는 이미 수동으로 설정을 마친 상태라 'IPv4 구성됨' 항목이 '수동'으로 표시됩니다. 설정을 마치기 전에는 'DHCP 사용'으로 보입니다. [세부사항...] 버튼을 클릭해서 프로파일 설정을 변경합니다.
![[네트워크 프로파일 상세 정보]](https://blog.kakaocdn.net/dn/exROOd/btsMJzbiolr/BFSthl6QVLOlYk82Ea7pl0/img.png)
[TCP/IP] 탭에서 'IPv4 구성' 항목을 '수동'으로 변경하는데, 그전에 그 아래의 3개 항목에 설정되어 있는 값을 메모해 놓는 게 좋습니다.
IPv4 구성 값을 수동으로 변경하면 곧바로 3개 항목이 전부 초기화가 되는데, 서브넷 마스크와 라우터는 기존값을 그대로 사용하면 되기 때문입니다. IP 주소도 특별히 사용하려는 주소값이 있는 게 아니라면 그대로 사용해도 괜찮습니다.

마지막으로 DNS 주소를 설정해 줍니다. 위에서부터 2개 주소값은 LG U+의 DNS 주소로, 기본으로 설정되어 있었습니다. 굳이 지우지는 않았고, 클라우드 플레어(1.1.1.1)와 구글(8.8.8.8) DNS를 추가로 설정해 주었습니다. (추가는 굳이 안 해줘도 무방합니다)

방화벽 설정
웹 서버로 사용할 목적이니, 보안을 위해 방화벽 활성화는 기본입니다. macOS 가 지원하는 방화벽을 사용하고, GUI로 설정할 수 있어 설정 과정 및 관리가 리눅스 서버에 비해 간편합니다.
다시 [시스템 설정] 앱의 [네트워크] 탭에 들어갑니다. 방화벽이 기본적으로 비활성화되어있는 것을 볼 수 있습니다.

방화벽을 활성화시키면, 아래의 [옵션...] 버튼이 활성화됩니다. 버튼을 클릭하면 허용/차단할 소프트웨어 리스트를 관리할 수 있습니다.

처음 실행해 보면 기본적으로 몇 가지 항목이 등록되어 있는 상태이고, +/- 버튼으로 직접 추가/삭제할 수 있습니다. 편리한 점은, 하단의 옵션 두 가지(~~ 자동으로 허용)를 활성화해놓으면, 수동으로 화이트 리스트를 추가하지 않아도 알아서 등록이 필요한 항목을 인식해서 표시해 줍니다. 아마도 Apple이 제공하는 공증 절차를 거친 소프트웨어를 화이트 리스트로 관리해 주는 게 아닐까 생각해 봅니다. 제 경우, 아래 리스트의 'com.docker.backend', 'nginx', 'Python', 'vncserver' 네 개 항목이 자동으로 등록된 항목입니다.

예시로, 저는 로드 밸런싱과 SSL/TLS 인증서 등록을 위해 nginx를 설치해서 사용 중입니다. 위에서 말씀드린 '~~자동으로 허용' 옵션을 활성화해놓았기 때문에, 화이트 리스트에 nginx가 등록이 되어있기 전에 nginx로 들어오는 요청이 인식되면 아래와 같이 허용 확인 컨펌 팝업이 표시됩니다. [허용] 버튼을 누르면 화이트 리스트에 자동으로 등록됩니다.
한 가지 번거로운 점이 있다면, 아래와 같은 컨펌 팝업이 표시되는 걸 보고 허용 버튼을 직접 눌러주어야 한다는 점입니다. 그러니 새로운 소프트웨어를 설치할 때마다 서버 맥북의 화면을 지켜보고 있어야겠네요. 아니면 직접 리스트에 등록해 주거나요.

포트포워딩 설정 (LG U+ 기준)
사설 IP 고정을 마쳤으니, 외부에서 실행 중인 서비스에 접속할 수 있도록 포트포워딩을 해줘야 합니다.
(설명과 캡처는 제가 사용 중인 LG U+ 인터넷을 기준으로 합니다.)
우선, 웹 브라우저에 게이트웨이 IP를 입력해서 공유기 설정 페이지에 접속합니다. 각자 네트워크 환경 구성에 따라 보이는 화면은 다를 수 있습니다. 저는 네트워크 단자함에 들어있는 HUB 한 대와 공유기 한 대로 구성해 놓은 상태라 아래 이미지와 같이 표시됩니다. 그리고 위에서 언급한 대로 저는 벽에서 바로 나오는 이더넷 포트에 랜선을 다이렉트로 연결해서 사용 중이기 때문에, 아래의 공유기 이미지가 아닌 표시해 놓은 HUB 모양 이미지를 클릭해서 접속했습니다.

이미지를 클릭하면 비밀번호를 요구합니다. 이 비밀번호는 각 단말기 하단에 붙어있는 스티커에 적혀있습니다. 그리고 비밀번호는 단말기마다 각자 다릅니다. 그러니 TV 옆에 있는 공유기 비밀번호로 백번 입력해 봐야 로그인 안됩니다. (제 얘기 아닙니다) 일반적으로 저런 메인 HUB는 가구 내의 네트워크 단자함에 넣어놓는다고 합니다. 제가 거주 중인 아파트는 네트워크 단자함이 현관의 신발장 안에 숨어있어, 이사 오고 처음으로 신발장 선반을 들어내고 단자함을 열어봤네요.

[네트워크 설정] - [NAT 설정] 메뉴로 진입합니다.

이제 마지막으로 포트 포워딩을 상황에 맞게 설정합니다. 저는 웹 서비스의 서버 용도로 사용할 것이기 때문에 HTTP/S 포트인 80과 443을 포워딩했고, 외부에서 SSH로 접속할 수 있게 22번으로 포워딩 설정을 해놓았습니다. 그 외 설정은 MySQL이나 RabbitMQ, Elasticsearch 등의 미들웨어에 직접 접속하기 위해 포워딩해 놓은 항목들입니다. 그리고 IP 주소는 위에서 설정한 맥북의 로컬 IP 주소를 입력합니다. (참고로, 최소한의 공격에 대한 보안 강화를 위해 기본 포트(예: MySQL 3306)는 사용하지 않았습니다.)

절전 모드(잠자기, 배터리) 설정
맥북이 절전 모드(또는 잠자기 모드)에 들어가게 되면, 외부 네트워크에서 맥북으로 접속할 수 없게 됩니다. 보통 맥북은 화면을 덮으면 자동으로 잠자기 모드에 진입하게 되는데요. 화면을 항상 열어놓고 운용하기에는 불편한 점이 많습니다. 그래서 저는 맨 위 사진처럼 화면을 덮은 채로 스탠드에 세워놓은 상태로 운용하고 있는데요. 이때 맥북이 잠자기 모드에 들지 않게 하기 위해서는 터미널 명령어를 사용해야 합니다.
# 자동 잠자기 비활성화
> sudo pmset -a sleep 0
# 잠자기 모드 진입 방지
> sudo pmset -a disablesleep 1
이전에 관련 내용을 작성한 글 링크를 첨부합니다.
[블로그: 맥북 화면 덮었을 때 잠자기 모드에 들지 않게 설정하는 방법 - https://cloverlaun.tistory.com/97]
맥북 화면 덮었을 때 잠자기 모드에 들지 않게 설정하는 방법
화면을 덮어도 잠자기 모드에 들지 않게 하는 명령어# 자동 잠자기 비활성화> sudo pmset -a sleep 0# 잠자기 모드 진입 방지> sudo pmset -a disablesleep 1 [옵션 설명]`-a` (all) : 모든 전원 상태(배터리 전원, A
cloverlaun.tistory.com
원격 접속 환경 구성
기본적인 환경 설정을 끝냈으니, 외부에서도 언제나 서버에 접속하여 제어할 수 있도록 구성할 차례입니다. 기본적으로 SSH 접속 기능을 활성화해서 마치 클라우드 서비스에 리눅스 인스턴스를 띄워놓고 사용하는 것만 같은 기분을 낼 수 있게 하고, 추가로 방화벽이나 Docker Desktop 관리 등 맥의 GUI로 접근해야만 하는 상황을 대비해 GUI 원격 제어 프로그램을 설치합니다.
원격 로그인 허용
macOS에 원격으로 접속하려면 가장 먼저 원격 로그인을 허용해주어야 합니다. 이는 원격 접속에 관련된 모든 소프트웨어가 영향을 받는다고 합니다.
[시스템 설정] 탭의 [일반] -> [공유] 화면으로 진입합니다. 만약 SSH만 사용한다면 '원격 로그인'만 활성화하면 되고, 저는 VNC 뷰어와 macOS 자체 편의 기능을 사용할 것이기 때문에 아래처럼 관련 옵션 세 개를 모두 활성화해놓았습니다.
그리고 각 항목마다 붙어있는 ⓘ 버튼을 클릭하면 접근 계정도 관리할 수 있습니다. 상황에 맞게 추가하면 될 것 같습니다.

SSH 접속 기능 활성화
SSH 접속에 사용할 인증 방식을 설정하고, SSH 서비스를 재시작해서 활성화해주면 설정이 끝납니다. 서버에서 터미널을 실행하여 `/etc/ssh/sshd_config` 파일을 수정하고 서비스를 재시작합니다.
sudo vim /etc/ssh/sshd_config
# 다음 설정을 추가 또는 수정
PubkeyAuthentication yes
PasswordAuthentication no
# SSH 서비스 재시작
sudo launchctl unload /System/Library/LaunchDaemons/ssh.plist
sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist
저는 오직 공개키 방식만 사용하고 ID/PW 방식은 사용하지 않기 때문에, `PubkeyAuthentication` 값만 `yes`로 설정했습니다. 이제 서버에 접근할 수 있는 클라이언트의 공개키를 등록해주어야 합니다.
공개키를 관리하는 파일은 `~/.ssh/authorized_keys` 입니다. 이 파일명과 경로는 기본값으로 등록되어 있는 것인데, 만약 바꾸고 싶다면, `/etc/ssh/sshd_config` 파일의 `AuthorizedKeysFile` 설정 값을 찾아서 변경해 주면 됩니다. 저는 그대로 사용했습니다. 이제 파일에 클라이언트에서 생성한 공개키를 추가해 주면 SSH 설정 완료입니다.
# authorized_keys 파일에 클라이언트 공개키 추가
echo "복사한_공개키_내용" >> ~/.ssh/authorized_keys

GUI 원격 소프트웨어 설치 (feat. RealVNC)
어쩌나 저쩌나 서버 OS가 macOS이기 때문에, SSH만으로 서버를 제어하고 관리하는 데에는 한계가 있습니다. 관리자 권한을 요구하거나 유저 Confirm이 필요한 동작은 GUI로 알림을 표시하는 경우가 많기 때문입니다. 예시로 위의 방화벽 설정 문단에서 언급한 방화벽 허용 확인 절차, macOS의 키체인 접근 시도 등이 있습니다.
그래서 언제든지 GUI 화면도 제어할 수 있도록 원격 제어 소프트웨어를 사용하기로 했습니다. 처음에는 구글 크롬 원격 데스크톱을 설치해서 사용해 봤는데, 자꾸 서버에서 연결이 끊겨버리는 문제가 있었습니다. macOS와의 호환이 안정적이지 않은 것인지 원인은 파악하지 못했지만, 계속 사용하기는 어렵다고 판단했습니다. 그래서 무료로 사용할 수 있는 소프트웨어를 찾아보다가, 최종적으로 RealVNC로 결정해서 사용 중입니다.

서버로 사용 중인 맥북에 'RealVNC Server for Desktop'을 다운받고 실행하면 로그인을 요구합니다. 회원가입 & 로그인을 하고 RealVNC Server Start를 클릭하여 아래 이미지와 같이 맥북을 원격 서버로 활성화시킵니다.

이제 다른 맥북에 Viewer를 설치하고 동일한 계정으로 로그인하면 활성화 상태인 원격 서버에 접속할 수 있습니다.
무료 버전이지만 원격 접속 퀄리티가 꽤 나쁘지 않습니다. 딜레이나 안정성이 크롬 데스크톱에 비해 더 좋다고 느껴집니다. 가끔 한 번씩 접속해서 잠깐 확인만 하고 끄는 용도로는 충분한 것 같습니다.
Docker 컨테이너 기반 서비스 관리
서버 운영을 위한 설정이 다 끝났습니다. 이제 서비스를 배포하기만 하면 됩니다. 저는 MySQL, RabbitMQ 같은 미들웨어와 제가 개발한 프로젝트를 모두 Docker 컨테이너로 구성했습니다.
서버를 macOS로 사용했을 때 장점 중 하나는 Docker Desktop 을 사용할 수 있다는 점입니다. CLI만으로도 충분히 관리할 수 있지만, 특정 컨테이너를 재시작하거나 로그를 확인해야 할 때는 GUI 환경이 확실히 편하긴 합니다.

Docker Desktop으로 컨테이너 관리하기
Docker Desktop 앱을 설치합니다. Desktop 앱 자체에 Docker 서버가 포함되어 있어, Docker를 별도로 설치할 필요가 없어 편합니다. 그리고 CLI 명령어를 동일하게 사용할 수 있으니, 상황에 맞게 CLI와 GUI를 취사선택할 수 있다는 점이 편하고 좋은 것 같습니다.
제 맥북은 M2 칩을 사용하기 때문에, Apple Silicon 버전을 다운받아서 설치합니다. Desktop 앱 설치 과정이 별로 복잡하지 않아서 좋습니다.
[Docker Desktop 다운로드: https://www.docker.com/products/docker-desktop/]

docker-compose 로 컨테이너 생성, 관리하기
관리해야 하는 컨테이너가 많아질수록 compose 사용은 선택이 아닌 필수인 것 같습니다. 프로젝트를 진행하면서 컨테이너를 재시작해야 하거나, 완전히 삭제했다가 다시 올려야 하는 경우가 종종 있었는데, 그럴 때마다 compose 파일로 스크립트를 작성해 놓은 덕분에 쉽고 편하게 작업할 수 있었습니다.
저는 서버의 루트 경로에 디렉터리를 하나 만들어서 compose 파일을 모아놓고 관리하고 있습니다. 제 프로젝트 컨테이너 외에 MySQL, MongoDB, Elasticsearch, RabbitMQ와 Jenkins를 모두 컨테이너로 관리하고 있어, 각각 디렉토리를 만들어 백업이 필요한 파일들을 compose 파일과 함께 관리합니다.
compose 파일의 내용은 이 글에서 정리하면 내용이 너무 길어질 것 같아 생략합니다.

동일한 Docker Network로 묶어서 관리하기
백엔드 서버와 DB 서버를 한 대의 머신으로 운영할 때 장점 중 하나는, 백엔드 서버가 DB에 로컬 호스트로 접속할 수 있다는 점입니다. 그래서 OSI 7 계층 모델의 4 계층인 전송 계층까지만 이용해도 접속이 가능합니다. 따라서 백엔드 컨테이너와 DB 컨테이너의 통신 간 보안이 강화된다는 이점이 있고, 네트워크 지연 시간이 감소한다는 이점이 있습니다.
그런데 Docker 컨테이너 간의 통신을 활성화하기 위해서는 동일한 Docker Network로 묶어줘야 합니다. 저는 사전에 bridge 모드를 사용하는 network를 생성해 놓고, 각 컨테이너의 compose 파일에 다음과 같이 작성했습니다.
services:
mysql:
container_name: my-mysql # 컨테이너 이름
...
...
networks:
- external-network # 아래의 networks 하위 항목과 매칭
networks:
external-network:
external: true # Docker 전역 네트워크를 사용한다.
name: my-network # 미리 생성해둔 network 이름
그리고 백엔드 서비스 컨테이너도 동일한 network로 묶어주면, 컨테이너 이름으로 접속이 가능하게 됩니다. 예시로, SpringBoot의 `application.properties` 를 다음과 같이 작성할 수 있습니다.
spring.datasource.url=jdbc:mysql://my-mysql:3306/my-db-name
마무리
맥북으로 홈 서버를 구축하는 과정은 AWS 같은 상용 클라우드 인스턴스를 임대했을 때보다 편한 점도 있고, 다르거나 정보가 부족한 점도 있는 것 같습니다. 그래서 제가 겪었던 과정 중 클라우드를 사용할 때와 다른 부분에 초점을 맞춰서 최대한 간결하게 정리해 보려고 노력했습니다.
이제 클라우드 임대료 걱정 없이 프로젝트를 할 수 있게 되었다는 점이 가장 큰 성과가 아닐까 싶습니다. 한 가지 아쉬운 점이 있다면, 가정용 네트워크 회선은 대역폭이 좁기 때문에 본격적인 서비스를 돌리기에는 부족할 수 있다는 것입니다. 제가 만든 서비스가 대박 날까 봐 걱정이네요.
아무튼, 저처럼 macOS를 서버로 사용해 보려는 분들께 도움이 되었으면 좋겠습니다.
'Server' 카테고리의 다른 글
동시성 문제 해결을 위한 메시지 큐 사용기 (0) | 2025.03.12 |
---|---|
BCrypt 암호화가 안전한 이유? (1) | 2025.03.08 |
개요
저는 디스플레이가 박살이 나버린 맥북으로 홈 서버를 구축해서 사이드 프로젝트를 배포했고, 개발용 서버로도 사용 중입니다.
비싼 돈 주고 산 16인치 맥북을 카페에서 실수로 떨어트렸는데, 모서리 부분이 아작이 나버렸습니다. 디스플레이 교체 비용 견적을 내보았는데 너무 비싸서, 차라리 새 맥북을 한대 더 사는 게 나을 것 같더라구요. 그래서 예정에 없던 새 맥북을 구매했습니다. 기분이 좋은데 안 좋네요.. 그런데 디스플레이만 망가졌지, 다른 건 멀쩡하게 작동하는 맥북을 그냥 썩히기에는 너무 아깝다는 생각이 들어, 클라우드 임대료도 아낄 겸 이 맥북을 홈 서버로 구축해서 써먹어보기로 했습니다.
결과적으로 최근에 진행했던 팀 프로젝트를 그 맥북에 성공적으로 배포해서 운영 중입니다. NCP 기준으로 4코어 16GB 인스턴스 월 예상 임대료가 17만 원 정도라고 나오던데, 이걸 맥북 충전 전기료만으로 퉁 쳤으니 매우 이득이라고 생각하고 있습니다. (맥북 값은 더 이상 생각하지 않기로 했습니다.) 개인적인 개발용 서버나 파일 서버로도 활용할 수 있으니, 최대한 끝까지 뽑아먹고 보내줄 생각입니다.
서버 운영을 위한 환경 설정
맥북을 서버로 운용하기 위해서 필요한 기본적인 환경 설정 방법을 정리해보겠습니다.
설정해주어야 하는 항목은 크게 사설 IP 고정과 포트포워딩, 방화벽 설정, 절전 모드 해제가 있습니다.
설명은 macOS 세콰이어 기준입니다.
사설 IP 고정
주기적으로 사설 IP가 변경되는 DHCP(유동 IP)를 비활성화하고, IP를 수동으로 고정시켜야 합니다. 그렇지 않으면 IP가 변경될 때마다 포트포워딩을 새로 해줘야 하니까요. 그리고 저는 안정적인 네트워크 환경을 위해서 유선 랜을 연결해서 사용 중입니다. 벽에서 나오는 이더넷 포트에 다이렉트로 랜선을 연결해, 집에 굴러다니는 허브에 연결해서 아래 사진과 같이 연결시켜 사용중입니다.

먼저, [시스템 설정] 앱을 실행해서 [네트워크] 탭에 들어갑니다. 언급한 대로 저는 유선랜 환경이기 때문에, 다음과 같이 네트워크 프로파일이 유선랜 하나만 활성화되어있는 상태입니다. 유선/무선 구분은 맨 앞의 아이콘 모양으로 판단할 수 있습니다.

네트워크 프로파일을 클릭하면 다음과 같이 현재 설정값이 표시됩니다. 저는 이미 수동으로 설정을 마친 상태라 'IPv4 구성됨' 항목이 '수동'으로 표시됩니다. 설정을 마치기 전에는 'DHCP 사용'으로 보입니다. [세부사항...] 버튼을 클릭해서 프로파일 설정을 변경합니다.
![[네트워크 프로파일 상세 정보]](https://blog.kakaocdn.net/dn/exROOd/btsMJzbiolr/BFSthl6QVLOlYk82Ea7pl0/img.png)
[TCP/IP] 탭에서 'IPv4 구성' 항목을 '수동'으로 변경하는데, 그전에 그 아래의 3개 항목에 설정되어 있는 값을 메모해 놓는 게 좋습니다.
IPv4 구성 값을 수동으로 변경하면 곧바로 3개 항목이 전부 초기화가 되는데, 서브넷 마스크와 라우터는 기존값을 그대로 사용하면 되기 때문입니다. IP 주소도 특별히 사용하려는 주소값이 있는 게 아니라면 그대로 사용해도 괜찮습니다.

마지막으로 DNS 주소를 설정해 줍니다. 위에서부터 2개 주소값은 LG U+의 DNS 주소로, 기본으로 설정되어 있었습니다. 굳이 지우지는 않았고, 클라우드 플레어(1.1.1.1)와 구글(8.8.8.8) DNS를 추가로 설정해 주었습니다. (추가는 굳이 안 해줘도 무방합니다)

방화벽 설정
웹 서버로 사용할 목적이니, 보안을 위해 방화벽 활성화는 기본입니다. macOS 가 지원하는 방화벽을 사용하고, GUI로 설정할 수 있어 설정 과정 및 관리가 리눅스 서버에 비해 간편합니다.
다시 [시스템 설정] 앱의 [네트워크] 탭에 들어갑니다. 방화벽이 기본적으로 비활성화되어있는 것을 볼 수 있습니다.

방화벽을 활성화시키면, 아래의 [옵션...] 버튼이 활성화됩니다. 버튼을 클릭하면 허용/차단할 소프트웨어 리스트를 관리할 수 있습니다.

처음 실행해 보면 기본적으로 몇 가지 항목이 등록되어 있는 상태이고, +/- 버튼으로 직접 추가/삭제할 수 있습니다. 편리한 점은, 하단의 옵션 두 가지(~~ 자동으로 허용)를 활성화해놓으면, 수동으로 화이트 리스트를 추가하지 않아도 알아서 등록이 필요한 항목을 인식해서 표시해 줍니다. 아마도 Apple이 제공하는 공증 절차를 거친 소프트웨어를 화이트 리스트로 관리해 주는 게 아닐까 생각해 봅니다. 제 경우, 아래 리스트의 'com.docker.backend', 'nginx', 'Python', 'vncserver' 네 개 항목이 자동으로 등록된 항목입니다.

예시로, 저는 로드 밸런싱과 SSL/TLS 인증서 등록을 위해 nginx를 설치해서 사용 중입니다. 위에서 말씀드린 '~~자동으로 허용' 옵션을 활성화해놓았기 때문에, 화이트 리스트에 nginx가 등록이 되어있기 전에 nginx로 들어오는 요청이 인식되면 아래와 같이 허용 확인 컨펌 팝업이 표시됩니다. [허용] 버튼을 누르면 화이트 리스트에 자동으로 등록됩니다.
한 가지 번거로운 점이 있다면, 아래와 같은 컨펌 팝업이 표시되는 걸 보고 허용 버튼을 직접 눌러주어야 한다는 점입니다. 그러니 새로운 소프트웨어를 설치할 때마다 서버 맥북의 화면을 지켜보고 있어야겠네요. 아니면 직접 리스트에 등록해 주거나요.

포트포워딩 설정 (LG U+ 기준)
사설 IP 고정을 마쳤으니, 외부에서 실행 중인 서비스에 접속할 수 있도록 포트포워딩을 해줘야 합니다.
(설명과 캡처는 제가 사용 중인 LG U+ 인터넷을 기준으로 합니다.)
우선, 웹 브라우저에 게이트웨이 IP를 입력해서 공유기 설정 페이지에 접속합니다. 각자 네트워크 환경 구성에 따라 보이는 화면은 다를 수 있습니다. 저는 네트워크 단자함에 들어있는 HUB 한 대와 공유기 한 대로 구성해 놓은 상태라 아래 이미지와 같이 표시됩니다. 그리고 위에서 언급한 대로 저는 벽에서 바로 나오는 이더넷 포트에 랜선을 다이렉트로 연결해서 사용 중이기 때문에, 아래의 공유기 이미지가 아닌 표시해 놓은 HUB 모양 이미지를 클릭해서 접속했습니다.

이미지를 클릭하면 비밀번호를 요구합니다. 이 비밀번호는 각 단말기 하단에 붙어있는 스티커에 적혀있습니다. 그리고 비밀번호는 단말기마다 각자 다릅니다. 그러니 TV 옆에 있는 공유기 비밀번호로 백번 입력해 봐야 로그인 안됩니다. (제 얘기 아닙니다) 일반적으로 저런 메인 HUB는 가구 내의 네트워크 단자함에 넣어놓는다고 합니다. 제가 거주 중인 아파트는 네트워크 단자함이 현관의 신발장 안에 숨어있어, 이사 오고 처음으로 신발장 선반을 들어내고 단자함을 열어봤네요.

[네트워크 설정] - [NAT 설정] 메뉴로 진입합니다.

이제 마지막으로 포트 포워딩을 상황에 맞게 설정합니다. 저는 웹 서비스의 서버 용도로 사용할 것이기 때문에 HTTP/S 포트인 80과 443을 포워딩했고, 외부에서 SSH로 접속할 수 있게 22번으로 포워딩 설정을 해놓았습니다. 그 외 설정은 MySQL이나 RabbitMQ, Elasticsearch 등의 미들웨어에 직접 접속하기 위해 포워딩해 놓은 항목들입니다. 그리고 IP 주소는 위에서 설정한 맥북의 로컬 IP 주소를 입력합니다. (참고로, 최소한의 공격에 대한 보안 강화를 위해 기본 포트(예: MySQL 3306)는 사용하지 않았습니다.)

절전 모드(잠자기, 배터리) 설정
맥북이 절전 모드(또는 잠자기 모드)에 들어가게 되면, 외부 네트워크에서 맥북으로 접속할 수 없게 됩니다. 보통 맥북은 화면을 덮으면 자동으로 잠자기 모드에 진입하게 되는데요. 화면을 항상 열어놓고 운용하기에는 불편한 점이 많습니다. 그래서 저는 맨 위 사진처럼 화면을 덮은 채로 스탠드에 세워놓은 상태로 운용하고 있는데요. 이때 맥북이 잠자기 모드에 들지 않게 하기 위해서는 터미널 명령어를 사용해야 합니다.
# 자동 잠자기 비활성화
> sudo pmset -a sleep 0
# 잠자기 모드 진입 방지
> sudo pmset -a disablesleep 1
이전에 관련 내용을 작성한 글 링크를 첨부합니다.
[블로그: 맥북 화면 덮었을 때 잠자기 모드에 들지 않게 설정하는 방법 - https://cloverlaun.tistory.com/97]
맥북 화면 덮었을 때 잠자기 모드에 들지 않게 설정하는 방법
화면을 덮어도 잠자기 모드에 들지 않게 하는 명령어# 자동 잠자기 비활성화> sudo pmset -a sleep 0# 잠자기 모드 진입 방지> sudo pmset -a disablesleep 1 [옵션 설명]`-a` (all) : 모든 전원 상태(배터리 전원, A
cloverlaun.tistory.com
원격 접속 환경 구성
기본적인 환경 설정을 끝냈으니, 외부에서도 언제나 서버에 접속하여 제어할 수 있도록 구성할 차례입니다. 기본적으로 SSH 접속 기능을 활성화해서 마치 클라우드 서비스에 리눅스 인스턴스를 띄워놓고 사용하는 것만 같은 기분을 낼 수 있게 하고, 추가로 방화벽이나 Docker Desktop 관리 등 맥의 GUI로 접근해야만 하는 상황을 대비해 GUI 원격 제어 프로그램을 설치합니다.
원격 로그인 허용
macOS에 원격으로 접속하려면 가장 먼저 원격 로그인을 허용해주어야 합니다. 이는 원격 접속에 관련된 모든 소프트웨어가 영향을 받는다고 합니다.
[시스템 설정] 탭의 [일반] -> [공유] 화면으로 진입합니다. 만약 SSH만 사용한다면 '원격 로그인'만 활성화하면 되고, 저는 VNC 뷰어와 macOS 자체 편의 기능을 사용할 것이기 때문에 아래처럼 관련 옵션 세 개를 모두 활성화해놓았습니다.
그리고 각 항목마다 붙어있는 ⓘ 버튼을 클릭하면 접근 계정도 관리할 수 있습니다. 상황에 맞게 추가하면 될 것 같습니다.

SSH 접속 기능 활성화
SSH 접속에 사용할 인증 방식을 설정하고, SSH 서비스를 재시작해서 활성화해주면 설정이 끝납니다. 서버에서 터미널을 실행하여 /etc/ssh/sshd_config
파일을 수정하고 서비스를 재시작합니다.
sudo vim /etc/ssh/sshd_config
# 다음 설정을 추가 또는 수정
PubkeyAuthentication yes
PasswordAuthentication no
# SSH 서비스 재시작
sudo launchctl unload /System/Library/LaunchDaemons/ssh.plist
sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist
저는 오직 공개키 방식만 사용하고 ID/PW 방식은 사용하지 않기 때문에, PubkeyAuthentication
값만 yes
로 설정했습니다. 이제 서버에 접근할 수 있는 클라이언트의 공개키를 등록해주어야 합니다.
공개키를 관리하는 파일은 ~/.ssh/authorized_keys
입니다. 이 파일명과 경로는 기본값으로 등록되어 있는 것인데, 만약 바꾸고 싶다면, /etc/ssh/sshd_config
파일의 AuthorizedKeysFile
설정 값을 찾아서 변경해 주면 됩니다. 저는 그대로 사용했습니다. 이제 파일에 클라이언트에서 생성한 공개키를 추가해 주면 SSH 설정 완료입니다.
# authorized_keys 파일에 클라이언트 공개키 추가
echo "복사한_공개키_내용" >> ~/.ssh/authorized_keys

GUI 원격 소프트웨어 설치 (feat. RealVNC)
어쩌나 저쩌나 서버 OS가 macOS이기 때문에, SSH만으로 서버를 제어하고 관리하는 데에는 한계가 있습니다. 관리자 권한을 요구하거나 유저 Confirm이 필요한 동작은 GUI로 알림을 표시하는 경우가 많기 때문입니다. 예시로 위의 방화벽 설정 문단에서 언급한 방화벽 허용 확인 절차, macOS의 키체인 접근 시도 등이 있습니다.
그래서 언제든지 GUI 화면도 제어할 수 있도록 원격 제어 소프트웨어를 사용하기로 했습니다. 처음에는 구글 크롬 원격 데스크톱을 설치해서 사용해 봤는데, 자꾸 서버에서 연결이 끊겨버리는 문제가 있었습니다. macOS와의 호환이 안정적이지 않은 것인지 원인은 파악하지 못했지만, 계속 사용하기는 어렵다고 판단했습니다. 그래서 무료로 사용할 수 있는 소프트웨어를 찾아보다가, 최종적으로 RealVNC로 결정해서 사용 중입니다.

서버로 사용 중인 맥북에 'RealVNC Server for Desktop'을 다운받고 실행하면 로그인을 요구합니다. 회원가입 & 로그인을 하고 RealVNC Server Start를 클릭하여 아래 이미지와 같이 맥북을 원격 서버로 활성화시킵니다.

이제 다른 맥북에 Viewer를 설치하고 동일한 계정으로 로그인하면 활성화 상태인 원격 서버에 접속할 수 있습니다.
무료 버전이지만 원격 접속 퀄리티가 꽤 나쁘지 않습니다. 딜레이나 안정성이 크롬 데스크톱에 비해 더 좋다고 느껴집니다. 가끔 한 번씩 접속해서 잠깐 확인만 하고 끄는 용도로는 충분한 것 같습니다.
Docker 컨테이너 기반 서비스 관리
서버 운영을 위한 설정이 다 끝났습니다. 이제 서비스를 배포하기만 하면 됩니다. 저는 MySQL, RabbitMQ 같은 미들웨어와 제가 개발한 프로젝트를 모두 Docker 컨테이너로 구성했습니다.
서버를 macOS로 사용했을 때 장점 중 하나는 Docker Desktop 을 사용할 수 있다는 점입니다. CLI만으로도 충분히 관리할 수 있지만, 특정 컨테이너를 재시작하거나 로그를 확인해야 할 때는 GUI 환경이 확실히 편하긴 합니다.

Docker Desktop으로 컨테이너 관리하기
Docker Desktop 앱을 설치합니다. Desktop 앱 자체에 Docker 서버가 포함되어 있어, Docker를 별도로 설치할 필요가 없어 편합니다. 그리고 CLI 명령어를 동일하게 사용할 수 있으니, 상황에 맞게 CLI와 GUI를 취사선택할 수 있다는 점이 편하고 좋은 것 같습니다.
제 맥북은 M2 칩을 사용하기 때문에, Apple Silicon 버전을 다운받아서 설치합니다. Desktop 앱 설치 과정이 별로 복잡하지 않아서 좋습니다.
[Docker Desktop 다운로드: https://www.docker.com/products/docker-desktop/]

docker-compose 로 컨테이너 생성, 관리하기
관리해야 하는 컨테이너가 많아질수록 compose 사용은 선택이 아닌 필수인 것 같습니다. 프로젝트를 진행하면서 컨테이너를 재시작해야 하거나, 완전히 삭제했다가 다시 올려야 하는 경우가 종종 있었는데, 그럴 때마다 compose 파일로 스크립트를 작성해 놓은 덕분에 쉽고 편하게 작업할 수 있었습니다.
저는 서버의 루트 경로에 디렉터리를 하나 만들어서 compose 파일을 모아놓고 관리하고 있습니다. 제 프로젝트 컨테이너 외에 MySQL, MongoDB, Elasticsearch, RabbitMQ와 Jenkins를 모두 컨테이너로 관리하고 있어, 각각 디렉토리를 만들어 백업이 필요한 파일들을 compose 파일과 함께 관리합니다.
compose 파일의 내용은 이 글에서 정리하면 내용이 너무 길어질 것 같아 생략합니다.

동일한 Docker Network로 묶어서 관리하기
백엔드 서버와 DB 서버를 한 대의 머신으로 운영할 때 장점 중 하나는, 백엔드 서버가 DB에 로컬 호스트로 접속할 수 있다는 점입니다. 그래서 OSI 7 계층 모델의 4 계층인 전송 계층까지만 이용해도 접속이 가능합니다. 따라서 백엔드 컨테이너와 DB 컨테이너의 통신 간 보안이 강화된다는 이점이 있고, 네트워크 지연 시간이 감소한다는 이점이 있습니다.
그런데 Docker 컨테이너 간의 통신을 활성화하기 위해서는 동일한 Docker Network로 묶어줘야 합니다. 저는 사전에 bridge 모드를 사용하는 network를 생성해 놓고, 각 컨테이너의 compose 파일에 다음과 같이 작성했습니다.
services:
mysql:
container_name: my-mysql # 컨테이너 이름
...
...
networks:
- external-network # 아래의 networks 하위 항목과 매칭
networks:
external-network:
external: true # Docker 전역 네트워크를 사용한다.
name: my-network # 미리 생성해둔 network 이름
그리고 백엔드 서비스 컨테이너도 동일한 network로 묶어주면, 컨테이너 이름으로 접속이 가능하게 됩니다. 예시로, SpringBoot의 application.properties
를 다음과 같이 작성할 수 있습니다.
spring.datasource.url=jdbc:mysql://my-mysql:3306/my-db-name
마무리
맥북으로 홈 서버를 구축하는 과정은 AWS 같은 상용 클라우드 인스턴스를 임대했을 때보다 편한 점도 있고, 다르거나 정보가 부족한 점도 있는 것 같습니다. 그래서 제가 겪었던 과정 중 클라우드를 사용할 때와 다른 부분에 초점을 맞춰서 최대한 간결하게 정리해 보려고 노력했습니다.
이제 클라우드 임대료 걱정 없이 프로젝트를 할 수 있게 되었다는 점이 가장 큰 성과가 아닐까 싶습니다. 한 가지 아쉬운 점이 있다면, 가정용 네트워크 회선은 대역폭이 좁기 때문에 본격적인 서비스를 돌리기에는 부족할 수 있다는 것입니다. 제가 만든 서비스가 대박 날까 봐 걱정이네요.
아무튼, 저처럼 macOS를 서버로 사용해 보려는 분들께 도움이 되었으면 좋겠습니다.
'Server' 카테고리의 다른 글
동시성 문제 해결을 위한 메시지 큐 사용기 (0) | 2025.03.12 |
---|---|
BCrypt 암호화가 안전한 이유? (1) | 2025.03.08 |