[Docker] 컨테이너에서 외부 host로 접근하기 - host.docker.internal

▶︎ host.docker.internal

host.docker.internal 이란 무엇일까?

api-test 라는 docker 컨테이너가 로컬에서 동작 중이라고 가정할 때 해당 컨테이너가 로컬과 통신할 수 있는 방법은 없을까?

예를 들어보자 , 로컬에 mysql 서버가 동작하고 있고 docker 컨테이너로 간단한 메시지 조회 API 서비스가 동작하고 있을 때 컨테이너에서 로컬의 MySQL 서버와 통신하여 데이터를 DB에 적재하려면 어떤 방법을 사용해야할까?

이런 경우 도커에서 제공하는 host.docker.internal 을 사용하여 쉽게 해결할 수 있다!

▶︎ 실습

‣ 컨테이너 생성

$ docker run -d -it --name mongodb -p 80:3000 --network api-net mongo:latest

‣ 컨테이너 접속

$ docker exec -it test bash

‣ CURL 설치

$ docker apt-get update -y
$ docker apt-get install -y curl


‣ 접속 테스트

이제 localhost로 curl 명령을 보내보자

$ curl localhost:3000

하지만 아래와 같은 오류가 발생한다.

curl: (7) Failed to connect to localhost port 3000 after 0 ms: Connection refused

그렇지만 나는 localhost에 API 서버를 분명히 띄워놨다. image


그럼 서버문제일까? 로컬 되돌아와서 curl 명령어를 실행해보자.

$ exit
$ curl localhost:3000

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>String Conversion</title>
  </head>
  <body>
    <form action="/upper" method="POST">
      <label for="word">Enter a word:</label>
      <input type="text" name="word" id="word">
      <button type="submit">Convert to Upper Case</button>
    </form>
    <br>
    <form action="/lower" method="POST">
      <label for="word">Enter a word:</label>
      <input type="text" name="word" id="word">
      <button type="submit">Convert to Lower Case</button>
    </form>
    <br>

  </body>
</html>%

정상적으로 받아와지고 있다 ..


‣ 해결

그렇다면 docker container에서 localhost에 어떻게 접근할 수 있을까?

• 방법 (1)

이 방법은 아주 단순하지만 그다지 좋지 않은 방법이다.

바로 내부 아이피를 사용하는 것인데 Windows에서는 ipconfig를 , Mac에서는 ipconfig getifaddr en0 을 입력해 간단히 내부아이피를 조회할 수 있다.

ipconfig getifaddr en0

192.168.219.180

그 다음 위에서 조회한 내부 아이피 주소를 이용하여 접근하면 된다

$ docker exec -it mongodb bash
$ curl 192.168.219.180:3000

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>String Conversion</title>
  </head>
  <body>
    <form action="/upper" method="POST">
      <label for="word">Enter a word:</label>
      <input type="text" name="word" id="word">
      <button type="submit">Convert to Upper Case</button>
    </form>
    <br>
    <form action="/lower" method="POST">
      <label for="word">Enter a word:</label>
      <input type="text" name="word" id="word">
      <button type="submit">Convert to Lower Case</button>
    </form>
    <br>

  </body>
</html>

잘 받아와진다.


• 방법 (2)

이 방법은 매우 좋은 방법이고 이 게시글을 작성하게 된 이유다.

바로 host.docker.internal을 이용하는 것이다.

$ docker exec -it mongodb bash
$ curl host.docker.internal:3000

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>String Conversion</title>
  </head>
  <body>
    <form action="/upper" method="POST">
      <label for="word">Enter a word:</label>
      <input type="text" name="word" id="word">
      <button type="submit">Convert to Upper Case</button>
    </form>
    <br>
    <form action="/lower" method="POST">
      <label for="word">Enter a word:</label>
      <input type="text" name="word" id="word">
      <button type="submit">Convert to Lower Case</button>
    </form>
    <br>

  </body>
</html>

IP 주소를 사용했었을 때와 동일한 결과를 출력함을 확인할 수 있다.

관련 글

지식 공유2분 읽기

[Docker] 컨테이너(Container)에 할당되는 CPU 제한하기

개요 이번 게시글에서는 도커 컨테이너에서 CPU를 최적으로 활용하는 방법에 대해서 기록해보려고 한다. 호스트 CPU Core 정보 확인 먼저 컨테이너에 CPU를 최적으로 할당하기 위해서는, 현재 호스트 시스템의 CPU 정보에 대해서...

도커
지식 공유1분 읽기

[Docker] 배그 최고급 꾸러기 시뮬레이터 배포

개요 최고급 꾸러미에 대한 확률 체감을 위한 시뮬레이터 프로그램을 구현하고 도커로 배포하였음. 배포 로직은 AWS EC2 인스턴스에 도커를 사용하여 nginx proxy manager를 배포하고 리버스 프록시로 홈 서버에 있는 시뮬레...

도커