Docker nginx proxy works with docker-compose v1, but not v2?

I’m trying to setup an nginx proxy for my docker containers to use simple subdomains instead of ports. I like using docker-compose to startup my containers and since I’m quite new to docker in general, I started using v2 format right away.

I’ve spend quite some time figuring out why this very popular and seemingly simple to use nginx proxy container did not work for me. It turned out that it is somehow related to my use of docker-compose v2.

  • Pull jobs directory from a repository into Jenkins from a Dockerfile
  • Bluemix: service bound to container does not appear in VCAP_SERVICES
  • can we update docker default configure?
  • Access port which is bind to 127.0.0.1 inside a docker container
  • Execute docker host command inside jenkins docker container
  • How can I create and use a variable inside docker?
  • I will post the docker-compose.yml files I was using first, which did not work for some reason:

    version: '2'
    
    services:
      nginx-proxy:
        image: jwilder/nginx-proxy:alpine
        container_name: nginx-proxy
        network_mode: bridge
        ports:
          - 80:80
          - 443:443
        volumes:
          - /var/run/docker.sock:/tmp/docker.sock:ro
        environment:
          - ENABLE_IPV6=true
          - DEFAULT_HOST=domain.com
    
      whoami:
        image: jwilder/whoami
        network_mode: bridge
        environment:
          - VIRTUAL_HOST=whoami.local
    

    And this is the example Jenkins container to test it:

    version: "2"
    
    services:
      jenkins:
        image: jenkins:2.46.2-alpine
        restart: always
        hostname: jenkins.domain.com
        network_mode: bridge
        expose:
          - 8080
          - 50000
        ports:
          - 8080:8080
          - 50000:50000
        volumes:
          - /srv/jenkins:/var/jenkins_home
        environment:
          - VIRTUAL_HOST=jenkins.domain.com
          - VIRTUAL_PORT=8080
    

    Now I will post the configuration which actually did work out of the box for me:

    nginx-proxy:
      image: jwilder/nginx-proxy:alpine
      container_name: nginx-proxy
      ports:
        - 80:80
        - 443:443
      volumes:
        - /var/run/docker.sock:/tmp/docker.sock:ro
      environment:
        - ENABLE_IPV6=true
        - DEFAULT_HOST=domain.com
    
    whoami:
      image: jwilder/whoami
      environment:
        - VIRTUAL_HOST=whoami.local
    

    And for the Jenkins container:

    jenkins:
      image: jenkins:2.46.2-alpine
      restart: always
      hostname: jenkins.domain.com
      expose:
        - 8080
        - 50000
      ports:
        - 8080:8080
        - 50000:50000
      volumes:
        - /srv/jenkins:/var/jenkins_home
      environment:
        - VIRTUAL_HOST=jenkins.domain.com
        - VIRTUAL_PORT=8080
    

    The only real difference I see is the removal of network_mode: bridge. I’ve added that when I noticed that with v2 there are seperate networks being created, but with v1 (or a simple docker run), they end up on the same network. Using network_mode: bridge seemed to solve this issue.

    Besides this, it’s only a structural change in the docker-compose.yml files, but there must be some other differences which stop this setup from working.

    Since V1 is deprecated and I would like to use v2 format… what do I have to change to make docker-compose v2 act like v1 and get the proxy to work correctly?

  • dockerfile: vim (compiled python), vim-ipython, and ipython notebook
  • Docker: Running multiple applications VS running multiple containers
  • How to login local machine and change system parameter when use docker for mac [closed]
  • Where mongoimport store the document in a Docker container
  • Keeping PostgreSQL data in docker and OSX
  • Are Dockerfiles stored on my machine?
  • One Solution collect form web for “Docker nginx proxy works with docker-compose v1, but not v2?”

    You need to make sure the containers are on the same network. In nginx-proxy, it won’t add an upstream setting if it can’t reach the node. You should see something like:

    $ docker exec -it nginx-proxy cat /etc/nginx/conf.d/default.conf
    # ....
    # whoami.local
    upstream whoami.local {
                                    ## Can be connect with "nginxproxy_default" network
                            # nginxproxy_whoami_1
                            server 172.19.0.3:8000;
    }
    # ....
    

    If that upstream section is empty, without the comments and server line, then it’s unable to find a common docker network to reach the container and it won’t be able to route traffic.

    I’m seeing that with the following compose file:

    version: '2'
    
    services:
      nginx-proxy:
        image: jwilder/nginx-proxy:alpine
        container_name: nginx-proxy
        ports:
          - 8080:80
          - 8443:443
        volumes:
          - /var/run/docker.sock:/tmp/docker.sock:ro
        environment:
          - ENABLE_IPV6=true
          - DEFAULT_HOST=domain.com
    
      whoami:
        image: jwilder/whoami
        environment:
          - VIRTUAL_HOST=whoami.local
    

    And I can verify it with:

    $ curl -H "Host: whoami.local" http://localhost:8080
    I'm b066afdb6e45
    

    With Jenkins, when you spin that up with a separate compose file (actually a separate compose project which happens by default when your in a different directory name), it will get a separate default network. The easiest solution I have is to use an external network. First you create it directly in docker:

    $ docker network create proxynet
    

    And then your compose file would include that external network:

    version: '2'
    
    networks:
      proxynet:
        external: true
    
    services:
      nginx-proxy:
        image: jwilder/nginx-proxy:alpine
        container_name: nginx-proxy
        ports:
          - 8080:80
          - 8443:443
        volumes:
          - /var/run/docker.sock:/tmp/docker.sock:ro
        networks:
          - proxynet
        environment:
          - ENABLE_IPV6=true
          - DEFAULT_HOST=domain.com
    
      whoami:
        image: jwilder/whoami
        environment:
          - VIRTUAL_HOST=whoami.local
        networks:
          - proxynet
    

    You would do the same with Jenkins:

    version: "2"
    
    networks:
      proxynet:
        external: true
    
    services:
      jenkins:
        image: jenkins:2.46.2-alpine
        restart: always
        hostname: jenkins.domain.com
        networks:
          - proxynet
        expose:
          - 8080
          - 50000
        ports:
          - 8080:8080
          - 50000:50000
        volumes:
          - /srv/jenkins:/var/jenkins_home
        environment:
          - VIRTUAL_HOST=jenkins.domain.com
          - VIRTUAL_PORT=8080
    
    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.