한 대의 서버에 8개 서비스를 PM2랑 Apache 리버스 프록시로 돌리고 있다
포트 하나씩 나눠주고 도메인으로 묶기
#인프라 #Apache #PM2 #리버스프록시
pm2 list 한 번 치면 블로그, 코인, 커플, 게임, 모니터링, 포트폴리오, 타로, 여행 플래너까지 여덟 줄이 쫙 뜬다. 도메인은 다 다른데, 실제로는 전부 컴퓨터 한 대에서 도는 거다. 처음엔 이게 되는 건가 싶었는데, 막상 해보니 구조만 잡으면 별거 아니었다. 이 글에선 서비스 하나하나를 어떻게 띄우고 어떻게 도메인으로 묶었는지 정리해본다. 각 서비스는 자기 포트에서 돈다 일단 Node 서버마다 포트를 하나씩 나눠줬다. 블로그 5000, 코인 5006, 커플 5010, 모니터링 5020, 타로 5025… 이런 식으로 안 겹치게. 근데 이걸 그냥 node app.js로 띄우면 터미널 닫는 순간 죽어버린다. 그래서 PM2 로 관리한다. 백그라운드로 돌려주고, 죽으면 자동 재시작하고, 서버 재부팅돼도 알아서 다시 살린다. # 서비스 등록 pm2 start app.js --name blog-server # 전체 상태 한눈에 보기 pm2 list # 코드 바꾸고 재시작 pm2 restart blog-server # 재부팅해도 자동으로 살아나게 pm2 save pm2 startup pm2 list를 치면 8개 서비스가 각각 online인지, 메모리는 얼마나 먹는지, 몇 번 재시작됐는지가 표로 쫙 나온다. 이거 하나로 서버 전체 상태가 파악돼서 편하다. 그럼 도메인 연결은 누가 하나 진짜 문제는 여기서부터다. 사용자는 coin.jaeyonging.com으로 들어오지 5006번 포트로 들어오지 않는다. 80/443으로 들어온 요청을 알맞은 내부 포트로 넘겨줄 누군가가 필요한데, 그 역할을 Apache 리버스 프록시 가 한다. 도메인마다 VirtualHost를 하나씩 만들어서, 그 도메인으로 온 요청을 해당 포트로 넘기면 된다. 코인 사이트 설정은 대략 이렇게 생겼다. VirtualHost *:443 ServerName coin.jaeyonging.com SSLEngine on SSLCertificateFile /.../wildcard.jaeyonging.com.crt.pem SSLCertificateKeyFile /.../wildcard.jaeyonging.com.key.pem ProxyPreserveHost On ProxyPass / http://localhost:5006/ ProxyPassReverse / http://localhost:5006/ /VirtualHost 핵심은 ProxyPass / http://localhost:5006/ 이 한 줄이다. coin 도메인으로 온 요청을 전부 내부 5006으로 넘긴다. 도메인이 8개면 이런 VirtualHost를 8개 만드는 거다. 웹소켓은 따로 신경 써야 한다 코인 사이트는 실시간 채팅이랑 시세 때문에 Socket.IO를 쓰는데, 웹소켓은 일반 HTTP랑 연결 방식이 달라서 프록시 설정을 따로 해줘야 했다. 이거 안 하면 채팅이 자꾸 끊긴다. RewriteEngine On RewriteCond %{HTTP:Upgrade} websocket [NC] RewriteCond %{HTTP:Connection} upgrade [NC] RewriteRule ^/?(.*) ws://localhost:5006/$1 [P,L] ProxyPass /socket.io/ http://localhost:5006/socket.io/ ProxyPassReverse /socket.io/ http://localhost:5006/socket.io/ Upgrade 헤더가 websocket이면 ws:// 프로토콜로 따로 넘기는 건데, 이걸 추가하고 나서야 실시간 통신이 안정적으로 붙었다. 웹소켓 쓰는 서비스를 프록시 뒤에 둘 거면 이건 거의 필수다. SSL은 와일드카드 인증서 하나로 도메인이 여러 개라고 인증서를 여러 개 받을 필요는 없었다. *.jaeyonging.com 와일드카드 인증서 하나로 모든 서브도메인을 커버한다. VirtualHost마다 같은 인증서 경로를 가리키게만 하면 된다. 덤으로 HSTS 헤더도 걸어서 브라우저가 무조건 HTTPS로만 붙게 강제했다. 정리하면 구조 자체는 단순하다. PM2가 서비스들을 각자 포트에서 살려두고, Apache가 도메인 보고 알맞은 포트로 길을 터준다. 이 둘만 이해하면 서버 한 대로 서비스 여러 개를 얼마든지 굴릴 수 있다. 개인 서버를 직접 굴리면서 제일 크게 배운 건, 결국 인프라도 "요청이 들어와서 어디로 흘러가는가"의 문제라는 거다. 도메인 → Apache → 포트 → Node로 이어지는 흐름만 머릿속에 그려지면, 나머지는 설정 파일 몇 줄 추가하는 일이었다.