Archived
11
0
Fork 0

Compare commits

...

56 commits

Author SHA1 Message Date
63347e82ed Patches for the SSL certificate stuff 2016-07-13 22:43:54 +02:00
d9d975f2c3 Softline for ssl certificate 2016-07-13 21:45:56 +02:00
Jason Wilder
a2ab8363ca Merge pull request #483 from jwilder/jw-docker-gen
Update to docker-gen 0.7.3
2016-06-13 08:18:07 -06:00
Jason Wilder
8ed5ab38b8 Update to docker-gen 0.7.3 2016-06-13 00:24:21 -06:00
Jason Wilder
db3ef67a7f Merge pull request #482 from jwilder/jw-revert
Revert 9c93efa
2016-06-13 00:21:38 -06:00
Jason Wilder
580517725f Revert 9c93efa 2016-06-13 00:10:49 -06:00
Jason Wilder
d1e6e1c0be Merge pull request #344 from schmunk42/feature/error-code
changed error code for non-usable/default SSL cert, fixes #341
2016-06-12 15:54:40 -06:00
Jason Wilder
fc619d63ad Merge pull request #460 from kumy/patch-1
Fix a typo in comment
2016-06-12 15:28:40 -06:00
Jason Wilder
c36b42933d Merge pull request #462 from kamermans/master
Disable HSTS when HTTPS_METHOD=noredirect
2016-06-12 15:28:08 -06:00
Jason Wilder
a0dee5c833 Remove -only-exposed from separate container instructions 2016-06-12 15:25:32 -06:00
Jason Wilder
fdfb0becd2 Merge pull request #480 from jwilder/jw-certs
Fix template error when /etc/nginx/certs does not exist
2016-06-12 14:28:35 -06:00
Jason Wilder
fdf93cafba Add docker-compose.yml v2 example 2016-06-12 14:10:46 -06:00
Jason Wilder
b325dad98d Remove -only-exposed from Procfile 2016-06-12 14:10:46 -06:00
Jason Wilder
9c93efaef9 Fix template error when /etc/nginx/certs does not exist 2016-06-12 14:10:40 -06:00
Jason Wilder
adf4573de4 Remove Circle CI badge 2016-06-12 10:45:59 -06:00
Jason Wilder
8393a57f1f Merge pull request #477 from jwilder/jw-nginx
Nginx updates
2016-06-10 20:22:07 -06:00
Jason Wilder
9b0138f944 Remove docker compose v2 notes 2016-06-10 20:11:58 -06:00
Jason Wilder
c256f31728 Update nginx 1.9.15 2016-06-10 20:08:10 -06:00
Steve Kamerman
da3e257843 Removed HSTS when HTTPS_METHOD=noredirect, added tests, improved docs wrt HSTS 2016-05-19 23:20:43 -04:00
Steve Kamerman
3d77979efb Expanded documentation on HTTPS_METHOD 2016-05-19 23:16:19 -04:00
kumy
8c76ea9f9b Fix a typo in comment 2016-05-17 01:46:46 +02:00
Jason Wilder
0ef8dca98c Merge pull request #443 from jwilder/jw-circle
Remove circle.yml
2016-05-04 16:52:41 -06:00
Jason Wilder
c30640b024 Remove circle.yml
Using travis now
2016-05-04 16:05:03 -06:00
Jason Wilder
e964b9d29f Merge pull request #441 from jwilder/jw-0.7.1
Update to docker-gen 0.7.1
2016-05-04 16:03:52 -06:00
Jason Wilder
d40d1d4052 Update to docker-gen 0.7.1 2016-05-04 14:51:30 -06:00
Jason Wilder
5b9264d945 Merge pull request #298 from kamermans/master
Added env var to disable SSL redirect
2016-05-01 17:45:45 -06:00
Jason Wilder
1c98df2de4 Merge pull request #337 from baptistedonaux/master
Support Overlay Network
2016-05-01 17:35:48 -06:00
Steve Kamerman
786a2375aa Using different path method to hopefully fix cert volume issue in CI systems 2016-04-20 12:47:14 -04:00
Steve Kamerman
f296b273ce Normalized indentation, added explicit CERT_NAME 2016-04-20 12:33:21 -04:00
Steve Kamerman
1d0a5d9194 Added SSL/HTTPS tests 2016-04-20 12:20:08 -04:00
Steve Kamerman
f294582ae8 Merge branch 'master' of https://github.com/jwilder/nginx-proxy 2016-04-20 11:05:20 -04:00
Baptiste Donaux
f66934567e Merge remote-tracking branch 'upstream/master' 2016-04-05 09:22:31 +02:00
Baptiste Donaux
6928d62e1e Upgrade Docker dependency from 1.9 to 1.10 2016-03-24 14:40:50 +01:00
Baptiste Donaux
88cc096aaf [FIX] expose port for separated containers test 2016-03-24 11:16:22 +01:00
Baptiste Donaux
6b88365465 Merge remote-tracking branch 'upstream/master' 2016-03-24 08:41:23 +01:00
Baptiste Donaux
74fb2acc4b Merge remote-tracking branch 'upstream/master' 2016-03-23 08:52:58 +01:00
Steve Kamerman
9671e0c1a2 Merge branch 'master' of https://github.com/jwilder/nginx-proxy 2016-03-18 13:47:11 -04:00
Baptiste Donaux
b42cd85570 Unit test - removed network creation 2016-02-26 09:12:11 +01:00
Baptiste Donaux
47631eb5de Merge remote-tracking branch 'upstream/master' 2016-02-25 09:59:04 +01:00
Baptiste Donaux
2b418319f2 Test to support overlay networks 2016-02-25 09:58:17 +01:00
Baptiste Donaux
163d1ce174 Upgrade docker-gen from 0.5.0 to 0.7.0 2016-02-25 08:26:41 +01:00
Baptiste Donaux
ebab7cf2b9 [TEMPLATE] fix variable call 2016-02-23 13:59:30 +01:00
Baptiste Donaux
658e20f661 Support container in one network shared with current container 2016-02-05 09:16:43 +01:00
Baptiste Donaux
9341f54e51 Merge pull request #1 from appropriate/overlay-support
Update README wording for overlay networking
2016-01-22 08:44:43 +01:00
Tobias Munk
b4e5f780e3 changed error code for non-usable/default SSL cert, fixes #341 2016-01-21 12:31:03 +01:00
Mike Dillon
5c828cb50a Update README wording for overlay networking 2016-01-20 23:30:55 -08:00
Baptiste Donaux
2eb977589c Complete documentation 2016-01-20 08:54:57 +01:00
Steve Kamerman
99963b4ab0 Merge branch 'master' of https://github.com/jwilder/nginx-proxy 2016-01-18 16:37:03 -05:00
Baptiste Donaux
13bb99c4d2 Update README - Nginx proxy must use host network to support overlay network 2016-01-17 12:35:29 +01:00
Baptiste Donaux
a66115f560 Use new Network interface to support new overlay network 2016-01-17 12:29:55 +01:00
Baptiste Donaux
deb4050fa4 UPGRADE docker-gen release from 0.4.2 to 0.5.0 2016-01-17 12:28:59 +01:00
Steve Kamerman
4a95d84d0d Trying to trigger CI 2015-12-02 21:46:05 -05:00
Steve Kamerman
58fc298dea Semantic change to trigger CI rebuild 2015-12-02 00:29:32 -05:00
Steve Kamerman
4bf7f888d0 Documented HTTPS_METHOD 2015-11-20 17:47:08 -05:00
Steve Kamerman
97c6340a9f Implemented HTTPS noredir 2015-11-20 17:37:06 -05:00
Steve Kamerman
9dd6ad8503 First try at HTTPS_METHOD 2015-11-20 16:53:50 -05:00
13 changed files with 336 additions and 57 deletions

