mirror of
				https://github.com/thib8956/nginx-proxy
				synced 2025-11-03 18:49:20 +00:00 
			
		
		
		
	Merge pull request #2569 from nginx-proxy/test/cleanup
tests: fix, cleanup and restructure test code
This commit is contained in:
		
							
								
								
									
										177
									
								
								test/conftest.py
									
									
									
									
									
								
							
							
						
						
									
										177
									
								
								test/conftest.py
									
									
									
									
									
								
							@@ -6,16 +6,19 @@ import shlex
 | 
			
		||||
import socket
 | 
			
		||||
import subprocess
 | 
			
		||||
import time
 | 
			
		||||
from typing import List
 | 
			
		||||
from typing import Iterator, List, Optional
 | 
			
		||||
 | 
			
		||||
import backoff
 | 
			
		||||
import docker
 | 
			
		||||
import docker.errors
 | 
			
		||||
import pytest
 | 
			
		||||
import requests
 | 
			
		||||
from _pytest._code.code import ReprExceptionInfo
 | 
			
		||||
from packaging.version import Version
 | 
			
		||||
from _pytest.fixtures import FixtureRequest
 | 
			
		||||
from docker import DockerClient
 | 
			
		||||
from docker.models.containers import Container
 | 
			
		||||
from requests.packages.urllib3.util.connection import HAS_IPV6
 | 
			
		||||
from docker.models.networks import Network
 | 
			
		||||
from packaging.version import Version
 | 
			
		||||
from requests import Response
 | 
			
		||||
from urllib3.util.connection import HAS_IPV6
 | 
			
		||||
 | 
			
		||||
logging.basicConfig(level=logging.INFO)
 | 
			
		||||
logging.getLogger('backoff').setLevel(logging.INFO)
 | 
			
		||||
@@ -40,8 +43,9 @@ test_container = 'nginx-proxy-pytest'
 | 
			
		||||
#
 | 
			
		||||
###############################################################################
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@contextlib.contextmanager
 | 
			
		||||
def ipv6(force_ipv6=True):
 | 
			
		||||
def ipv6(force_ipv6: bool = True):
 | 
			
		||||
    """
 | 
			
		||||
    Meant to be used as a context manager to force IPv6 sockets:
 | 
			
		||||
 | 
			
		||||
@@ -59,10 +63,10 @@ def ipv6(force_ipv6=True):
 | 
			
		||||
    FORCE_CONTAINER_IPV6 = False
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class requests_for_docker(object):
 | 
			
		||||
class RequestsForDocker:
 | 
			
		||||
    """
 | 
			
		||||
    Proxy for calling methods of the requests module.
 | 
			
		||||
    When a HTTP response failed due to HTTP Error 404 or 502, retry a few times.
 | 
			
		||||
    When an HTTP response failed due to HTTP Error 404 or 502, retry a few times.
 | 
			
		||||
    Provides method `get_conf` to extract the nginx-proxy configuration content.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
@@ -71,7 +75,7 @@ class requests_for_docker(object):
 | 
			
		||||
            self.session.verify = CA_ROOT_CERTIFICATE
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def get_nginx_proxy_containers() -> List[Container]:
 | 
			
		||||
    def get_nginx_proxy_container() -> Container:
 | 
			
		||||
        """
 | 
			
		||||
        Return list of containers
 | 
			
		||||
        """
 | 
			
		||||
