이전 글에서는 nginx-proxy 를 사용하여 하나의 서버에서 다양한 서브도메인을 처리하는 방법을 살펴보았다 (참고: Docker 를 사용한 가상 호스트(Virtual Host) 구축 및 서브 도메인 연결). nginx-proxy 이미지에 포함된 docker-gen 이 새로운 컨테이너가 실행 될 때마다 실행되는 컨테이너의 VIRTUAL_HOST 환경변수를 읽어들이는 방식이다. 이 때 내가 겪었던 문제는 docker-compose 를 통하여 컨테이너를 실행할 경우 서브 도메인 연결이 실패한다는 점이었다. nginx-proxy 의 로그를 살펴보면 다음과 같이 nginx -s reload 가 실패하는 것을 볼 수 있다.

dockergen.1 | 2017/07/11 07:48:43 Received event start for container d4e6b438872d
dockergen.1 | 2017/07/11 07:48:43 Generated '/etc/nginx/conf.d/default.conf' from 8 containers
dockergen.1 | 2017/07/11 07:48:43 Running 'nginx -s reload'
dockergen.1 | 2017/07/11 07:48:43 Error running notify command: nginx -s reload, exit status 1

문제 발생 원인

이 문제는 nginx-proxy 컨테이너와 새로 실행되는 컨테이너가 (로그에서는 container d4e6b438872d) 같은 네트워크에 속해 있지 않기 때문에 발생하는 것으로 보인다. docker-compose 를 수행하면 compose 내에 있는 service 들 끼리 자동적으로 네트워크를 설정하는데, 이 네트워크는 nginx-proxy 에서 접근할 수 없으므로 문제가 발생하는 것이다. 예를 들어 wordpress 디렉토리에서 docker-compose 를 수행할 경우 wordpress-default 라는 네트워크가 만들어진다(존재하는 네트워크의 목록은 docker network ls 명령으로 확인이 가능하다). Docker 의 네트워크에 대해서는 문서를 참고하면 좋다.

nginx-proxy 의 네트워크 확인

따라서 문제를 해결하기 위해서는 nginx-proxy 가 서브 도메인을 담당하는 컨테이너들과 같은 네트워크에 속하도록 설정해야 한다. 그러므로 nginx-proxy 의 네트워크나 docker-compose 로 생긴 컨테이너가 속한 네트워크를 찾아야 하는데, docker inspect <container> 명령을 이용하여 실행 중인 컨테이너의 네트워크를 확인할 수 있다. NetworkSettings 아래에 Networks 가 존재하며, 여기에서 해당 컨테이너가 속해 있는 네트워크를 확인할 수 있다. 나의 경우 해당하는 부분은 다음과 같다.

Networks: {
    bridge: {
        IPAMConfig: null,
        Links: null,
        Aliases: null,
        NetworkID: 1c856e0515caf284713b1bef2369df6c7a1beb2c3e91d6ae4361c9d2f4f11764,
        EndpointID: 78378336490f770ac39ff11fdecb843b674c357e66cbdff9ec82c63cb0a53610,
        Gateway: 172.17.0.1,
        IPAddress: 172.17.0.2,
        IPPrefixLen: 16,
        IPv6Gateway: ,
        GlobalIPv6Address: ,
        GlobalIPv6PrefixLen: 0,
        MacAddress: 02:42:ac:11:00:02
    }
}

즉 나의 nginx-proxy 가 속해 있는 네트워크의 이름은 기본 네트워크인 bridge 인 것을 확인할 수 있다.

Option 1. nginx-proxy 와 같은 네트워크를 사용하도록 docker-compose 수정

첫 번째 방법은 docker-compose 를 수정하여 nginx-proxy 의 네트워크로 포함되도록 하는 것이다. 이를 위해서는 아래와 같이 networks 를 정의하고, 각각의 service 내에서는 network_mode: bridge 를 설정해 주면 된다.

version: '2'
services:
    myapp:
        network_mode: bridge
...
networks:
    default:
        external:
            name: bridge

여기서 external 은 외부에 이미 존재하는 네트워크를 의미한다.

Option 2. nginx-proxy 에 네트워크 추가

둘째로는 nginx-proxy 가 여러 네트워크에 속하게 하는 방법이다. 여기서는 docker-compose 로 생성된 (또는 docker-compose 에 기술된) 네트워크에 nginx-proxy 를 추가하면 되겠다. 컨테이너에 네트워크를 추가하기 위해서는 docker network connect [OPTIONS] <network> <container> 명령을 사용하면 된다(참고: docker network connect). 명령 사용 후 docker inspect 를 통하여 네트워크가 추가된 것을 볼 수 있다. 다만 docker-gen 은 컨테이너 로드 및 삭제 시 작동하므로 네트워크 설정 후 해당하는 컨테이너를 삭제 후 다시 수행해 주어야 할 것이다.

기타

  • 네트워크를 하나 만들고 nginx-proxy 와 서브 도메인을 처리하는 컨테이너만을 여기에 넣어 두는 것이 가장 효율적인 방법이 될 것이다. 다시 nginx-proxy 를 설정해야 할 경우 시도해 볼 예정.

참고

docker network - https://docs.docker.com/engine/reference/commandline/network/

카테고리:

업데이트: