본문 바로가기
DevOps/Docker

Docker - Docker와 로컬 환경 통신

by 개발하는 경제학도 2026. 1. 31.

— 왜 붙고, 왜 안 붙는지 주소 관점으로 이해하기

Docker 네트워크 문제를 코드가 아니라
“누가 누구를 어떤 주소로 보느냐” 기준으로 정리한 기록


오늘의 한 줄 요약

Docker 통신 문제의 90%는 주소 문제다.
localhost, service name, host 주소만 구분하면 끝난다.


배경

로컬에서 Spring Boot 애플리케이션을 실행한 상태에서
Docker로 여러 서비스를 띄워 연동 테스트를 진행했다.

  • DB (예: MongoDB)
  • 외부 서비스 

문제는 다음과 같았다.

  • 컨테이너 안에서는 되는데 로컬에서는 안 됨
  • localhost로 붙었는데 연결 실패
  • 헬스체크는 실패하는데 서비스는 떠 있음

결론적으로 네트워크 구조를 정확히 이해하지 못한 상태였다.


Docker 네트워크 구조 한 장 요약

Docker bridge 네트워크

  • docker compose up 실행 시
  • 프로젝트 전용 user-defined bridge 네트워크가 자동 생성됨
  • 이 bridge는 가상 L2 스위치 역할을 함
 
컨테이너 ── veth ── bridge ── veth ── 컨테이너
  • 같은 bridge에 붙은 컨테이너끼리는 사설 IP로 직접 통신 가능
  • 네트워크 격리는 유지됨

service 이름 = 컨테이너 DNS 이름

Docker는 내장 DNS (127.0.0.11) 를 제공한다.

services:
  mongo:
    image: mongo

같은 bridge 네트워크에 있는 컨테이너 내부에서는:

mongodb://mongo:27017
 

이게 가능한 이유는:

  • mongo라는 service 이름이
  • Docker DNS를 통해 컨테이너 IP로 자동 변환되기 때문

📌 service 이름은 코드 이름이 아니라 “환경이 제공하는 네트워크 이름”


localhost의 진짜 의미

핵심: localhost는 항상 “나 자신”

위치localhost 의미
로컬 터미널 로컬 머신
컨테이너 내부 해당 컨테이너
Kubernetes Pod 해당 Pod

그래서 아래는 모두 실패한다.

  • 컨테이너 → 다른 컨테이너 (localhost)
  • 컨테이너 → 호스트 (localhost)

로컬 ↔ Docker 컨테이너 통신 규칙

1️⃣ 로컬 → Docker 컨테이너

👉 ports:로 포트가 열려 있어야 한다

 
services:
  mongo:
    image: mongo

로컬 애플리케이션에서는:

mongodb://localhost:27017
 

의미:

  • ports = 호스트 ↔ 컨테이너를 잇는 다리
  • 로컬에서 접근할 땐 항상 호스트 포트 기준

2️⃣ Docker 컨테이너 → 로컬

👉 Mac / Windows (Docker Desktop)

http://host.docker.internal:8080
  • localhost ❌ (컨테이너 자신)
  • host.docker.internal ⭕ (호스트 머신)

📌 Docker가 제공하는 특수 DNS 이름


주의: 로컬 애플리케이션 바인딩

컨테이너에서 로컬 애플리케이션으로 접근하려면
로컬 서버가 외부 요청을 받아야 한다.

 
server.address=0.0.0.0
server.port=8080
  • 127.0.0.1만 바인딩되어 있으면 ❌
  • 0.0.0.0 = 모든 인터페이스에서 listen

실제 구성 예시 (로컬 + Docker 혼합)

로컬에서 실행 중

  • Spring Boot 애플리케이션

Docker로 실행

  • MongoDB
  • 외부 서비스

통신 방식

주체접근 주소
로컬 Spring → Mongo localhost:27017
로컬 Spring → 외부 서비스 localhost:{외부 서비스_port}
외부 서비스 컨테이너 → Spring host.docker.internal:8080
컨테이너 ↔ 컨테이너 service명:포트

흔한 실수 정리

  • ❌ 컨테이너 안에서 localhost로 다른 서비스 접근
  • ❌ service 이름을 로컬에서 사용
  • ❌ 포트 publish 없이 로컬에서 접근 시도
  • ❌ 컨테이너 → 로컬 호출 시 host.docker.internal 미사용

정리하며 얻은 결론

  • Docker 네트워크는 어렵지 않다.
  • 주소를 환경 기준으로 나누면 끝난다.
 
로컬 → localhost 
컨테이너 → service name 
컨테이너 → 로컬 → host.docker.internal

한 줄 결론

Docker ↔ 로컬 통신은
“누가 실행 주체인지”와 “어디서 보느냐”만 구분하면 된다.

댓글