Nginx컨테이너와 API서버 컨테이너를 통신하기 위해 도커의 네트워크 개념을 알아야 한다.
도커 네트워크를 확인해보자
docker network ls
도커가 자동으로 생성한 bridge, host, none 네트워크를 확인 할 수 있다.
도커 컨테이너를 생성 할 때 network옵션을 주지 않으면 기본 bridge에 연결된다.
bridge들은 16 bit prefix를 가진 서브넷 ip를 쓰게 되며,
같은 bridge 내 컨테이너들은 서로 컨테이너 명으로 통신 할 수 있다.
도커 기본 bridge는 모든 컨테이너가 생성될 때 기본적으로 연결되는 network이므로 새로 bridge를 만들어 쓰도록 하자.
docker network create {your_network}
docker network create 명령어로 새로운 bridge를 생성한다.
구동중인 컨테이너를 방금 만든 bridge에 연결하자
docker network connect {your_bridge} {your_container_id}
도커를 처음 만들 때 커스텀 브릿지에 연결할 수도 있다.
docker run --netowrk {your_bridge} {docker_image}
또는 docker-compose에 컨테이너별 networks 항목에 명시해주면 된다.
이제 nginx 컨테이너의 설정파일을 수정해줘야한다.
nginx.conf의 기본 경로는 /etc/nginx/nginx.conf 이다. (다를 수도 있다.)
cat으로 내용을 띄워보면 하단 http 블럭에 'include /etc/nginx/conf.d/*.conf' 라고 씌여있는 걸 볼 수 있다.
nginx.conf 파일을 직접 수정해주어도 되고, 해당 경로의 파일을 수정해도 되고, {your_file}.conf를 해당 경로에 생성해도 된다.
아무튼 http 블럭에 아래 내용을 추가한다.
upstream {your_resolver_name} {
server {your_API_container_id}:{PORT};
}
server {
location /api {
proxy_pass http://{your_resolver_name}$request_uri
}
}
nginx가 reverse proxy의 역할을 수행하여 '~/api'로 요청된 요청을 upstream에 명시된 서버로 전달한다.
API서버와는 같은 docker network bridge에 있기 때문에 컨테이너 ID를 ip대신 명시 할 수 있다.
그림으로는 위와 같이 구성 할 수 있다.
외부에서 서버로 온 요청은 Docker의 network를 통해 nginx컨테이너로 전달된다.
nginx 컨테이너를 생성할 때 외부에 노출할 port를 80번으로 했기 때문에 80포트로 들어온 요청이 Nginx로 들어오게 된다.
그리고 nginx는 그 중에서도 ~/api uri로 들어온 요청을 API서버로 전달하게 된다.
즉, API 컨테이너는 외부로 노출되는 포트가 없음에도 Nginx의 Reverse Proxy를 통해 client에게 응답해줄 수 있게 된다.