This commit is contained in:
Thomas LÉVEIL 2017-06-22 17:46:53 +00:00 committed by GitHub
commit c4576d49e9
17 changed files with 216 additions and 75 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
**/__pycache__/
**/.cache/
*.pyc

View file

@ -135,13 +135,17 @@ First start nginx with a volume:
$ docker run -d -p 80:80 --name nginx -v /tmp/nginx:/etc/nginx/conf.d -t nginx
Then start the docker-gen container with the shared volume and template:
Then start the docker-gen container with:
- the `NGINX_CONTAINER` environment variable set to the name of the container running nginx
- the shared volume
- the template
```
$ docker run --volumes-from nginx \
-e NGINX_CONTAINER=nginx \
-v /var/run/docker.sock:/tmp/docker.sock:ro \
-v $(pwd):/etc/docker-gen/templates \
-t jwilder/docker-gen -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
-t jwilder/docker-gen -notify-sighup nginx -only-exposed -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
```
Finally, start your containers with `VIRTUAL_HOST` environment variables.

View file

@ -10,12 +10,14 @@ services:
dockergen:
image: jwilder/docker-gen
command: -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
command: -notify-sighup nginx -only-exposed -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
volumes_from:
- nginx
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl
environment:
- NGINX_CONTAINER=nginx
whoami:
image: jwilder/whoami

View file

