Program Tip

Docker 포트에 가상 호스트 할당

programtip 2020. 10. 5. 20:37
반응형

Docker 포트에 가상 호스트 할당


사용자 지정 도메인 (* .foo)에 대한 모든 웹 요청이 Docker 호스트의 IP 주소에 매핑되도록 와일드 카드 DNS를 설정했습니다. Apache (또는 Nginx) 인스턴스를 실행하는 여러 컨테이너가있는 경우 각 컨테이너는 Apache 포트 (80)를 일부 외부 인바운드 포트에 매핑합니다.

내가 원하는 것은 내 사용자 지정 DNS 서버를 통해 이미 올바른 IP 주소 (Docker 호스트의)에 매핑 된 container-1.foo에 대한 요청을 만들고 기본 포트 80 요청을 올바른 Docker 외부에 프록시하는 것입니다. 지정된 컨테이너의 올바른 Apache 인스턴스가 사용자 지정 도메인을 기반으로 응답 할 수 있도록 포트. 마찬가지로 container-2.foo는 두 번째 컨테이너의 아파치로 프록시되는 식입니다.

이에 대한 사전 구축 된 솔루션이 있습니까, Docker 호스트에서 Nginx 프록시를 실행하는 것이 최선의 방법입니까, 아니면 Docker 컨테이너를 관리 할 수있는 가능성이있는 node.js 프록시를 작성해야합니까 (웹을 통해 시작 / 중지 / 재실행해야합니까). ) 또는 ...? Docker 컨테이너를 외부 포트 및 컨테이너 저글링이 아닌 자연스러운 이벤트처럼 사용할 수있는 옵션은 무엇입니까?


이 답변은 약간 늦을 수 있지만 자동 리버스 프록시가 필요합니다. 이를 위해 두 가지 솔루션을 사용했습니다.

  • jwilder / nginx-proxy
  • Traefik

