
새 테넌트가 생기면 할 일이 두 가지였다. 서버를 만들고, 그 서버에 도메인을 연결한다. 이전 버전까지는 둘 다 손으로 했다. 한두 번이면 괜찮지만, 테넌트가 늘어나면 번거로워지고 번거로운 일에는 실수가 끼어든다.
지금 여러 테넌트를 한곳에서 관리하는 시스템을 만들고 있다. 컨테이너를 띄우는 쪽은 앞선 글에서 Node.js와 Dockerode로 자동화했다. 이 글에서는 나머지 절반, 띄운 컨테이너에 (서브)도메인을 붙이는 일을 Nginx Proxy Manager API로 자동화한 과정을 정리한다.
컨테이너만 뜨고 주소가 없으면 반쪽이다
앞선 작업에서 클라이언트가 특정 API를 호출하면 Dockerode가 컨테이너를 만들고 지우도록 해 두었다. 그런데 컨테이너가 떠도 사용자가 들어올 주소가 없으면 프로비저닝은 끝난 게 아니다. 각 테넌트가 자기 도메인으로 접속하려면 누군가 리버스 프록시에 “이 도메인은 저 컨테이너로"라는 규칙을 추가해야 한다. 그 누군가가 지금까지는 나였다.
그래서 컨테이너를 만드는 흐름 끝에 Nginx Proxy Manager API 호출을 붙여, Proxy Host까지 자동으로 만들게 했다.
Proxy Host는 도메인이 아니라 라우팅 규칙이다
Proxy Host는 한마디로 “이 주소로 들어오는 요청은 저 서버로 보내라"는 규칙이다. 이름 때문에 도메인 자체로 착각하기 쉬운데, 도메인은 규칙의 입력일 뿐이고 Proxy Host는 리버스 프록시 설정 전체를 가리킨다.

테넌트 단위로 보면 이렇다.
tenant1.yourdomain.com→ tenant1 컨테이너로 트래픽을 전달하는 규칙tenant2.yourdomain.com→ tenant2 컨테이너로 트래픽을 전달하는 규칙
테넌트 하나가 늘면 규칙 하나가 는다. 반복되는 일이니 코드로 넘기기 좋다.
API로 보내면 설정 파일은 Nginx Proxy Manager가 쓴다
아래 정보를 담아 API로 보내면 Nginx Proxy Manager가 설정 파일을 알아서 만든다.
Request Payload:
{
"domain_names": ["app.yourdomain.com", "www.app.yourdomain.com"],
"forward_host": "192.168.1.100",
"forward_port": 3000,
"forward_scheme": "http",
"certificate_id": 1,
"ssl_forced": true
}
그 결과 생성되는 설정 파일:
# /data/nginx/proxy_host/1.conf
server {
listen 80;
server_name app.yourdomain.com www.app.yourdomain.com;
location / {
proxy_pass http://192.168.1.100:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# ... 기타 프록시 설정
}
}
domain_names가 server_name으로, forward_scheme·forward_host·forward_port가 proxy_pass 한 줄로 들어간다. 내가 다루는 건 JSON 필드 여섯 개이고, nginx 문법은 Nginx Proxy Manager가 책임진다. 설정 파일을 직접 만지지 않으니 테넌트가 늘어도 conf 파일을 잘못 고쳐서 다른 테넌트까지 깨뜨릴 일이 적다.
API 한 번에 서버와 도메인이 같이 붙었다
결과는 성공이다. 이제 해당 API를 호출하면 서버 생성과 도메인 연결이 순식간에 끝난다. 생각만 해보던 기능이 실제로 만들어졌다.
정리
컨테이너 생성(Dockerode)과 도메인 연결(Nginx Proxy Manager)을 API 호출 하나로 묶어, 테넌트 프로비저닝을 손 없이 끝내게 했다.
Proxy Host는 도메인이 아니라 “이 도메인은 저 서버로"라는 라우팅 규칙이고, JSON 여섯 필드면 만들어진다.
손으로 하던 일 두 개가 API 하나가 됐다. 테넌트가 몇 명이 되든 할 일은 같다.