View file

@ -1,4 +1,4 @@
FROM nginx:1.9.12
FROM nginx:1.9.15
MAINTAINER Jason Wilder mail@jasonwilder.com
# Install wget and install/updates certificates
@ -17,7 +17,7 @@ RUN echo "daemon off;" >> /etc/nginx/nginx.conf \
ADD https://github.com/jwilder/forego/releases/download/v0.16.1/forego /usr/local/bin/forego
RUN chmod u+x /usr/local/bin/forego
ENV DOCKER_GEN_VERSION 0.7.0
ENV DOCKER_GEN_VERSION 0.7.3
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 \
@ -28,7 +28,12 @@ WORKDIR /app/
ENV DOCKER_HOST unix:///tmp/docker.sock
VOLUME ["/etc/nginx/certs"]
# VOLUME ["/etc/nginx/certs"]
# <madmaurice> Adding softlink to fit current cert structure
RUN mkdir -p /etc/nginx/certs && ln -s /ssl/cert.pem /etc/nginx/certs/zom.bi.crt && ln -s /ssl/cert.key /etc/nginx/certs/zom.bi.key
# Diffie Hallman generating different primes
RUN openssl dhparam -out /etc/nginx/certs/zom.bi.dhparam.pem 2048
ENTRYPOINT ["/app/docker-entrypoint.sh"]
CMD ["forego", "start", "-r"]