@@ -80,69 +84,69 @@ class requests_for_docker(object):
 | 
			
		||||
            pytest.fail("Too many running nginxproxy/nginx-proxy:test containers", pytrace=False)
 | 
			
		||||
        elif len(nginx_proxy_containers) == 0:
 | 
			
		||||
            pytest.fail("No running nginxproxy/nginx-proxy:test container", pytrace=False)
 | 
			
		||||
        return nginx_proxy_containers
 | 
			
		||||
        return nginx_proxy_containers.pop()
 | 
			
		||||
 | 
			
		||||
    def get_conf(self):
 | 
			
		||||
    def get_conf(self) -> bytes:
 | 
			
		||||
        """
 | 
			
		||||
        Return the nginx config file
 | 
			
		||||
        """
 | 
			
		||||
        nginx_proxy_containers = self.get_nginx_proxy_containers()
 | 
			
		||||
        return get_nginx_conf_from_container(nginx_proxy_containers[0])
 | 
			
		||||
        nginx_proxy_container = self.get_nginx_proxy_container()
 | 
			
		||||
        return get_nginx_conf_from_container(nginx_proxy_container)
 | 
			
		||||
 | 
			
		||||
    def get_ip(self) -> str:
 | 
			
		||||
        """
 | 
			
		||||
        Return the nginx container ip address
 | 
			
		||||
        """
 | 
			
		||||
        nginx_proxy_containers = self.get_nginx_proxy_containers()
 | 
			
		||||
        return container_ip(nginx_proxy_containers[0])
 | 
			
		||||
        nginx_proxy_container = self.get_nginx_proxy_container()
 | 
			
		||||
        return container_ip(nginx_proxy_container)
 | 
			
		||||
 | 
			
		||||
    def get(self, *args, **kwargs):
 | 
			
		||||
    def get(self, *args, **kwargs) -> Response:
 | 
			
		||||
        with ipv6(kwargs.pop('ipv6', False)):
 | 
			
		||||
            @backoff.on_predicate(backoff.constant, lambda r: r.status_code in (404, 502), interval=.3, max_tries=30, jitter=None)
 | 
			
		||||
            def _get(*args, **kwargs):
 | 
			
		||||
                return self.session.get(*args, **kwargs)
 | 
			
		||||
            def _get(*_args, **_kwargs):
 | 
			
		||||
                return self.session.get(*_args, **_kwargs)
 | 
			
		||||
            return _get(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def post(self, *args, **kwargs):
 | 
			
		||||
    def post(self, *args, **kwargs) -> Response:
 | 
			
		||||
        with ipv6(kwargs.pop('ipv6', False)):
 | 
			
		||||
            @backoff.on_predicate(backoff.constant, lambda r: r.status_code in (404, 502), interval=.3, max_tries=30, jitter=None)
 | 
			
		||||
            def _post(*args, **kwargs):
 | 
			
		||||
                return self.session.post(*args, **kwargs)
 | 
			
		||||
            def _post(*_args, **_kwargs):
 | 
			
		||||
                return self.session.post(*_args, **_kwargs)
 | 
			
		||||
            return _post(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def put(self, *args, **kwargs):
 | 
			
		||||
    def put(self, *args, **kwargs) -> Response:
 | 
			
		||||
        with ipv6(kwargs.pop('ipv6', False)):
 | 
			
		||||
            @backoff.on_predicate(backoff.constant, lambda r: r.status_code in (404, 502), interval=.3, max_tries=30, jitter=None)
 | 
			
		||||
            def _put(*args, **kwargs):
 | 
			
		||||
                return self.session.put(*args, **kwargs)
 | 
			
		||||
            def _put(*_args, **_kwargs):
 | 
			
		||||
                return self.session.put(*_args, **_kwargs)
 | 
			
		||||
            return _put(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def head(self, *args, **kwargs):
 | 
			
		||||
    def head(self, *args, **kwargs) -> Response:
 | 
			
		||||
        with ipv6(kwargs.pop('ipv6', False)):
 | 
			
		||||
            @backoff.on_predicate(backoff.constant, lambda r: r.status_code in (404, 502), interval=.3, max_tries=30, jitter=None)
 | 
			
		||||
            def _head(*args, **kwargs):
 | 
			
		||||
                return self.session.head(*args, **kwargs)
 | 
			
		||||
            def _head(*_args, **_kwargs):
 | 
			
		||||
                return self.session.head(*_args, **_kwargs)
 | 
			
		||||
            return _head(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def delete(self, *args, **kwargs):
 | 
			
		||||
    def delete(self, *args, **kwargs) -> Response:
 | 
			
		||||
        with ipv6(kwargs.pop('ipv6', False)):
 | 
			
		||||
            @backoff.on_predicate(backoff.constant, lambda r: r.status_code in (404, 502), interval=.3, max_tries=30, jitter=None)
 | 
			
		||||
            def _delete(*args, **kwargs):
 | 
			
		||||
                return self.session.delete(*args, **kwargs)
 | 
			
		||||
            def _delete(*_args, **_kwargs):
 | 
			
		||||
                return self.session.delete(*_args, **_kwargs)
 | 
			
		||||
            return _delete(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def options(self, *args, **kwargs):
 | 
			
		||||
    def options(self, *args, **kwargs) -> Response:
 | 
			
		||||
        with ipv6(kwargs.pop('ipv6', False)):
 | 
			
		||||
            @backoff.on_predicate(backoff.constant, lambda r: r.status_code in (404, 502), interval=.3, max_tries=30, jitter=None)
 | 
			
		||||
            def _options(*args, **kwargs):
 | 
			
		||||
                return self.session.options(*args, **kwargs)
 | 
			
		||||
            def _options(*_args, **_kwargs):
 | 
			
		||||
                return self.session.options(*_args, **_kwargs)
 | 
			
		||||
            return _options(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def __getattr__(self, name):
 | 
			
		||||
        return getattr(requests, name)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def container_ip(container: Container):
 | 
			
		||||
def container_ip(container: Container) -> str:
 | 
			
		||||
    """
 | 
			
		||||
    return the IP address of a container.
 | 
			
		||||
 | 
			
		||||
@@ -171,7 +175,7 @@ def container_ip(container: Container):
 | 
			
		||||
        return net_info[network_name]["IPAddress"]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def container_ipv6(container):
 | 
			
		||||
def container_ipv6(container: Container) -> str:
 | 
			
		||||
    """
 | 
			
		||||
    return the IPv6 address of a container.
 | 
			
		||||
    """
 | 
			
		||||
@@ -188,7 +192,7 @@ def container_ipv6(container):
 | 
			
		||||
    return net_info[network_name]["GlobalIPv6Address"]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def nginx_proxy_dns_resolver(domain_name):
 | 
			
		||||
def nginx_proxy_dns_resolver(domain_name: str) -> Optional[str]:
 | 
			
		||||
    """
 | 
			
		||||
    if "nginx-proxy" if found in host, return the ip address of the docker container
 | 
			
		||||
    issued from the docker image nginxproxy/nginx-proxy:test.
 | 
			
		||||
@@ -200,18 +204,18 @@ def nginx_proxy_dns_resolver(domain_name):
 | 
			
		||||
    if 'nginx-proxy' in domain_name:
 | 
			
		||||
        nginxproxy_containers = docker_client.containers.list(filters={"status": "running", "ancestor": "nginxproxy/nginx-proxy:test"})
 | 
			
		||||
        if len(nginxproxy_containers) == 0:
 | 
			
		||||
            log.warn(f"no container found from image nginxproxy/nginx-proxy:test while resolving {domain_name!r}")
 | 
			
		||||
            log.warning(f"no container found from image nginxproxy/nginx-proxy:test while resolving {domain_name!r}")
 | 
			
		||||
            exited_nginxproxy_containers = docker_client.containers.list(filters={"status": "exited", "ancestor": "nginxproxy/nginx-proxy:test"})
 | 
			
		||||
            if len(exited_nginxproxy_containers) > 0:
 | 
			
		||||
                exited_nginxproxy_container_logs = exited_nginxproxy_containers[0].logs()
 | 
			
		||||
                log.warn(f"nginxproxy/nginx-proxy:test container might have exited unexpectedly. Container logs: " + "\n" + exited_nginxproxy_container_logs.decode())
 | 
			
		||||
            return
 | 
			
		||||
                log.warning(f"nginxproxy/nginx-proxy:test container might have exited unexpectedly. Container logs: " + "\n" + exited_nginxproxy_container_logs.decode())
 | 
			
		||||
            return None
 | 
			
		||||
        nginxproxy_container = nginxproxy_containers[0]
 | 
			
		||||
        ip = container_ip(nginxproxy_container)
 | 
			
		||||
        log.info(f"resolving domain name {domain_name!r} as IP address {ip} of nginx-proxy container {nginxproxy_container.name}")
 | 
			
		||||
        return ip
 | 
			
		||||
 | 
			
		||||
def docker_container_dns_resolver(domain_name):
 | 
			
		||||
def docker_container_dns_resolver(domain_name: str) -> Optional[str]:
 | 
			
		||||
    """
 | 
			
		||||
    if domain name is of the form "XXX.container.docker" or "anything.XXX.container.docker", return the ip address of the docker container
 | 
			
		||||
    named XXX.
 | 
			
		||||
@@ -224,15 +228,15 @@ def docker_container_dns_resolver(domain_name):
 | 
			
		||||
    match = re.search(r'(^|.+\.)(?P<container>[^.]+)\.container\.docker$', domain_name)
 | 
			
		||||
    if not match:
 | 
			
		||||
        log.debug(f"{domain_name!r} does not match")
 | 
			
		||||
        return
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    container_name = match.group('container')
 | 
			
		||||
    log.debug(f"looking for container {container_name!r}")
 | 
			
		||||
    try:
 | 
			
		||||
        container = docker_client.containers.get(container_name)
 | 
			
		||||
    except docker.errors.NotFound:
 | 
			
		||||
        log.warn(f"container named {container_name!r} not found while resolving {domain_name!r}")
 | 
			
		||||
        return
 | 
			
		||||
        log.warning(f"container named {container_name!r} not found while resolving {domain_name!r}")
 | 
			
		||||
        return None
 | 
			
		||||
    log.debug(f"container {container.name!r} found ({container.short_id})")
 | 
			
		||||
 | 
			
		||||
    ip = container_ip(container)
 | 
			
		||||
@@ -252,7 +256,7 @@ def monkey_patch_urllib_dns_resolver():
 | 
			
		||||
        logging.getLogger('DNS').debug(f"resolving domain name {repr(args)}")
 | 
			
		||||
        _args = list(args)
 | 
			
		||||
 | 
			
		||||
        # Fail early when querying IP directly and it is forced ipv6 when not supported,
 | 
			
		||||
        # Fail early when querying IP directly, and it is forced ipv6 when not supported,
 | 
			
		||||
        # Otherwise a pytest container not using the host network fails to pass `test_raw-ip-vhost`.
 | 
			
		||||
        if FORCE_CONTAINER_IPV6 and not HAS_IPV6:
 | 
			
		||||
            pytest.skip("This system does not support IPv6")
 | 
			
		||||
@@ -274,19 +278,12 @@ def monkey_patch_urllib_dns_resolver():
 | 
			
		||||
    socket.getaddrinfo = new_getaddrinfo
 | 
			
		||||
    return prv_getaddrinfo
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def restore_urllib_dns_resolver(getaddrinfo_func):
 | 
			
		||||
    socket.getaddrinfo = getaddrinfo_func
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def remove_all_containers():
 | 
			
		||||
    for container in docker_client.containers.list(all=True):
 | 
			
		||||
        if PYTEST_RUNNING_IN_CONTAINER and container.name == test_container:
 | 
			
		||||
            continue  # pytest is running within a Docker container, so we do not want to remove that particular container
 | 
			
		||||
        logging.info(f"removing container {container.name}")
 | 
			
		||||
        container.remove(v=True, force=True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_nginx_conf_from_container(container):
 | 
			
		||||
def get_nginx_conf_from_container(container: Container) -> bytes:
 | 
			
		||||
    """
 | 
			
		||||
    return the nginx /etc/nginx/conf.d/default.conf file content from a container
 | 
			
		||||
    """
 | 
			
		||||
@@ -301,20 +298,20 @@ def get_nginx_conf_from_container(container):
 | 
			
		||||
        return conffile.read()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def docker_compose_up(compose_file='docker-compose.yml'):
 | 
			
		||||
def docker_compose_up(compose_file: str):
 | 
			
		||||
    logging.info(f'{DOCKER_COMPOSE} -f {compose_file} up -d')
 | 
			
		||||
    try:
 | 
			
		||||
        subprocess.check_output(shlex.split(f'{DOCKER_COMPOSE} -f {compose_file} up -d'), stderr=subprocess.STDOUT)
 | 
			
		||||
    except subprocess.CalledProcessError as e:
 | 
			
		||||
        pytest.fail(f"Error while runninng '{DOCKER_COMPOSE} -f {compose_file} up -d':\n{e.output}", pytrace=False)
 | 
			
		||||
        pytest.fail(f"Error while running '{DOCKER_COMPOSE} -f {compose_file} up -d':\n{e.output}", pytrace=False)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def docker_compose_down(compose_file='docker-compose.yml'):
 | 
			
		||||
def docker_compose_down(compose_file: str):
 | 
			
		||||
    logging.info(f'{DOCKER_COMPOSE} -f {compose_file} down -v')
 | 
			
		||||
    try:
 | 
			
		||||
        subprocess.check_output(shlex.split(f'{DOCKER_COMPOSE} -f {compose_file} down -v'), stderr=subprocess.STDOUT)
 | 
			
		||||
    except subprocess.CalledProcessError as e:
 | 
			
		||||
        pytest.fail(f"Error while runninng '{DOCKER_COMPOSE} -f {compose_file} down -v':\n{e.output}", pytrace=False)
 | 
			
		||||
        pytest.fail(f"Error while running '{DOCKER_COMPOSE} -f {compose_file} down -v':\n{e.output}", pytrace=False)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def wait_for_nginxproxy_to_be_ready():
 | 
			
		||||
@@ -333,7 +330,7 @@ def wait_for_nginxproxy_to_be_ready():
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture
 | 
			
		||||
def docker_compose_file(request):
 | 
			
		||||
def docker_compose_file(request: FixtureRequest) -> Iterator[Optional[str]]:
 | 
			
		||||
    """Fixture naming the docker compose file to consider.
 | 
			
		||||
 | 
			
		||||
    If a YAML file exists with the same name as the test module (with the `.py` extension replaced
 | 
			
		||||
@@ -343,25 +340,28 @@ def docker_compose_file(request):
 | 
			
		||||
    Tests can override this fixture to specify a custom location.
 | 
			
		||||
    """
 | 
			
		||||
    test_module_dir = os.path.dirname(request.module.__file__)
 | 
			
		||||
    yml_file = os.path.join(test_module_dir, request.module.__name__ + '.yml')
 | 
			
		||||
    yaml_file = os.path.join(test_module_dir, request.module.__name__ + '.yaml')
 | 
			
		||||
    yml_file = os.path.join(test_module_dir, f"{request.module.__name__}.yml")
 | 
			
		||||
    yaml_file = os.path.join(test_module_dir, f"{request.module.__name__}.yaml")
 | 
			
		||||
    default_file = os.path.join(test_module_dir, 'docker-compose.yml')
 | 
			
		||||
 | 
			
		||||
    docker_compose_file = None
 | 
			
		||||
 | 
			
		||||
    if os.path.isfile(yml_file):
 | 
			
		||||
        docker_compose_file = yml_file
 | 
			
		||||
    elif os.path.isfile(yaml_file):
 | 
			
		||||
        docker_compose_file = yaml_file
 | 
			
		||||
    else:
 | 
			
		||||
    elif os.path.isfile(default_file):
 | 
			
		||||
        docker_compose_file = default_file
 | 
			
		||||
 | 
			
		||||
    if not os.path.isfile(docker_compose_file):
 | 
			
		||||
    if docker_compose_file is None:
 | 
			
		||||
        logging.error("Could not find any docker compose file named either '{0}.yml', '{0}.yaml' or 'docker-compose.yml'".format(request.module.__name__))
 | 
			
		||||
    else:
 | 
			
		||||
        logging.debug(f"using docker compose file {docker_compose_file}")
 | 
			
		||||
 | 
			
		||||
    logging.debug(f"using docker compose file {docker_compose_file}")
 | 
			
		||||
    return docker_compose_file
 | 
			
		||||
    yield docker_compose_file
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def connect_to_network(network):
 | 
			
		||||
def connect_to_network(network: Network) -> Optional[Network]:
 | 
			
		||||
    """
 | 
			
		||||
    If we are running from a container, connect our container to the given network
 | 
			
		||||
 | 
			
		||||
@@ -371,8 +371,8 @@ def connect_to_network(network):
 | 
			
		||||
        try:
 | 
			
		||||
            my_container = docker_client.containers.get(test_container)
 | 
			
		||||
        except docker.errors.NotFound:
 | 
			
		||||
            logging.warn(f"container {test_container} not found")
 | 
			
		||||
            return
 | 
			
		||||
            logging.warning(f"container {test_container} not found")
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        # figure out our container networks
 | 
			
		||||
        my_networks = list(my_container.attrs["NetworkSettings"]["Networks"].keys())
 | 
			
		||||
@@ -389,7 +389,7 @@ def connect_to_network(network):
 | 
			
		||||
            return network
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def disconnect_from_network(network=None):
 | 
			
		||||
def disconnect_from_network(network: Network = None):
 | 
			
		||||
    """
 | 
			
		||||
    If we are running from a container, disconnect our container from the given network.
 | 
			
		||||
 | 
			
		||||
@@ -399,7 +399,7 @@ def disconnect_from_network(network=None):
 | 
			
		||||
        try:
 | 
			
		||||
            my_container = docker_client.containers.get(test_container)
 | 
			
		||||
        except docker.errors.NotFound:
 | 
			
		||||
            logging.warn(f"container {test_container} not found")
 | 
			
		||||
            logging.warning(f"container {test_container} not found")
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        # figure out our container networks
 | 
			
		||||
@@ -411,7 +411,7 @@ def disconnect_from_network(network=None):
 | 
			
		||||
            network.disconnect(my_container)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def connect_to_all_networks():
 | 
			
		||||
def connect_to_all_networks() -> List[Network]:
 | 
			
		||||
    """
 | 
			
		||||
    If we are running from a container, connect our container to all current docker networks.
 | 
			
		||||
 | 
			
		||||
@@ -427,6 +427,7 @@ def connect_to_all_networks():
 | 
			
		||||
 | 
			
		||||
class DockerComposer(contextlib.AbstractContextManager):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self._networks = None
 | 
			
		||||
        self._docker_compose_file = None
 | 
			
		||||
 | 
			
		||||
    def __exit__(self, *exc_info):
 | 
			
		||||
@@ -440,13 +441,12 @@ class DockerComposer(contextlib.AbstractContextManager):
 | 
			
		||||
        docker_compose_down(self._docker_compose_file)
 | 
			
		||||
        self._docker_compose_file = None
 | 
			
		||||
 | 
			
		||||
    def compose(self, docker_compose_file):
 | 
			
		||||
    def compose(self, docker_compose_file: Optional[str]):
 | 
			
		||||
        if docker_compose_file == self._docker_compose_file:
 | 
			
		||||
            return
 | 
			
		||||
        self._down()
 | 
			
		||||
        if docker_compose_file is None:
 | 
			
		||||
            return
 | 
			
		||||
        remove_all_containers()
 | 
			
		||||
        docker_compose_up(docker_compose_file)
 | 
			
		||||
        self._networks = connect_to_all_networks()
 | 
			
		||||
        wait_for_nginxproxy_to_be_ready()
 | 
			
		||||
@@ -462,14 +462,14 @@ class DockerComposer(contextlib.AbstractContextManager):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope="module")
 | 
			
		||||
def docker_composer():
 | 
			
		||||
def docker_composer() ->  Iterator[DockerComposer]:
 | 
			
		||||
    with DockerComposer() as d:
 | 
			
		||||
        yield d
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture
 | 
			
		||||
def ca_root_certificate():
 | 
			
		||||
    return CA_ROOT_CERTIFICATE
 | 
			
		||||
def ca_root_certificate() -> Iterator[str]:
 | 
			
		||||
    yield CA_ROOT_CERTIFICATE
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture
 | 
			
		||||
@@ -480,7 +480,7 @@ def monkey_patched_dns():
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture
 | 
			
		||||
def docker_compose(monkey_patched_dns, docker_composer, docker_compose_file):
 | 
			
		||||
def docker_compose(monkey_patched_dns, docker_composer, docker_compose_file) -> Iterator[DockerClient]:
 | 
			
		||||
    """Ensures containers described in a docker compose file are started.
 | 
			
		||||
 | 
			
		||||
    A custom docker compose file name can be specified by overriding the `docker_compose_file`
 | 
			
		||||
@@ -493,12 +493,12 @@ def docker_compose(monkey_patched_dns, docker_composer, docker_compose_file):
 | 
			
		||||
    yield docker_client
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture()
 | 
			
		||||
def nginxproxy():
 | 
			
		||||
@pytest.fixture
 | 
			
		||||
def nginxproxy() -> Iterator[RequestsForDocker]:
 | 
			
		||||
    """
 | 
			
		||||
    Provides the `nginxproxy` object that can be used in the same way the requests module is:
 | 
			
		||||
 | 
			
		||||
    r = nginxproxy.get("http://foo.com")
 | 
			
		||||
    r = nginxproxy.get("https://foo.com")
 | 
			
		||||
 | 
			
		||||
    The difference is that in case an HTTP requests has status code 404 or 502 (which mostly
 | 
			
		||||
    indicates that nginx has just reloaded), we retry up to 30 times the query.
 | 
			
		||||
@@ -507,15 +507,15 @@ def nginxproxy():
 | 
			
		||||
    made against containers to use the containers IPv6 address when set to `True`. If IPv6 is not
 | 
			
		||||
    supported by the system or docker, that particular test will be skipped.
 | 
			
		||||
    """
 | 
			
		||||
    yield requests_for_docker()
 | 
			
		||||
    yield RequestsForDocker()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture()
 | 
			
		||||
def acme_challenge_path():
 | 
			
		||||
@pytest.fixture
 | 
			
		||||
def acme_challenge_path() -> Iterator[str]:
 | 
			
		||||
    """
 | 
			
		||||
    Provides fake Let's Encrypt ACME challenge path used in certain tests
 | 
			
		||||
    """
 | 
			
		||||
    return ".well-known/acme-challenge/test-filename"
 | 
			
		||||
    yield ".well-known/acme-challenge/test-filename"
 | 
			
		||||
 | 
			
		||||
###############################################################################
 | 
			
		||||
#
 | 
			
		||||
@@ -523,14 +523,13 @@ def acme_challenge_path():
 | 
			
		||||
#
 | 
			
		||||
###############################################################################
 | 
			
		||||
 | 
			
		||||
# pytest hook to display additionnal stuff in test report
 | 
			
		||||
# pytest hook to display additional stuff in test report
 | 
			
		||||
def pytest_runtest_logreport(report):
 | 
			
		||||
    if report.failed:
 | 
			
		||||
        if isinstance(report.longrepr, ReprExceptionInfo):
 | 
			
		||||
            test_containers = docker_client.containers.list(all=True, filters={"ancestor": "nginxproxy/nginx-proxy:test"})
 | 
			
		||||
            for container in test_containers:
 | 
			
		||||
                report.longrepr.addsection('nginx-proxy logs', container.logs())
 | 
			
		||||
                report.longrepr.addsection('nginx-proxy conf', get_nginx_conf_from_container(container))
 | 
			
		||||
        test_containers = docker_client.containers.list(all=True, filters={"ancestor": "nginxproxy/nginx-proxy:test"})
 | 
			
		||||
        for container in test_containers:
 | 
			
		||||
            report.longrepr.addsection('nginx-proxy logs', container.logs().decode())
 | 
			
		||||
            report.longrepr.addsection('nginx-proxy conf', get_nginx_conf_from_container(container).decode())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Py.test `incremental` marker, see http://stackoverflow.com/a/12579625/107049
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
#                                                                             #
 | 
			
		||||
# This script is meant to run the test suite from a Docker container.         #
 | 
			
		||||
#                                                                             #
 | 
			
		||||
# This is usefull when you want to run the test suite from Mac or             #
 | 
			
		||||
# This is useful when you want to run the test suite from Mac or             #
 | 
			
		||||
# Docker Toolbox.                                                             #
 | 
			
		||||
#                                                                             #
 | 
			
		||||
###############################################################################
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,6 @@
 | 
			
		||||
backoff==2.2.1
 | 
			
		||||
docker==7.1.0
 | 
			
		||||
packaging==24.2
 | 
			
		||||
pytest==8.3.4
 | 
			
		||||
requests==2.32.3
 | 
			
		||||
urllib3==2.3.0
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@ class Handler(http.server.SimpleHTTPRequestHandler):
 | 
			
		||||
        self.send_header("Content-Type", "text/plain")
 | 
			
		||||
        self.end_headers()
 | 
			
		||||
 | 
			
		||||
        if (len(response_body)):
 | 
			
		||||
        if len(response_body):
 | 
			
		||||
            self.wfile.write(response_body.encode())
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
 
 | 
			
		||||
@@ -1 +0,0 @@
 | 
			
		||||
This directory contains tests that showcase scenarios known to break the expected behavior of nginx-proxy.
 | 
			
		||||
@@ -1,6 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_redirect_acme_challenge_location_disabled(docker_compose, nginxproxy, acme_challenge_path):
 | 
			
		||||
    r = nginxproxy.get(
 | 
			
		||||
        f"http://web1.nginx-proxy.tld/{acme_challenge_path}",
 | 
			
		||||
@@ -1,6 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_redirect_acme_challenge_location_enabled(docker_compose, nginxproxy, acme_challenge_path):
 | 
			
		||||
    r = nginxproxy.get(
 | 
			
		||||
        f"http://web1.nginx-proxy.tld/{acme_challenge_path}",
 | 
			
		||||
@@ -1,6 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_redirect_acme_challenge_location_legacy(docker_compose, nginxproxy, acme_challenge_path):
 | 
			
		||||
    r = nginxproxy.get(
 | 
			
		||||
        f"http://web1.nginx-proxy.tld/{acme_challenge_path}",
 | 
			
		||||
@@ -1,22 +1,25 @@
 | 
			
		||||
"""
 | 
			
		||||
Test that nginx-proxy-tester can build successfully
 | 
			
		||||
"""
 | 
			
		||||
import pytest
 | 
			
		||||
import docker
 | 
			
		||||
import pathlib
 | 
			
		||||
import re
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
import docker
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
client = docker.from_env()
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope = "session")
 | 
			
		||||
def docker_build(request):
 | 
			
		||||
    # Define Dockerfile path
 | 
			
		||||
    dockerfile_path = os.path.join(os.path.dirname(__file__), "requirements/")
 | 
			
		||||
    current_file_path = pathlib.Path(__file__)
 | 
			
		||||
    dockerfile_path = current_file_path.parent.parent.joinpath("requirements")
 | 
			
		||||
    dockerfile_name = "Dockerfile-nginx-proxy-tester"
 | 
			
		||||
 | 
			
		||||
    # Build the Docker image
 | 
			
		||||
    image, logs = client.images.build(
 | 
			
		||||
        path = dockerfile_path,
 | 
			
		||||
        path = dockerfile_path.as_posix(),
 | 
			
		||||
        dockerfile = dockerfile_name,
 | 
			
		||||
        rm = True,  # Remove intermediate containers
 | 
			
		||||
        tag = "nginx-proxy-tester-ci",  # Tag for the built image
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
def test_custom_default_conf_does_not_apply_to_unknown_vhost(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://nginx-proxy/")
 | 
			
		||||
    assert r.status_code == 503
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "81"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 81
 | 
			
		||||
      WEB_PORTS: "81"
 | 
			
		||||
      VIRTUAL_HOST: web1.nginx-proxy.example
 | 
			
		||||
 | 
			
		||||
  web2:
 | 
			
		||||
@@ -19,7 +19,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "82"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 82
 | 
			
		||||
      WEB_PORTS: "82"
 | 
			
		||||
      VIRTUAL_HOST: web2.nginx-proxy.example
 | 
			
		||||
 | 
			
		||||
  web3:
 | 
			
		||||
@@ -27,5 +27,5 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "83"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 83
 | 
			
		||||
      WEB_PORTS: "83"
 | 
			
		||||
      VIRTUAL_HOST: web3.nginx-proxy.example
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
def test_custom_conf_does_not_apply_to_unknown_vhost(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://nginx-proxy/")
 | 
			
		||||
    assert r.status_code == 503
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "81"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 81
 | 
			
		||||
      WEB_PORTS: "81"
 | 
			
		||||
      VIRTUAL_HOST: web1.nginx-proxy.example
 | 
			
		||||
 | 
			
		||||
  web2:
 | 
			
		||||
@@ -18,5 +18,5 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "82"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 82
 | 
			
		||||
      WEB_PORTS: "82"
 | 
			
		||||
      VIRTUAL_HOST: web2.nginx-proxy.example
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
def test_custom_conf_does_not_apply_to_unknown_vhost(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://nginx-proxy/")
 | 
			
		||||
    assert r.status_code == 503
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "81"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 81
 | 
			
		||||
      WEB_PORTS: "81"
 | 
			
		||||
      VIRTUAL_HOST: web1.nginx-proxy.example
 | 
			
		||||
 | 
			
		||||
  web2:
 | 
			
		||||
@@ -19,7 +19,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "82"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 82
 | 
			
		||||
      WEB_PORTS: "82"
 | 
			
		||||
      VIRTUAL_HOST: web2.nginx-proxy.example
 | 
			
		||||
  
 | 
			
		||||
  regex:
 | 
			
		||||
@@ -27,5 +27,5 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "83"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 83
 | 
			
		||||
      WEB_PORTS: "83"
 | 
			
		||||
      VIRTUAL_HOST: ~^regex.*\.nginx-proxy\.example$
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
def test_custom_conf_does_not_apply_to_unknown_vhost(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://nginx-proxy/")
 | 
			
		||||
    assert r.status_code == 503
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "81"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 81
 | 
			
		||||
      WEB_PORTS: "81"
 | 
			
		||||
      VIRTUAL_HOST: web1.nginx-proxy.example
 | 
			
		||||
 | 
			
		||||
  web2:
 | 
			
		||||
@@ -19,7 +19,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "82"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 82
 | 
			
		||||
      WEB_PORTS: "82"
 | 
			
		||||
      VIRTUAL_HOST: web2.nginx-proxy.example
 | 
			
		||||
  
 | 
			
		||||
  regex:
 | 
			
		||||
@@ -27,5 +27,5 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "83"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 83
 | 
			
		||||
      WEB_PORTS: "83"
 | 
			
		||||
      VIRTUAL_HOST: ~^regex.*\.nginx-proxy\.example$
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
def test_custom_conf_does_not_apply_to_unknown_vhost(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://nginx-proxy/")
 | 
			
		||||
    assert r.status_code == 503
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "81"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 81
 | 
			
		||||
      WEB_PORTS: "81"
 | 
			
		||||
      VIRTUAL_HOST: web1.nginx-proxy.example
 | 
			
		||||
 | 
			
		||||
  web2:
 | 
			
		||||
@@ -18,5 +18,5 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "82"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 82
 | 
			
		||||
      WEB_PORTS: "82"
 | 
			
		||||
      VIRTUAL_HOST: web2.nginx-proxy.example
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
import json
 | 
			
		||||
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_debug_endpoint_is_enabled_globally(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://enabled.debug.nginx-proxy.example/nginx-proxy-debug")
 | 
			
		||||
    assert r.status_code == 200
 | 
			
		||||
@@ -11,7 +11,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "81"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 81
 | 
			
		||||
      WEB_PORTS: "81"
 | 
			
		||||
      VIRTUAL_HOST: enabled.debug.nginx-proxy.example
 | 
			
		||||
  
 | 
			
		||||
  debug_stripped:
 | 
			
		||||
@@ -19,7 +19,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "82"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 82
 | 
			
		||||
      WEB_PORTS: "82"
 | 
			
		||||
      VIRTUAL_HOST_MULTIPORTS: |-
 | 
			
		||||
        stripped.debug.nginx-proxy.example:
 | 
			
		||||
          "/1":
 | 
			
		||||
@@ -48,7 +48,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "84"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 84
 | 
			
		||||
      WEB_PORTS: "84"
 | 
			
		||||
      VIRTUAL_HOST: ~^regexp.*\.debug.nginx-proxy.example
 | 
			
		||||
 | 
			
		||||
  debug_disabled:
 | 
			
		||||
@@ -56,7 +56,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "83"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 83
 | 
			
		||||
      WEB_PORTS: "83"
 | 
			
		||||
      VIRTUAL_HOST: disabled.debug.nginx-proxy.example
 | 
			
		||||
    labels:
 | 
			
		||||
      com.github.nginx-proxy.nginx-proxy.debug-endpoint: "false"
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
import json
 | 
			
		||||
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_debug_endpoint_is_disabled_globally(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://disabled1.debug.nginx-proxy.example/nginx-proxy-debug")
 | 
			
		||||
    assert r.status_code == 404 
 | 
			
		||||
@@ -9,7 +9,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "81"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 81
 | 
			
		||||
      WEB_PORTS: "81"
 | 
			
		||||
      VIRTUAL_HOST: disabled1.debug.nginx-proxy.example
 | 
			
		||||
  
 | 
			
		||||
  debug_disabled2:
 | 
			
		||||
@@ -17,7 +17,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "82"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 82
 | 
			
		||||
      WEB_PORTS: "82"
 | 
			
		||||
      VIRTUAL_HOST: disabled2.debug.nginx-proxy.example
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -26,7 +26,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "83"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 83
 | 
			
		||||
      WEB_PORTS: "83"
 | 
			
		||||
      VIRTUAL_HOST: enabled.debug.nginx-proxy.example
 | 
			
		||||
    labels:
 | 
			
		||||
      com.github.nginx-proxy.nginx-proxy.debug-endpoint: "true"
 | 
			
		||||
@@ -1,6 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_fallback_on_default(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://unknown.nginx-proxy.tld/port")
 | 
			
		||||
    assert r.status_code == 200
 | 
			
		||||
@@ -5,7 +5,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "81"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 81
 | 
			
		||||
      WEB_PORTS: "81"
 | 
			
		||||
      VIRTUAL_HOST: web1.tld
 | 
			
		||||
 | 
			
		||||
  # WHEN nginx-proxy runs with DEFAULT_HOST set to web1.tld
 | 
			
		||||
@@ -1,5 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
def test_unknown_virtual_host(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://nginx-proxy/port")
 | 
			
		||||
    assert r.status_code == 503
 | 
			
		||||
@@ -4,7 +4,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "81"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 81
 | 
			
		||||
      WEB_PORTS: "81"
 | 
			
		||||
      VIRTUAL_HOST: web1.nginx-proxy.tld
 | 
			
		||||
 | 
			
		||||
  web2:
 | 
			
		||||
@@ -12,7 +12,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "82"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 82
 | 
			
		||||
      WEB_PORTS: "82"
 | 
			
		||||
      VIRTUAL_HOST: web2.nginx-proxy.tld
 | 
			
		||||
 | 
			
		||||
  sut:
 | 
			
		||||
							
								
								
									
										1
									
								
								test/test_dockergen/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								test/test_dockergen/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
			
		||||
nginx.tmpl
 | 
			
		||||
@@ -19,7 +19,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "80"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 80
 | 
			
		||||
      WEB_PORTS: "80"
 | 
			
		||||
      VIRTUAL_HOST: whoami.nginx.container.docker
 | 
			
		||||
 | 
			
		||||
volumes:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_nohttp_missing_cert_disabled(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://nohttp-missing-cert-disabled.nginx-proxy.tld/", allow_redirects=False)
 | 
			
		||||
    assert r.status_code == 503
 | 
			
		||||
@@ -7,7 +7,7 @@ import pytest
 | 
			
		||||
from docker.errors import NotFound
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture()
 | 
			
		||||
@pytest.fixture
 | 
			
		||||
def web1(docker_compose):
 | 
			
		||||
    """
 | 
			
		||||
    pytest fixture creating a web container with `VIRTUAL_HOST=web1.nginx-proxy` listening on port 81.
 | 
			
		||||
@@ -22,7 +22,7 @@ def web1(docker_compose):
 | 
			
		||||
        },
 | 
			
		||||
        ports={"81/tcp": None}
 | 
			
		||||
    )
 | 
			
		||||
    docker_compose.networks.get("test_default").connect(container)
 | 
			
		||||
    docker_compose.networks.get("test_events-net").connect(container)
 | 
			
		||||
    sleep(2)  # give it some time to initialize and for docker-gen to detect it
 | 
			
		||||
    yield container
 | 
			
		||||
    try:
 | 
			
		||||
@@ -30,7 +30,7 @@ def web1(docker_compose):
 | 
			
		||||
    except NotFound:
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
@pytest.fixture()
 | 
			
		||||
@pytest.fixture
 | 
			
		||||
def web2(docker_compose):
 | 
			
		||||
    """
 | 
			
		||||
    pytest fixture creating a web container with `VIRTUAL_HOST=nginx-proxy`, `VIRTUAL_PATH=/web2/` and `VIRTUAL_DEST=/` listening on port 82.
 | 
			
		||||
@@ -47,7 +47,7 @@ def web2(docker_compose):
 | 
			
		||||
        },
 | 
			
		||||
        ports={"82/tcp": None}
 | 
			
		||||
    )
 | 
			
		||||
    docker_compose.networks.get("test_default").connect(container)
 | 
			
		||||
    docker_compose.networks.get("test_events-net").connect(container)
 | 
			
		||||
    sleep(2)  # give it some time to initialize and for docker-gen to detect it
 | 
			
		||||
    yield container
 | 
			
		||||
    try:
 | 
			
		||||
@@ -1,3 +1,7 @@
 | 
			
		||||
networks:
 | 
			
		||||
  default:
 | 
			
		||||
    name: test_events-net
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
  nginxproxy:
 | 
			
		||||
    image: nginxproxy/nginx-proxy:test
 | 
			
		||||
@@ -4,7 +4,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "80"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 80
 | 
			
		||||
      WEB_PORTS: "80"
 | 
			
		||||
      VIRTUAL_HOST: web.nginx-proxy.tld
 | 
			
		||||
 | 
			
		||||
  web-server-tokens-off:
 | 
			
		||||
@@ -12,7 +12,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "80"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 80
 | 
			
		||||
      WEB_PORTS: "80"
 | 
			
		||||
      VIRTUAL_HOST: web-server-tokens-off.nginx-proxy.tld
 | 
			
		||||
      SERVER_TOKENS: "off"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "80"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 80
 | 
			
		||||
      WEB_PORTS: "80"
 | 
			
		||||
      VIRTUAL_HOST: web.nginx-proxy.tld
 | 
			
		||||
 | 
			
		||||
  web-server-tokens-off:
 | 
			
		||||
@@ -12,7 +12,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "80"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 80
 | 
			
		||||
      WEB_PORTS: "80"
 | 
			
		||||
      VIRTUAL_HOST: web-server-tokens-off.nginx-proxy.tld
 | 
			
		||||
      SERVER_TOKENS: "off"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_forwards_to_bridge_network_container(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://bridge-network.nginx-proxy.tld/port")
 | 
			
		||||
    assert r.status_code == 200   
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_forwards_to_host_network_container_1(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://host-network-1.nginx-proxy.tld:8888/port")
 | 
			
		||||
    assert r.status_code == 200
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
def test_htpasswd_regex_virtual_host_is_restricted(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://regex.htpasswd.nginx-proxy.example/port")
 | 
			
		||||
    assert r.status_code == 401
 | 
			
		||||
@@ -4,7 +4,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "80"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 80
 | 
			
		||||
      WEB_PORTS: "80"
 | 
			
		||||
      VIRTUAL_HOST: ~^regex.*\.nginx-proxy\.example$
 | 
			
		||||
 | 
			
		||||
  sut:
 | 
			
		||||
@@ -1,5 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
def test_htpasswd_virtual_host_is_restricted(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://htpasswd.nginx-proxy.tld/port")
 | 
			
		||||
    assert r.status_code == 401
 | 
			
		||||
@@ -4,7 +4,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "80"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 80
 | 
			
		||||
      WEB_PORTS: "80"
 | 
			
		||||
      VIRTUAL_HOST: htpasswd.nginx-proxy.tld
 | 
			
		||||
 | 
			
		||||
  sut:
 | 
			
		||||
@@ -1,5 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
def test_htpasswd_virtual_path_is_restricted(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://htpasswd.nginx-proxy.tld/foo/port")
 | 
			
		||||
    assert r.status_code == 401
 | 
			
		||||
@@ -4,7 +4,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "80"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 80
 | 
			
		||||
      WEB_PORTS: "80"
 | 
			
		||||
      VIRTUAL_HOST: htpasswd.nginx-proxy.tld
 | 
			
		||||
      VIRTUAL_PATH: /foo/
 | 
			
		||||
      VIRTUAL_DEST: /
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
import pytest
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_http2_global_disabled_config(docker_compose, nginxproxy):
 | 
			
		||||
    conf = nginxproxy.get_conf().decode('ASCII')
 | 
			
		||||
    r = nginxproxy.get("http://http2-global-disabled.nginx-proxy.tld")
 | 
			
		||||
@@ -4,7 +4,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "80"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 80
 | 
			
		||||
      WEB_PORTS: "80"
 | 
			
		||||
      VIRTUAL_HOST: http2-global-disabled.nginx-proxy.tld
 | 
			
		||||
 | 
			
		||||
  sut:
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
import pytest
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
    #Python Requests is not able to do native http3 requests. 
 | 
			
		||||
    #We only check for directives which should enable http3.
 | 
			
		||||
 | 
			
		||||
# Python Requests is not able to do native http3 requests.
 | 
			
		||||
# We only check for directives which should enable http3.
 | 
			
		||||
 | 
			
		||||
def test_http3_global_disabled_ALTSVC_header(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://http3-global-disabled.nginx-proxy.tld/headers")
 | 
			
		||||
@@ -4,7 +4,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "80"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 80
 | 
			
		||||
      WEB_PORTS: "80"
 | 
			
		||||
      VIRTUAL_HOST: http3-global-disabled.nginx-proxy.tld
 | 
			
		||||
 | 
			
		||||
  sut:
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
import pytest
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
    #Python Requests is not able to do native http3 requests. 
 | 
			
		||||
    #We only check for directives which should enable http3.
 | 
			
		||||
 | 
			
		||||
# Python Requests is not able to do native http3 requests.
 | 
			
		||||
# We only check for directives which should enable http3.
 | 
			
		||||
 | 
			
		||||
def test_http3_global_enabled_ALTSVC_header(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://http3-global-enabled.nginx-proxy.tld/headers")
 | 
			
		||||
@@ -4,7 +4,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "80"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 80
 | 
			
		||||
      WEB_PORTS: "80"
 | 
			
		||||
      VIRTUAL_HOST: http3-global-enabled.nginx-proxy.tld
 | 
			
		||||
 | 
			
		||||
  sut:
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
import pytest
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
    #Python Requests is not able to do native http3 requests. 
 | 
			
		||||
    #We only check for directives which should enable http3.
 | 
			
		||||
 | 
			
		||||
# Python Requests is not able to do native http3 requests.
 | 
			
		||||
# We only check for directives which should enable http3.
 | 
			
		||||
 | 
			
		||||
def test_http3_vhost_enabled_ALTSVC_header(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://http3-vhost-enabled.nginx-proxy.tld/headers")
 | 
			
		||||
@@ -4,7 +4,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "80"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 80
 | 
			
		||||
      WEB_PORTS: "80"
 | 
			
		||||
      VIRTUAL_HOST: http3-vhost-enabled.nginx-proxy.tld
 | 
			
		||||
    labels:
 | 
			
		||||
      com.github.nginx-proxy.nginx-proxy.http3.enable: "true"
 | 
			
		||||
@@ -14,7 +14,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "80"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 80
 | 
			
		||||
      WEB_PORTS: "80"
 | 
			
		||||
      VIRTUAL_HOST: http3-vhost-disabled.nginx-proxy.tld
 | 
			
		||||
    labels:
 | 
			
		||||
      com.github.nginx-proxy.nginx-proxy.http3.enable: "false"
 | 
			
		||||
@@ -24,7 +24,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "80"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 80
 | 
			
		||||
      WEB_PORTS: "80"
 | 
			
		||||
      VIRTUAL_HOST: http3-vhost-default-disabled.nginx-proxy.tld
 | 
			
		||||
 | 
			
		||||
  sut:
 | 
			
		||||
@@ -1,5 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
def test_network_web1(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://web1.nginx-proxy.example/port")
 | 
			
		||||
    assert r.status_code == 200   
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "81"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 81
 | 
			
		||||
      WEB_PORTS: "81"
 | 
			
		||||
      VIRTUAL_HOST: web1.nginx-proxy.example
 | 
			
		||||
      NETWORK_ACCESS: internal
 | 
			
		||||
 | 
			
		||||
@@ -13,7 +13,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "82"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 82
 | 
			
		||||
      WEB_PORTS: "82"
 | 
			
		||||
      VIRTUAL_HOST: web2.nginx-proxy.example
 | 
			
		||||
 | 
			
		||||
  sut:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
def test_network_web1(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://nginx-proxy.example/web1/port")
 | 
			
		||||
    assert r.status_code == 200   
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "81"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 81
 | 
			
		||||
      WEB_PORTS: "81"
 | 
			
		||||
      VIRTUAL_HOST: nginx-proxy.example
 | 
			
		||||
      VIRTUAL_PATH: /web1/
 | 
			
		||||
      VIRTUAL_DEST: /
 | 
			
		||||
@@ -15,7 +15,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "82"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 82
 | 
			
		||||
      WEB_PORTS: "82"
 | 
			
		||||
      VIRTUAL_HOST: nginx-proxy.example
 | 
			
		||||
      VIRTUAL_PATH: /web2/
 | 
			
		||||
      VIRTUAL_DEST: /
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_forwards_to_ipv4_only_network(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://ipv4only.nginx-proxy.tld/port")
 | 
			
		||||
    assert r.status_code == 200   
 | 
			
		||||
@@ -16,7 +16,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "80"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 80
 | 
			
		||||
      WEB_PORTS: "80"
 | 
			
		||||
      VIRTUAL_HOST: ipv4only.nginx-proxy.tld
 | 
			
		||||
    networks:
 | 
			
		||||
      ipv4net:
 | 
			
		||||
@@ -1,6 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_forwards_to_ipv4_only_network(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://ipv4only.nginx-proxy.tld/port")
 | 
			
		||||
    assert r.status_code == 200   
 | 
			
		||||
@@ -16,7 +16,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "80"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 80
 | 
			
		||||
      WEB_PORTS: "80"
 | 
			
		||||
      VIRTUAL_HOST: ipv4only.nginx-proxy.tld
 | 
			
		||||
    networks:
 | 
			
		||||
      ipv4net:
 | 
			
		||||
@@ -1,6 +1,3 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_unknown_virtual_host_ipv4(docker_compose, nginxproxy):
 | 
			
		||||
    r = nginxproxy.get("http://nginx-proxy/port")
 | 
			
		||||
    assert r.status_code == 503
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "81"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 81
 | 
			
		||||
      WEB_PORTS: "81"
 | 
			
		||||
      VIRTUAL_HOST: web1.nginx-proxy.tld
 | 
			
		||||
    networks:
 | 
			
		||||
      - net1
 | 
			
		||||
@@ -21,7 +21,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "82"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 82
 | 
			
		||||
      WEB_PORTS: "82"
 | 
			
		||||
      VIRTUAL_HOST: web2.nginx-proxy.tld
 | 
			
		||||
    networks:
 | 
			
		||||
      - net1
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "80"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 80
 | 
			
		||||
      WEB_PORTS: "80"
 | 
			
		||||
      VIRTUAL_HOST: keepalive-disabled.nginx-proxy.test
 | 
			
		||||
    labels:
 | 
			
		||||
      com.github.nginx-proxy.nginx-proxy.keepalive: "disabled"
 | 
			
		||||
@@ -14,7 +14,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "80"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 80
 | 
			
		||||
      WEB_PORTS: "80"
 | 
			
		||||
      VIRTUAL_HOST: keepalive-enabled.nginx-proxy.test
 | 
			
		||||
    labels:
 | 
			
		||||
      com.github.nginx-proxy.nginx-proxy.keepalive: "64"
 | 
			
		||||
@@ -27,7 +27,7 @@ services:
 | 
			
		||||
    expose:
 | 
			
		||||
      - "80"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 80
 | 
			
		||||
      WEB_PORTS: "80"
 | 
			
		||||
      VIRTUAL_HOST: keepalive-auto.nginx-proxy.test
 | 
			
		||||
 | 
			
		||||
  sut:
 | 
			
		||||
@@ -1,16 +1,16 @@
 | 
			
		||||
import pytest
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
def test_loadbalance_hash(docker_compose, nginxproxy):
 | 
			
		||||
    conf = nginxproxy.get_conf().decode('ASCII')
 | 
			
		||||
    r1 = nginxproxy.get("http://loadbalance-enabled.nginx-proxy.tld")
 | 
			
		||||
    r2 = nginxproxy.get("http://loadbalance-enabled.nginx-proxy.tld")
 | 
			
		||||
    assert re.search(r"hash \$remote_addr\;", conf)
 | 
			
		||||
    assert r1.status_code == 200
 | 
			
		||||
    assert r2.text == r1.text
 | 
			
		||||
 | 
			
		||||
def test_loadbalance_roundrobin(docker_compose, nginxproxy):
 | 
			
		||||
    r1 = nginxproxy.get("http://loadbalance-disabled.nginx-proxy.tld")
 | 
			
		||||
    r2 = nginxproxy.get("http://loadbalance-disabled.nginx-proxy.tld")
 | 
			
		||||
    assert r1.status_code == 200
 | 
			
		||||
    assert r2.text != r1.text
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_loadbalance_hash(docker_compose, nginxproxy):
 | 
			
		||||
    conf = nginxproxy.get_conf().decode('ASCII')
 | 
			
		||||
    r1 = nginxproxy.get("http://loadbalance-enabled.nginx-proxy.tld")
 | 
			
		||||
    r2 = nginxproxy.get("http://loadbalance-enabled.nginx-proxy.tld")
 | 
			
		||||
    assert re.search(r"hash \$remote_addr\;", conf)
 | 
			
		||||
    assert r1.status_code == 200
 | 
			
		||||
    assert r2.text == r1.text
 | 
			
		||||
 | 
			
		||||
def test_loadbalance_roundrobin(docker_compose, nginxproxy):
 | 
			
		||||
    r1 = nginxproxy.get("http://loadbalance-disabled.nginx-proxy.tld")
 | 
			
		||||
    r2 = nginxproxy.get("http://loadbalance-disabled.nginx-proxy.tld")
 | 
			
		||||
    assert r1.status_code == 200
 | 
			
		||||
    assert r2.text != r1.text
 | 
			
		||||
@@ -1,27 +1,27 @@
 | 
			
		||||
services:
 | 
			
		||||
  loadbalance-hash:
 | 
			
		||||
    image: web
 | 
			
		||||
    expose:
 | 
			
		||||
      - "81"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 81
 | 
			
		||||
      VIRTUAL_HOST: loadbalance-enabled.nginx-proxy.tld
 | 
			
		||||
    labels:
 | 
			
		||||
      com.github.nginx-proxy.nginx-proxy.loadbalance: "hash $$remote_addr;"
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 2
 | 
			
		||||
 | 
			
		||||
  loadbalance-roundrobin:
 | 
			
		||||
    image: web
 | 
			
		||||
    expose:
 | 
			
		||||
      - "82"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: 82
 | 
			
		||||
      VIRTUAL_HOST: loadbalance-disabled.nginx-proxy.tld
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 2
 | 
			
		||||
 | 
			
		||||
  sut:
 | 
			
		||||
    image: nginxproxy/nginx-proxy:test
 | 
			
		||||
    volumes:
 | 
			
		||||
      - /var/run/docker.sock:/tmp/docker.sock:ro
 | 
			
		||||
services:
 | 
			
		||||
  loadbalance-hash:
 | 
			
		||||
    image: web
 | 
			
		||||
    expose:
 | 
			
		||||
      - "81"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: "81"
 | 
			
		||||
      VIRTUAL_HOST: loadbalance-enabled.nginx-proxy.tld
 | 
			
		||||
    labels:
 | 
			
		||||
      com.github.nginx-proxy.nginx-proxy.loadbalance: "hash $$remote_addr;"
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 2
 | 
			
		||||
 | 
			
		||||
  loadbalance-roundrobin:
 | 
			
		||||
    image: web
 | 
			
		||||
    expose:
 | 
			
		||||
      - "82"
 | 
			
		||||
    environment:
 | 
			
		||||
      WEB_PORTS: "82"
 | 
			
		||||
      VIRTUAL_HOST: loadbalance-disabled.nginx-proxy.tld
 | 
			
		||||
    deploy:
 | 
			
		||||
      replicas: 2
 | 
			
		||||
 | 
			
		||||
  sut:
 | 
			
		||||
    image: nginxproxy/nginx-proxy:test
 | 
			
		||||
    volumes:
 | 
			
		||||
      - /var/run/docker.sock:/tmp/docker.sock:ro
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user