티스토리 뷰
# 문제 발생 원인 분석
# docker-compose.yaml
version: '3.9'
services:
proxy-server:
container_name: proxy-server
build:
context: ./build/proxy
dockerfile: proxy.Dockerfile
command: ./app/proxy -p 80 -e grpc-server:80
restart: always
deploy:
mode: replicated
replicas: 1
depends_on:
- grpc-server
web:
container_name: web
build:
context: .
dockerfile: ./build/web/Dockerfile
restart: always
ports:
- 3000:3000
deploy:
mode: replicated
replicas: 1
proxy-server와 web은 docker compose로 구성한 default 네트워크에 속해 있다.
따라서 proxy-server의 포트를 외부로 노출시키지 않아도 web에서 서비스 이름을 사용해 http 요청을 보낼 수 있을 것이라 예상했다.
그러나 아래와 같이 해당 url로는 요청을 보낼 수 없다는 오류가 발생한 것을 확인했다.
그래서 web 컨테이너의 터미널에서 proxy-server로 ping을 찍어 봤다.
ping 명령어가 잘 동작하는 것을 확인했다.
분명 서비스들이 동일한 네트워크에 속해있고 포트 번호도 일치하는데 무엇이 문제일까?
문제는 React의 동작 원리에서 찾을 수 있었다.
React의 CSR(Client Side Rendering) 방식으로 인해 브라우저(클라이언트)는 페이지에 접속하기 위해 필요한 데이터를 모두 받아온다. 그런 뒤에 브라우저에서 페이지가 렌더링된다.
이때 받아온 Javascript 코드도 브라우저에서 실행된다.
페이지 내에서 사용자가 서버로 요청을 보내는 상호작용이 발생하면 브라우저에서 요청이 실행된다.
그런데 아래의 그림과 같이 브라우저는 docker compose로 구성된 네트워크로부터 외부로 노출된 일부 포트를 통해 오직 React 앱과 통신이 가능할 뿐 네트워크 내부에 어떤 서비스가 있는지 알 수 없고 서비스 이름을 사용해 다른 서비스에 접근할 수도 없다.
즉, name not resolved 에러는 브라우저가 인식할 수 없는 서비스에 접근하려는 시도로 인해 발생하는 오류라는 것을 확인할 수 있다.
# 문제 해결 방안
가장 간단한 방법으로는 proxy-server의 포트를 외부로 노출시키는 것이다.
proxy-server를 localhost의 8080번 포트로 노출시키고 web에서는 http://localhost:8080으로 요청을 보내도록 수정했다.
# docker-compose.yaml
version: '3.9'
services:
proxy-server:
container_name: proxy-server
build:
context: ./build/proxy
dockerfile: proxy.Dockerfile
command: ./app/proxy -p 80 -e grpc-server:80
restart: always
ports:
- 8080:80
deploy:
mode: replicated
replicas: 1
depends_on:
- grpc-server
web:
container_name: web
build:
context: .
dockerfile: ./build/web/Dockerfile
restart: always
ports:
- 3000:3000
deploy:
mode: replicated
replicas: 1
물론 이 방법은 개발 환경에서나 편법으로 쓸만하지 프로덕션 환경에서 사용하기 어려울 수 있다.
프로덕션 환경에서는 nginx나 caddy 같은 프록시 서버를 사용할 수도 있고 내가 모르는 다른 방법도 있을 것이다.
프록시 서버를 사용하는 방법은 관련 자료들을 찾아보고 별도의 포스트로 작성해보고자 한다.
# Reference
net::ERR_NAME_NOT_RESOLVED docker
'개발 부스러기' 카테고리의 다른 글
WSL에서 Go 사용하기 (0) | 2023.12.26 |
---|---|
Chainlink - Data Feeds (0) | 2023.10.31 |
바빌로니아 법 (The Babylonian Method) (0) | 2023.04.10 |
[Nginx] Reverse Proxy 설정 (0) | 2023.04.03 |
[Go] gRPC서버 요청에 담긴 메타데이터 읽기 (0) | 2023.03.31 |