@ -1,4 +1,23 @@
{{ $CurrentContainer := where $ "ID" .Docker.CurrentContainerID | first }}
{{ $NginxContainerName := coalesce $.Env.NGINX_CONTAINER $CurrentContainer.Name }}
{{ $NginxContainer := where $ "Name" $NginxContainerName | first }}
# -----------------------------------------------------------------------------
# $.Env.NGINX_CONTAINER: {{ $.Env.NGINX_CONTAINER }}
# Docker-gen container name: {{ $CurrentContainer.Name }}
# Nginx container name: {{ $NginxContainerName }}
# Nginx container found: {{ if $NginxContainer }}yes{{ else }}no{{ end }}
# Nginx networks: {{ json $NginxContainer.Networks }}
# -----------------------------------------------------------------------------
{{ if not $NginxContainer }}
###############################################################################
# #
# Could not determine which container is running nginx. #
# Make sure to provide a correct value for the `NGINX_CONTAINER` environment #
# variable. #
# #
###############################################################################
{{ end }}
{{ define "upstream" }}
{{ if .Address }}
@ -110,7 +129,7 @@ upstream {{ $upstream_name }} {
{{ range $container := $containers }}
{{ $addrLen := len $container.Addresses }}
{{ range $knownNetwork := $CurrentContainer.Networks }}
{{ range $knownNetwork := $NginxContainer.Networks }}
{{ range $containerNetwork := $container.Networks }}
{{ if or (eq $knownNetwork.Name $containerNetwork.Name) (eq $knownNetwork.Name "host") }}
## Can be connect with "{{ $containerNetwork.Name }}" network
@ -273,6 +292,5 @@ server {
ssl_certificate_key /etc/nginx/certs/default.key;
}
{{ end }}
{{ end }}
{{ end }}

1
test/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/nginx.tmpl

View file

@ -47,6 +47,7 @@ This test suite uses [pytest](http://doc.pytest.org/en/latest/). The [conftest.p
- docker_compose
- nginxproxy
- nginx_tmpl
### docker_compose fixture
@ -96,6 +97,10 @@ Furthermore, the nginxproxy methods accept an additional keyword parameter: `ipv
assert r.text == "answer from port 81\n"
### nginx_tmpl fixture
The `nginx_tmpl` fixture extracts the `nginx.tmpl` template file from the `jwilder/nginx-proxy:test` image and copy it into the `test` directory. This is useful for tests which requires to mount the template file into a container as a volume.
### The web docker image

View file

@ -370,7 +370,8 @@ def disconnect_from_network(network=None):
def connect_to_all_networks():
"""
If we are running from a container, connect our container to all current docker networks.
If we are running from a container, connect our container to all current docker networks but the 'bridge' and
'none' networks.
:return: a list of networks we connected to
"""
@ -378,7 +379,7 @@ def connect_to_all_networks():
return []
else:
# find the list of docker networks
networks = filter(lambda network: len(network.containers) > 0 and network.name != 'bridge', docker_client.networks.list())
networks = filter(lambda network: len(network.containers) > 0 and network.name not in ('bridge', 'none'), docker_client.networks.list())
return [connect_to_network(network) for network in networks]
@ -429,6 +430,27 @@ def nginxproxy():
yield requests_for_docker()
@pytest.yield_fixture(scope="module")
def nginx_tmpl():
"""
pytest fixture which extracts the the nginx config template from
the jwilder/nginx-proxy:test image into the test directory
"""
script_dir = os.path.dirname(__file__)
logging.info("extracting nginx.tmpl from jwilder/nginx-proxy:test")
print(docker_client.containers.run(
image='jwilder/nginx-proxy:test',
remove=True,
volumes=['{current_dir}:{current_dir}'.format(current_dir=script_dir)],
entrypoint='sh',
command='-xc "cp /app/nginx.tmpl {current_dir} && chmod 777 {current_dir}/nginx.tmpl"'.format(
current_dir=script_dir),
stderr=True))
yield os.path.join(script_dir, 'nginx.tmpl')
logging.info("removing nginx.tmpl")
os.remove(os.path.join(script_dir, "nginx.tmpl"))
###############################################################################
#
# Py.test hooks

View file

@ -1 +0,0 @@
nginx.tmpl

View file

@ -1,38 +0,0 @@
import os
import docker
import logging
import pytest
@pytest.yield_fixture(scope="module")
def nginx_tmpl():
"""
pytest fixture which extracts the the nginx config template from
the jwilder/nginx-proxy:test image
"""
script_dir = os.path.dirname(__file__)
logging.info("extracting nginx.tmpl from jwilder/nginx-proxy:test")
docker_client = docker.from_env()
print(docker_client.containers.run(
image='jwilder/nginx-proxy:test',
remove=True,
volumes=['{current_dir}:{current_dir}'.format(current_dir=script_dir)],
entrypoint='sh',
command='-xc "cp /app/nginx.tmpl {current_dir} && chmod 777 {current_dir}/nginx.tmpl"'.format(
current_dir=script_dir),
stderr=True))
yield
logging.info("removing nginx.tmpl")
os.remove(os.path.join(script_dir, "nginx.tmpl"))
def test_unknown_virtual_host_is_503(nginx_tmpl, docker_compose, nginxproxy):
r = nginxproxy.get("http://unknown.nginx.container.docker/")
assert r.status_code == 503
def test_forwards_to_whoami(nginx_tmpl, docker_compose, nginxproxy):
r = nginxproxy.get("http://whoami.nginx.container.docker/")
assert r.status_code == 200
whoami_container = docker_compose.containers.get("whoami")
assert r.text == "I'm %s\n" % whoami_container.id[:12]

View file

@ -0,0 +1,18 @@
from time import sleep
def test_nginx_is_running(nginx_tmpl, docker_compose):
sleep(3)
assert docker_compose.containers.get("nginx").status == "running"
def test_unknown_virtual_host_is_503(nginx_tmpl, docker_compose, nginxproxy):
r = nginxproxy.get("http://unknown.nginx.container.docker/")
assert r.status_code == 503
def test_forwards_to_whoami(nginx_tmpl, docker_compose, nginxproxy):
r = nginxproxy.get("http://whoami.nginx.container.docker/")
assert r.status_code == 200
whoami_container = docker_compose.containers.get("whoami")
assert r.text == "I'm %s\n" % whoami_container.id[:12]

View file

@ -14,7 +14,7 @@ services:
- nginx
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl
- ../nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl
web:
image: web

View file

@ -1,6 +1,5 @@
import os
from time import sleep
import docker
import logging
import pytest
@ -27,26 +26,9 @@ pytestmark = pytest.mark.skipif(
reason="Docker compose syntax v3 requires docker engine v1.13 or later (got %s)" % raw_version)
@pytest.yield_fixture(scope="module")
def nginx_tmpl():
"""
pytest fixture which extracts the the nginx config template from
the jwilder/nginx-proxy:test image
"""
script_dir = os.path.dirname(__file__)
logging.info("extracting nginx.tmpl from jwilder/nginx-proxy:test")
docker_client = docker.from_env()
print(docker_client.containers.run(
image='jwilder/nginx-proxy:test',
remove=True,
volumes=['{current_dir}:{current_dir}'.format(current_dir=script_dir)],
entrypoint='sh',
command='-xc "cp /app/nginx.tmpl {current_dir} && chmod 777 {current_dir}/nginx.tmpl"'.format(
current_dir=script_dir),
stderr=True))
yield
logging.info("removing nginx.tmpl")
os.remove(os.path.join(script_dir, "nginx.tmpl"))
def test_nginx_is_running(nginx_tmpl, docker_compose):
sleep(3)
assert docker_compose.containers.get("nginx").status == "running"
def test_unknown_virtual_host_is_503(nginx_tmpl, docker_compose, nginxproxy):
@ -59,8 +41,3 @@ def test_forwards_to_whoami(nginx_tmpl, docker_compose, nginxproxy):
assert r.status_code == 200
whoami_container = docker_compose.containers.get("whoami")
assert r.text == "I'm %s\n" % whoami_container.id[:12]
if __name__ == '__main__':
import doctest
doctest.testmod()

View file

@ -1,4 +1,5 @@
version: '3'
services:
nginx:
image: nginx
@ -11,7 +12,7 @@ services:
command: -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl
- ../nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl
- nginx_conf:/etc/nginx/conf.d
web:

View file

@ -0,0 +1,18 @@
from time import sleep
def test_nginx_is_running(nginx_tmpl, docker_compose):
sleep(3)
assert docker_compose.containers.get("nginx").status == "running"
def test_unknown_virtual_host_is_503(nginx_tmpl, docker_compose, nginxproxy):
r = nginxproxy.get("http://unknown.nginx.container.docker/")
assert r.status_code == 503
def test_forwards_to_whoami(nginx_tmpl, docker_compose, nginxproxy):
r = nginxproxy.get("http://whoami.nginx.container.docker/")
assert r.status_code == 200
whoami_container = docker_compose.containers.get("whoami")
assert r.text == "I'm %s\n" % whoami_container.id[:12]

View file

@ -0,0 +1,50 @@
# In this compose file, we define a dockergen container which has no network.
# This should not be an issue since the docker-gen process is not binding to any port or isn't making any
# network connection to any other container.
---
version: '2'
networks:
nginx-net: {}
volumes:
nginx_conf: {}
nginx_certs: {}
services:
nginx:
image: nginx
container_name: nginx
volumes:
- nginx_conf:/etc/nginx/conf.d
- nginx_certs:/etc/nginx/certs
networks:
- nginx-net
dockergen:
image: jwilder/docker-gen
command: -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
volumes_from:
- nginx
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- nginx_conf:/etc/nginx/conf.d
- nginx_certs:/etc/nginx/certs
- ../nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl
environment:
NGINX_CONTAINER: nginx
networks: []
web:
image: web
container_name: whoami
expose:
- "80"
environment:
WEB_PORTS: 80
VIRTUAL_HOST: whoami.nginx.container.docker
networks:
- nginx-net

View file

@ -0,0 +1,18 @@
from time import sleep
def test_nginx_is_running(nginx_tmpl, docker_compose):
sleep(3)
assert docker_compose.containers.get("nginx").status == "running"
def test_unknown_virtual_host_is_503(nginx_tmpl, docker_compose, nginxproxy):
r = nginxproxy.get("http://unknown.nginx.container.docker/")
assert r.status_code == 503
def test_forwards_to_whoami(nginx_tmpl, docker_compose, nginxproxy):
r = nginxproxy.get("http://whoami.nginx.container.docker/")
assert r.status_code == 200
whoami_container = docker_compose.containers.get("whoami")
assert r.text == "I'm %s\n" % whoami_container.id[:12]

View file

@ -0,0 +1,45 @@
# In this compose file we define a dockergen container which is running the docker-gen process with the
# `-only-exposed` option. This should not be an issue since the template for the nginx config file should only
# have to deal with upstream containers which are required to have at least one port exposed, and since the nginx
# container with no exposed port makes no sense.
---
version: '2'
networks:
default: {}
volumes:
nginx_conf: {}
nginx_certs: {}
services:
nginx:
image: nginx
container_name: nginx
volumes:
- nginx_conf:/etc/nginx/conf.d
- nginx_certs:/etc/nginx/certs
dockergen:
image: jwilder/docker-gen
command: -notify-sighup nginx -only-exposed -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
volumes_from:
- nginx
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- nginx_conf:/etc/nginx/conf.d
- nginx_certs:/etc/nginx/certs
- ../nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl
environment:
NGINX_CONTAINER: nginx
web:
image: web
container_name: whoami
expose:
- "80"
environment:
WEB_PORTS: 80
VIRTUAL_HOST: whoami.nginx.container.docker