시간이 지남에 따라 Traefik을 사용하는 것을 선호합니다. 대부분 잘 문서화되고 유지 관리되고 더 많은 기능이 제공되기 때문입니다 (다양한 전략 및 우선 순위, 상태 확인, 회로 차단기, ACME / Let 's Encrypt를 사용한 자동 SSL 인증서 등).


jwilder / nginx-proxy 사용

Docker 컨테이너 Jason Wilder의 nginx-proxy Docker image 를 실행할 때 유지 관리 할 구성없이 다른 컨테이너에 대한 역방향 프록시로 설정된 nginx 서버를 가져옵니다.

VIRTUAL_HOST환경 변수로 다른 컨테이너를 실행하면 nginx-proxy가 해당 ip : port를 검색하고 nginx 구성을 업데이트합니다.

*.test.localDocker 호스트의 IP 주소에 매핑 되도록 DNS가 설정되었다고 가정 하고 다음 컨테이너를 시작하여 빠른 데모를 실행하십시오.

# start the reverse proxy
docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock jwilder/nginx-proxy

# start a first container for http://tutum.test.local
docker run -d -e "VIRTUAL_HOST=tutum.test.local" tutum/hello-world

# start a second container for http://deis.test.local
docker run -d -e "VIRTUAL_HOST=deis.test.local" deis/helloworld

Traefik 사용

Traefik 컨테이너를 실행할 때 컨테이너에서 발견 된 도커 레이블이 지정된 전달 규칙을 재구성하는 역방향 프록시 서버가 설정됩니다 .

*.test.localDocker 호스트의 IP 주소에 매핑 되도록 DNS가 설정되었다고 가정 하고 다음 컨테이너를 시작하여 빠른 데모를 실행하십시오.

# start the reverse proxy
docker run --rm -it -p 80:80 -v /var/run/docker.sock:/var/run/docker.sock traefik --docker

# start a first container for http://tutum.test.local
docker run -d -l "traefik.frontend.rule=Host:tutum.test.local" tutum/hello-world

# start a second container for http://deis.test.local
docker run -d -l "traefik.frontend.rule=Host:deis.test.local" deis/helloworld

가능한 대답은 다음 두 가지입니다. (1) Docker로 포트를 직접 설정하고 Nginx / Apache를 사용하여 가상 호스트를 프록시하거나 (2) Dokku사용 하여 포트와 가상 호스트를 관리합니다 (이 방법 1을 수행하는 방법을 배웠습니다).

방법 1a (도커를 사용하여 직접 포트 할당)

1 단계 : 원하는 포트 번호를 할당하여 호스트에 nginx.conf 또는 Apache를 설정합니다. 호스트에서 실행되는이 웹 서버는 가상 호스트 프록시를 수행합니다. Docker와 관련하여 특별한 것은 없습니다. 일반적인 가상 호스트 호스팅입니다. 다음으로 2 단계에서 Docker가 올바른 호스트 포트 번호를 사용하도록하는 특별한 부분이 있습니다.

2 단계 : 다음과 같이 Docker의 포트 매핑을 설정하려면 "-p"를 사용하여 Docker에서 포트 번호를 할당하고 다음과 같이 Docker 내에서 사용자 지정 환경 변수를 설정하려면 "-e"를 사용합니다.

port=12345 # <-- the vhost port setting used in nginx/apache
IMAGE=myapps/container-1
id=$(docker run -d -p :$port -e PORT=$port $IMAGE)
# -p :$port will establish a mapping of 12345->12345 from outside docker to
# inside of docker.
# Then, the application must observe the PORT environment variable
# to launch itself on that port; This is set by -e PORT=$port.

# Additional goodies:
echo $id # <-- the running id of your container
echo $id > /app/files/CONTAINER # <-- remember Docker id for this instance
docker ps # <-- check that the app is running
docker logs $id # <-- look at the output of the running instance
docker kill $id # <-- to kill the app

방법 1b 하드 코딩 된 애플리케이션 포트

...if you're application uses a hardcoded port, for example port 5000 (i.e. cannot be configured via PORT environment variable, as in Method 1a), then it can be hardcoded through Docker like this:

publicPort=12345
id=$(docker run -d -p $publicPort:5000 $IMAGE)
# -p $publicPort:5000 will map port 12345 outside of Docker to port 5000 inside
# of Docker. Therefore, nginx/apache must be configured to vhost proxy to 12345,
# and the application within Docker must be listening on 5000.

Method 2 (let Dokku figure out the ports)

At the moment, a pretty good option for managing Docker vhosts is Dokku. An upcoming option may be to use Flynn, but as of right now Flynn is just getting started and not quite ready. Therefore we go with Dokku for now: After following the Dokku install instructions, for a single domain, enable vhosts by creating the "VHOST" file:

echo yourdomain.com > /home/git/VHOST
# in your case: echo foo > /home/git/VHOST

Now, when an app is pushed via SSH to Dokku (see Dokku docs for how to do this), Dokku will look at the VHOST file and for the particular app pushed (let's say you pushed "container-1"), it will generate the following file:

/home/git/container-1/nginx.conf

And it will have the following contents:

upstream container-1 { server 127.0.0.1:49162; }
server {
  listen      80;
  server_name container-1.yourdomain.com;
  location    / {
    proxy_pass  http://container-1;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-For $remote_addr;
  }
}

When the server is rebooted, Dokku will ensure that Docker starts the application with the port mapped to its initially deployed port (49162 here), rather than getting assigned randomly another port. To achieve this deterministic assignment, Dokku saves the initially assigned port into /home/git/container-1/PORT and on the next launch it sets the PORT environment to this value, and also maps Docker's port assignments to be this port on both the host-side and the app-side. This is opposed to the first launch, when Dokku will set PORT=5000 and then figure out whatever random port Dokku maps on the VPS side to 5000 on the app side. It's round about (and might even change in the future), but it works!

The way VHOST works, under the hood, is: upon doing a git push of the app via SSH, Dokku will execute hooks that live in /var/lib/dokku/plugins/nginx-vhosts. These hooks are also located in the Dokku source code here and are responsible for writing the nginx.conf files with the correct vhost settings. If you don't have this directory under /var/lib/dokku, then try running dokku plugins-install.


With docker, you want the internal ips to remain normal (e.g. 80) and figure out how to wire up the random ports.

One way to handle them, is with a reverse proxy like hipache. Point your dns at it, and then you can reconfigure the proxy as your containers come up and down. Take a look at http://txt.fliglio.com/2013/09/protyping-web-stuff-with-docker/ to see how this could work.

If you're looking for something more robust, you may want to take a look at "service discovery." (a look at service discovery with docker: http://txt.fliglio.com/2013/12/service-discovery-with-docker-docker-links-and-beyond/)

참고URL : https://stackoverflow.com/questions/18497564/assigning-vhosts-to-docker-ports

반응형