요즘 도커로 로컬 개발 환경 세팅하는데, 컨테이너 몇 개 띄우는 게 일이네요.
특히 앱 컨테이너랑 DB 컨테이너 간 네트워크 연결이 좀 꼬여서요.
서비스를 띄울 때마다 IP 같은 거 신경 쓰기 너무 귀찮고...
혹시 개발용 DB 컨테이너랑 앱 컨테이너 연결할 때, 가장 깔끔하고 효율적인 네트워크 설정 방법 아시는 분 계신가요?
브릿지 말고 다른 거 추천해주실 거 있나요?
이거 아는 사람 댓글로 간단하게라도 공유 부탁드려요!
와, 저도 이 문제 때문에 몇 번이나 밤샜던 기억이 나요.
솔직히 개발 환경 셋업할 때 컨테이너 네트워크 설정하는 게 정말 '만렙' 영역 같아요.
브릿지 모드나 IP 주소 같은 거 직접 건드리는 건 너무 불안정하고, 나중에 컨테이너 재시작할 때마다 IP가 바뀔까 봐 스트레스 받죠.
질문 주신 내용만 들어도 '이건 네트워크 레벨의 근본적인 해결책이 필요하다'는 느낌이 팍 오는데요.
결론부터 말씀드리자면, 네, Docker Compose를 사용하시는 게 현재로서는 가장 깔끔하고 업계 표준에 가까운 방법이에요.
하지만 그냥 Compose만 쓰면 된다고 끝내기엔, 왜 이게 작동하는지, 그리고 이 방식이 어떤 장점을 가지는지, 또 어떤 주의점을 챙겨야 하는지까지 아는 게 중요해서 좀 길게 설명드릴게요.
--- ### 1.
왜 Compose를 써야 하는가?
(근본적인 문제 해결) 질문자님이 겪는 불편함의 핵심은 '서비스 간의 이름 기반 통신'이 어렵다는 점이에요.
일반적으로 docker run으로 컨테이너를 띄우면, 각 컨테이너는 마치 독립된 작은 컴퓨터처럼 동작해요.
그래서 앱 컨테이너에서 DB 컨테이너에 접속하려면, "너의 IP 주소는 뭐야?
지금 몇 번이야?" 하고 물어봐야 하거든요.
근데 Docker는 컨테이너를 띄우고 내릴 때마다 IP를 할당하고 해제하기 때문에, 이 IP 주소를 코드나 설정 파일에 하드코딩하는 순간, '재현성(Reproducibility)'이라는 게 깨져요. Compose를 사용하고 커스텀 네트워크를 지정해주는 과정은, 이 문제를 **'서비스 이름 기반의 DNS 레졸루션'**으로 해결해주는 거예요.
쉽게 비유하자면 이렇습니다. * 기존 방식 (IP 사용): 친구 A한테 전화할 때 "너희 동네 번지 123-45"라고 정확한 주소를 외워야 하는 것과 같아요.
(IP 주소는 변할 수 있음) * Compose 방식 (서비스 이름 사용): 친구 A한테 그냥 "철수한테 전화해"라고만 말하면, 통신망(Docker 내부 네트워크)이 알아서 현재 접속 가능한 최신 번호로 연결해주는 것과 같아요.
(서비스 이름은 고정적) --- ### 2.
추천 네트워크 설정: Docker Compose + Custom Bridge 브릿지 말고 다른 걸 추천해달라고 하셨는데, 사실 Compose가 내부적으로 **'사용자 정의된 브릿지 네트워크'**를 생성하고 그 위에 모든 서비스를 연결해주는 원리예요.
이게 그냥 기본 브릿지보다 훨씬 강력한데, 그 이유는 '서비스 디스커버리(Service Discovery)' 기능이 내장되어 있기 때문이에요.
작동 원리 상세 설명: 1.
docker-compose.yml 파일을 작성합니다.
2.
networks: 섹션에서 커스텀 네트워크를 정의합니다.
3.
모든 서비스(app, db 등)를 이 커스텀 네트워크에 연결합니다.
4.
Compose가 이 네트워크에 접속 가능한 모든 컨테이너 이름(서비스 이름)을 자동으로 DNS 레코드로 등록해줍니다.
5.
앱 컨테이너는 DB 컨테이너의 IP를 알 필요 없이, 그냥 environment: 변수나 DB 연결 문자열에 db_service_name 을 적어주면 돼요.
6.
Docker 내부 DNS가 이 db_service_name을 실제 컨테이너 IP로 매핑해줍니다.
실무 팁: 환경 변수 활용이 필수예요. 코드 레벨에서 DB 연결 정보를 하드코딩하는 건 정말 최악의 습관입니다.
반드시 .env 파일이나 docker-compose.yml의 environment: 섹션을 통해 **환경 변수(Environment Variables)**로 넘겨주세요.
예를 들어, SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/mydb 와 같이, 서비스 이름(db)을 호스트명으로 사용해야 합니다.
--- ### 3.
만약 Compose가 아니라 '순수 Docker CLI'만 써야 한다면?
만약 CI/CD 파이프라인이나 특정 스크립트 때문에 docker-compose.yml 파일 생성이 어렵고, 순수 docker run 명령어로만 띄워야 하는 극한의 상황이라면, 명시적으로 커스텀 브릿지 네트워크를 생성하고 모든 컨테이너를 그 네트워크에 연결해야 합니다.
[단계별 순서] 1.
네트워크 생성: docker network create my_dev_net 2.
DB 컨테이너 실행 및 연결: docker run -d --network my_dev_net --name db_container postgres 3.
App 컨테이너 실행 및 연결: docker run -d --network my_dev_net --name app_container your_app_image
️ 주의점 (이 경우의 어려움): 이 경우에도 서비스 이름 기반의 DNS가 작동하는 건 맞지만, 앱 컨테이너가 DB 컨테이너를 찾을 때 **docker-compose.yml에서 제공하는 것과 동일한 방식의 이름 해석(Name Resolution)**을 할 수 있도록 앱 코드나 프레임워크 설정에 약간의 추가 작업이 필요할 수 있어요.
️ 결론: 이 복잡성을 피하기 위해 Docker Compose를 사용하는 것이 압도적으로 효율적입니다.
--- ### 4.
흔히 저지르는 실수와 체크리스트 (
가장 중요
) 여기서 실질적인 '주의점'을 몇 가지 짚어드릴게요.
이 부분이 실제 개발자들이 가장 많이 막히는 지점이에요.
실수 1: 포트 매핑만 신경 쓰고 연결성을 놓치는 경우 (가장 흔함) * 오해: docker-compose.yml에서 ports: "5432:5432"를 설정하면, 컨테이너 외부에서 5432로 접속할 수 있게 된다.
localhost:5432 같은 것을 쓰지 말고, **서비스 이름(db)과 내부 포트(5432)**를 써야 합니다.
실수 2: 데이터 영속성(Volume)을 잊는 경우 * DB 컨테이너를 띄우고 테스트하다가 컨테이너를 삭제하거나 재시작할 때, 데이터가 날아가는 경우가 있습니다.volumes:를 지정해서 호스트 머신의 특정 경로에 데이터를 저장해야 합니다.기타 설정 ...
volumes: - ./data/postgres:/var/lib/postgresql/data # 이 부분이 핵심!
``` **❌ 실수 3: 앱 컨테이너의 시작 순서 문제** * 앱 컨테이너가 DB 컨테이너가 완전히 준비되기도 전에 먼저 시작하려고 시도할 수 있어요.
* **해결:** `depends_on`을 사용하거나, 더 확실한 방법은 앱 컨테이너의 시작 스크립트(entrypoint)에 **'DB 연결 시도 및 3초 대기 후 재시도 로직'**을 넣는 겁니다.
(이게 가장 튼튼한 방법이에요.) --- ### 요약 정리 (한눈에 보는 체크리스트) | 항목 | 사용 방법 | 설정 값 (예시) | 중요도 | 비고 | | :--- | :--- | :--- | :--- | :--- | | **네트워크 방식** | Docker Compose | `networks:` 섹션 정의 | ⭐⭐⭐⭐⭐ | 기본 브릿지 대신 커스텀 네트워크 사용 권장 | | **DB 접속 주소** | 서비스 이름 사용 | `jdbc:postgresql://db_service_name:5432/db_name` | ⭐⭐⭐⭐⭐ | 절대 `localhost`나 `127.0.0.1` 사용 금지 | | **데이터 저장** | Volume 마운트 | `volumes: - ./data:/var/lib/data` | ⭐⭐⭐⭐ | 재시작해도 데이터가 사라지지 않게 보장 | | **시작 순서 관리** | 의존성 설정 | `depends_on: - db` 또는 스크립트 재시도 로직 | ⭐⭐⭐⭐ | 앱이 DB보다 먼저 켜지려 할 때를 대비 | 이 정도면 충분히 복잡하고 깊은 내용이 되었을 것 같습니다.
만약 이 가이드대로 세팅했는데도 연결 문제가 발생한다면, 90% 이상은 **DB 접속 주소(호스트명)**나 **포트 번호**를 잘못 지정했거나, **Volume 설정**이 누락되었기 때문일 거예요.
혹시 사용하시는 DB 종류(Postgres, MySQL 등)나 앱 프레임워크(Spring Boot, Django 등)를 알려주시면, 해당 프레임워크에 최적화된 환경 변수 예시까지 같이 봐드릴 수 있습니다!
화이팅입니다!
이 정도만 알아도 개발 환경 세팅 스트레스가 80%는 줄어들 거예요.
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
등록 로그인