From 3954774d65454cf4298b6f288698520dd1c2302b Mon Sep 17 00:00:00 2001 From: Brian Prodoehl Date: Tue, 19 May 2015 16:16:50 -0400 Subject: [PATCH 01/55] Fix a couple things in the README. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index de16e0c..e4cfac3 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ Then start the docker-gen container with the shared volume and template: $ docker run --volumes-from nginx \ -v /var/run/docker.sock:/tmp/docker.sock \ -v $(pwd):/etc/docker-gen/templates \ - -t docker-gen -notify-sighup nginx -watch -only-published /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf + -t jwilder/docker-gen -notify-sighup nginx -watch -only-exposed /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf ``` Finally, start your containers with `VIRTUAL_HOST` environment variables. From a10d1b50bf7859d5b2c156c7a2a75192b12541d1 Mon Sep 17 00:00:00 2001 From: Kuo-Cheng Yeu Date: Thu, 21 May 2015 15:19:58 +0800 Subject: [PATCH 02/55] add support for ssl_dhparams to prevent 'Logjam' attack --- nginx.tmpl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nginx.tmpl b/nginx.tmpl index e7a4542..50574c4 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -105,6 +105,10 @@ server { ssl_certificate /etc/nginx/certs/{{ (printf "%s.crt" $cert) }}; ssl_certificate_key /etc/nginx/certs/{{ (printf "%s.key" $cert) }}; + {{ if (exists (printf "/etc/nginx/certs/%s.dhparams.pem" $cert)) }} + ssl_dhparam {{ printf "/etc/nginx/certs/%s.dhparams.pem" $cert }}; + {{ end }} + add_header Strict-Transport-Security "max-age=31536000"; {{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }} From da0191a778443692745845add08b1ff39d10b368 Mon Sep 17 00:00:00 2001 From: Kuo-Cheng Yeu Date: Thu, 21 May 2015 15:37:19 +0800 Subject: [PATCH 03/55] add 'Diffie-Hellman Groups' section in README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index e4cfac3..b078315 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,12 @@ hosts in use. The certificate and keys should be named after the virtual host w `.key` extension. For example, a container with `VIRTUAL_HOST=foo.bar.com` should have a `foo.bar.com.crt` and `foo.bar.com.key` file in the certs directory. +#### Diffie-Hellman Groups + +If you have Diffie-Hellman groups enabled, the files should be named after the virtual host with a +`dhparams` suffix and `.pem` extension. For example, a container with `VIRTUAL_HOST=foo.bar.com` +should have a `foo.bar.com.dhparams.pem` file in the certs directory. + #### Wildcard Certificates Wildcard certificates and keys should be name after the domain name with a `.crt` and `.key` extension. From d74a4146c82e14664bf7da80260b6e3a01be8276 Mon Sep 17 00:00:00 2001 From: Kuo-Cheng Yeu Date: Thu, 21 May 2015 23:43:09 +0800 Subject: [PATCH 04/55] fix indention, and file nameing --- README.md | 4 ++-- nginx.tmpl | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b078315..8bab1ec 100644 --- a/README.md +++ b/README.md @@ -86,8 +86,8 @@ hosts in use. The certificate and keys should be named after the virtual host w #### Diffie-Hellman Groups If you have Diffie-Hellman groups enabled, the files should be named after the virtual host with a -`dhparams` suffix and `.pem` extension. For example, a container with `VIRTUAL_HOST=foo.bar.com` -should have a `foo.bar.com.dhparams.pem` file in the certs directory. +`dhparam` suffix and `.pem` extension. For example, a container with `VIRTUAL_HOST=foo.bar.com` +should have a `foo.bar.com.dhparam.pem` file in the certs directory. #### Wildcard Certificates diff --git a/nginx.tmpl b/nginx.tmpl index 50574c4..f674b49 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -105,9 +105,9 @@ server { ssl_certificate /etc/nginx/certs/{{ (printf "%s.crt" $cert) }}; ssl_certificate_key /etc/nginx/certs/{{ (printf "%s.key" $cert) }}; - {{ if (exists (printf "/etc/nginx/certs/%s.dhparams.pem" $cert)) }} - ssl_dhparam {{ printf "/etc/nginx/certs/%s.dhparams.pem" $cert }}; - {{ end }} + {{ if (exists (printf "/etc/nginx/certs/%s.dhparam.pem" $cert)) }} + ssl_dhparam {{ printf "/etc/nginx/certs/%s.dhparam.pem" $cert }}; + {{ end }} add_header Strict-Transport-Security "max-age=31536000"; From 6719f7636fc63a9d4f4fc349aae03e2fe9a15a45 Mon Sep 17 00:00:00 2001 From: Ryan Trauntvein Date: Fri, 5 Jun 2015 10:24:45 -0700 Subject: [PATCH 05/55] Encourage using read-only mount for docker.sock --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 8bab1ec..68b22f1 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ See [Automated Nginx Reverse Proxy for Docker][2] for why you might want to use To run it: - $ docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock jwilder/nginx-proxy + $ docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy Then start any containers you want proxied with an env var `VIRTUAL_HOST=subdomain.youdomain.com` @@ -39,7 +39,7 @@ If you would like to connect to your backend using HTTPS instead of HTTP, set `V To set the default host for nginx use the env var `DEFAULT_HOST=foo.bar.com` for example - $ docker run -d -p 80:80 -e DEFAULT_HOST=foo.bar.com -v /var/run/docker.sock:/tmp/docker.sock jwilder/nginx-proxy + $ docker run -d -p 80:80 -e DEFAULT_HOST=foo.bar.com -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy ### Separate Containers @@ -60,7 +60,7 @@ Then start the docker-gen container with the shared volume and template: ``` $ docker run --volumes-from nginx \ - -v /var/run/docker.sock:/tmp/docker.sock \ + -v /var/run/docker.sock:/tmp/docker.sock:ro \ -v $(pwd):/etc/docker-gen/templates \ -t jwilder/docker-gen -notify-sighup nginx -watch -only-exposed /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf ``` @@ -76,7 +76,7 @@ certificates or optionally specifying a cert name (for SNI) as an environment va To enable SSL: - $ docker run -d -p 80:80 -p 443:443 -v /path/to/certs:/etc/nginx/certs -v /var/run/docker.sock:/tmp/docker.sock jwilder/nginx-proxy + $ docker run -d -p 80:80 -p 443:443 -v /path/to/certs:/etc/nginx/certs -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy The contents of `/path/to/certs` should contain the certificates and private keys for any virtual hosts in use. The certificate and keys should be named after the virtual host with a `.crt` and @@ -128,7 +128,7 @@ In order to be able to securize your virtual host, you have to create a file nam $ docker run -d -p 80:80 -p 443:443 \ -v /path/to/htpasswd:/etc/nginx/htpasswd \ -v /path/to/certs:/etc/nginx/certs \ - -v /var/run/docker.sock:/tmp/docker.sock \ + -v /var/run/docker.sock:/tmp/docker.sock:ro \ jwilder/nginx-proxy ``` @@ -154,7 +154,7 @@ RUN { \ Or it can be done by mounting in your custom configuration in your `docker run` command: - $ docker run -d -p 80:80 -p 443:443 -v /path/to/my_proxy.conf:/etc/nginx/conf.d/my_proxy.conf:ro -v /var/run/docker.sock:/tmp/docker.sock jwilder/nginx-proxy + $ docker run -d -p 80:80 -p 443:443 -v /path/to/my_proxy.conf:/etc/nginx/conf.d/my_proxy.conf:ro -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy #### Per-VIRTUAL_HOST @@ -164,7 +164,7 @@ In order to allow virtual hosts to be dynamically configured as backends are add For example, if you have a virtual host named `app.example.com`, you could provide a custom configuration for that host as follows: - $ docker run -d -p 80:80 -p 443:443 -v /path/to/vhost.d:/etc/nginx/vhost.d:ro -v /var/run/docker.sock:/tmp/docker.sock jwilder/nginx-proxy + $ docker run -d -p 80:80 -p 443:443 -v /path/to/vhost.d:/etc/nginx/vhost.d:ro -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy $ { echo 'server_tokens off;'; echo 'client_max_body_size 100m;'; } > /path/to/vhost.d/app.example.com If you are using multiple hostnames for a single container (e.g. `VIRTUAL_HOST=example.com,www.example.com`), the virtual host configuration file must exist for each hostname. If you would like to use the same configuration for multiple virtual host names, you can use a symlink: From 89fe2a38984e080edca90ed8cca37fa420b5a631 Mon Sep 17 00:00:00 2001 From: Joseph Page Date: Sat, 20 Jun 2015 22:25:52 +0200 Subject: [PATCH 06/55] Update to nginx 1.9.2 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 8179d97..1b90965 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM nginx:1.9.0 +FROM nginx:1.9.2 MAINTAINER Jason Wilder jwilder@litl.com # Install wget and install/updates certificates From f36ca3d7a37d6bcd148c6b5e2e77f446fe9b470c Mon Sep 17 00:00:00 2001 From: Mike Dillon Date: Tue, 23 Jun 2015 17:05:12 -0700 Subject: [PATCH 07/55] Prevent generating broken config Fixes #115 --- Dockerfile | 2 +- nginx.tmpl | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1b90965..abfae74 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,7 @@ RUN echo "daemon off;" >> /etc/nginx/nginx.conf \ RUN wget -P /usr/local/bin https://godist.herokuapp.com/projects/ddollar/forego/releases/current/linux-amd64/forego \ && chmod u+x /usr/local/bin/forego -ENV DOCKER_GEN_VERSION 0.3.9 +ENV DOCKER_GEN_VERSION 0.4.0 RUN wget https://github.com/jwilder/docker-gen/releases/download/$DOCKER_GEN_VERSION/docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \ && tar -C /usr/local/bin -xvzf docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \ diff --git a/nginx.tmpl b/nginx.tmpl index f674b49..70c8ba0 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -58,11 +58,13 @@ upstream {{ $host }} { {{ end }} {{/* Else default to standard web port 80 */}} {{ else }} - {{ range $address := $container.Addresses }} - {{ if eq $address.Port "80" }} + {{ $address := where $container.Addresses "Port" "80" | first }} + {{ if $address }} # {{$container.Name}} - server {{ $address.IP }}:{{ $address.Port }}; - {{ end }} + server {{ $address.IP }}:80; + {{ else }} + # {{$container.Name}} + server {{ $container.IP }} down; {{ end }} {{ end }} {{ end }} From c4923d1f58159088edbe35723a3d6276cdac47c5 Mon Sep 17 00:00:00 2001 From: Viranch Mehta Date: Sat, 4 Jul 2015 18:43:52 +0530 Subject: [PATCH 08/55] Use container host's IP:port if we're connected to a swarm master --- nginx.tmpl | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index 70c8ba0..8f079e4 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -44,24 +44,40 @@ upstream {{ $host }} { {{ $addrLen := len $container.Addresses }} {{/* If only 1 port exposed, use that */}} {{ if eq $addrLen 1 }} - {{ with $address := index $container.Addresses 0 }} - # {{$container.Name}} - server {{ $address.IP }}:{{ $address.Port }}; + {{ $address := index $container.Addresses 0 }} + {{/* If we got the containers from swarm and this container's port is published to host, use host IP:PORT */}} + {{ if and $container.Node $address.HostPort }} + # {{ $container.Node.Name }}/{{$container.Name}} + server {{ $container.Node.Address.IP }}:{{ $address.HostPort }}; + {{/* If there is no swarm node or the port is not published on host, use container's IP:PORT */}} + {{ else }} + # {{$container.Name}} + server {{ $address.IP }}:{{ $address.Port }}; {{ end }} {{/* If more than one port exposed, use the one matching VIRTUAL_PORT env var */}} {{ else if $container.Env.VIRTUAL_PORT }} {{ range $address := .Addresses }} {{ if eq $address.Port $container.Env.VIRTUAL_PORT }} - # {{$container.Name}} - server {{ $address.IP }}:{{ $address.Port }}; + {{ if and $container.Node $address.HostPort }} + # {{ $container.Node.Name }}/{{$container.Name}} + server {{ $container.Node.Address.IP }}:{{ $address.HostPort }}; + {{ else }} + # {{$container.Name}} + server {{ $address.IP }}:{{ $address.Port }}; + {{ end }} {{ end }} {{ end }} {{/* Else default to standard web port 80 */}} {{ else }} {{ $address := where $container.Addresses "Port" "80" | first }} {{ if $address }} - # {{$container.Name}} - server {{ $address.IP }}:80; + {{ if and $container.Node $address.HostPort }} + # {{ $container.Node.Name }}/{{$container.Name}} + server {{ $container.Node.Address.IP }}:{{ $address.HostPort }}; + {{ else }} + # {{$container.Name}} + server {{ $address.IP }}:80; + {{ end }} {{ else }} # {{$container.Name}} server {{ $container.IP }} down; From dece1e8ef4ea45e6efea763713513b1f68cbe503 Mon Sep 17 00:00:00 2001 From: Russ Ferriday Date: Tue, 7 Jul 2015 11:07:45 +0100 Subject: [PATCH 09/55] Trivial text improvements --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 68b22f1..3dcd67d 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ a 503. ### Basic Authentication Support -In order to be able to securize your virtual host, you have to create a file named as its equivalent VIRTUAL_HOST variable on directory +In order to be able to secure your virtual host, you have to create a file named as its equivalent VIRTUAL_HOST variable on directory /etc/nginx/htpasswd/$VIRTUAL_HOST ``` @@ -132,7 +132,7 @@ $ docker run -d -p 80:80 -p 443:443 \ jwilder/nginx-proxy ``` -You'll need apache2-utils on the machine you plan to create de htpasswd file. Follow these [instructions](http://httpd.apache.org/docs/2.2/programs/htpasswd.html) +You'll need apache2-utils on the machine where you plan to create the htpasswd file. Follow these [instructions](http://httpd.apache.org/docs/2.2/programs/htpasswd.html) ### Custom Nginx Configuration From 784507df1a3200ca9d4c9840e58992f45a3ee5b9 Mon Sep 17 00:00:00 2001 From: Viranch Mehta Date: Sat, 11 Jul 2015 01:19:44 +0530 Subject: [PATCH 10/55] Cascade two else blocks into one using coalesce on VIRTUAL_PORT and 80 This also takes care of the case when VIRTUAL_PORT is not actually exposed. --- nginx.tmpl | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index 8f079e4..147ee05 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -54,29 +54,17 @@ upstream {{ $host }} { # {{$container.Name}} server {{ $address.IP }}:{{ $address.Port }}; {{ end }} - {{/* If more than one port exposed, use the one matching VIRTUAL_PORT env var */}} - {{ else if $container.Env.VIRTUAL_PORT }} - {{ range $address := .Addresses }} - {{ if eq $address.Port $container.Env.VIRTUAL_PORT }} - {{ if and $container.Node $address.HostPort }} - # {{ $container.Node.Name }}/{{$container.Name}} - server {{ $container.Node.Address.IP }}:{{ $address.HostPort }}; - {{ else }} - # {{$container.Name}} - server {{ $address.IP }}:{{ $address.Port }}; - {{ end }} - {{ end }} - {{ end }} - {{/* Else default to standard web port 80 */}} + {{/* If more than one port exposed, use the one matching VIRTUAL_PORT env var, falling back to standard web port 80 */}} {{ else }} - {{ $address := where $container.Addresses "Port" "80" | first }} + {{ $port := coalesce $container.Env.VIRTUAL_PORT "80" }} + {{ $address := where $container.Addresses "Port" $port | first }} {{ if $address }} {{ if and $container.Node $address.HostPort }} # {{ $container.Node.Name }}/{{$container.Name}} server {{ $container.Node.Address.IP }}:{{ $address.HostPort }}; {{ else }} # {{$container.Name}} - server {{ $address.IP }}:80; + server {{ $address.IP }}:{{ $address.Port }}; {{ end }} {{ else }} # {{$container.Name}} From 4f5351265ab47111169a8f56b897bac999f86ff6 Mon Sep 17 00:00:00 2001 From: Viranch Mehta Date: Wed, 15 Jul 2015 20:51:10 +0530 Subject: [PATCH 11/55] Use define & template for re-usable blocks of upstream server template --- nginx.tmpl | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index 147ee05..92a203c 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -1,3 +1,20 @@ +{{ define "upstream" }} + {{ if .Address }} + {{/* If we got the containers from swarm and this container's port is published to host, use host IP:PORT */}} + {{ if and .Container.Node.ID .Address.HostPort }} + # {{ .Container.Node.Name }}/{{ .Container.Name }} + server {{ .Container.Node.Address.IP }}:{{ .Address.HostPort }}; + {{/* If there is no swarm node or the port is not published on host, use container's IP:PORT */}} + {{ else }} + # {{ .Container.Name }} + server {{ .Address.IP }}:{{ .Address.Port }}; + {{ end }} + {{ else }} + # {{ .Container.Name }} + server {{ .Container.IP }} down; + {{ end }} +{{ end }} + # If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the # scheme used to connect to this server map $http_x_forwarded_proto $proxy_x_forwarded_proto { @@ -45,31 +62,12 @@ upstream {{ $host }} { {{/* If only 1 port exposed, use that */}} {{ if eq $addrLen 1 }} {{ $address := index $container.Addresses 0 }} - {{/* If we got the containers from swarm and this container's port is published to host, use host IP:PORT */}} - {{ if and $container.Node $address.HostPort }} - # {{ $container.Node.Name }}/{{$container.Name}} - server {{ $container.Node.Address.IP }}:{{ $address.HostPort }}; - {{/* If there is no swarm node or the port is not published on host, use container's IP:PORT */}} - {{ else }} - # {{$container.Name}} - server {{ $address.IP }}:{{ $address.Port }}; - {{ end }} + {{ template "upstream" (dict "Container" $container "Address" $address) }} {{/* If more than one port exposed, use the one matching VIRTUAL_PORT env var, falling back to standard web port 80 */}} {{ else }} {{ $port := coalesce $container.Env.VIRTUAL_PORT "80" }} {{ $address := where $container.Addresses "Port" $port | first }} - {{ if $address }} - {{ if and $container.Node $address.HostPort }} - # {{ $container.Node.Name }}/{{$container.Name}} - server {{ $container.Node.Address.IP }}:{{ $address.HostPort }}; - {{ else }} - # {{$container.Name}} - server {{ $address.IP }}:{{ $address.Port }}; - {{ end }} - {{ else }} - # {{$container.Name}} - server {{ $container.IP }} down; - {{ end }} + {{ template "upstream" (dict "Container" $container "Address" $address) }} {{ end }} {{ end }} } From abb42bbc52f834307295d071c2a201ece0cc1b17 Mon Sep 17 00:00:00 2001 From: Jason Wilder Date: Thu, 16 Jul 2015 16:55:54 -0600 Subject: [PATCH 12/55] Update nginx badge to 1.9.2 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3dcd67d..b144796 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![nginx 1.9.0](https://img.shields.io/badge/nginx-1.9.0-brightgreen.svg) ![License MIT](https://img.shields.io/badge/license-MIT-blue.svg) +![nginx 1.9.2](https://img.shields.io/badge/nginx-1.9.2-brightgreen.svg) ![License MIT](https://img.shields.io/badge/license-MIT-blue.svg) nginx-proxy sets up a container running nginx and [docker-gen][1]. docker-gen generates reverse proxy configs for nginx and reloads nginx when containers are started and stopped. From e1c685b679ad29c7617972adb3329348ec0881a4 Mon Sep 17 00:00:00 2001 From: Jason Wilder Date: Mon, 20 Jul 2015 10:05:01 -0600 Subject: [PATCH 13/55] Update boot2docker instructions --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index b144796..d55cd39 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,11 @@ Then start any containers you want proxied with an env var `VIRTUAL_HOST=subdoma Provided your DNS is setup to forward foo.bar.com to the a host running nginx-proxy, the request will be routed to a container with the VIRTUAL_HOST env var set. +If your are using `boot2docker` start `nginx-proxy` with: + + $ $(boot2docker shellinit) + $ docker run -p 80:80 -e DOCKER_HOST -e DOCKER_CERT_PATH -e DOCKER_TLS_VERIFY -v $DOCKER_CERT_PATH:$DOCKER_CERT_PATH -it jwilder/nginx-proxy + ### Multiple Ports If your container exposes multiple ports, nginx-proxy will default to the service running on port 80. If you need to specify a different port, you can set a VIRTUAL_PORT env var to select a different one. If your container only exposes one port and it has a VIRTUAL_HOST env var set, that port will be selected. From b0647dd5e9676cac84b3ef0be605ca186c198a68 Mon Sep 17 00:00:00 2001 From: Wolfgang Ebner Date: Fri, 24 Jul 2015 10:39:56 +0200 Subject: [PATCH 14/55] set default_server also for https --- nginx.tmpl | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index 92a203c..2c8afa0 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -49,8 +49,8 @@ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; server { - listen 80; server_name _; # This is just an invalid value which will never trigger on a real hostname. + listen 80; return 503; } @@ -72,6 +72,8 @@ upstream {{ $host }} { {{ end }} } +{{ $default_server := and ($.Env.DEFAULT_HOST) (eq $.Env.DEFAULT_HOST $host) }} + {{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost, falling back to "http" */}} {{ $proto := or (first (groupByKeys $containers "Env.VIRTUAL_PROTO")) "http" }} @@ -92,12 +94,13 @@ upstream {{ $host }} { server { server_name {{ $host }}; + listen 80 {{ if $default_server }}default_server{{ end }}; return 301 https://$host$request_uri; } server { server_name {{ $host }}; - listen 443 ssl spdy; + listen 443 ssl spdy {{ if $default_server }}default_server{{ end }}; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA; @@ -130,16 +133,8 @@ server { {{ else }} server { - {{ if $.Env.DEFAULT_HOST }} - {{ if eq $.Env.DEFAULT_HOST $host }} - listen 80 default_server; - server_name {{ $host }}; - {{ else }} - server_name {{ $host }}; - {{ end }} - {{ else }} - server_name {{ $host }}; - {{ end }} + server_name {{ $host }}; + listen 80 {{ if $default_server }}default_server{{ end }}; {{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }} include {{ printf "/etc/nginx/vhost.d/%s" $host }}; @@ -157,7 +152,7 @@ server { {{ if (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }} server { server_name {{ $host }}; - listen 443 ssl spdy; + listen 443 ssl spdy {{ if $default_server }}default_server{{ end }}; return 503; ssl_certificate /etc/nginx/certs/default.crt; From 6965b1ead421340cae410d0672a680458f2b7a2a Mon Sep 17 00:00:00 2001 From: Wolfgang Ebner Date: Sun, 26 Jul 2015 11:38:45 +0200 Subject: [PATCH 15/55] fallback when DEFAULT_HOST is not set --- nginx.tmpl | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index 2c8afa0..b4140f9 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -72,7 +72,8 @@ upstream {{ $host }} { {{ end }} } -{{ $default_server := and ($.Env.DEFAULT_HOST) (eq $.Env.DEFAULT_HOST $host) }} +{{ $default_host := or ($.Env.DEFAULT_HOST) "" }} +{{ $default_server := index (dict $host "" $default_host "default_server") $host }} {{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost, falling back to "http" */}} {{ $proto := or (first (groupByKeys $containers "Env.VIRTUAL_PROTO")) "http" }} @@ -94,13 +95,13 @@ upstream {{ $host }} { server { server_name {{ $host }}; - listen 80 {{ if $default_server }}default_server{{ end }}; + listen 80 {{ $default_server }}; return 301 https://$host$request_uri; } server { server_name {{ $host }}; - listen 443 ssl spdy {{ if $default_server }}default_server{{ end }}; + listen 443 ssl spdy {{ $default_server }}; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA; @@ -134,7 +135,7 @@ server { server { server_name {{ $host }}; - listen 80 {{ if $default_server }}default_server{{ end }}; + listen 80 {{ $default_server }}; {{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }} include {{ printf "/etc/nginx/vhost.d/%s" $host }}; @@ -152,7 +153,7 @@ server { {{ if (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }} server { server_name {{ $host }}; - listen 443 ssl spdy {{ if $default_server }}default_server{{ end }}; + listen 443 ssl spdy {{ $default_server }}; return 503; ssl_certificate /etc/nginx/certs/default.crt; From 2eff96969ab47c2828fc9bb9dbbb359a75df9249 Mon Sep 17 00:00:00 2001 From: Richard Bateman Date: Fri, 14 Aug 2015 11:29:44 -0600 Subject: [PATCH 16/55] Add support for overriding default proxy settings - If /etc/nginx/proxy.conf exists use that, otherwise use the default --- README.md | 17 +++++++++++++++++ nginx.tmpl | 4 ++++ 2 files changed, 21 insertions(+) diff --git a/README.md b/README.md index d55cd39..f34f2f1 100644 --- a/README.md +++ b/README.md @@ -143,6 +143,23 @@ You'll need apache2-utils on the machine where you plan to create the htpasswd f If you need to configure Nginx beyond what is possible using environment variables, you can provide custom configuration files on either a proxy-wide or per-`VIRTUAL_HOST` basis. +#### Overriding default proxy settings + +If you want to override the default proxy settings for the nginx container, add a configuration file at `/etc/nginx/proxy.conf`. A file with the default settings would +look like this: + +```Nginx +# HTTP 1.1 support +proxy_http_version 1.1; +proxy_buffering off; +proxy_set_header Host $http_host; +proxy_set_header Upgrade $http_upgrade; +proxy_set_header Connection $proxy_connection; +proxy_set_header X-Real-IP $remote_addr; +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; +``` + #### Proxy-wide To add settings on a proxy-wide basis, add your configuration file under `/etc/nginx/conf.d` using a name ending in `.conf`. diff --git a/nginx.tmpl b/nginx.tmpl index b4140f9..fba5e74 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -38,6 +38,9 @@ log_format vhost '$host $remote_addr - $remote_user [$time_local] ' access_log /proc/self/fd/1 vhost; error_log /proc/self/fd/2; +{{ if (exists "/etc/nginx/proxy.conf") }} +include /etc/nginx/proxy.conf; +{{ else }} # HTTP 1.1 support proxy_http_version 1.1; proxy_buffering off; @@ -47,6 +50,7 @@ proxy_set_header Connection $proxy_connection; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; +{{ end }} server { server_name _; # This is just an invalid value which will never trigger on a real hostname. From d07a7d74874ade3c018c34284ee90e96367b1099 Mon Sep 17 00:00:00 2001 From: Richard Bateman Date: Fri, 14 Aug 2015 11:31:58 -0600 Subject: [PATCH 17/55] Fix example command in docs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f34f2f1..891d8fc 100644 --- a/README.md +++ b/README.md @@ -192,4 +192,4 @@ For example, if you have a virtual host named `app.example.com`, you could provi If you are using multiple hostnames for a single container (e.g. `VIRTUAL_HOST=example.com,www.example.com`), the virtual host configuration file must exist for each hostname. If you would like to use the same configuration for multiple virtual host names, you can use a symlink: $ { echo 'server_tokens off;'; echo 'client_max_body_size 100m;'; } > /path/to/vhost.d/www.example.com - $ ln -s www.example.com /path/to/vhost.d/example.com + $ ln -s /path/to/vhost.d/www.example.com /path/to/vhost.d/example.com From b131b00e1984adb54f6905f92ba38ca83d181e1f Mon Sep 17 00:00:00 2001 From: Richard Bateman Date: Fri, 14 Aug 2015 11:34:56 -0600 Subject: [PATCH 18/55] Add support for vhosts.d/defaults file with default vhost options - Only used if it exists and a vhost-specific one doesn't --- README.md | 5 +++++ nginx.tmpl | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/README.md b/README.md index 891d8fc..6c36a9f 100644 --- a/README.md +++ b/README.md @@ -193,3 +193,8 @@ If you are using multiple hostnames for a single container (e.g. `VIRTUAL_HOST=e $ { echo 'server_tokens off;'; echo 'client_max_body_size 100m;'; } > /path/to/vhost.d/www.example.com $ ln -s /path/to/vhost.d/www.example.com /path/to/vhost.d/example.com + +#### Per-VIRTUAL_HOST default configuration + +If you want most of your virtual hosts to use a default single configuration and then override on a few specific ones, add those settings to the `/etc/nginx/vhost.d/default` file. This file +will be used on any virtual host which does not have a `/etc/nginx/vhost.d/{VIRTUAL_HOST}` file associated with it. diff --git a/nginx.tmpl b/nginx.tmpl index fba5e74..b9b06dc 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -125,6 +125,8 @@ server { {{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }} include {{ printf "/etc/nginx/vhost.d/%s" $host }}; + {{ else if (exists /etc/vhost.d/defaults) }} + include /etc/nginx/vhost.d/defaults {{ end }} location / { @@ -143,6 +145,8 @@ server { {{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }} include {{ printf "/etc/nginx/vhost.d/%s" $host }}; + {{ else if (exists /etc/vhost.d/defaults) }} + include /etc/nginx/vhost.d/defaults {{ end }} location / { From d9ee7ed704e991c8e5a9b8737488fb477a7dca19 Mon Sep 17 00:00:00 2001 From: Richard Bateman Date: Fri, 14 Aug 2015 11:36:39 -0600 Subject: [PATCH 19/55] Add support for adding options to the location block of a vhost --- README.md | 21 +++++++++++++++++++++ nginx.tmpl | 10 ++++++++++ 2 files changed, 31 insertions(+) diff --git a/README.md b/README.md index 6c36a9f..c975129 100644 --- a/README.md +++ b/README.md @@ -198,3 +198,24 @@ If you are using multiple hostnames for a single container (e.g. `VIRTUAL_HOST=e If you want most of your virtual hosts to use a default single configuration and then override on a few specific ones, add those settings to the `/etc/nginx/vhost.d/default` file. This file will be used on any virtual host which does not have a `/etc/nginx/vhost.d/{VIRTUAL_HOST}` file associated with it. + +#### Per-VIRTUAL_HOST location configuration + +To add settings to the "location" block on a per-`VIRTUAL_HOST` basis, add your configuration file under `/etc/nginx/vhost.d` +just like the previous section except with the suffix `_location`. + +For example, if you have a virtual host named `app.example.com` and you have configured a proxy_cache `my-cache` in another custom file, you could tell it to use a proxy cache as follows: + + $ docker run -d -p 80:80 -p 443:443 -v /path/to/vhost.d:/etc/nginx/vhost.d:ro -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy + $ { echo 'proxy_cache my-cache;'; echo 'proxy_cache_valid 200 302 60m;'; echo 'proxy_cache_valid 404 1m;' } > /path/to/vhost.d/app.example.com_location + +If you are using multiple hostnames for a single container (e.g. `VIRTUAL_HOST=example.com,www.example.com`), the virtual host configuration file must exist for each hostname. If you would like to use the same configuration for multiple virtual host names, you can use a symlink: + + $ { echo 'proxy_cache my-cache;'; echo 'proxy_cache_valid 200 302 60m;'; echo 'proxy_cache_valid 404 1m;' } > /path/to/vhost.d/app.example.com_location + $ ln -s /path/to/vhost.d/www.example.com /path/to/vhost.d/example.com + +#### Per-VIRTUAL_HOST location default configuration + +If you want most of your virtual hosts to use a default single `location` block configuration and then override on a few specific ones, add those settings to the `/etc/nginx/vhost.d/default_location` file. This file +will be used on any virtual host which does not have a `/etc/nginx/vhost.d/{VIRTUAL_HOST}` file associated with it. + diff --git a/nginx.tmpl b/nginx.tmpl index b9b06dc..82ddb11 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -135,6 +135,11 @@ server { auth_basic "Restricted {{ $host }}"; auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }}; {{ end }} + {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }} + include {{ printf "/etc/nginx/vhost.d/%s_location"}} + {{ else if (exists /etc/vhost.d/defaults_location) }} + include /etc/nginx/vhost.d/defaults_location + {{ end }} } } {{ else }} @@ -155,6 +160,11 @@ server { auth_basic "Restricted {{ $host }}"; auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }}; {{ end }} + {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }} + include {{ printf "/etc/nginx/vhost.d/%s_location"}} + {{ else if (exists /etc/vhost.d/defaults_location) }} + include /etc/nginx/vhost.d/defaults_location + {{ end }} } } From 405f4876b924d612085b4ae9a75b2d5658d10bdc Mon Sep 17 00:00:00 2001 From: Richard Bateman Date: Fri, 14 Aug 2015 12:10:47 -0600 Subject: [PATCH 20/55] As per pull request feedback, update names to be consistent --- nginx.tmpl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index 82ddb11..f211565 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -125,8 +125,8 @@ server { {{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }} include {{ printf "/etc/nginx/vhost.d/%s" $host }}; - {{ else if (exists /etc/vhost.d/defaults) }} - include /etc/nginx/vhost.d/defaults + {{ else if (exists /etc/vhost.d/default) }} + include /etc/nginx/vhost.d/default {{ end }} location / { @@ -137,8 +137,8 @@ server { {{ end }} {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }} include {{ printf "/etc/nginx/vhost.d/%s_location"}} - {{ else if (exists /etc/vhost.d/defaults_location) }} - include /etc/nginx/vhost.d/defaults_location + {{ else if (exists /etc/vhost.d/default_location) }} + include /etc/nginx/vhost.d/default_location {{ end }} } } @@ -150,8 +150,8 @@ server { {{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }} include {{ printf "/etc/nginx/vhost.d/%s" $host }}; - {{ else if (exists /etc/vhost.d/defaults) }} - include /etc/nginx/vhost.d/defaults + {{ else if (exists /etc/vhost.d/default) }} + include /etc/nginx/vhost.d/default {{ end }} location / { @@ -162,8 +162,8 @@ server { {{ end }} {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }} include {{ printf "/etc/nginx/vhost.d/%s_location"}} - {{ else if (exists /etc/vhost.d/defaults_location) }} - include /etc/nginx/vhost.d/defaults_location + {{ else if (exists /etc/vhost.d/default_location) }} + include /etc/nginx/vhost.d/default_location {{ end }} } } From 66711ff026d0f61cc6ba4f2ccee77a896bce32bd Mon Sep 17 00:00:00 2001 From: Richard Bateman Date: Fri, 14 Aug 2015 12:19:53 -0600 Subject: [PATCH 21/55] Add warning about consequences of incorrectly using proxy_config.conf --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c975129..4c49729 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,8 @@ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; ``` +***NOTE***: If you provide this file it will replace the defaults; you may want to check the .tmpl file to make sure you have all of the needed options. + #### Proxy-wide To add settings on a proxy-wide basis, add your configuration file under `/etc/nginx/conf.d` using a name ending in `.conf`. From 5089bf77dd99fe466ee95651bc4b533000b0f2bc Mon Sep 17 00:00:00 2001 From: Richard Bateman Date: Fri, 14 Aug 2015 12:34:10 -0600 Subject: [PATCH 22/55] Update wording in docs as per pull request feedback --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4c49729..6825a26 100644 --- a/README.md +++ b/README.md @@ -143,9 +143,9 @@ You'll need apache2-utils on the machine where you plan to create the htpasswd f If you need to configure Nginx beyond what is possible using environment variables, you can provide custom configuration files on either a proxy-wide or per-`VIRTUAL_HOST` basis. -#### Overriding default proxy settings +#### Replacing default proxy settings -If you want to override the default proxy settings for the nginx container, add a configuration file at `/etc/nginx/proxy.conf`. A file with the default settings would +If you want to replace the default proxy settings for the nginx container, add a configuration file at `/etc/nginx/proxy.conf`. A file with the default settings would look like this: ```Nginx From 235528338ca6d141d6e32d0a092cb796c7a56827 Mon Sep 17 00:00:00 2001 From: Rich Date: Wed, 19 Aug 2015 23:52:54 -0400 Subject: [PATCH 23/55] fix 2 minor English language typos --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d55cd39..060c82b 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Then start any containers you want proxied with an env var `VIRTUAL_HOST=subdoma Provided your DNS is setup to forward foo.bar.com to the a host running nginx-proxy, the request will be routed to a container with the VIRTUAL_HOST env var set. -If your are using `boot2docker` start `nginx-proxy` with: +If you are using `boot2docker` start `nginx-proxy` with: $ $(boot2docker shellinit) $ docker run -p 80:80 -e DOCKER_HOST -e DOCKER_CERT_PATH -e DOCKER_TLS_VERIFY -v $DOCKER_CERT_PATH:$DOCKER_CERT_PATH -it jwilder/nginx-proxy @@ -163,7 +163,7 @@ Or it can be done by mounting in your custom configuration in your `docker run` #### Per-VIRTUAL_HOST -To add settings on a per-`VIRTUAL_HOST` basis, add your configuration file under `/etc/nginx/vhost.d`. Unlike in the proxy-wide case, which allows mutliple config files with any name ending in `.conf`, the per-`VIRTUAL_HOST` file must be named exactly after the `VIRTUAL_HOST`. +To add settings on a per-`VIRTUAL_HOST` basis, add your configuration file under `/etc/nginx/vhost.d`. Unlike in the proxy-wide case, which allows multiple config files with any name ending in `.conf`, the per-`VIRTUAL_HOST` file must be named exactly after the `VIRTUAL_HOST`. In order to allow virtual hosts to be dynamically configured as backends are added and removed, it makes the most sense to mount an external directory as `/etc/nginx/vhost.d` as opposed to using derived images or mounting individual configuration files. From 924fcd7984b767c1b527c05a45266339e21ca35d Mon Sep 17 00:00:00 2001 From: Mike Dillon Date: Sun, 23 Aug 2015 09:00:23 -0700 Subject: [PATCH 24/55] Remove error_log setting from nginx.tmpl It's already set correctly in nginx.conf --- nginx.tmpl | 1 - 1 file changed, 1 deletion(-) diff --git a/nginx.tmpl b/nginx.tmpl index b4140f9..9cf3093 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -36,7 +36,6 @@ log_format vhost '$host $remote_addr - $remote_user [$time_local] ' '"$http_referer" "$http_user_agent"'; access_log /proc/self/fd/1 vhost; -error_log /proc/self/fd/2; # HTTP 1.1 support proxy_http_version 1.1; From 682914dec74b646621e54d9d66a469cdb642fb66 Mon Sep 17 00:00:00 2001 From: Mike Dillon Date: Sun, 23 Aug 2015 18:39:49 -0700 Subject: [PATCH 25/55] Document the need to EXPOSE the proxied port --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 060c82b..005e7a0 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ Then start any containers you want proxied with an env var `VIRTUAL_HOST=subdoma $ docker run -e VIRTUAL_HOST=foo.bar.com ... +The containers being proxied must [expose](https://docs.docker.com/reference/run/#expose-incoming-ports) the port to be proxied, either by using the `EXPOSE` directive in their `Dockerfile` or by using the `--expose` flag to `docker run` or `docker create`. + Provided your DNS is setup to forward foo.bar.com to the a host running nginx-proxy, the request will be routed to a container with the VIRTUAL_HOST env var set. If you are using `boot2docker` start `nginx-proxy` with: From e5ad1ecfd1cf8d374ab109bb6adc682ae072361e Mon Sep 17 00:00:00 2001 From: Mike Dillon Date: Mon, 24 Aug 2015 19:37:45 -0700 Subject: [PATCH 26/55] Remove boot2docker-specific instructions Both boot2docker and docker-machine will work fine with the normal `docker run` command used in the rest of the docs. --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index 005e7a0..c440329 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,6 @@ The containers being proxied must [expose](https://docs.docker.com/reference/run Provided your DNS is setup to forward foo.bar.com to the a host running nginx-proxy, the request will be routed to a container with the VIRTUAL_HOST env var set. -If you are using `boot2docker` start `nginx-proxy` with: - - $ $(boot2docker shellinit) - $ docker run -p 80:80 -e DOCKER_HOST -e DOCKER_CERT_PATH -e DOCKER_TLS_VERIFY -v $DOCKER_CERT_PATH:$DOCKER_CERT_PATH -it jwilder/nginx-proxy - ### Multiple Ports If your container exposes multiple ports, nginx-proxy will default to the service running on port 80. If you need to specify a different port, you can set a VIRTUAL_PORT env var to select a different one. If your container only exposes one port and it has a VIRTUAL_HOST env var set, that port will be selected. From d3f56468b112bb3ef0898e7cd4d02d2b9cecc90d Mon Sep 17 00:00:00 2001 From: Ray Walker Date: Wed, 26 Aug 2015 12:49:59 +1000 Subject: [PATCH 27/55] Fix for #188 - remove hostname from default SSL block --- nginx.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nginx.tmpl b/nginx.tmpl index b4140f9..6cb771d 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -152,7 +152,7 @@ server { {{ if (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }} server { - server_name {{ $host }}; + server_name _; listen 443 ssl spdy {{ $default_server }}; return 503; From d066bd32e0fee73fd1ead5018dd167c56572e806 Mon Sep 17 00:00:00 2001 From: Ray Walker Date: Wed, 26 Aug 2015 18:35:47 +1000 Subject: [PATCH 28/55] Fix for #188 - add SSL server block outside hosts loop --- nginx.tmpl | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/nginx.tmpl b/nginx.tmpl index 6cb771d..31e6ce1 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -54,6 +54,17 @@ server { return 503; } +{{ if (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }} +server { + server_name _; # This is just an invalid value which will never trigger on a real hostname. + listen 443 ssl spdy; + return 503; + + ssl_certificate /etc/nginx/certs/default.crt; + ssl_certificate_key /etc/nginx/certs/default.key; +} +{{ end }} + {{ range $host, $containers := groupByMulti $ "Env.VIRTUAL_HOST" "," }} upstream {{ $host }} { @@ -152,7 +163,7 @@ server { {{ if (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }} server { - server_name _; + server_name {{ $host }}; listen 443 ssl spdy {{ $default_server }}; return 503; From ae0da36d75430204253f46bf2dedb6244748115c Mon Sep 17 00:00:00 2001 From: CoreOS Admin Date: Sat, 29 Aug 2015 18:38:43 -0600 Subject: [PATCH 29/55] Fix bugs in config file from refactor --- nginx.tmpl | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index f211565..6fc0bee 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -125,8 +125,8 @@ server { {{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }} include {{ printf "/etc/nginx/vhost.d/%s" $host }}; - {{ else if (exists /etc/vhost.d/default) }} - include /etc/nginx/vhost.d/default + {{ else if (exists "/etc/vhost.d/default") }} + include /etc/nginx/vhost.d/default; {{ end }} location / { @@ -135,11 +135,11 @@ server { auth_basic "Restricted {{ $host }}"; auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }}; {{ end }} - {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }} - include {{ printf "/etc/nginx/vhost.d/%s_location"}} - {{ else if (exists /etc/vhost.d/default_location) }} - include /etc/nginx/vhost.d/default_location - {{ end }} + {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }} + include {{ printf "/etc/nginx/vhost.d/%s_location" $host}}; + {{ else if (exists "/etc/vhost.d/default_location") }} + include /etc/nginx/vhost.d/default_location; + {{ end }} } } {{ else }} @@ -150,8 +150,8 @@ server { {{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }} include {{ printf "/etc/nginx/vhost.d/%s" $host }}; - {{ else if (exists /etc/vhost.d/default) }} - include /etc/nginx/vhost.d/default + {{ else if (exists "/etc/vhost.d/default") }} + include /etc/nginx/vhost.d/default; {{ end }} location / { @@ -160,11 +160,11 @@ server { auth_basic "Restricted {{ $host }}"; auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }}; {{ end }} - {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }} - include {{ printf "/etc/nginx/vhost.d/%s_location"}} - {{ else if (exists /etc/vhost.d/default_location) }} - include /etc/nginx/vhost.d/default_location - {{ end }} + {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }} + include {{ printf "/etc/nginx/vhost.d/%s_location" $host}}; + {{ else if (exists "/etc/vhost.d/default_location") }} + include /etc/nginx/vhost.d/default_location; + {{ end }} } } From d844c124ff5fd2e28cfc2a612f9ba8fb622985cc Mon Sep 17 00:00:00 2001 From: Bernardo Farah Date: Tue, 1 Sep 2015 09:38:43 -0700 Subject: [PATCH 30/55] Bumping to latest Docker Gen version As per [this](https://github.com/jwilder/docker-gen/issues/114) ticket. Thanks again! --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index abfae74..e58d98e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,7 @@ RUN echo "daemon off;" >> /etc/nginx/nginx.conf \ RUN wget -P /usr/local/bin https://godist.herokuapp.com/projects/ddollar/forego/releases/current/linux-amd64/forego \ && chmod u+x /usr/local/bin/forego -ENV DOCKER_GEN_VERSION 0.4.0 +ENV DOCKER_GEN_VERSION 0.4.1 RUN wget https://github.com/jwilder/docker-gen/releases/download/$DOCKER_GEN_VERSION/docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \ && tar -C /usr/local/bin -xvzf docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \ From 900a676af89340c6cb1650742ddcad30c25f62b3 Mon Sep 17 00:00:00 2001 From: Mike Dillon Date: Sun, 23 Aug 2015 09:00:58 -0700 Subject: [PATCH 31/55] Move access_log from the http level to server This prevents duplicate access_log entries from being written for each request --- nginx.tmpl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/nginx.tmpl b/nginx.tmpl index 9cf3093..07d6ee5 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -35,7 +35,7 @@ log_format vhost '$host $remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"'; -access_log /proc/self/fd/1 vhost; +access_log off; # HTTP 1.1 support proxy_http_version 1.1; @@ -50,6 +50,7 @@ proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; server { server_name _; # This is just an invalid value which will never trigger on a real hostname. listen 80; + access_log /var/log/nginx/access.log vhost; return 503; } @@ -95,12 +96,14 @@ upstream {{ $host }} { server { server_name {{ $host }}; listen 80 {{ $default_server }}; + access_log /var/log/nginx/access.log vhost; return 301 https://$host$request_uri; } server { server_name {{ $host }}; listen 443 ssl spdy {{ $default_server }}; + access_log /var/log/nginx/access.log vhost; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA; @@ -135,6 +138,7 @@ server { server { server_name {{ $host }}; listen 80 {{ $default_server }}; + access_log /var/log/nginx/access.log vhost; {{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }} include {{ printf "/etc/nginx/vhost.d/%s" $host }}; @@ -153,6 +157,7 @@ server { server { server_name {{ $host }}; listen 443 ssl spdy {{ $default_server }}; + access_log /var/log/nginx/access.log vhost; return 503; ssl_certificate /etc/nginx/certs/default.crt; From d83ba3da1ede656c07b79d85731d81dffcf5f0f2 Mon Sep 17 00:00:00 2001 From: Thomas LEVEIL Date: Fri, 11 Sep 2015 22:05:54 +0000 Subject: [PATCH 32/55] refuse to start if the docker sock isn't available --- Dockerfile | 2 +- docker-entrypoint.sh | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 docker-entrypoint.sh diff --git a/Dockerfile b/Dockerfile index abfae74..d4b3e0b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,4 +30,4 @@ ENV DOCKER_HOST unix:///tmp/docker.sock VOLUME ["/etc/nginx/certs"] -CMD ["forego", "start", "-r"] +ENTRYPOINT ["/app/docker-entrypoint.sh"] diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100644 index 0000000..2ce3833 --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -e + +if [[ $DOCKER_HOST == unix://* ]]; then + socket_file=${DOCKER_HOST#unix://} + if ! [ -S $socket_file ]; then + cat >&2 <<-EOT + ERROR: you need to share your docker host socket with a volume at $socket_file + Typically you should run your jwilder/nginx-proxy with: \`-v /var/run/docker.sock:$socket_file:ro\` + See documentation at http://git.io/vZaGJ + EOT + exit 1 + fi +fi + +exec forego start -r \ No newline at end of file From 1aac9960197f56d502a6147337337fd3b1bfa365 Mon Sep 17 00:00:00 2001 From: Thomas LEVEIL Date: Sat, 12 Sep 2015 10:37:21 +0000 Subject: [PATCH 33/55] conform to Docker official images best practices https://github.com/docker-library/official-images/blob/master/README.md#consistency --- Dockerfile | 1 + docker-entrypoint.sh | 33 +++++++++++++++++++++++---------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index d4b3e0b..4b30a67 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,3 +31,4 @@ ENV DOCKER_HOST unix:///tmp/docker.sock VOLUME ["/etc/nginx/certs"] ENTRYPOINT ["/app/docker-entrypoint.sh"] +CMD ["nginx-proxy"] diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 2ce3833..2d19d89 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -1,16 +1,29 @@ #!/bin/bash set -e -if [[ $DOCKER_HOST == unix://* ]]; then - socket_file=${DOCKER_HOST#unix://} - if ! [ -S $socket_file ]; then - cat >&2 <<-EOT - ERROR: you need to share your docker host socket with a volume at $socket_file - Typically you should run your jwilder/nginx-proxy with: \`-v /var/run/docker.sock:$socket_file:ro\` - See documentation at http://git.io/vZaGJ - EOT - exit 1 +check_unix_socket() { + if [[ $DOCKER_HOST == unix://* ]]; then + socket_file=${DOCKER_HOST#unix://} + if ! [ -S $socket_file ]; then + cat >&2 <<-EOT + ERROR: you need to share your docker host socket with a volume at $socket_file + Typically you should run your jwilder/nginx-proxy with: \`-v /var/run/docker.sock:$socket_file:ro\` + See documentation at http://git.io/vZaGJ + EOT + exit 1 + fi fi +} + +################################################################################ + +# check for the expected command +if [ "$1" = 'nginx-proxy' ]; then + check_unix_socket + exec forego start -r fi -exec forego start -r \ No newline at end of file +# else default to run whatever the user wanted like "bash" +exec "$@" + + From f95ff82ad09efb9f615cb81736fa78445594831c Mon Sep 17 00:00:00 2001 From: Mike Dillon Date: Sat, 12 Sep 2015 07:18:12 -0700 Subject: [PATCH 34/55] Adjust entrypoint to always warn on missing socket Also chmod the entrypoint --- Dockerfile | 2 +- docker-entrypoint.sh | 37 +++++++++++++++---------------------- 2 files changed, 16 insertions(+), 23 deletions(-) mode change 100644 => 100755 docker-entrypoint.sh diff --git a/Dockerfile b/Dockerfile index 4b30a67..4035f59 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,4 +31,4 @@ ENV DOCKER_HOST unix:///tmp/docker.sock VOLUME ["/etc/nginx/certs"] ENTRYPOINT ["/app/docker-entrypoint.sh"] -CMD ["nginx-proxy"] +CMD ["forego", "start", "-r"] diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh old mode 100644 new mode 100755 index 2d19d89..6353314 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -1,29 +1,22 @@ #!/bin/bash set -e -check_unix_socket() { - if [[ $DOCKER_HOST == unix://* ]]; then - socket_file=${DOCKER_HOST#unix://} - if ! [ -S $socket_file ]; then - cat >&2 <<-EOT - ERROR: you need to share your docker host socket with a volume at $socket_file - Typically you should run your jwilder/nginx-proxy with: \`-v /var/run/docker.sock:$socket_file:ro\` - See documentation at http://git.io/vZaGJ - EOT - exit 1 - fi +# Warn if the DOCKER_HOST socket does not exist +if [[ $DOCKER_HOST == unix://* ]]; then + socket_file=${DOCKER_HOST#unix://} + if ! [ -S $socket_file ]; then + cat >&2 <<-EOT + ERROR: you need to share your Docker host socket with a volume at $socket_file + Typically you should run your jwilder/nginx-proxy with: \`-v /var/run/docker.sock:$socket_file:ro\` + See the documentation at http://git.io/vZaGJ + EOT + socketMissing=1 fi -} - -################################################################################ - -# check for the expected command -if [ "$1" = 'nginx-proxy' ]; then - check_unix_socket - exec forego start -r fi -# else default to run whatever the user wanted like "bash" +# If the user has run the default command and the socket doesn't exist, fail +if [ "$socketMissing" = 1 -a "$1" = forego -a "$2" = start -a "$3" = '-r' ]; then + exit 1 +fi + exec "$@" - - From d45c10ca6625a986bfce2f366ca46c7b3fc63bda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Roub=C3=AD=C4=8Dek?= Date: Wed, 23 Sep 2015 17:43:31 +0200 Subject: [PATCH 35/55] Use nginx 1.9.5 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 0445b4d..cc80e08 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM nginx:1.9.2 +FROM nginx:1.9.5 MAINTAINER Jason Wilder jwilder@litl.com # Install wget and install/updates certificates From 249fb204f1c0fcf6f9f788448369e1b208649ce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Roub=C3=AD=C4=8Dek?= Date: Wed, 23 Sep 2015 17:47:18 +0200 Subject: [PATCH 36/55] Use HTTP/2 instead of SPDY --- nginx.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nginx.tmpl b/nginx.tmpl index 08f6c01..224d2b5 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -61,7 +61,7 @@ server { {{ if (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }} server { server_name _; # This is just an invalid value which will never trigger on a real hostname. - listen 443 ssl spdy; + listen 443 ssl http2; return 503; ssl_certificate /etc/nginx/certs/default.crt; From e06d5917a2e6241b1f9c7ac1a7cdd7288a8702a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Roub=C3=AD=C4=8Dek?= Date: Wed, 23 Sep 2015 17:48:40 +0200 Subject: [PATCH 37/55] Use HTTP/2 instead of SPDY --- nginx.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index 224d2b5..788ca90 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -117,7 +117,7 @@ server { server { server_name {{ $host }}; - listen 443 ssl spdy {{ $default_server }}; + listen 443 ssl http2 {{ $default_server }}; access_log /var/log/nginx/access.log vhost; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; @@ -185,7 +185,7 @@ server { {{ if (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }} server { server_name {{ $host }}; - listen 443 ssl spdy {{ $default_server }}; + listen 443 ssl http2 {{ $default_server }}; access_log /var/log/nginx/access.log vhost; return 503; From d46d9ad94394b28b52a33cf6fa79a7c37d218eb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Roub=C3=AD=C4=8Dek?= Date: Wed, 23 Sep 2015 17:49:51 +0200 Subject: [PATCH 38/55] Use nginx 1.9.5 badge in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b4b1df7..4053506 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![nginx 1.9.2](https://img.shields.io/badge/nginx-1.9.2-brightgreen.svg) ![License MIT](https://img.shields.io/badge/license-MIT-blue.svg) +![nginx 1.9.5](https://img.shields.io/badge/nginx-1.9.5-brightgreen.svg) ![License MIT](https://img.shields.io/badge/license-MIT-blue.svg) nginx-proxy sets up a container running nginx and [docker-gen][1]. docker-gen generates reverse proxy configs for nginx and reloads nginx when containers are started and stopped. From 4bd30f5d2c2ea3ff5dfa0cda6f8eccce6d2d7da6 Mon Sep 17 00:00:00 2001 From: Thomas LEVEIL Date: Sun, 13 Sep 2015 19:33:11 +0000 Subject: [PATCH 39/55] add test suite. See #197 This test suite is implemented using [bats](https://github.com/sstephenson/bats). Not all features are tested. For instance ssl features and custom nginx config are missing. Probably others. This test suite won't work with TravisCI. Too many evenings were wasted trying to overcome [issues](http://stackoverflow.com/questions/32846800/travis-fails-to-stop-docker-containers) that arises only on the TravisCI platform. However it runs on [CircleCI](https://circleci.com) which is also free for opensource projects. --- circle.yml | 21 ++ test/README.md | 14 + test/default-host.bats | 38 ++ test/docker.bats | 117 ++++++ test/lib/README.md | 6 + test/lib/bats/batslib.bash | 596 ++++++++++++++++++++++++++++++ test/lib/bats/batslib/output.bash | 264 +++++++++++++ test/lib/docker_helpers.bash | 61 +++ test/lib/helpers.bash | 22 ++ test/multiple-hosts.bats | 47 +++ test/multiple-ports.bats | 54 +++ test/test_helpers.bash | 128 +++++++ test/wildcard-hosts.bats | 68 ++++ 13 files changed, 1436 insertions(+) create mode 100644 circle.yml create mode 100644 test/README.md create mode 100644 test/default-host.bats create mode 100644 test/docker.bats create mode 100644 test/lib/README.md create mode 100644 test/lib/bats/batslib.bash create mode 100644 test/lib/bats/batslib/output.bash create mode 100644 test/lib/docker_helpers.bash create mode 100644 test/lib/helpers.bash create mode 100644 test/multiple-hosts.bats create mode 100644 test/multiple-ports.bats create mode 100644 test/test_helpers.bash create mode 100644 test/wildcard-hosts.bats diff --git a/circle.yml b/circle.yml new file mode 100644 index 0000000..8deabde --- /dev/null +++ b/circle.yml @@ -0,0 +1,21 @@ +machine: + pre: + # install docker 1.7.1 + - sudo curl -L -o /usr/bin/docker 'https://s3-external-1.amazonaws.com/circle-downloads/docker-1.7.1-circleci'; sudo chmod 0755 /usr/bin/docker; true + services: + - docker + +dependencies: + override: + - sudo add-apt-repository ppa:duggan/bats --yes + - sudo apt-get update -qq + - sudo apt-get install -qq bats + - docker pull jwilder/docker-gen + - docker pull nginx + - docker pull python:3 + - docker pull rancher/socat-docker + +test: + override: + - docker build -t jwilder/nginx-proxy:bats . + - bats test \ No newline at end of file diff --git a/test/README.md b/test/README.md new file mode 100644 index 0000000..721d436 --- /dev/null +++ b/test/README.md @@ -0,0 +1,14 @@ +Test suite +========== + +This test suite is implemented on top of the [Bats](https://github.com/sstephenson/bats/blob/master/README.md) test framework. + +It is intended to verify the correct behavior of the Docker image `jwilder/nginx-proxy:bats`. + +Running the test suite +---------------------- + +Make sure you have Bats installed, then run: + + docker build -t jwilder/nginx-proxy:bats . + bats test/ \ No newline at end of file diff --git a/test/default-host.bats b/test/default-host.bats new file mode 100644 index 0000000..0adf686 --- /dev/null +++ b/test/default-host.bats @@ -0,0 +1,38 @@ +#!/usr/bin/env bats +load test_helpers + +function setup { + # make sure to stop any web container before each test so we don't + # have any unexpected contaiener running with VIRTUAL_HOST or VIRUTAL_PORT set + docker ps -q --filter "label=bats-type=web" | xargs -r docker stop >&2 +} + + +@test "[$TEST_FILE] DEFAULT_HOST=web1.bats" { + SUT_CONTAINER=bats-nginx-proxy-${TEST_FILE}-1 + + # GIVEN a webserver with VIRTUAL_HOST set to web.bats + docker_clean bats-web + run docker run -d \ + --label bats-type="web" \ + --name bats-web \ + -e VIRTUAL_HOST=web.bats \ + --expose 80 \ + -w /var/www \ + python:3 \ + python -m http.server 80 + assert_success + + # WHEN nginx-proxy runs with DEFAULT_HOST set to web.bats + run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro -e DEFAULT_HOST=web.bats + assert_success + docker_wait_for_log $SUT_CONTAINER 3 "Watching docker events" + + # THEN querying the proxy without Host header → 200 + run curl_container $SUT_CONTAINER / --head + assert_output -l 0 $'HTTP/1.1 200 OK\r' + + # THEN querying the proxy with any other Host header → 200 + run curl_container $SUT_CONTAINER / --head --header "Host: something.I.just.made.up" + assert_output -l 0 $'HTTP/1.1 200 OK\r' +} diff --git a/test/docker.bats b/test/docker.bats new file mode 100644 index 0000000..13d84a2 --- /dev/null +++ b/test/docker.bats @@ -0,0 +1,117 @@ +#!/usr/bin/env bats +load test_helpers + + +@test "[$TEST_FILE] start 2 web containers" { + prepare_web_container bats-web1 81 -e VIRTUAL_HOST=web1.bats + prepare_web_container bats-web2 82 -e VIRTUAL_HOST=web2.bats +} + + +@test "[$TEST_FILE] -v /var/run/docker.sock:/tmp/docker.sock:ro" { + SUT_CONTAINER=bats-nginx-proxy-${TEST_FILE}-1 + + # WHEN nginx-proxy runs on our docker host using the default unix socket + run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro + assert_success + docker_wait_for_log $SUT_CONTAINER 3 "Watching docker events" + + # THEN + assert_nginxproxy_behaves $SUT_CONTAINER +} + + +@test "[$TEST_FILE] -v /var/run/docker.sock:/f00.sock:ro -e DOCKER_HOST=unix:///f00.sock" { + SUT_CONTAINER=bats-nginx-proxy-${TEST_FILE}-2 + + # WHEN nginx-proxy runs on our docker host using a custom unix socket + run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/f00.sock:ro -e DOCKER_HOST=unix:///f00.sock + assert_success + docker_wait_for_log $SUT_CONTAINER 3 "Watching docker events" + + # THEN + assert_nginxproxy_behaves $SUT_CONTAINER +} + + +@test "[$TEST_FILE] -e DOCKER_HOST=tcp://..." { + SUT_CONTAINER=bats-nginx-proxy-${TEST_FILE}-3 + # GIVEN a container exposing our docker host over TCP + run docker_tcp bats-docker-tcp + assert_success + sleep 1s + + # WHEN nginx-proxy runs on our docker host using tcp to connect to our docker host + run nginxproxy $SUT_CONTAINER -e DOCKER_HOST="tcp://bats-docker-tcp:2375" --link bats-docker-tcp:bats-docker-tcp + assert_success + docker_wait_for_log $SUT_CONTAINER 3 "Watching docker events" + + # THEN + assert_nginxproxy_behaves $SUT_CONTAINER +} + + +@test "[$TEST_FILE] separated containers (nginx + docker-gen + nginx.tmpl)" { + docker_clean bats-nginx + docker_clean bats-docker-gen + + # GIVEN a simple nginx container + run docker run -d \ + --name bats-nginx \ + -v /etc/nginx/conf.d/ \ + -v /etc/nginx/certs/ \ + nginx:latest + assert_success + run retry 5 1s curl --silent --fail -A "before-docker-gen" --head http://$(docker_ip bats-nginx)/ + assert_output -l 0 $'HTTP/1.1 200 OK\r' + + # WHEN docker-gen runs on our docker host + run docker run -d \ + --name bats-docker-gen \ + -v /var/run/docker.sock:/tmp/docker.sock:ro \ + -v $BATS_TEST_DIRNAME/../nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro \ + --volumes-from bats-nginx \ + jwilder/docker-gen:latest \ + -notify-sighup bats-nginx \ + -watch \ + -only-exposed \ + /etc/docker-gen/templates/nginx.tmpl \ + /etc/nginx/conf.d/default.conf + assert_success + docker_wait_for_log bats-docker-gen 6 "Watching docker events" + + # Give some time to the docker-gen container to notify bats-nginx so it + # reloads its config + sleep 2s + + run docker_running_state bats-nginx + assert_output "true" || { + docker logs bats-docker-gen + false + } >&2 + + # THEN + assert_nginxproxy_behaves bats-nginx +} + + +# $1 nginx-proxy container +function assert_nginxproxy_behaves { + local -r container=$1 + + # Querying the proxy without Host header → 503 + run curl_container $container / --head + assert_output -l 0 $'HTTP/1.1 503 Service Temporarily Unavailable\r' + + # Querying the proxy with Host header → 200 + run curl_container $container /data --header "Host: web1.bats" + assert_output "answer from port 81" + + run curl_container $container /data --header "Host: web2.bats" + assert_output "answer from port 82" + + # Querying the proxy with unknown Host header → 503 + run curl_container $container /data --header "Host: webFOO.bats" --head + assert_output -l 0 $'HTTP/1.1 503 Service Temporarily Unavailable\r' +} + diff --git a/test/lib/README.md b/test/lib/README.md new file mode 100644 index 0000000..bd444fd --- /dev/null +++ b/test/lib/README.md @@ -0,0 +1,6 @@ +bats lib +======== + +found on https://github.com/sstephenson/bats/pull/110 + +When that pull request will be merged, that lib won't be necessary anymore. \ No newline at end of file diff --git a/test/lib/bats/batslib.bash b/test/lib/bats/batslib.bash new file mode 100644 index 0000000..003ada6 --- /dev/null +++ b/test/lib/bats/batslib.bash @@ -0,0 +1,596 @@ +# +# batslib.bash +# ------------ +# +# The Standard Library is a collection of test helpers intended to +# simplify testing. It contains the following types of test helpers. +# +# - Assertions are functions that perform a test and output relevant +# information on failure to help debugging. They return 1 on failure +# and 0 otherwise. +# +# All output is formatted for readability using the functions of +# `output.bash' and sent to the standard error. +# + +source "${BATS_LIB}/batslib/output.bash" + + +######################################################################## +# ASSERTIONS +######################################################################## + +# Fail and display a message. When no parameters are specified, the +# message is read from the standard input. Other functions use this to +# report failure. +# +# Globals: +# none +# Arguments: +# $@ - [=STDIN] message +# Returns: +# 1 - always +# Inputs: +# STDIN - [=$@] message +# Outputs: +# STDERR - message +fail() { + (( $# == 0 )) && batslib_err || batslib_err "$@" + return 1 +} + +# Fail and display details if the expression evaluates to false. Details +# include the expression, `$status' and `$output'. +# +# NOTE: The expression must be a simple command. Compound commands, such +# as `[[', can be used only when executed with `bash -c'. +# +# Globals: +# status +# output +# Arguments: +# $1 - expression +# Returns: +# 0 - expression evaluates to TRUE +# 1 - otherwise +# Outputs: +# STDERR - details, on failure +assert() { + if ! "$@"; then + { local -ar single=( + 'expression' "$*" + 'status' "$status" + ) + local -ar may_be_multi=( + 'output' "$output" + ) + local -ir width="$( batslib_get_max_single_line_key_width \ + "${single[@]}" "${may_be_multi[@]}" )" + batslib_print_kv_single "$width" "${single[@]}" + batslib_print_kv_single_or_multi "$width" "${may_be_multi[@]}" + } | batslib_decorate 'assertion failed' \ + | fail + fi +} + +# Fail and display details if the expected and actual values do not +# equal. Details include both values. +# +# Globals: +# none +# Arguments: +# $1 - actual value +# $2 - expected value +# Returns: +# 0 - values equal +# 1 - otherwise +# Outputs: +# STDERR - details, on failure +assert_equal() { + if [[ $1 != "$2" ]]; then + batslib_print_kv_single_or_multi 8 \ + 'expected' "$2" \ + 'actual' "$1" \ + | batslib_decorate 'values do not equal' \ + | fail + fi +} + +# Fail and display details if `$status' is not 0. Details include +# `$status' and `$output'. +# +# Globals: +# status +# output +# Arguments: +# none +# Returns: +# 0 - `$status' is 0 +# 1 - otherwise +# Outputs: +# STDERR - details, on failure +assert_success() { + if (( status != 0 )); then + { local -ir width=6 + batslib_print_kv_single "$width" 'status' "$status" + batslib_print_kv_single_or_multi "$width" 'output' "$output" + } | batslib_decorate 'command failed' \ + | fail + fi +} + +# Fail and display details if `$status' is 0. Details include `$output'. +# +# Optionally, when the expected status is specified, fail when it does +# not equal `$status'. In this case, details include the expected and +# actual status, and `$output'. +# +# Globals: +# status +# output +# Arguments: +# $1 - [opt] expected status +# Returns: +# 0 - `$status' is not 0, or +# `$status' equals the expected status +# 1 - otherwise +# Outputs: +# STDERR - details, on failure +assert_failure() { + (( $# > 0 )) && local -r expected="$1" + if (( status == 0 )); then + batslib_print_kv_single_or_multi 6 'output' "$output" \ + | batslib_decorate 'command succeeded, but it was expected to fail' \ + | fail + elif (( $# > 0 )) && (( status != expected )); then + { local -ir width=8 + batslib_print_kv_single "$width" \ + 'expected' "$expected" \ + 'actual' "$status" + batslib_print_kv_single_or_multi "$width" \ + 'output' "$output" + } | batslib_decorate 'command failed as expected, but status differs' \ + | fail + fi +} + +# Fail and display details if the expected does not match the actual +# output or a fragment of it. +# +# By default, the entire output is matched. The assertion fails if the +# expected output does not equal `$output'. Details include both values. +# +# When `-l ' is used, only the -th line is matched. The +# assertion fails if the expected line does not equal +# `${lines[}'. Details include the compared lines and . +# +# When `-l' is used without the argument, the output is searched +# for the expected line. The expected line is matched against each line +# in `${lines[@]}'. If no match is found the assertion fails. Details +# include the expected line and `$output'. +# +# By default, literal matching is performed. Options `-p' and `-r' +# enable partial (i.e. substring) and extended regular expression +# matching, respectively. Specifying an invalid extended regular +# expression with `-r' displays an error. +# +# Options `-p' and `-r' are mutually exclusive. When used +# simultaneously, an error is displayed. +# +# Globals: +# output +# lines +# Options: +# -l - match against the -th element of `${lines[@]}' +# -l - search `${lines[@]}' for the expected line +# -p - partial matching +# -r - extended regular expression matching +# Arguments: +# $1 - expected output +# Returns: +# 0 - expected matches the actual output +# 1 - otherwise +# Outputs: +# STDERR - details, on failure +# error message, on error +assert_output() { + local -i is_match_line=0 + local -i is_match_contained=0 + local -i is_mode_partial=0 + local -i is_mode_regex=0 + + # Handle options. + while (( $# > 0 )); do + case "$1" in + -l) + if (( $# > 2 )) && [[ $2 =~ ^([0-9]|[1-9][0-9]+)$ ]]; then + is_match_line=1 + local -ri idx="$2" + shift + else + is_match_contained=1; + fi + shift + ;; + -p) is_mode_partial=1; shift ;; + -r) is_mode_regex=1; shift ;; + --) break ;; + *) break ;; + esac + done + + if (( is_match_line )) && (( is_match_contained )); then + echo "\`-l' and \`-l ' are mutually exclusive" \ + | batslib_decorate 'ERROR: assert_output' \ + | fail + return $? + fi + + if (( is_mode_partial )) && (( is_mode_regex )); then + echo "\`-p' and \`-r' are mutually exclusive" \ + | batslib_decorate 'ERROR: assert_output' \ + | fail + return $? + fi + + # Arguments. + local -r expected="$1" + + if (( is_mode_regex == 1 )) && [[ '' =~ $expected ]] || (( $? == 2 )); then + echo "Invalid extended regular expression: \`$expected'" \ + | batslib_decorate 'ERROR: assert_output' \ + | fail + return $? + fi + + # Matching. + if (( is_match_contained )); then + # Line contained in output. + if (( is_mode_regex )); then + local -i idx + for (( idx = 0; idx < ${#lines[@]}; ++idx )); do + [[ ${lines[$idx]} =~ $expected ]] && return 0 + done + { local -ar single=( + 'regex' "$expected" + ) + local -ar may_be_multi=( + 'output' "$output" + ) + local -ir width="$( batslib_get_max_single_line_key_width \ + "${single[@]}" "${may_be_multi[@]}" )" + batslib_print_kv_single "$width" "${single[@]}" + batslib_print_kv_single_or_multi "$width" "${may_be_multi[@]}" + } | batslib_decorate 'no output line matches regular expression' \ + | fail + elif (( is_mode_partial )); then + local -i idx + for (( idx = 0; idx < ${#lines[@]}; ++idx )); do + [[ ${lines[$idx]} == *"$expected"* ]] && return 0 + done + { local -ar single=( + 'substring' "$expected" + ) + local -ar may_be_multi=( + 'output' "$output" + ) + local -ir width="$( batslib_get_max_single_line_key_width \ + "${single[@]}" "${may_be_multi[@]}" )" + batslib_print_kv_single "$width" "${single[@]}" + batslib_print_kv_single_or_multi "$width" "${may_be_multi[@]}" + } | batslib_decorate 'no output line contains substring' \ + | fail + else + local -i idx + for (( idx = 0; idx < ${#lines[@]}; ++idx )); do + [[ ${lines[$idx]} == "$expected" ]] && return 0 + done + { local -ar single=( + 'line' "$expected" + ) + local -ar may_be_multi=( + 'output' "$output" + ) + local -ir width="$( batslib_get_max_single_line_key_width \ + "${single[@]}" "${may_be_multi[@]}" )" + batslib_print_kv_single "$width" "${single[@]}" + batslib_print_kv_single_or_multi "$width" "${may_be_multi[@]}" + } | batslib_decorate 'output does not contain line' \ + | fail + fi + elif (( is_match_line )); then + # Specific line. + if (( is_mode_regex )); then + if ! [[ ${lines[$idx]} =~ $expected ]]; then + batslib_print_kv_single 5 \ + 'index' "$idx" \ + 'regex' "$expected" \ + 'line' "${lines[$idx]}" \ + | batslib_decorate 'regular expression does not match line' \ + | fail + fi + elif (( is_mode_partial )); then + if [[ ${lines[$idx]} != *"$expected"* ]]; then + batslib_print_kv_single 9 \ + 'index' "$idx" \ + 'substring' "$expected" \ + 'line' "${lines[$idx]}" \ + | batslib_decorate 'line does not contain substring' \ + | fail + fi + else + if [[ ${lines[$idx]} != "$expected" ]]; then + batslib_print_kv_single 8 \ + 'index' "$idx" \ + 'expected' "$expected" \ + 'actual' "${lines[$idx]}" \ + | batslib_decorate 'line differs' \ + | fail + fi + fi + else + # Entire output. + if (( is_mode_regex )); then + if ! [[ $output =~ $expected ]]; then + batslib_print_kv_single_or_multi 6 \ + 'regex' "$expected" \ + 'output' "$output" \ + | batslib_decorate 'regular expression does not match output' \ + | fail + fi + elif (( is_mode_partial )); then + if [[ $output != *"$expected"* ]]; then + batslib_print_kv_single_or_multi 9 \ + 'substring' "$expected" \ + 'output' "$output" \ + | batslib_decorate 'output does not contain substring' \ + | fail + fi + else + if [[ $output != "$expected" ]]; then + batslib_print_kv_single_or_multi 8 \ + 'expected' "$expected" \ + 'actual' "$output" \ + | batslib_decorate 'output differs' \ + | fail + fi + fi + fi +} + +# Fail and display details if the unexpected matches the actual output +# or a fragment of it. +# +# By default, the entire output is matched. The assertion fails if the +# unexpected output equals `$output'. Details include `$output'. +# +# When `-l ' is used, only the -th line is matched. The +# assertion fails if the unexpected line equals `${lines[}'. +# Details include the compared line and . +# +# When `-l' is used without the argument, the output is searched +# for the unexpected line. The unexpected line is matched against each +# line in `${lines[]}'. If a match is found the assertion fails. +# Details include the unexpected line, the index where it was found and +# `$output' (with the unexpected line highlighted in it if `$output` is +# longer than one line). +# +# By default, literal matching is performed. Options `-p' and `-r' +# enable partial (i.e. substring) and extended regular expression +# matching, respectively. On failure, the substring or the regular +# expression is added to the details (if not already displayed). +# Specifying an invalid extended regular expression with `-r' displays +# an error. +# +# Options `-p' and `-r' are mutually exclusive. When used +# simultaneously, an error is displayed. +# +# Globals: +# output +# lines +# Options: +# -l - match against the -th element of `${lines[@]}' +# -l - search `${lines[@]}' for the unexpected line +# -p - partial matching +# -r - extended regular expression matching +# Arguments: +# $1 - unexpected output +# Returns: +# 0 - unexpected matches the actual output +# 1 - otherwise +# Outputs: +# STDERR - details, on failure +# error message, on error +refute_output() { + local -i is_match_line=0 + local -i is_match_contained=0 + local -i is_mode_partial=0 + local -i is_mode_regex=0 + + # Handle options. + while (( $# > 0 )); do + case "$1" in + -l) + if (( $# > 2 )) && [[ $2 =~ ^([0-9]|[1-9][0-9]+)$ ]]; then + is_match_line=1 + local -ri idx="$2" + shift + else + is_match_contained=1; + fi + shift + ;; + -L) is_match_contained=1; shift ;; + -p) is_mode_partial=1; shift ;; + -r) is_mode_regex=1; shift ;; + --) break ;; + *) break ;; + esac + done + + if (( is_match_line )) && (( is_match_contained )); then + echo "\`-l' and \`-l ' are mutually exclusive" \ + | batslib_decorate 'ERROR: refute_output' \ + | fail + return $? + fi + + if (( is_mode_partial )) && (( is_mode_regex )); then + echo "\`-p' and \`-r' are mutually exclusive" \ + | batslib_decorate 'ERROR: refute_output' \ + | fail + return $? + fi + + # Arguments. + local -r unexpected="$1" + + if (( is_mode_regex == 1 )) && [[ '' =~ $unexpected ]] || (( $? == 2 )); then + echo "Invalid extended regular expression: \`$unexpected'" \ + | batslib_decorate 'ERROR: refute_output' \ + | fail + return $? + fi + + # Matching. + if (( is_match_contained )); then + # Line contained in output. + if (( is_mode_regex )); then + local -i idx + for (( idx = 0; idx < ${#lines[@]}; ++idx )); do + if [[ ${lines[$idx]} =~ $unexpected ]]; then + { local -ar single=( + 'regex' "$unexpected" + 'index' "$idx" + ) + local -a may_be_multi=( + 'output' "$output" + ) + local -ir width="$( batslib_get_max_single_line_key_width \ + "${single[@]}" "${may_be_multi[@]}" )" + batslib_print_kv_single "$width" "${single[@]}" + if batslib_is_single_line "${may_be_multi[1]}"; then + batslib_print_kv_single "$width" "${may_be_multi[@]}" + else + may_be_multi[1]="$( printf '%s' "${may_be_multi[1]}" \ + | batslib_prefix \ + | batslib_mark '>' "$idx" )" + batslib_print_kv_multi "${may_be_multi[@]}" + fi + } | batslib_decorate 'no line should match the regular expression' \ + | fail + return $? + fi + done + elif (( is_mode_partial )); then + local -i idx + for (( idx = 0; idx < ${#lines[@]}; ++idx )); do + if [[ ${lines[$idx]} == *"$unexpected"* ]]; then + { local -ar single=( + 'substring' "$unexpected" + 'index' "$idx" + ) + local -a may_be_multi=( + 'output' "$output" + ) + local -ir width="$( batslib_get_max_single_line_key_width \ + "${single[@]}" "${may_be_multi[@]}" )" + batslib_print_kv_single "$width" "${single[@]}" + if batslib_is_single_line "${may_be_multi[1]}"; then + batslib_print_kv_single "$width" "${may_be_multi[@]}" + else + may_be_multi[1]="$( printf '%s' "${may_be_multi[1]}" \ + | batslib_prefix \ + | batslib_mark '>' "$idx" )" + batslib_print_kv_multi "${may_be_multi[@]}" + fi + } | batslib_decorate 'no line should contain substring' \ + | fail + return $? + fi + done + else + local -i idx + for (( idx = 0; idx < ${#lines[@]}; ++idx )); do + if [[ ${lines[$idx]} == "$unexpected" ]]; then + { local -ar single=( + 'line' "$unexpected" + 'index' "$idx" + ) + local -a may_be_multi=( + 'output' "$output" + ) + local -ir width="$( batslib_get_max_single_line_key_width \ + "${single[@]}" "${may_be_multi[@]}" )" + batslib_print_kv_single "$width" "${single[@]}" + if batslib_is_single_line "${may_be_multi[1]}"; then + batslib_print_kv_single "$width" "${may_be_multi[@]}" + else + may_be_multi[1]="$( printf '%s' "${may_be_multi[1]}" \ + | batslib_prefix \ + | batslib_mark '>' "$idx" )" + batslib_print_kv_multi "${may_be_multi[@]}" + fi + } | batslib_decorate 'line should not be in output' \ + | fail + return $? + fi + done + fi + elif (( is_match_line )); then + # Specific line. + if (( is_mode_regex )); then + if [[ ${lines[$idx]} =~ $unexpected ]] || (( $? == 0 )); then + batslib_print_kv_single 5 \ + 'index' "$idx" \ + 'regex' "$unexpected" \ + 'line' "${lines[$idx]}" \ + | batslib_decorate 'regular expression should not match line' \ + | fail + fi + elif (( is_mode_partial )); then + if [[ ${lines[$idx]} == *"$unexpected"* ]]; then + batslib_print_kv_single 9 \ + 'index' "$idx" \ + 'substring' "$unexpected" \ + 'line' "${lines[$idx]}" \ + | batslib_decorate 'line should not contain substring' \ + | fail + fi + else + if [[ ${lines[$idx]} == "$unexpected" ]]; then + batslib_print_kv_single 5 \ + 'index' "$idx" \ + 'line' "${lines[$idx]}" \ + | batslib_decorate 'line should differ' \ + | fail + fi + fi + else + # Entire output. + if (( is_mode_regex )); then + if [[ $output =~ $unexpected ]] || (( $? == 0 )); then + batslib_print_kv_single_or_multi 6 \ + 'regex' "$unexpected" \ + 'output' "$output" \ + | batslib_decorate 'regular expression should not match output' \ + | fail + fi + elif (( is_mode_partial )); then + if [[ $output == *"$unexpected"* ]]; then + batslib_print_kv_single_or_multi 9 \ + 'substring' "$unexpected" \ + 'output' "$output" \ + | batslib_decorate 'output should not contain substring' \ + | fail + fi + else + if [[ $output == "$unexpected" ]]; then + batslib_print_kv_single_or_multi 6 \ + 'output' "$output" \ + | batslib_decorate 'output equals, but it was expected to differ' \ + | fail + fi + fi + fi +} \ No newline at end of file diff --git a/test/lib/bats/batslib/output.bash b/test/lib/bats/batslib/output.bash new file mode 100644 index 0000000..aa9cb87 --- /dev/null +++ b/test/lib/bats/batslib/output.bash @@ -0,0 +1,264 @@ +# +# output.bash +# ----------- +# +# Private functions implementing output formatting. Used by public +# helper functions. +# + +# Print a message to the standard error. When no parameters are +# specified, the message is read from the standard input. +# +# Globals: +# none +# Arguments: +# $@ - [=STDIN] message +# Returns: +# none +# Inputs: +# STDIN - [=$@] message +# Outputs: +# STDERR - message +batslib_err() { + { if (( $# > 0 )); then + echo "$@" + else + cat - + fi + } >&2 +} + +# Count the number of lines in the given string. +# +# TODO(ztombol): Fix tests and remove this note after #93 is resolved! +# NOTE: Due to a bug in Bats, `batslib_count_lines "$output"' does not +# give the same result as `${#lines[@]}' when the output contains +# empty lines. +# See PR #93 (https://github.com/sstephenson/bats/pull/93). +# +# Globals: +# none +# Arguments: +# $1 - string +# Returns: +# none +# Outputs: +# STDOUT - number of lines +batslib_count_lines() { + local -i n_lines=0 + local line + while IFS='' read -r line || [[ -n $line ]]; do + (( ++n_lines )) + done < <(printf '%s' "$1") + echo "$n_lines" +} + +# Determine whether all strings are single-line. +# +# Globals: +# none +# Arguments: +# $@ - strings +# Returns: +# 0 - all strings are single-line +# 1 - otherwise +batslib_is_single_line() { + for string in "$@"; do + (( $(batslib_count_lines "$string") > 1 )) && return 1 + done + return 0 +} + +# Determine the length of the longest key that has a single-line value. +# +# This function is useful in determining the correct width of the key +# column in two-column format when some keys may have multi-line values +# and thus should be excluded. +# +# Globals: +# none +# Arguments: +# $odd - key +# $even - value of the previous key +# Returns: +# none +# Outputs: +# STDOUT - length of longest key +batslib_get_max_single_line_key_width() { + local -i max_len=-1 + while (( $# != 0 )); do + local -i key_len="${#1}" + batslib_is_single_line "$2" && (( key_len > max_len )) && max_len="$key_len" + shift 2 + done + echo "$max_len" +} + +# Print key-value pairs in two-column format. +# +# Keys are displayed in the first column, and their corresponding values +# in the second. To evenly line up values, the key column is fixed-width +# and its width is specified with the first parameter (possibly computed +# using `batslib_get_max_single_line_key_width'). +# +# Globals: +# none +# Arguments: +# $1 - width of key column +# $even - key +# $odd - value of the previous key +# Returns: +# none +# Outputs: +# STDOUT - formatted key-value pairs +batslib_print_kv_single() { + local -ir col_width="$1"; shift + while (( $# != 0 )); do + printf '%-*s : %s\n' "$col_width" "$1" "$2" + shift 2 + done +} + +# Print key-value pairs in multi-line format. +# +# The key is displayed first with the number of lines of its +# corresponding value in parenthesis. Next, starting on the next line, +# the value is displayed. For better readability, it is recommended to +# indent values using `batslib_prefix'. +# +# Globals: +# none +# Arguments: +# $odd - key +# $even - value of the previous key +# Returns: +# none +# Outputs: +# STDOUT - formatted key-value pairs +batslib_print_kv_multi() { + while (( $# != 0 )); do + printf '%s (%d lines):\n' "$1" "$( batslib_count_lines "$2" )" + printf '%s\n' "$2" + shift 2 + done +} + +# Print all key-value pairs in either two-column or multi-line format +# depending on whether all values are single-line. +# +# If all values are single-line, print all pairs in two-column format +# with the specified key column width (identical to using +# `batslib_print_kv_single'). +# +# Otherwise, print all pairs in multi-line format after indenting values +# with two spaces for readability (identical to using `batslib_prefix' +# and `batslib_print_kv_multi') +# +# Globals: +# none +# Arguments: +# $1 - width of key column (for two-column format) +# $even - key +# $odd - value of the previous key +# Returns: +# none +# Outputs: +# STDOUT - formatted key-value pairs +batslib_print_kv_single_or_multi() { + local -ir width="$1"; shift + local -a pairs=( "$@" ) + + local -a values=() + local -i i + for (( i=1; i < ${#pairs[@]}; i+=2 )); do + values+=( "${pairs[$i]}" ) + done + + if batslib_is_single_line "${values[@]}"; then + batslib_print_kv_single "$width" "${pairs[@]}" + else + local -i i + for (( i=1; i < ${#pairs[@]}; i+=2 )); do + pairs[$i]="$( batslib_prefix < <(printf '%s' "${pairs[$i]}") )" + done + batslib_print_kv_multi "${pairs[@]}" + fi +} + +# Prefix each line read from the standard input with the given string. +# +# Globals: +# none +# Arguments: +# $1 - [= ] prefix string +# Returns: +# none +# Inputs: +# STDIN - lines +# Outputs: +# STDOUT - prefixed lines +batslib_prefix() { + local -r prefix="${1:- }" + local line + while IFS='' read -r line || [[ -n $line ]]; do + printf '%s%s\n' "$prefix" "$line" + done +} + +# Mark select lines of the text read from the standard input by +# overwriting their beginning with the given string. +# +# Usually the input is indented by a few spaces using `batslib_prefix' +# first. +# +# Globals: +# none +# Arguments: +# $1 - marking string +# $@ - indices (zero-based) of lines to mark +# Returns: +# none +# Inputs: +# STDIN - lines +# Outputs: +# STDOUT - lines after marking +batslib_mark() { + local -r symbol="$1"; shift + # Sort line numbers. + set -- $( sort -nu <<< "$( printf '%d\n' "$@" )" ) + + local line + local -i idx=0 + while IFS='' read -r line || [[ -n $line ]]; do + if (( ${1:--1} == idx )); then + printf '%s\n' "${symbol}${line:${#symbol}}" + shift + else + printf '%s\n' "$line" + fi + (( ++idx )) + done +} + +# Enclose the input text in header and footer lines. +# +# The header contains the given string as title. The output is preceded +# and followed by an additional newline to make it stand out more. +# +# Globals: +# none +# Arguments: +# $1 - title +# Returns: +# none +# Inputs: +# STDIN - text +# Outputs: +# STDOUT - decorated text +batslib_decorate() { + echo + echo "-- $1 --" + cat - + echo '--' + echo +} \ No newline at end of file diff --git a/test/lib/docker_helpers.bash b/test/lib/docker_helpers.bash new file mode 100644 index 0000000..05eb0be --- /dev/null +++ b/test/lib/docker_helpers.bash @@ -0,0 +1,61 @@ +## functions to help deal with docker + +# Removes container $1 +function docker_clean { + docker kill $1 &>/dev/null ||: + sleep .25s + docker rm -vf $1 &>/dev/null ||: + sleep .25s +} + +# get the ip of docker container $1 +function docker_ip { + docker inspect --format '{{ .NetworkSettings.IPAddress }}' $1 +} + +# get the running state of container $1 +# → true/false +# fails if the container does not exist +function docker_running_state { + docker inspect -f {{.State.Running}} $1 +} + +# get the docker container $1 PID +function docker_pid { + docker inspect --format {{.State.Pid}} $1 +} + +# asserts logs from container $1 contains $2 +function docker_assert_log { + local -r container=$1 + shift + run docker logs $container + assert_output -p "$*" +} + +# wait for container $2 to contain a given text in its log +# $1 container +# $2 timeout in second +# $* text to wait for +function docker_wait_for_log { + local -r container=$1 + shift + local -ir timeout_sec=$1 + shift + retry $(( $timeout_sec * 2 )) .5s docker_assert_log $container "$*" +} + +# Create a docker container named $1 which exposes the docker host unix +# socket over tcp on port 2375. +# +# $1 container name +function docker_tcp { + local container_name="$1" + docker_clean $container_name + docker run -d \ + --name $container_name \ + --expose 2375 \ + -v /var/run/docker.sock:/var/run/docker.sock \ + rancher/socat-docker + docker -H tcp://$(docker_ip $container_name):2375 version +} diff --git a/test/lib/helpers.bash b/test/lib/helpers.bash new file mode 100644 index 0000000..dffcd66 --- /dev/null +++ b/test/lib/helpers.bash @@ -0,0 +1,22 @@ +## add the retry function to bats + +# Retry a command $1 times until it succeeds. Wait $2 seconds between retries. +function retry { + local attempts=$1 + shift + local delay=$1 + shift + local i + + for ((i=0; i < attempts; i++)); do + run "$@" + if [ "$status" -eq 0 ]; then + echo "$output" + return 0 + fi + sleep $delay + done + + echo "Command \"$@\" failed $attempts times. Status: $status. Output: $output" >&2 + false +} diff --git a/test/multiple-hosts.bats b/test/multiple-hosts.bats new file mode 100644 index 0000000..0380509 --- /dev/null +++ b/test/multiple-hosts.bats @@ -0,0 +1,47 @@ +#!/usr/bin/env bats +load test_helpers +SUT_CONTAINER=bats-nginx-proxy-${TEST_FILE} + +function setup { + # make sure to stop any web container before each test so we don't + # have any unexpected contaiener running with VIRTUAL_HOST or VIRUTAL_PORT set + docker ps -q --filter "label=bats-type=web" | xargs -r docker stop >&2 +} + + +@test "[$TEST_FILE] start a nginx-proxy container" { + run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro + assert_success + docker_wait_for_log $SUT_CONTAINER 3 "Watching docker events" +} + +@test "[$TEST_FILE] nginx-proxy forwards requests for 2 hosts" { + # WHEN a container runs a web server with VIRTUAL_HOST set for multiple hosts + docker_clean bats-multiple-hosts-1 + run docker run -d \ + --label bats-type="web" \ + --name bats-multiple-hosts-1 \ + -e VIRTUAL_HOST=multiple-hosts-1-A.bats,multiple-hosts-1-B.bats \ + --expose 80 \ + -w /data \ + python:3 python -m http.server 80 + assert_success + run retry 5 1s curl_container bats-multiple-hosts-1 / --head + assert_output -l 0 $'HTTP/1.0 200 OK\r' + + # THEN querying the proxy without Host header → 503 + run curl_container $SUT_CONTAINER / --head + assert_output -l 0 $'HTTP/1.1 503 Service Temporarily Unavailable\r' + + # THEN querying the proxy with unknown Host header → 503 + run curl_container $SUT_CONTAINER /data --header "Host: webFOO.bats" --head + assert_output -l 0 $'HTTP/1.1 503 Service Temporarily Unavailable\r' + + # THEN + run curl_container $SUT_CONTAINER / --head --header 'Host: multiple-hosts-1-A.bats' + assert_output -l 0 $'HTTP/1.1 200 OK\r' || (echo $output; echo $status; false) + + # THEN + run curl_container $SUT_CONTAINER / --head --header 'Host: multiple-hosts-1-B.bats' + assert_output -l 0 $'HTTP/1.1 200 OK\r' +} diff --git a/test/multiple-ports.bats b/test/multiple-ports.bats new file mode 100644 index 0000000..a711056 --- /dev/null +++ b/test/multiple-ports.bats @@ -0,0 +1,54 @@ +#!/usr/bin/env bats +load test_helpers +SUT_CONTAINER=bats-nginx-proxy-${TEST_FILE} + +function setup { + # make sure to stop any web container before each test so we don't + # have any unexpected contaiener running with VIRTUAL_HOST or VIRUTAL_PORT set + docker ps -q --filter "label=bats-type=web" | xargs -r docker stop >&2 +} + + +@test "[$TEST_FILE] start a nginx-proxy container" { + # GIVEN nginx-proxy + run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro + assert_success + docker_wait_for_log $SUT_CONTAINER 3 "Watching docker events" +} + + +@test "[$TEST_FILE] nginx-proxy defaults to the service running on port 80" { + # WHEN + prepare_web_container bats-web-${TEST_FILE}-1 "80 90" -e VIRTUAL_HOST=web.bats + + # THEN + assert_response_is_from_port 80 +} + + +@test "[$TEST_FILE] VIRTUAL_PORT=90 while port 80 is also exposed" { + # GIVEN + prepare_web_container bats-web-${TEST_FILE}-2 "80 90" -e VIRTUAL_HOST=web.bats -e VIRTUAL_PORT=90 + + # THEN + assert_response_is_from_port 90 +} + + +@test "[$TEST_FILE] single exposed port != 80" { + # GIVEN + prepare_web_container bats-web-${TEST_FILE}-3 1234 -e VIRTUAL_HOST=web.bats + + # THEN + assert_response_is_from_port 1234 +} + + +# assert querying nginx-proxy provides a response from the expected port of the web container +# $1 port we are expecting an response from +function assert_response_is_from_port { + local -r port=$1 + run curl_container $SUT_CONTAINER /data --header "Host: web.bats" + assert_output "answer from port $port" +} + diff --git a/test/test_helpers.bash b/test/test_helpers.bash new file mode 100644 index 0000000..9063736 --- /dev/null +++ b/test/test_helpers.bash @@ -0,0 +1,128 @@ +# Test if requirements are met +( + type docker &>/dev/null || ( echo "docker is not available"; exit 1 ) + type curl &>/dev/null || ( echo "curl is not available"; exit 1 ) +)>&2 + + +# set a few global variables +SUT_IMAGE=jwilder/nginx-proxy:bats +TEST_FILE=$(basename $BATS_TEST_FILENAME .bats) + + +# load the Bats stdlib (see https://github.com/sstephenson/bats/pull/110) +DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +export BATS_LIB="${DIR}/lib/bats" +load "${BATS_LIB}/batslib.bash" + + +# load additional bats helpers +load ${DIR}/lib/helpers.bash +load ${DIR}/lib/docker_helpers.bash + + +# Define functions specific to our test suite + +# run the SUT docker container +# and makes sure it remains started +# and displays the nginx-proxy start logs +# +# $1 container name +# $@ other options for the `docker run` command +function nginxproxy { + local -r container_name=$1 + shift + docker_clean $container_name \ + && docker run -d \ + --name $container_name \ + "$@" \ + $SUT_IMAGE \ + && wait_for_nginxproxy_container_to_start $container_name \ + && docker logs $container_name +} + + +# wait until the nginx-proxy container is ready to operate +# +# $1 container name +function wait_for_nginxproxy_container_to_start { + local -r container_name=$1 + sleep .5s # give time to eventually fail to initialize + + function is_running { + run docker_running_state $container_name + assert_output "true" + } + retry 3 1 is_running +} + + +# Send a HTTP request to container $1 for path $2 and +# Additional curl options can be passed as $@ +# +# $1 container name +# $2 HTTP path to query +# $@ additional options to pass to the curl command +function curl_container { + local -r container=$1 + local -r path=$2 + shift 2 + curl --silent \ + --connect-timeout 5 \ + --max-time 20 \ + "$@" \ + http://$(docker_ip $container)${path} +} + + +# start a container running (one or multiple) webservers listening on given ports +# +# $1 container name +# $2 container port(s). If multiple ports, provide them as a string: "80 90" with a space as a separator +# $@ `docker run` additional options +function prepare_web_container { + local -r container_name=$1 + local -r ports=$2 + shift 2 + local -r options="$@" + + local expose_option="" + for port in $ports; do + expose_option="${expose_option}--expose=$port " + done + + ( # used for debugging purpose. Will be display if test fails + echo "container_name: $container_name" + echo "ports: $ports" + echo "options: $options" + echo "expose_option: $expose_option" + )>&2 + + docker_clean $container_name + + # GIVEN a container exposing 1 webserver on ports 1234 + run docker run -d \ + --label bats-type="web" \ + --name $container_name \ + $expose_option \ + -w /var/www/ \ + $options \ + -e PYTHON_PORTS="$ports" \ + python:3 sh -c " + for port in \$PYTHON_PORTS; do + echo starting a web server listening on port \$port; + mkdir /var/www/\$port + cd /var/www/\$port + echo \"answer from port \$port\" > data + python -m http.server \$port & + done + wait + " + assert_success + + # THEN querying directly port works + for port in $ports; do + run retry 5 1s curl --silent --fail http://$(docker_ip $container_name):$port/data + assert_output "answer from port $port" + done +} \ No newline at end of file diff --git a/test/wildcard-hosts.bats b/test/wildcard-hosts.bats new file mode 100644 index 0000000..8242fc1 --- /dev/null +++ b/test/wildcard-hosts.bats @@ -0,0 +1,68 @@ +#!/usr/bin/env bats +load test_helpers +SUT_CONTAINER=bats-nginx-proxy-${TEST_FILE} + +function setup { + # make sure to stop any web container before each test so we don't + # have any unexpected contaiener running with VIRTUAL_HOST or VIRUTAL_PORT set + docker ps -q --filter "label=bats-type=web" | xargs -r docker stop >&2 +} + + +@test "[$TEST_FILE] start a nginx-proxy container" { + # GIVEN + run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro + assert_success + docker_wait_for_log $SUT_CONTAINER 3 "Watching docker events" +} + + +@test "[$TEST_FILE] VIRTUAL_HOST=*.wildcard.bats" { + # WHEN + prepare_web_container bats-wildcard-hosts-1 80 -e VIRTUAL_HOST=*.wildcard.bats + + # THEN + assert_200 f00.wildcard.bats + assert_200 bar.wildcard.bats + assert_503 unexpected.host.bats +} + +@test "[$TEST_FILE] VIRTUAL_HOST=wildcard.bats.*" { + # WHEN + prepare_web_container bats-wildcard-hosts-2 80 -e VIRTUAL_HOST=wildcard.bats.* + + # THEN + assert_200 wildcard.bats.f00 + assert_200 wildcard.bats.bar + assert_503 unexpected.host.bats +} + +@test "[$TEST_FILE] VIRTUAL_HOST=~^foo\.bar\..*\.bats" { + # WHEN + prepare_web_container bats-wildcard-hosts-2 80 -e VIRTUAL_HOST=~^foo\.bar\..*\.bats + + # THEN + assert_200 foo.bar.whatever.bats + assert_200 foo.bar.why.not.bats + assert_503 unexpected.host.bats + +} + + +# assert that querying nginx-proxy with the given Host header produces a `HTTP 200` response +# $1 Host HTTP header to use when querying nginx-proxy +function assert_200 { + local -r host=$1 + + run curl_container $SUT_CONTAINER / --head --header "Host: $host" + assert_output -l 0 $'HTTP/1.1 200 OK\r' +} + +# assert that querying nginx-proxy with the given Host header produces a `HTTP 503` response +# $1 Host HTTP header to use when querying nginx-proxy +function assert_503 { + local -r host=$1 + + run curl_container $SUT_CONTAINER / --head --header "Host: $host" + assert_output -l 0 $'HTTP/1.1 503 Service Temporarily Unavailable\r' +} \ No newline at end of file From b4d1acbf2d38539daa6a0caacc9566601f5a20aa Mon Sep 17 00:00:00 2001 From: Thomas LEVEIL Date: Wed, 30 Sep 2015 23:40:04 +0000 Subject: [PATCH 40/55] tests: refactoring --- test/default-host.bats | 11 +---------- test/docker.bats | 2 +- test/multiple-hosts.bats | 20 +++++--------------- 3 files changed, 7 insertions(+), 26 deletions(-) diff --git a/test/default-host.bats b/test/default-host.bats index 0adf686..503bb9f 100644 --- a/test/default-host.bats +++ b/test/default-host.bats @@ -12,16 +12,7 @@ function setup { SUT_CONTAINER=bats-nginx-proxy-${TEST_FILE}-1 # GIVEN a webserver with VIRTUAL_HOST set to web.bats - docker_clean bats-web - run docker run -d \ - --label bats-type="web" \ - --name bats-web \ - -e VIRTUAL_HOST=web.bats \ - --expose 80 \ - -w /var/www \ - python:3 \ - python -m http.server 80 - assert_success + prepare_web_container bats-web 80 -e VIRTUAL_HOST=web.bats # WHEN nginx-proxy runs with DEFAULT_HOST set to web.bats run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro -e DEFAULT_HOST=web.bats diff --git a/test/docker.bats b/test/docker.bats index 13d84a2..44d31b9 100644 --- a/test/docker.bats +++ b/test/docker.bats @@ -62,7 +62,7 @@ load test_helpers -v /etc/nginx/certs/ \ nginx:latest assert_success - run retry 5 1s curl --silent --fail -A "before-docker-gen" --head http://$(docker_ip bats-nginx)/ + run retry 5 1s curl --silent --fail --head http://$(docker_ip bats-nginx)/ assert_output -l 0 $'HTTP/1.1 200 OK\r' # WHEN docker-gen runs on our docker host diff --git a/test/multiple-hosts.bats b/test/multiple-hosts.bats index 0380509..c5c5749 100644 --- a/test/multiple-hosts.bats +++ b/test/multiple-hosts.bats @@ -17,17 +17,7 @@ function setup { @test "[$TEST_FILE] nginx-proxy forwards requests for 2 hosts" { # WHEN a container runs a web server with VIRTUAL_HOST set for multiple hosts - docker_clean bats-multiple-hosts-1 - run docker run -d \ - --label bats-type="web" \ - --name bats-multiple-hosts-1 \ - -e VIRTUAL_HOST=multiple-hosts-1-A.bats,multiple-hosts-1-B.bats \ - --expose 80 \ - -w /data \ - python:3 python -m http.server 80 - assert_success - run retry 5 1s curl_container bats-multiple-hosts-1 / --head - assert_output -l 0 $'HTTP/1.0 200 OK\r' + prepare_web_container bats-multiple-hosts-1 80 -e VIRTUAL_HOST=multiple-hosts-1-A.bats,multiple-hosts-1-B.bats # THEN querying the proxy without Host header → 503 run curl_container $SUT_CONTAINER / --head @@ -38,10 +28,10 @@ function setup { assert_output -l 0 $'HTTP/1.1 503 Service Temporarily Unavailable\r' # THEN - run curl_container $SUT_CONTAINER / --head --header 'Host: multiple-hosts-1-A.bats' - assert_output -l 0 $'HTTP/1.1 200 OK\r' || (echo $output; echo $status; false) + run curl_container $SUT_CONTAINER /data --header 'Host: multiple-hosts-1-A.bats' + assert_output "answer from port 80" # THEN - run curl_container $SUT_CONTAINER / --head --header 'Host: multiple-hosts-1-B.bats' - assert_output -l 0 $'HTTP/1.1 200 OK\r' + run curl_container $SUT_CONTAINER /data --header 'Host: multiple-hosts-1-B.bats' + assert_output "answer from port 80" } From 865b14e02977cef0062fc26c9a875a8539f3ad9d Mon Sep 17 00:00:00 2001 From: Thomas LEVEIL Date: Wed, 30 Sep 2015 23:56:25 +0000 Subject: [PATCH 41/55] tests: fix minor bug in docker_wait_for_log --- test/lib/docker_helpers.bash | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/lib/docker_helpers.bash b/test/lib/docker_helpers.bash index 05eb0be..bbaf27e 100644 --- a/test/lib/docker_helpers.bash +++ b/test/lib/docker_helpers.bash @@ -33,15 +33,14 @@ function docker_assert_log { assert_output -p "$*" } -# wait for container $2 to contain a given text in its log +# wait for a container to produce a given text in its log # $1 container # $2 timeout in second # $* text to wait for function docker_wait_for_log { local -r container=$1 - shift - local -ir timeout_sec=$1 - shift + local -ir timeout_sec=$2 + shift 2 retry $(( $timeout_sec * 2 )) .5s docker_assert_log $container "$*" } From 92be4b6d54860635455396dbd42c59a86691f72b Mon Sep 17 00:00:00 2001 From: Thomas LEVEIL Date: Wed, 30 Sep 2015 23:57:13 +0000 Subject: [PATCH 42/55] doc --- test/lib/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lib/README.md b/test/lib/README.md index bd444fd..1021dc4 100644 --- a/test/lib/README.md +++ b/test/lib/README.md @@ -3,4 +3,4 @@ bats lib found on https://github.com/sstephenson/bats/pull/110 -When that pull request will be merged, that lib won't be necessary anymore. \ No newline at end of file +When that pull request will be merged, the `test/lib/bats` won't be necessary anymore. \ No newline at end of file From 6b5e12a946ccb991306d78e3240866fbc936bfca Mon Sep 17 00:00:00 2001 From: Mike Dillon Date: Tue, 6 Oct 2015 21:18:00 -0700 Subject: [PATCH 43/55] Add missing access_log statement to HTTPS fallback --- nginx.tmpl | 1 + 1 file changed, 1 insertion(+) diff --git a/nginx.tmpl b/nginx.tmpl index 788ca90..6b45b90 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -62,6 +62,7 @@ server { server { server_name _; # This is just an invalid value which will never trigger on a real hostname. listen 443 ssl http2; + access_log /var/log/nginx/access.log vhost; return 503; ssl_certificate /etc/nginx/certs/default.crt; From 5c2280df84afe974f85f8d3622c2597cc5fa6bf7 Mon Sep 17 00:00:00 2001 From: Jonas Svatos Date: Thu, 8 Oct 2015 12:03:28 +0200 Subject: [PATCH 44/55] fix condition for default config location Signed-off-by: Jonas Svatos --- nginx.tmpl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index 6b45b90..6300d89 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -139,7 +139,7 @@ server { {{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }} include {{ printf "/etc/nginx/vhost.d/%s" $host }}; - {{ else if (exists "/etc/vhost.d/default") }} + {{ else if (exists "/etc/nginx/vhost.d/default") }} include /etc/nginx/vhost.d/default; {{ end }} @@ -151,7 +151,7 @@ server { {{ end }} {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }} include {{ printf "/etc/nginx/vhost.d/%s_location" $host}}; - {{ else if (exists "/etc/vhost.d/default_location") }} + {{ else if (exists "/etc/nginx/vhost.d/default_location") }} include /etc/nginx/vhost.d/default_location; {{ end }} } @@ -165,7 +165,7 @@ server { {{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }} include {{ printf "/etc/nginx/vhost.d/%s" $host }}; - {{ else if (exists "/etc/vhost.d/default") }} + {{ else if (exists "/etc/nginx/vhost.d/default") }} include /etc/nginx/vhost.d/default; {{ end }} @@ -177,7 +177,7 @@ server { {{ end }} {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }} include {{ printf "/etc/nginx/vhost.d/%s_location" $host}}; - {{ else if (exists "/etc/vhost.d/default_location") }} + {{ else if (exists "/etc/nginx/vhost.d/default_location") }} include /etc/nginx/vhost.d/default_location; {{ end }} } From 495b0ad8b6c844e64a4283c11b9478f6a06b0b49 Mon Sep 17 00:00:00 2001 From: Jason Wilder Date: Thu, 8 Oct 2015 22:08:04 -0600 Subject: [PATCH 45/55] Add circleci build status badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4053506..22cae63 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![nginx 1.9.5](https://img.shields.io/badge/nginx-1.9.5-brightgreen.svg) ![License MIT](https://img.shields.io/badge/license-MIT-blue.svg) +![nginx 1.9.5](https://img.shields.io/badge/nginx-1.9.5-brightgreen.svg) ![License MIT](https://img.shields.io/badge/license-MIT-blue.svg) ![Build](https://circleci.com/gh/jwilder/nginx-proxy.svg?&style=shield&circle-token=2da3ee844076a47371bd45da81cf27409ca7306a) nginx-proxy sets up a container running nginx and [docker-gen][1]. docker-gen generates reverse proxy configs for nginx and reloads nginx when containers are started and stopped. From 99560da65c03189be3c1f158b68b81f889ae7693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=89VEIL?= Date: Fri, 9 Oct 2015 15:33:29 +0200 Subject: [PATCH 46/55] fix CircleCI badge link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 22cae63..80c4c6b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![nginx 1.9.5](https://img.shields.io/badge/nginx-1.9.5-brightgreen.svg) ![License MIT](https://img.shields.io/badge/license-MIT-blue.svg) ![Build](https://circleci.com/gh/jwilder/nginx-proxy.svg?&style=shield&circle-token=2da3ee844076a47371bd45da81cf27409ca7306a) +![nginx 1.9.5](https://img.shields.io/badge/nginx-1.9.5-brightgreen.svg) ![License MIT](https://img.shields.io/badge/license-MIT-blue.svg) [![Build](https://circleci.com/gh/jwilder/nginx-proxy.svg?&style=shield&circle-token=2da3ee844076a47371bd45da81cf27409ca7306a)](https://circleci.com/gh/jwilder/nginx-proxy) nginx-proxy sets up a container running nginx and [docker-gen][1]. docker-gen generates reverse proxy configs for nginx and reloads nginx when containers are started and stopped. From 5fe9411d8820e07ca2a5031828dd18f60532a894 Mon Sep 17 00:00:00 2001 From: Mike Dillon Date: Fri, 9 Oct 2015 23:07:46 -0700 Subject: [PATCH 47/55] Change line endings to Unix --- test/multiple-ports.bats | 108 +++++++++++++++---------------- test/wildcard-hosts.bats | 136 +++++++++++++++++++-------------------- 2 files changed, 122 insertions(+), 122 deletions(-) diff --git a/test/multiple-ports.bats b/test/multiple-ports.bats index a711056..a8ff314 100644 --- a/test/multiple-ports.bats +++ b/test/multiple-ports.bats @@ -1,54 +1,54 @@ -#!/usr/bin/env bats -load test_helpers -SUT_CONTAINER=bats-nginx-proxy-${TEST_FILE} - -function setup { - # make sure to stop any web container before each test so we don't - # have any unexpected contaiener running with VIRTUAL_HOST or VIRUTAL_PORT set - docker ps -q --filter "label=bats-type=web" | xargs -r docker stop >&2 -} - - -@test "[$TEST_FILE] start a nginx-proxy container" { - # GIVEN nginx-proxy - run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro - assert_success - docker_wait_for_log $SUT_CONTAINER 3 "Watching docker events" -} - - -@test "[$TEST_FILE] nginx-proxy defaults to the service running on port 80" { - # WHEN - prepare_web_container bats-web-${TEST_FILE}-1 "80 90" -e VIRTUAL_HOST=web.bats - - # THEN - assert_response_is_from_port 80 -} - - -@test "[$TEST_FILE] VIRTUAL_PORT=90 while port 80 is also exposed" { - # GIVEN - prepare_web_container bats-web-${TEST_FILE}-2 "80 90" -e VIRTUAL_HOST=web.bats -e VIRTUAL_PORT=90 - - # THEN - assert_response_is_from_port 90 -} - - -@test "[$TEST_FILE] single exposed port != 80" { - # GIVEN - prepare_web_container bats-web-${TEST_FILE}-3 1234 -e VIRTUAL_HOST=web.bats - - # THEN - assert_response_is_from_port 1234 -} - - -# assert querying nginx-proxy provides a response from the expected port of the web container -# $1 port we are expecting an response from -function assert_response_is_from_port { - local -r port=$1 - run curl_container $SUT_CONTAINER /data --header "Host: web.bats" - assert_output "answer from port $port" -} - +#!/usr/bin/env bats +load test_helpers +SUT_CONTAINER=bats-nginx-proxy-${TEST_FILE} + +function setup { + # make sure to stop any web container before each test so we don't + # have any unexpected contaiener running with VIRTUAL_HOST or VIRUTAL_PORT set + docker ps -q --filter "label=bats-type=web" | xargs -r docker stop >&2 +} + + +@test "[$TEST_FILE] start a nginx-proxy container" { + # GIVEN nginx-proxy + run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro + assert_success + docker_wait_for_log $SUT_CONTAINER 3 "Watching docker events" +} + + +@test "[$TEST_FILE] nginx-proxy defaults to the service running on port 80" { + # WHEN + prepare_web_container bats-web-${TEST_FILE}-1 "80 90" -e VIRTUAL_HOST=web.bats + + # THEN + assert_response_is_from_port 80 +} + + +@test "[$TEST_FILE] VIRTUAL_PORT=90 while port 80 is also exposed" { + # GIVEN + prepare_web_container bats-web-${TEST_FILE}-2 "80 90" -e VIRTUAL_HOST=web.bats -e VIRTUAL_PORT=90 + + # THEN + assert_response_is_from_port 90 +} + + +@test "[$TEST_FILE] single exposed port != 80" { + # GIVEN + prepare_web_container bats-web-${TEST_FILE}-3 1234 -e VIRTUAL_HOST=web.bats + + # THEN + assert_response_is_from_port 1234 +} + + +# assert querying nginx-proxy provides a response from the expected port of the web container +# $1 port we are expecting an response from +function assert_response_is_from_port { + local -r port=$1 + run curl_container $SUT_CONTAINER /data --header "Host: web.bats" + assert_output "answer from port $port" +} + diff --git a/test/wildcard-hosts.bats b/test/wildcard-hosts.bats index 8242fc1..4e1484f 100644 --- a/test/wildcard-hosts.bats +++ b/test/wildcard-hosts.bats @@ -1,68 +1,68 @@ -#!/usr/bin/env bats -load test_helpers -SUT_CONTAINER=bats-nginx-proxy-${TEST_FILE} - -function setup { - # make sure to stop any web container before each test so we don't - # have any unexpected contaiener running with VIRTUAL_HOST or VIRUTAL_PORT set - docker ps -q --filter "label=bats-type=web" | xargs -r docker stop >&2 -} - - -@test "[$TEST_FILE] start a nginx-proxy container" { - # GIVEN - run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro - assert_success - docker_wait_for_log $SUT_CONTAINER 3 "Watching docker events" -} - - -@test "[$TEST_FILE] VIRTUAL_HOST=*.wildcard.bats" { - # WHEN - prepare_web_container bats-wildcard-hosts-1 80 -e VIRTUAL_HOST=*.wildcard.bats - - # THEN - assert_200 f00.wildcard.bats - assert_200 bar.wildcard.bats - assert_503 unexpected.host.bats -} - -@test "[$TEST_FILE] VIRTUAL_HOST=wildcard.bats.*" { - # WHEN - prepare_web_container bats-wildcard-hosts-2 80 -e VIRTUAL_HOST=wildcard.bats.* - - # THEN - assert_200 wildcard.bats.f00 - assert_200 wildcard.bats.bar - assert_503 unexpected.host.bats -} - -@test "[$TEST_FILE] VIRTUAL_HOST=~^foo\.bar\..*\.bats" { - # WHEN - prepare_web_container bats-wildcard-hosts-2 80 -e VIRTUAL_HOST=~^foo\.bar\..*\.bats - - # THEN - assert_200 foo.bar.whatever.bats - assert_200 foo.bar.why.not.bats - assert_503 unexpected.host.bats - -} - - -# assert that querying nginx-proxy with the given Host header produces a `HTTP 200` response -# $1 Host HTTP header to use when querying nginx-proxy -function assert_200 { - local -r host=$1 - - run curl_container $SUT_CONTAINER / --head --header "Host: $host" - assert_output -l 0 $'HTTP/1.1 200 OK\r' -} - -# assert that querying nginx-proxy with the given Host header produces a `HTTP 503` response -# $1 Host HTTP header to use when querying nginx-proxy -function assert_503 { - local -r host=$1 - - run curl_container $SUT_CONTAINER / --head --header "Host: $host" - assert_output -l 0 $'HTTP/1.1 503 Service Temporarily Unavailable\r' -} \ No newline at end of file +#!/usr/bin/env bats +load test_helpers +SUT_CONTAINER=bats-nginx-proxy-${TEST_FILE} + +function setup { + # make sure to stop any web container before each test so we don't + # have any unexpected contaiener running with VIRTUAL_HOST or VIRUTAL_PORT set + docker ps -q --filter "label=bats-type=web" | xargs -r docker stop >&2 +} + + +@test "[$TEST_FILE] start a nginx-proxy container" { + # GIVEN + run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro + assert_success + docker_wait_for_log $SUT_CONTAINER 3 "Watching docker events" +} + + +@test "[$TEST_FILE] VIRTUAL_HOST=*.wildcard.bats" { + # WHEN + prepare_web_container bats-wildcard-hosts-1 80 -e VIRTUAL_HOST=*.wildcard.bats + + # THEN + assert_200 f00.wildcard.bats + assert_200 bar.wildcard.bats + assert_503 unexpected.host.bats +} + +@test "[$TEST_FILE] VIRTUAL_HOST=wildcard.bats.*" { + # WHEN + prepare_web_container bats-wildcard-hosts-2 80 -e VIRTUAL_HOST=wildcard.bats.* + + # THEN + assert_200 wildcard.bats.f00 + assert_200 wildcard.bats.bar + assert_503 unexpected.host.bats +} + +@test "[$TEST_FILE] VIRTUAL_HOST=~^foo\.bar\..*\.bats" { + # WHEN + prepare_web_container bats-wildcard-hosts-2 80 -e VIRTUAL_HOST=~^foo\.bar\..*\.bats + + # THEN + assert_200 foo.bar.whatever.bats + assert_200 foo.bar.why.not.bats + assert_503 unexpected.host.bats + +} + + +# assert that querying nginx-proxy with the given Host header produces a `HTTP 200` response +# $1 Host HTTP header to use when querying nginx-proxy +function assert_200 { + local -r host=$1 + + run curl_container $SUT_CONTAINER / --head --header "Host: $host" + assert_output -l 0 $'HTTP/1.1 200 OK\r' +} + +# assert that querying nginx-proxy with the given Host header produces a `HTTP 503` response +# $1 Host HTTP header to use when querying nginx-proxy +function assert_503 { + local -r host=$1 + + run curl_container $SUT_CONTAINER / --head --header "Host: $host" + assert_output -l 0 $'HTTP/1.1 503 Service Temporarily Unavailable\r' +} From 2cba8a8d5f525c1e9ba4b8c06e396d2ee14fc522 Mon Sep 17 00:00:00 2001 From: Mike Dillon Date: Fri, 9 Oct 2015 23:10:38 -0700 Subject: [PATCH 48/55] Avoid xargs -r The -r option is not available on OS X --- test/default-host.bats | 5 ++++- test/multiple-hosts.bats | 5 ++++- test/multiple-ports.bats | 5 ++++- test/wildcard-hosts.bats | 5 ++++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/test/default-host.bats b/test/default-host.bats index 503bb9f..4e9d84e 100644 --- a/test/default-host.bats +++ b/test/default-host.bats @@ -4,7 +4,10 @@ load test_helpers function setup { # make sure to stop any web container before each test so we don't # have any unexpected contaiener running with VIRTUAL_HOST or VIRUTAL_PORT set - docker ps -q --filter "label=bats-type=web" | xargs -r docker stop >&2 + CIDS=( $(docker ps -q --filter "label=bats-type=web") ) + if [ ${#CIDS[@]} -gt 0 ]; then + docker stop ${CIDS[@]} >&2 + fi } diff --git a/test/multiple-hosts.bats b/test/multiple-hosts.bats index c5c5749..695aec1 100644 --- a/test/multiple-hosts.bats +++ b/test/multiple-hosts.bats @@ -5,7 +5,10 @@ SUT_CONTAINER=bats-nginx-proxy-${TEST_FILE} function setup { # make sure to stop any web container before each test so we don't # have any unexpected contaiener running with VIRTUAL_HOST or VIRUTAL_PORT set - docker ps -q --filter "label=bats-type=web" | xargs -r docker stop >&2 + CIDS=( $(docker ps -q --filter "label=bats-type=web") ) + if [ ${#CIDS[@]} -gt 0 ]; then + docker stop ${CIDS[@]} >&2 + fi } diff --git a/test/multiple-ports.bats b/test/multiple-ports.bats index a8ff314..a520571 100644 --- a/test/multiple-ports.bats +++ b/test/multiple-ports.bats @@ -5,7 +5,10 @@ SUT_CONTAINER=bats-nginx-proxy-${TEST_FILE} function setup { # make sure to stop any web container before each test so we don't # have any unexpected contaiener running with VIRTUAL_HOST or VIRUTAL_PORT set - docker ps -q --filter "label=bats-type=web" | xargs -r docker stop >&2 + CIDS=( $(docker ps -q --filter "label=bats-type=web") ) + if [ ${#CIDS[@]} -gt 0 ]; then + docker stop ${CIDS[@]} >&2 + fi } diff --git a/test/wildcard-hosts.bats b/test/wildcard-hosts.bats index 4e1484f..88ca1e7 100644 --- a/test/wildcard-hosts.bats +++ b/test/wildcard-hosts.bats @@ -5,7 +5,10 @@ SUT_CONTAINER=bats-nginx-proxy-${TEST_FILE} function setup { # make sure to stop any web container before each test so we don't # have any unexpected contaiener running with VIRTUAL_HOST or VIRUTAL_PORT set - docker ps -q --filter "label=bats-type=web" | xargs -r docker stop >&2 + CIDS=( $(docker ps -q --filter "label=bats-type=web") ) + if [ ${#CIDS[@]} -gt 0 ]; then + docker stop ${CIDS[@]} >&2 + fi } From 0d2bc381791bf15746e363b8dcf9acc5a28fdd6c Mon Sep 17 00:00:00 2001 From: Mike Dillon Date: Fri, 9 Oct 2015 23:11:03 -0700 Subject: [PATCH 49/55] Run curl commands from a sibling container --- test/docker.bats | 2 +- test/test_helpers.bash | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/docker.bats b/test/docker.bats index 44d31b9..d5fde7c 100644 --- a/test/docker.bats +++ b/test/docker.bats @@ -62,7 +62,7 @@ load test_helpers -v /etc/nginx/certs/ \ nginx:latest assert_success - run retry 5 1s curl --silent --fail --head http://$(docker_ip bats-nginx)/ + run retry 5 1s docker run --rm appropriate/curl --silent --fail --head http://$(docker_ip bats-nginx)/ assert_output -l 0 $'HTTP/1.1 200 OK\r' # WHEN docker-gen runs on our docker host diff --git a/test/test_helpers.bash b/test/test_helpers.bash index 9063736..d4f0842 100644 --- a/test/test_helpers.bash +++ b/test/test_helpers.bash @@ -1,7 +1,7 @@ # Test if requirements are met ( type docker &>/dev/null || ( echo "docker is not available"; exit 1 ) - type curl &>/dev/null || ( echo "curl is not available"; exit 1 ) + #type curl &>/dev/null || ( echo "curl is not available"; exit 1 ) )>&2 @@ -67,7 +67,7 @@ function curl_container { local -r container=$1 local -r path=$2 shift 2 - curl --silent \ + docker run --rm appropriate/curl --silent \ --connect-timeout 5 \ --max-time 20 \ "$@" \ @@ -122,7 +122,7 @@ function prepare_web_container { # THEN querying directly port works for port in $ports; do - run retry 5 1s curl --silent --fail http://$(docker_ip $container_name):$port/data + run retry 5 1s docker run --rm appropriate/curl --silent --fail http://$(docker_ip $container_name):$port/data assert_output "answer from port $port" done } \ No newline at end of file From b1a08843da6cf2983dec7cebb490aee2cf086273 Mon Sep 17 00:00:00 2001 From: Mike Dillon Date: Sun, 11 Oct 2015 10:55:17 -0700 Subject: [PATCH 50/55] Avoid breakage from IFS being reset in "run" See https://github.com/sstephenson/bats/issues/89 --- test/test_helpers.bash | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/test_helpers.bash b/test/test_helpers.bash index d4f0842..c4a2d1c 100644 --- a/test/test_helpers.bash +++ b/test/test_helpers.bash @@ -87,6 +87,7 @@ function prepare_web_container { local -r options="$@" local expose_option="" + IFS=$' \t\n' # See https://github.com/sstephenson/bats/issues/89 for port in $ports; do expose_option="${expose_option}--expose=$port " done @@ -121,6 +122,7 @@ function prepare_web_container { assert_success # THEN querying directly port works + IFS=$' \t\n' # See https://github.com/sstephenson/bats/issues/89 for port in $ports; do run retry 5 1s docker run --rm appropriate/curl --silent --fail http://$(docker_ip $container_name):$port/data assert_output "answer from port $port" From 30e565f0ed62a2bf34ab62a356e432957f12ac10 Mon Sep 17 00:00:00 2001 From: Mike Dillon Date: Sun, 11 Oct 2015 11:04:00 -0700 Subject: [PATCH 51/55] Check "docker version" from a sibling container --- test/lib/docker_helpers.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lib/docker_helpers.bash b/test/lib/docker_helpers.bash index bbaf27e..c60c222 100644 --- a/test/lib/docker_helpers.bash +++ b/test/lib/docker_helpers.bash @@ -56,5 +56,5 @@ function docker_tcp { --expose 2375 \ -v /var/run/docker.sock:/var/run/docker.sock \ rancher/socat-docker - docker -H tcp://$(docker_ip $container_name):2375 version + docker run --rm --link "$container_name:docker" docker version } From ec393e3d180c9652bfa055d6b2bde7d96056f013 Mon Sep 17 00:00:00 2001 From: Mike Dillon Date: Sun, 11 Oct 2015 11:04:34 -0700 Subject: [PATCH 52/55] Pull additional images needed for Circle CI --- circle.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/circle.yml b/circle.yml index 8deabde..6fcd063 100644 --- a/circle.yml +++ b/circle.yml @@ -14,6 +14,8 @@ dependencies: - docker pull nginx - docker pull python:3 - docker pull rancher/socat-docker + - docker pull appropriate/curl + - docker pull docker test: override: From 6e7ff3451bcb453796b12ecb074f2f7a90321c31 Mon Sep 17 00:00:00 2001 From: Mike Dillon Date: Sun, 11 Oct 2015 11:27:38 -0700 Subject: [PATCH 53/55] Remove commented out line --- test/test_helpers.bash | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test_helpers.bash b/test/test_helpers.bash index c4a2d1c..d8e7496 100644 --- a/test/test_helpers.bash +++ b/test/test_helpers.bash @@ -1,7 +1,6 @@ # Test if requirements are met ( type docker &>/dev/null || ( echo "docker is not available"; exit 1 ) - #type curl &>/dev/null || ( echo "curl is not available"; exit 1 ) )>&2 From 5c6a63568dfb32e53d8a3dee5a2c65c70090bb15 Mon Sep 17 00:00:00 2001 From: Mike Dillon Date: Mon, 12 Oct 2015 20:59:53 -0700 Subject: [PATCH 54/55] Remove --rm from docker run commands Trying to avoid "Failed to destroy btrfs snapshot" errors on CircleCI --- test/docker.bats | 2 +- test/lib/docker_helpers.bash | 2 +- test/test_helpers.bash | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/docker.bats b/test/docker.bats index d5fde7c..f4ec665 100644 --- a/test/docker.bats +++ b/test/docker.bats @@ -62,7 +62,7 @@ load test_helpers -v /etc/nginx/certs/ \ nginx:latest assert_success - run retry 5 1s docker run --rm appropriate/curl --silent --fail --head http://$(docker_ip bats-nginx)/ + run retry 5 1s docker run appropriate/curl --silent --fail --head http://$(docker_ip bats-nginx)/ assert_output -l 0 $'HTTP/1.1 200 OK\r' # WHEN docker-gen runs on our docker host diff --git a/test/lib/docker_helpers.bash b/test/lib/docker_helpers.bash index c60c222..ae93409 100644 --- a/test/lib/docker_helpers.bash +++ b/test/lib/docker_helpers.bash @@ -56,5 +56,5 @@ function docker_tcp { --expose 2375 \ -v /var/run/docker.sock:/var/run/docker.sock \ rancher/socat-docker - docker run --rm --link "$container_name:docker" docker version + docker run --link "$container_name:docker" docker version } diff --git a/test/test_helpers.bash b/test/test_helpers.bash index d8e7496..9e4690c 100644 --- a/test/test_helpers.bash +++ b/test/test_helpers.bash @@ -66,7 +66,7 @@ function curl_container { local -r container=$1 local -r path=$2 shift 2 - docker run --rm appropriate/curl --silent \ + docker run appropriate/curl --silent \ --connect-timeout 5 \ --max-time 20 \ "$@" \ @@ -123,7 +123,7 @@ function prepare_web_container { # THEN querying directly port works IFS=$' \t\n' # See https://github.com/sstephenson/bats/issues/89 for port in $ports; do - run retry 5 1s docker run --rm appropriate/curl --silent --fail http://$(docker_ip $container_name):$port/data + run retry 5 1s docker run appropriate/curl --silent --fail http://$(docker_ip $container_name):$port/data assert_output "answer from port $port" done -} \ No newline at end of file +} From 1d9db94535272b738d47a76f4c8dc838de0fc577 Mon Sep 17 00:00:00 2001 From: Mike Dillon Date: Mon, 12 Oct 2015 21:16:55 -0700 Subject: [PATCH 55/55] Use docker:1.7 image to match CircleCI's version --- circle.yml | 4 ++-- test/lib/docker_helpers.bash | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/circle.yml b/circle.yml index 6fcd063..d0c24ec 100644 --- a/circle.yml +++ b/circle.yml @@ -15,9 +15,9 @@ dependencies: - docker pull python:3 - docker pull rancher/socat-docker - docker pull appropriate/curl - - docker pull docker + - docker pull docker:1.7 test: override: - docker build -t jwilder/nginx-proxy:bats . - - bats test \ No newline at end of file + - bats test diff --git a/test/lib/docker_helpers.bash b/test/lib/docker_helpers.bash index ae93409..b5165af 100644 --- a/test/lib/docker_helpers.bash +++ b/test/lib/docker_helpers.bash @@ -56,5 +56,5 @@ function docker_tcp { --expose 2375 \ -v /var/run/docker.sock:/var/run/docker.sock \ rancher/socat-docker - docker run --link "$container_name:docker" docker version + docker run --link "$container_name:docker" docker:1.7 version }