diff --git a/nginx.tmpl b/nginx.tmpl index eb00afe..7d3edf1 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -1,4 +1,5 @@ {{ $CurrentContainer := where $ "ID" .Docker.CurrentContainerID | first }} +{{ $proxyAppKey := coalesce $CurrentContainer.Env.APP_KEY "" }} {{ define "upstream" }} {{ if .Address }} @@ -81,18 +82,23 @@ upstream {{ $host }} { {{ range $knownNetwork := $CurrentContainer.Networks }} {{ range $containerNetwork := $container.Networks }} {{ if eq $knownNetwork.Name $containerNetwork.Name }} - ## Can be connect with "{{ $containerNetwork.Name }}" network + {{/* If the APP_KEY matches */}} + {{ $appKey := coalesce $container.Env.APP_KEY "" }} - {{/* 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 }} + {{ if eq $proxyAppKey $appKey }} + ## 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 }} @@ -165,6 +171,9 @@ server { location / { proxy_pass {{ trim $proto }}://{{ trim $host }}; + {{ if (not (eq "" $proxyAppKey)) }} + add_header X-App-Key {{ $proxyAppKey }}; + {{ end }} {{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }} auth_basic "Restricted {{ $host }}"; auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }}; @@ -194,6 +203,9 @@ server { location / { proxy_pass {{ trim $proto }}://{{ trim $host }}; + {{ if (not (eq "" $proxyAppKey)) }} + add_header X-App-Key {{ $proxyAppKey }}; + {{ end }} {{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }} auth_basic "Restricted {{ $host }}"; auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }}; diff --git a/test/app-env.bats b/test/app-env.bats new file mode 100644 index 0000000..2d57656 --- /dev/null +++ b/test/app-env.bats @@ -0,0 +1,63 @@ +#!/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" { + # GIVEN + run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro -e APP_KEY=green + assert_success + docker_wait_for_log $SUT_CONTAINER 9 "Watching docker events" +} + + +@test "[$TEST_FILE] VIRTUAL_HOST=green.app.bats APP_KEY=green" { + # WHEN + prepare_web_container bats-app-env-1 80 -e VIRTUAL_HOST=green.app.bats -e APP_KEY=green + dockergen_wait_for_event $SUT_CONTAINER start bats-app-env-1 + sleep 1 + + # THEN + assert_200 green.app.bats + assert_output -p "X-App-Key: green" +} + +@test "[$TEST_FILE] VIRTUAL_HOST=blue.app.bats APP_KEY=blue" { + # WHEN + prepare_web_container bats-app-env-2 80 -e VIRTUAL_HOST=blue.app.bats -e APP_KEY=blue + dockergen_wait_for_event $SUT_CONTAINER start bats-app-env-2 + sleep 1 + + # THEN + assert_503 blue.app.bats + refute_output -p "X-App-Key: blue" +} + +@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' +}