View file

@ -2,12 +2,12 @@
.PHONY : test
update-dependencies:
docker pull jwilder/docker-gen:0.7.0
docker pull jwilder/docker-gen:0.7.3
docker pull nginx:1.9.12
docker pull python:3
docker pull rancher/socat-docker:latest
docker pull appropriate/curl:latest
docker pull docker:1.9
docker pull docker:1.10
test:
docker build -t jwilder/nginx-proxy:bats .

View file

@ -1,2 +1,2 @@
nginx: nginx
dockergen: docker-gen -watch -only-exposed -notify "nginx -s reload" /app/nginx.tmpl /etc/nginx/conf.d/default.conf
dockergen: docker-gen -watch -notify "nginx -s reload" /app/nginx.tmpl /etc/nginx/conf.d/default.conf

View file

@ -1,4 +1,4 @@
![nginx 1.9.12](https://img.shields.io/badge/nginx-1.9.12-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) [![Build Status](https://travis-ci.org/jwilder/nginx-proxy.svg?branch=master)](https://travis-ci.org/jwilder/nginx-proxy) [![](https://img.shields.io/docker/stars/jwilder/nginx-proxy.svg)](https://hub.docker.com/r/jwilder/nginx-proxy 'DockerHub') [![](https://img.shields.io/docker/pulls/jwilder/nginx-proxy.svg)](https://hub.docker.com/r/jwilder/nginx-proxy 'DockerHub')
![nginx 1.9.15](https://img.shields.io/badge/nginx-1.9.15-brightgreen.svg) ![License MIT](https://img.shields.io/badge/license-MIT-blue.svg) [![Build Status](https://travis-ci.org/jwilder/nginx-proxy.svg?branch=master)](https://travis-ci.org/jwilder/nginx-proxy) [![](https://img.shields.io/docker/stars/jwilder/nginx-proxy.svg)](https://hub.docker.com/r/jwilder/nginx-proxy 'DockerHub') [![](https://img.shields.io/docker/pulls/jwilder/nginx-proxy.svg)](https://hub.docker.com/r/jwilder/nginx-proxy 'DockerHub')
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.
@ -19,10 +19,31 @@ 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.
### Docker-compose
### Docker Compose
Currently this does not work with the new v2 syntax of docker-compose (due to not being compatible with the new network overlay see [#304](https://github.com/jwilder/nginx-proxy/issues/304)). It does work when using the old docker-composer syntax.
```yaml
version: '2'
services:
nginx-proxy:
image: jwilder/nginx-proxy
container_name: nginx-proxy
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
whoami:
image: jwilder/whoami
container_name: whoami
environment:
- VIRTUAL_HOST=whoami.local
```
```shell
$ docker-compose up
$ curl -H "Host: whoami.local" localhost
I''m 5b129ab83266
```
### Multiple Ports
@ -39,6 +60,20 @@ If you need to support multiple virtual hosts for a container, you can separate
You can also use wildcards at the beginning and the end of host name, like `*.bar.com` or `foo.bar.*`. Or even a regular expression, which can be very useful in conjunction with a wildcard DNS service like [xip.io](http://xip.io), using `~^foo\.bar\..*\.xip\.io` will match `foo.bar.127.0.0.1.xip.io`, `foo.bar.10.0.2.2.xip.io` and all other given IPs. More information about this topic can be found in the nginx documentation about [`server_names`](http://nginx.org/en/docs/http/server_names.html).
### Multiple Networks
With the addition of [overlay networking](https://docs.docker.com/engine/userguide/networking/get-started-overlay/) in Docker 1.9, your `nginx-proxy` container may need to connect to backend containers on multiple networks. By default, if you don't pass the `--net` flag when your `nginx-proxy` container is created, it will only be attached to the default `bridge` network. This means that it will not be able to connect to containers on networks other than `bridge`.
If you want your `nginx-proxy` container to be attached to a different network, you must pass the `--net=my-network` option in your `docker create` or `docker run` command. At the time of this writing, only a single network can be specified at container creation time. To attach to other networks, you can use the `docker network connect` command after your container is created:
```console
$ docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro \
--name my-nginx-proxy --net my-network jwilder/nginx-proxy
$ docker network connect my-other-network my-nginx-proxy
```
In this example, the `my-nginx-proxy` container will be connected to `my-network` and `my-other-network` and will be able to proxy to other containers attached to those networks.
### SSL Backends
If you would like to connect to your backend using HTTPS instead of HTTP, set `VIRTUAL_PROTO=https` on the backend container.
@ -70,7 +105,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: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
-t jwilder/docker-gen -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
```
Finally, start your containers with `VIRTUAL_HOST` environment variables.
@ -116,7 +151,7 @@ should provide compatibility with clients back to Firefox 1, Chrome 1, IE 7, Ope
Windows XP IE8, Android 2.3, Java 7. The configuration also enables HSTS, and SSL
session caches.
The behavior for the proxy when port 80 and 443 are exposed is as follows:
The default behavior for the proxy when port 80 and 443 are exposed is as follows:
* If a container has a usable cert, port 80 will redirect to 443 for that container so that HTTPS
is always preferred when available.
@ -127,6 +162,15 @@ to establish a connection. A self-signed or generic cert named `default.crt` an
will allow a client browser to make a SSL connection (likely w/ a warning) and subsequently receive
a 503.
To serve traffic in both SSL and non-SSL modes without redirecting to SSL, you can include the
environment variable `HTTPS_METHOD=noredirect` (the default is `HTTPS_METHOD=redirect`). You can also
disable the non-SSL site entirely with `HTTPS_METHOD=nohttp`. `HTTPS_METHOD` must be specified
on each container for which you want to override the default behavior. If `HTTPS_METHOD=noredirect` is
used, Strict Transport Security (HSTS) is disabled to prevent HTTPS users from being redirected by the
client. If you cannot get to the HTTP site after changing this setting, your browser has probably cached
the HSTS policy and is automatically redirecting you back to HTTPS. You will need to clear your browser's
HSTS cache or use an incognito window / different browser.
### Basic Authentication Support
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

View file

@ -1,17 +0,0 @@
machine:
pre:
- sudo curl -L -o /usr/bin/docker 'https://s3-external-1.amazonaws.com/circle-downloads/docker-1.9.1-circleci'
- sudo chmod 0755 /usr/bin/docker
services:
- docker
dependencies:
override:
- sudo add-apt-repository ppa:duggan/bats --yes
- sudo apt-get update -qq
- sudo apt-get install -qq bats
- make update-dependencies
test:
override:
- make test

9
docker-compose.yml Normal file
View file

@ -0,0 +1,9 @@
nginxproxy:
build: .
ports:
- "443:443"
- "80:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
volumes_from:
- ssl:ro

View file

@ -1,3 +1,5 @@
{{ $CurrentContainer := where $ "ID" .Docker.CurrentContainerID | first }}
{{ define "upstream" }}
{{ if .Address }}
{{/* If we got the containers from swarm and this container's port is published to host, use host IP:PORT */}}
@ -5,13 +7,13 @@
# {{ .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 }}
{{ else if .Network }}
# {{ .Container.Name }}
server {{ .Address.IP }}:{{ .Address.Port }};
server {{ .Network.IP }}:{{ .Address.Port }};
{{ end }}
{{ else }}
{{ else if .Network }}
# {{ .Container.Name }}
server {{ .Container.IP }} down;
server {{ .Network.IP }} down;
{{ end }}
{{ end }}
@ -75,15 +77,24 @@ server {
upstream {{ $host }} {
{{ range $container := $containers }}
{{ $addrLen := len $container.Addresses }}
{{/* If only 1 port exposed, use that */}}
{{ if eq $addrLen 1 }}
{{ $address := index $container.Addresses 0 }}
{{ 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 }}
{{ template "upstream" (dict "Container" $container "Address" $address) }}
{{ range $knownNetwork := $CurrentContainer.Networks }}
{{ range $containerNetwork := $container.Networks }}
{{ if eq $knownNetwork.Name $containerNetwork.Name }}
## Can be connect with "{{ $containerNetwork.Name }}" network
{{/* If only 1 port exposed, use that */}}
{{ if eq $addrLen 1 }}
{{ $address := index $container.Addresses 0 }}
{{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }}
{{/* 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 }}
{{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }}
{{ end }}
{{ end }}
{{ end }}
{{ end }}
{{ end }}
}
@ -94,6 +105,9 @@ upstream {{ $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" }}
{{/* Get the HTTPS_METHOD defined by containers w/ the same vhost, falling back to "redirect" */}}
{{ $https_method := or (first (groupByKeys $containers "Env.HTTPS_METHOD")) "redirect" }}
{{/* Get the first cert name defined by containers w/ the same vhost */}}
{{ $certName := (first (groupByKeys $containers "Env.CERT_NAME")) }}
@ -104,17 +118,21 @@ upstream {{ $host }} {
{{ $vhostCert := replace $vhostCert ".crt" "" -1 }}
{{ $vhostCert := replace $vhostCert ".key" "" -1 }}
{{/* Use the cert specifid on the container or fallback to the best vhost match */}}
{{/* Use the cert specified on the container or fallback to the best vhost match */}}
{{ $cert := (coalesce $certName $vhostCert) }}
{{ if (and (ne $cert "") (exists (printf "/etc/nginx/certs/%s.crt" $cert)) (exists (printf "/etc/nginx/certs/%s.key" $cert))) }}
{{ $is_https := (and (ne $cert "") (exists (printf "/etc/nginx/certs/%s.crt" $cert)) (exists (printf "/etc/nginx/certs/%s.key" $cert))) }}
{{ if $is_https }}
{{ if eq $https_method "redirect" }}
server {
server_name {{ $host }};
listen 80 {{ $default_server }};
access_log /var/log/nginx/access.log vhost;
return 301 https://$host$request_uri;
}
{{ end }}
server {
server_name {{ $host }};
@ -135,7 +153,9 @@ server {
ssl_dhparam {{ printf "/etc/nginx/certs/%s.dhparam.pem" $cert }};
{{ end }}
{{ if (ne $https_method "noredirect") }}
add_header Strict-Transport-Security "max-age=31536000";
{{ end }}
{{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }}
include {{ printf "/etc/nginx/vhost.d/%s" $host }};
@ -156,7 +176,10 @@ server {
{{ end }}
}
}
{{ else }}
{{ end }}
{{ if or (not $is_https) (eq $https_method "noredirect") }}
server {
server_name {{ $host }};
@ -183,12 +206,12 @@ server {
}
}
{{ if (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }}
{{ if (and (not $is_https) (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }}
server {
server_name {{ $host }};
listen 443 ssl http2 {{ $default_server }};
access_log /var/log/nginx/access.log vhost;
return 503;
return 500;
ssl_certificate /etc/nginx/certs/default.crt;
ssl_certificate_key /etc/nginx/certs/default.key;

View file

@ -11,7 +11,7 @@ load test_helpers
@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
# 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 9 "Watching docker events"
@ -24,7 +24,7 @@ load test_helpers
@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
# 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 9 "Watching docker events"
@ -45,7 +45,7 @@ load test_helpers
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 9 "Watching docker events"
# THEN
assert_nginxproxy_behaves $SUT_CONTAINER
}
@ -54,7 +54,7 @@ load test_helpers
@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 \
--label bats-type="nginx" \
@ -73,7 +73,8 @@ load test_helpers
-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:0.7.0 \
--expose 80 \
jwilder/docker-gen:0.7.3 \
-notify-sighup bats-nginx \
-watch \
-only-exposed \
@ -81,8 +82,8 @@ load test_helpers
/etc/nginx/conf.d/default.conf
assert_success
docker_wait_for_log bats-docker-gen 9 "Watching docker events"
# Give some time to the docker-gen container to notify bats-nginx so it
# Give some time to the docker-gen container to notify bats-nginx so it
# reloads its config
sleep 2s
@ -91,7 +92,7 @@ load test_helpers
docker logs bats-docker-gen
false
} >&2
# THEN
assert_nginxproxy_behaves bats-nginx
}
@ -115,9 +116,8 @@ function assert_nginxproxy_behaves {
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'
}

View file

@ -62,5 +62,5 @@ function docker_tcp {
--expose 2375 \
-v /var/run/docker.sock:/var/run/docker.sock \
rancher/socat-docker
docker run --label bats-type="docker" --link "$container_name:docker" docker:1.9 version
docker run --label bats-type="docker" --link "$container_name:docker" docker:1.10 version
}

View file

@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIID7TCCAtWgAwIBAgIJAOGkf5EnexJVMA0GCSqGSIb3DQEBCwUAMIGMMQswCQYD
VQQGEwJVUzERMA8GA1UECAwIVmlyZ2luaWExDzANBgNVBAcMBlJlc3RvbjERMA8G
A1UECgwIRmFrZSBPcmcxGzAZBgNVBAMMEioubmdpbngtcHJveHkuYmF0czEpMCcG
CSqGSIb3DQEJARYad2VibWFzdGVyQG5naW54LXByb3h5LmJhdHMwHhcNMTYwNDIw
MTUzOTUxWhcNMjYwNDE4MTUzOTUxWjCBjDELMAkGA1UEBhMCVVMxETAPBgNVBAgM
CFZpcmdpbmlhMQ8wDQYDVQQHDAZSZXN0b24xETAPBgNVBAoMCEZha2UgT3JnMRsw
GQYDVQQDDBIqLm5naW54LXByb3h5LmJhdHMxKTAnBgkqhkiG9w0BCQEWGndlYm1h
c3RlckBuZ2lueC1wcm94eS5iYXRzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEA0Amkj3iaQn8Z2CW6n24zSuWu2OoLCkHZAk8eprkI4kKoPBvjusynkm8E
phq65jebToHoldfuQ0wM61DzhD15bHwS3x9CrOVbShsmdnGALz+wdR0/4Likx50I
YZdecTOAlkoZudnX5FZ4ngOxjqcym7p5T8TrSS97a0fx99gitZY0p+Nu2tip4o3t
WBMs+SoPWTlQ1SrSmL8chC8O2knyBl/w1nHmDnMuR6FGcHdhLncApw9t5spgfv7p
OrMF4tQxJQNk10TnflmEMkGmy+pfk2e0cQ1Kwp3Nmzm7ECkggxxyjU3ihKiFK+09
8aSCi7gDAY925+mV6LZ5oLMpO3KJvQIDAQABo1AwTjAdBgNVHQ4EFgQU+NvFo37z
9Dyq8Mu82SPtV7q1gYQwHwYDVR0jBBgwFoAU+NvFo37z9Dyq8Mu82SPtV7q1gYQw
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAI1ityDV0UsCVHSpB2LN+
QXlk8XS0ACIJ8Q0hbOj3BmYrdAVglG4P6upDEueaaxwsaBTagkTP8nxZ9dhfZHyZ
5YLNwYsiG5iqb8e0ecHx3uJT/0YiXn/8rBvxEZna4Fl8seGdp7BjOWUAS2Nv8tn4
EJJvRdfX/O8XgPc95DM4lwQ/dvyWmavMI4lnl0n1IQV9WPGaIQhYPU9WEQK6iMUB
o1kx8YbOJQD0ZBRfqpriNt1/8ylkkSYYav8QT9JFvQFCWEvaX71QF+cuOwC7ZYBH
4ElXwEUrYBHKiPo0q0VsTtMvLh7h/T5czrIhG/NpfVJPtQOk8aVwNScL3/n+TGU8
6g==
-----END CERTIFICATE-----

View file

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDQCaSPeJpCfxnY
JbqfbjNK5a7Y6gsKQdkCTx6muQjiQqg8G+O6zKeSbwSmGrrmN5tOgeiV1+5DTAzr
UPOEPXlsfBLfH0Ks5VtKGyZ2cYAvP7B1HT/guKTHnQhhl15xM4CWShm52dfkVnie
A7GOpzKbunlPxOtJL3trR/H32CK1ljSn427a2Knije1YEyz5Kg9ZOVDVKtKYvxyE
Lw7aSfIGX/DWceYOcy5HoUZwd2EudwCnD23mymB+/uk6swXi1DElA2TXROd+WYQy
QabL6l+TZ7RxDUrCnc2bObsQKSCDHHKNTeKEqIUr7T3xpIKLuAMBj3bn6ZXotnmg
syk7com9AgMBAAECggEAa7wCp3XqVPNjW+c1/ShhkbDeWmDhtL8i9aopkmeSbTHd
07sRtQQU56Vsf+Sp010KpZ5q52Z6cglpS1eRtHLtdbvPPhL/QXBJVVg4E/B1VIKk
DBJIqUSVuPXeiEOOWgs01R+ssO1ae1o4foQlKF33vGPWPPQacL0RKh6I9TPNzcD7
n4rujlHk72N/bNydyK2rnyKB4vAI5TbZPLps+Xe123CmgZnW3JClcWV9B4foRmiu
a5Iq1WYAK2GYKbYwgqDRyYBC27m91a7U31pE4GQD+xQdlz6kcOlCU5hAcPK3h7j0
fLQqn8g+YAtc0nBKKB4NZe3QEzTiVMorT0VitxI71QKBgQDnirardZaXOFzYGzB3
j+FGB9BUW54hnHr5BxOYrfmEJ5umJjJWaGupfYrQsPArrJP1//WbqVZIPvdQParD
mQhLmSp1r/VNzGB6pISmzU1ZGDHsmBxYseh366om5YBQUFU2vmbil9VkrkM4fsJG
tcS9V/nVY/EM7Yp3PzjfLlhC1wKBgQDmA1YJmnZvIbLp3PoKqM69QiCLKztVm7nX
xpu3b3qbXEzXkt2sP5PHmr+s13hOPQFKRJ2hk4UN9WqpnFoHw5E5eWWhSa/peUZm
r10Y5XspiFtRHHiu6ABXB49eB4fen+vHEZHKyRJ4rFthKjjBHdNPC8bmwnT3jE85
/8a26FLZiwKBgQDXEi8JZslBn9YF2oOTm28KCLoHka551AsaA+u892T8z3mxxGsf
fhD7N6TYonIEb2Jkr6OpOortwqcgvpc+5oghCJ27AX2fDUdUxDp/YdYF+wZsmQJD
lMW1lo7PYIBmmaf9mLCiq5xIz+GauYul+LNNmUl0YEgI1SC4EV63WCodswKBgDMX
GJxHd/kVViVGFTAa8NjvAEWJU8OfNHduQRZMp8IsjVDw6VYiRRP4Fo0wyyMtv8Sc
WxsRpmNEWO3VsdW5pd9LTLy3nmBQtMeIOjiWeHXwOMBaf5/yHmk2X6z2JULY6Mkt
6OFPKlAtkJqTg0m58z7Ckeqd1NdLjimG27+y+PwjAoGAFt0cbC1Ust2BE6YEspSX
ofpAnJsyKrbF9iVUyXDUP99sdqYQfPJ5uqPGkP59lJGkTLtebuitqi6FCyrsT6Fq
AWLiExbqebAqcuAZw2S+iuK27S4rrkjVGF53J7vH3rOzCBUXaRx6GKfTjUqedHdg
9Kw+LP6IFnMTb+EGLo+GqHs=
-----END PRIVATE KEY-----

146
test/ssl.bats Normal file
View file

@ -0,0 +1,146 @@
#!/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
stop_bats_containers web
}
@test "[$TEST_FILE] start a nginx-proxy container" {
run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro -v ${DIR}/lib/ssl:/etc/nginx/certs:ro
assert_success
docker_wait_for_log $SUT_CONTAINER 9 "Watching docker events"
}
@test "[$TEST_FILE] test SSL for VIRTUAL_HOST=*.nginx-proxy.bats" {
# WHEN
prepare_web_container bats-ssl-hosts-1 "80 443" \
-e VIRTUAL_HOST=*.nginx-proxy.bats \
-e CERT_NAME=nginx-proxy.bats
dockergen_wait_for_event $SUT_CONTAINER start bats-ssl-hosts-1
sleep 1
# THEN
assert_301 test.nginx-proxy.bats
assert_200_https test.nginx-proxy.bats
}
@test "[$TEST_FILE] test HTTPS_METHOD=nohttp" {
# WHEN
prepare_web_container bats-ssl-hosts-2 "80 443" \
-e VIRTUAL_HOST=*.nginx-proxy.bats \
-e CERT_NAME=nginx-proxy.bats \
-e HTTPS_METHOD=nohttp
dockergen_wait_for_event $SUT_CONTAINER start bats-ssl-hosts-2
sleep 1
# THEN
assert_503 test.nginx-proxy.bats
assert_200_https test.nginx-proxy.bats
}
@test "[$TEST_FILE] test HTTPS_METHOD=noredirect" {
# WHEN
prepare_web_container bats-ssl-hosts-3 "80 443" \
-e VIRTUAL_HOST=*.nginx-proxy.bats \
-e CERT_NAME=nginx-proxy.bats \
-e HTTPS_METHOD=noredirect
dockergen_wait_for_event $SUT_CONTAINER start bats-ssl-hosts-3
sleep 1
# THEN
assert_200 test.nginx-proxy.bats
assert_200_https test.nginx-proxy.bats
}
@test "[$TEST_FILE] test SSL Strict-Transport-Security" {
# WHEN
prepare_web_container bats-ssl-hosts-4 "80 443" \
-e VIRTUAL_HOST=*.nginx-proxy.bats \
-e CERT_NAME=nginx-proxy.bats
dockergen_wait_for_event $SUT_CONTAINER start bats-ssl-hosts-1
sleep 1
# THEN
assert_301 test.nginx-proxy.bats
assert_200_https test.nginx-proxy.bats
assert_output -p "Strict-Transport-Security: max-age=31536000"
}
@test "[$TEST_FILE] test HTTPS_METHOD=noredirect disables Strict-Transport-Security" {
# WHEN
prepare_web_container bats-ssl-hosts-5 "80 443" \
-e VIRTUAL_HOST=*.nginx-proxy.bats \
-e CERT_NAME=nginx-proxy.bats \
-e HTTPS_METHOD=noredirect
dockergen_wait_for_event $SUT_CONTAINER start bats-ssl-hosts-3
sleep 1
# THEN
assert_200 test.nginx-proxy.bats
assert_200_https test.nginx-proxy.bats
refute_output -p "Strict-Transport-Security: max-age=31536000"
}
@test "[$TEST_FILE] stop all bats containers" {
stop_bats_containers
}
# 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'
}
# 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_301 {
local -r host=$1
run curl_container $SUT_CONTAINER / --head --header "Host: $host"
assert_output -l 0 $'HTTP/1.1 301 Moved Permanently\r'
}
# 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_https {
local -r host=$1
run curl_container_https $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_https {
local -r host=$1
run curl_container_https $SUT_CONTAINER / --head --header "Host: $host"
assert_output -l 0 $'HTTP/1.1 503 Service Temporarily Unavailable\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_301_https {
local -r host=$1
run curl_container_https $SUT_CONTAINER / --head --header "Host: $host"
assert_output -l 0 $'HTTP/1.1 301 Moved Permanently\r'
}

View file

@ -74,6 +74,23 @@ function curl_container {
http://$(docker_ip $container)${path}
}
# Send a HTTPS request to container $1 for path $2 and
# Additional curl options can be passed as $@
#
# $1 container name
# $2 HTTPS path to query
# $@ additional options to pass to the curl command
function curl_container_https {
local -r container=$1
local -r path=$2
shift 2
docker run --label bats-type="curl" appropriate/curl --silent \
--connect-timeout 5 \
--max-time 20 \
--insecure \
"$@" \
https://$(docker_ip $container)${path}
}
# start a container running (one or multiple) webservers listening on given ports
#