FastAPI 서버를 Docker 컨테이너로 실행하고, 로컬에서 실행 중인 Spring Boot 서버로 API 요청을 보내려고 했는데, 127.0.0.1로는 접근이 불가능한 문제를 만났다. 🤔 이 문제를 해결하는 과정과 방법을 정리해본다.
🔥 문제 상황: 컨테이너에서 로컬 서버로 API 요청이 안 된다
컨테이너 내부의 FastAPI 서버에서 로컬 환경에서 실행 중인 Spring Boot 서버(localhost:8080)로 API 요청을 보내려고 했지만, 127.0.0.1을 사용하면 연결이 안 됐다. ❌
🚨 문제의 원인
- 컨테이너 내부에서 127.0.0.1(localhost)을 호출하면, 컨테이너 자체의 로컬 주소를 가리킨다.
- 실제 Spring Boot 서버는 **호스트 운영체제(로컬 머신)**에서 실행 중이므로, 컨테이너에서는 localhost로 직접 접근할 수 없다.
- 컨테이너는 기본적으로 격리된 네트워크 환경에서 실행되므로, 호스트 머신과 바로 통신할 수 없다.
🎯 해결 방법: host.docker.internal 사용
Docker 컨테이너 내부에서 **로컬 호스트(OS에서 실행 중인 서버)**로 접근하려면 host.docker.internal을 사용해야 한다.
BASE_URL = "http://127.0.0.1:8080/api/v1/.." # 기존에 요청하던 end-point
⬇️
BASE_URL = "http://host.docker.internal:8080/api/v1/.." # 수정한 end-point
🛠️ Docker Compose에서 네트워크 설정 (대체 방법)
또 다른 방법은 Docker Compose의 네트워크 기능을 활용하는 것이다.
이건 두 서버 모두를 컨테이너로 띄우고, 두 서비스르 docker-compose 로 묶어 배포하는 방식이다.
docker-compose 로 묶게 되면 서로 간 통신 시에 서로의 서비스명으로 통신 가능하다.
version: '3.8'
services:
fastapi:
build: .
ports:
- "8000:8000"
networks:
- my_network
spring:
image: openjdk:11
ports:
- "8080:8080"
networks:
- my_network
networks:
my_network:
driver: bridge
✅ Docker-Compose 시 서버로 요청하는 코드
Docker Compose에서 같은 네트워크에 있는 서비스 간에는 컨테이너 이름을 직접 사용하여 접근할 수 있다.
BASE_URL = "http://spring:8080" # 컨테이너 네트워크 이름 사용
이렇게 하면 http://spring:8080을 통해 FastAPI 컨테이너에서 Spring Boot 컨테이너로 요청을 보낼 수 있다.
🤔 컨테이너가 로컬 네트워크와 통신하지 못하는 이유
1️⃣ 컨테이너는 독립된 네트워크 공간에서 실행됨
Docker는 컨테이너를 실행할 때 기본적으로 격리된 네트워크 환경을 생성한다. 즉, 각 컨테이너는 자체 네트워크를 가지고 있으며, 기본적으로 호스트 시스템과 직접 통신할 수 없다.
2️⃣ 127.0.0.1은 컨테이너 내부를 가리킴
컨테이너 내부에서 localhost 또는 127.0.0.1을 사용하면 해당 컨테이너 내부의 네트워크를 참조하게 된다. 그러나 실제 Spring Boot 서버는 호스트 머신에서 실행 중이므로, 이 주소로는 접근할 수 없다.
3️⃣ 컨테이너 네트워크와 호스트 네트워크는 분리됨
- 컨테이너 내부에서 외부 요청을 하려면, host.docker.internal을 사용하여 호스트 머신으로의 네트워크 통신을 허용해야 한다.
- 또는, Docker Compose의 커스텀 네트워크 설정을 사용하여 컨테이너 간 통신을 가능하게 해야 한다.
🚀 정리: 어떤 방법이 더 좋을까?
방법 | 사용 시기 | 장점 | 단점 |
host.docker.internal | 로컬 개발 중, 컨테이너 -> 로컬 서버 요청 |
간편한 설정 | 운영 환경에서는 사용 불가 |
Docker Compose 네트워크 | 컨테이너 간 통신 | 운영환경에서도 사용 가능 | 네트워크 설정이 필요 |
🔹 로컬에서 컨테이너가 호스트 머신의 API를 호출해야 할 때 → host.docker.internal
🔹 운영 환경에서 컨테이너 간 통신을 설정해야 할 때 → Docker Compose 네트워크
'AlgoMate' 카테고리의 다른 글
github에 올릴 수 없는 환경변수는 어떻게 배포환경에 추가해야할까? (0) | 2025.02.22 |
---|---|
host.docker.internal은 왜 운영환경에서 사용하기 어려울까⁉️ (0) | 2025.02.19 |
Selenium을 통한 크롤링 시, 마주하는 reCAPTCHA 해결기 (0) | 2025.02.19 |
Redis만으로도 비동기 처리는 가능하잖아‼️ 근데 왜 Celery+Redis를 사용해야 할까 (0) | 2025.02.18 |
🚀 크롤링 서버 vs 메인 서버, 크롤링한 데이터를 어디서 저장해야 할까? (0) | 2025.02.17 |