1
0
Fork 0
mirror of https://github.com/nginx-proxy/nginx-proxy synced 2024-05-09 09:06:16 +02:00

Compare commits

...

333 Commits

Author SHA1 Message Date
dannycarrera 86a2674835
Merge 3e9d9fd61d into 94fb8459cd 2024-03-16 19:51:30 +00:00
Daniel Carrera 3e9d9fd61d Merge branch 'master' into feature/virtual_host_alias
# Conflicts:
#	README.md
#	nginx.tmpl
2024-03-16 14:46:53 -04:00
Nicolas Duchon 94fb8459cd
Merge pull request #2410 from pini-gh/pini-refactor-template-3
refactor: add 'ports' dict to the data structure
2024-03-12 21:35:11 +01:00
Nicolas Duchon c7bf75609b
Merge pull request #2411 from nginx-proxy/dependabot/pip/test/requirements/pytest-8.1.1
ci: bump pytest from 8.1.0 to 8.1.1 in /test/requirements
2024-03-12 21:12:40 +01:00
Nicolas Duchon 3c3b3675c1
Merge pull request #2413 from Huge/patch-1
Update README.md to use 1.5 version and link DockerHub
2024-03-12 21:11:50 +01:00
Huge 16b84ea1b5
Update README.md to use 1.5 version and link DockerHub 2024-03-12 14:23:56 +01:00
dependabot[bot] 6441daf25b
ci: bump pytest from 8.1.0 to 8.1.1 in /test/requirements
Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.1.0 to 8.1.1.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/8.1.0...8.1.1)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-11 04:19:22 +00:00
Gilles Filippini 45770e04bd refactor: add 'ports' dict to the data structure
Nothing changes for the legacy syntax, but adding this level to the data
structure enables advanced port configuration.
2024-03-09 20:13:42 +01:00
Nicolas Duchon 26b0a0008b
Merge pull request #2408 from nginx-proxy/dependabot/pip/test/requirements/pytest-8.1.0
ci: bump pytest from 8.0.2 to 8.1.0 in /test/requirements
2024-03-04 22:06:21 +01:00
Nicolas Duchon 4b38bf259d
Merge pull request #2405 from nginx-proxy/refactor-template-2
refactor: template internal data structure
2024-03-04 22:03:30 +01:00
dependabot[bot] 12e1360fc3
ci: bump pytest from 8.0.2 to 8.1.0 in /test/requirements
Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.0.2 to 8.1.0.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/8.0.2...8.1.0)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-04 04:52:02 +00:00
Nicolas Duchon b09575297d
docs: typo in comments
Co-authored-by: Niek <100143256+SchoNie@users.noreply.github.com>
2024-02-27 13:27:11 +01:00
Nicolas Duchon 418f1a3cd0
fix: don't re-assign variable
Co-authored-by: pini-gh <pini@debian.org>
2024-02-27 13:20:39 +01:00
Nicolas Duchon 60618afe52
Merge pull request #2407 from nginx-proxy/dependabot/pip/test/requirements/pytest-8.0.2
ci: bump pytest from 8.0.1 to 8.0.2 in /test/requirements
2024-02-26 08:20:17 +01:00
dependabot[bot] 2a5521625d
ci: bump pytest from 8.0.1 to 8.0.2 in /test/requirements
Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.0.1 to 8.0.2.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/8.0.1...8.0.2)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-26 04:49:11 +00:00
Nicolas Duchon b8b53794bf
Merge pull request #2406 from nginx-proxy/dependabot/docker/nginxproxy/docker-gen-0.12.0-debian
build: bump nginxproxy/docker-gen from 0.11.2 to 0.12.0
2024-02-25 11:51:11 +01:00
dependabot[bot] d588c96dff
build: bump nginxproxy/docker-gen from 0.11.2-debian to 0.12.0-debian
Bumps nginxproxy/docker-gen from 0.11.2-debian to 0.12.0-debian.

---
updated-dependencies:
- dependency-name: nginxproxy/docker-gen
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-25 10:42:38 +00:00
Nicolas Duchon f960061e2d
Merge pull request #2404 from nginx-proxy/network-host
docs: add comment about host network to compose example
2024-02-25 10:01:02 +01:00
Nicolas Duchon e97be61272
refactor: refactor virtual paths 2024-02-24 21:51:50 +01:00
Nicolas Duchon 4d9d067630
refactor: refactor virtual hosts 2024-02-24 21:51:38 +01:00
Michael Bianco 8c95ed1cc0
docs: add comment about host network to compose example 2024-02-22 05:59:51 -07:00
Nicolas Duchon 9d2eeb7273
Merge pull request #2399 from nginx-proxy/dependabot/pip/test/requirements/pytest-8.0.1
ci: bump pytest from 7.4.4 to 8.0.1 in /test/requirements
2024-02-21 17:55:46 +01:00
Nicolas Duchon 24592e39a3
Merge pull request #2402 from SchoNie/htpasswd-tests
tests: htpasswd
2024-02-21 08:42:56 +01:00
Niek a9f8a9c32a htpasswd tests 2024-02-21 08:34:38 +01:00
Nicolas Duchon da006557d0
Merge pull request #2400 from SchoNie/tests-remove-obsolete
tests: remove obsolete stress-test
2024-02-21 08:33:58 +01:00
Niek 4464269c51 remove obsolete stress-test 2024-02-20 15:21:09 +01:00
Nicolas Duchon b4902f145d
Merge pull request #2401 from SchoNie/docs-htpasswd-readability
docs: htpasswd readability
2024-02-19 22:42:24 +01:00
Niek d4438b5a09
prevent double slash 2024-02-19 12:23:19 +01:00
Niek 50750bea53
highlight variables similar to other in readme 2024-02-19 12:21:02 +01:00
dependabot[bot] 0dd4f7a8a8
ci: bump pytest from 7.4.4 to 8.0.1 in /test/requirements
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.4.4 to 8.0.1.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.4.4...8.0.1)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-19 04:53:15 +00:00
Nicolas Duchon a2a441e1db
docs: update nginx badge 2024-02-18 10:08:23 +01:00
Nicolas Duchon 5a32bffd6f
Merge pull request #2398 from nginx-proxy/dependabot/docker/nginx-1.25.4
build: bump nginx from 1.25.3 to 1.25.4
2024-02-18 09:56:22 +01:00
Nicolas Duchon 745a2035cf
Merge pull request #2397 from whomobile/patch-1
fix typo README.md
2024-02-16 10:59:15 +01:00
dependabot[bot] 29168655cf
build: bump nginx from 1.25.3 to 1.25.4
Bumps nginx from 1.25.3 to 1.25.4.

---
updated-dependencies:
- dependency-name: nginx
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-16 04:25:16 +00:00
Man Kim 2eaf689172
fix typo README.md
ngingx to nginx
2024-02-15 14:37:21 -08:00
Nicolas Duchon e75c2dfb79
build: revert nginx to 1.25.3 (#2396)
* Revert "build: update docs and tests with nginx 1.25.4"

This reverts commit d9b1751f97.

* Revert "build: bump nginx from 1.25.3 to 1.25.4"

This reverts commit 1aef017df2.
2024-02-15 09:50:12 +01:00
Nicolas Duchon 020b993654
Merge pull request #2395 from nginx-proxy/dependabot/docker/nginx-1.25.4
build: bump nginx from 1.25.3 to 1.25.4
2024-02-15 08:54:52 +01:00
Nicolas Duchon 5583b385cb
style: docs linting 2024-02-15 08:41:11 +01:00
Nicolas Duchon d9b1751f97
build: update docs and tests with nginx 1.25.4 2024-02-15 08:40:46 +01:00
dependabot[bot] 1aef017df2
build: bump nginx from 1.25.3 to 1.25.4
Bumps nginx from 1.25.3 to 1.25.4.

---
updated-dependencies:
- dependency-name: nginx
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-15 04:46:02 +00:00
Nicolas Duchon 5c0c8c93d8
Merge pull request #2393 from SchoNie/tests-nonstandardport-hostheader
tests: non standard port Host header check
2024-02-13 18:23:14 +01:00
Niek cb59c24470
tests non standard port Host header 2024-02-13 15:24:37 +01:00
Nicolas Duchon 887e2e950c
Merge pull request #2390 from nginx-proxy/dependabot/docker/nginxproxy/docker-gen-0.11.2-debian
build: bump nginxproxy/docker-gen from 0.11.1 to 0.11.2
2024-02-10 19:25:13 +01:00
dependabot[bot] 3a19382702
build: bump nginxproxy/docker-gen from 0.11.1-debian to 0.11.2-debian
Bumps nginxproxy/docker-gen from 0.11.1-debian to 0.11.2-debian.

---
updated-dependencies:
- dependency-name: nginxproxy/docker-gen
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-10 18:16:49 +00:00
Nicolas Duchon f47c874c5a
Merge pull request #2197 from darh/json_log_format
Add more control over log_format config directive
2024-02-10 19:16:11 +01:00
Nicolas Duchon 25883ac05f
style: remove extra blank lines 2024-02-10 19:04:56 +01:00
Nicolas Duchon 62f55b4428
docs: add logging documentation 2024-02-10 19:03:13 +01:00
Nicolas Duchon 76778cebb1
refactor: parse LOG_JSON as boolean + avoid unnecessary backticks 2024-02-10 18:40:18 +01:00
Nicolas Duchon 8aefce916f
tests: fix the json log test compose files 2024-02-10 18:02:42 +01:00
Denis Arh de9809a9e5 Add more control over log_format config directive
Introduces 3 new environmental variables:
 - `LOG_FORMAT`
 - `LOG_FORMAT_ESCAPE`
 - `LOG_JSON`

`LOG_FORMAT` and `LOG_FORMAT_ESCAPE` default to standard values.
When `LOG_JSON` is set, defaults are changed to: `{"time_local":"$time_iso8601","client_ip":"$http_x_forwarded_for","remote_addr":"$remote_addr","request":"$request","status":"$status","body_bytes_sent":"$body_bytes_sent","request_time":"$request_time","upstream_response_time":"$upstream_response_time","upstream_addr":"$upstream_addr","http_referrer":"$http_referer","http_user_agent":"$http_user_agent","request_id":"$request_id"}`and `json`.

See `nginx.tmpl` and https://nginx.org/en/docs/http/ngx_http_log_module.html#log_format for details
2024-02-10 17:39:16 +01:00
Nicolas Duchon e50429e87e
Merge pull request #2389 from nginx-proxy/2300
feat: define basic auth for virtual path
2024-02-10 16:33:27 +01:00
jmformenti fa23c11edb
feat: define basic auth for virtual path 2024-02-10 16:24:00 +01:00
Nicolas Duchon df890def7c
Merge pull request #2388 from nginx-proxy/2386
fix: add non standard port to Host header
2024-02-10 16:06:46 +01:00
Nicolas Duchon 40a347bfae
fix: add non standard port to Host header 2024-02-10 15:23:35 +01:00
Nicolas Duchon af56ba2254
Merge pull request #2387 from nginx-proxy/1780
fix: set worker_rlimit_nofile to (worker_connections x 2)
2024-02-10 14:17:40 +01:00
Nicolas Duchon 5d10467c42
fix: set worker_rlimit_nofile to (worker_connections x 2) 2024-02-10 13:56:38 +01:00
Nicolas Duchon 3d61f47b54
Merge pull request #2383 from lysliu/patch-1
Add s390x support
2024-02-01 11:19:41 +01:00
Yan Song Liu af5acae58a
Add s390x support
Add s390x support

Signed-off-by: Yan Song Liu <lysliu@cn.ibm.com>
2024-02-01 14:42:15 +08:00
Nicolas Duchon e8d95764fb
Merge pull request #2381 from nginx-proxy/dependabot/github_actions/peter-evans/dockerhub-description-4
ci: bump peter-evans/dockerhub-description from 3 to 4
2024-01-29 19:59:23 +01:00
dependabot[bot] bfe9e0ac1d
ci: bump peter-evans/dockerhub-description from 3 to 4
Bumps [peter-evans/dockerhub-description](https://github.com/peter-evans/dockerhub-description) from 3 to 4.
- [Release notes](https://github.com/peter-evans/dockerhub-description/releases)
- [Commits](https://github.com/peter-evans/dockerhub-description/compare/v3...v4)

---
updated-dependencies:
- dependency-name: peter-evans/dockerhub-description
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-29 04:35:11 +00:00
Nicolas Duchon d46881fb58
Merge pull request #2321 from theFra985/patch-1
Add support for grpcs protocol
2024-01-16 18:59:45 +01:00
Nicolas Duchon 6f042854e1
Merge pull request #2364 from nginx-proxy/keepalive
feat: keepalive auto setting
2024-01-13 11:40:45 +01:00
Nicolas Duchon 14347a4178
Merge pull request #2372 from nginx-proxy/add-openssl-back
build: add the openssl cli back to the alpine image
2024-01-10 17:11:52 +01:00
Nicolas Duchon 63411b2407
build: add the openssl cli back to the alpine image 2024-01-10 17:00:47 +01:00
Nicolas Duchon b492cae053
Merge pull request #2369 from SchoNie/nginx-proxy-tester-compose
Install docker compose dependencies in nginx-proxy-tester image
2024-01-05 17:44:31 +01:00
Niek 329b69fe76
Update test readme 2024-01-05 14:33:05 +01:00
Niek 1433daed4d
Install docker dependencies in nginx-proxy-tester image 2024-01-05 14:32:11 +01:00
Nicolas Duchon a3de83c7d1
Merge pull request #2365 from nginx-proxy/dependabot/pip/test/requirements/pytest-7.4.4
ci: bump pytest from 7.4.3 to 7.4.4 in /test/requirements
2024-01-01 10:58:15 +01:00
dependabot[bot] e2bd0d6365
ci: bump pytest from 7.4.3 to 7.4.4 in /test/requirements
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.4.3 to 7.4.4.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.4.3...7.4.4)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-01 04:39:54 +00:00
Nicolas Duchon d12689cd52 docs: keepalive auto setting 2023-12-26 19:10:42 +01:00
Nicolas Duchon 2aa35aa637 tests: keepalive auto setting 2023-12-26 19:07:09 +01:00
Nicolas Duchon 443ee5202c test: do we get desired number of idle keepalive connections 2023-12-26 18:52:43 +01:00
Nicolas Duchon d56e8f1d8a refactor: $server_found and $servers aren't both needed 2023-12-26 18:43:05 +01:00
Nicolas Duchon 7ce72d59a9 feat: add auto keepalive setting 2023-12-26 18:33:28 +01:00
Nicolas Duchon 26db13387e refactor: explicitely default keepalive to disabled 2023-12-26 17:58:24 +01:00
Nicolas Duchon 35c6b2afe5
Merge pull request #2362 from nginx-proxy/dependabot/docker/nginxproxy/forego-0.18.1-debian
build: bump nginxproxy/forego from 0.17.3 to 0.18.1
2023-12-25 21:26:58 +01:00
Nicolas Duchon beeb80732a docs: mention color disabling 2023-12-25 21:19:02 +01:00
dependabot[bot] 47ee75d780
build: bump nginxproxy/forego from 0.17.3-debian to 0.18.1-debian
Bumps nginxproxy/forego from 0.17.3-debian to 0.18.1-debian.

---
updated-dependencies:
- dependency-name: nginxproxy/forego
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-25 20:12:56 +00:00
Nicolas Duchon 53656ffe51
Merge pull request #2360 from nginx-proxy/dependabot/docker/nginxproxy/docker-gen-0.11.1-debian
build: bump nginxproxy/docker-gen from 0.11.0 to 0.11.1
2023-12-25 21:11:57 +01:00
Nicolas Duchon 795cc1332b
Merge pull request #2358 from nginx-proxy/proxy_buffering
feat: enable proxy_buffering
2023-12-25 20:45:51 +01:00
dependabot[bot] 051c8a5105
build: bump nginxproxy/docker-gen from 0.11.0-debian to 0.11.1-debian
Bumps nginxproxy/docker-gen from 0.11.0-debian to 0.11.1-debian.

---
updated-dependencies:
- dependency-name: nginxproxy/docker-gen
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-25 19:45:00 +00:00
Nicolas Duchon 4fbd14f1fd
Merge pull request #2359 from nginx-proxy/cleanup-dockerfiles
refactor: cleanup dockerfiles
2023-12-25 20:22:37 +01:00
Nicolas Duchon eb9fca85cf refactor: remove already present or unneeded dependencies 2023-12-25 19:19:57 +01:00
Nicolas Duchon 758b43a5b2 refactor: remove unneeded nginx.conf modification
the upstream nginx.conf already has "worker_processes  auto;"
2023-12-25 19:18:00 +01:00
Nicolas Duchon de4cb3d2b0 refactor: move nginx daemon off to procfile 2023-12-25 19:16:10 +01:00
Nicolas Duchon 5c1db95551 feat: enable proxy_buffering 2023-12-25 17:27:34 +01:00
Nicolas Duchon 4a8aa5db67
docs: fix two links in updated README.md 2023-12-25 11:27:22 +01:00
Nicolas Duchon ac3131844f
Merge pull request #2357 from nginx-proxy/split-docs
docs: split documentation
2023-12-25 11:24:43 +01:00
Nicolas Duchon 7f43f0a66b docs: split documentation 2023-12-25 11:22:47 +01:00
Nicolas Duchon 18e788575d
Merge pull request #2356 from nginx-proxy/revert-2355
test: revert "Fix test" and "Sleep longer"
2023-12-24 15:35:52 +01:00
Nicolas Duchon a4ced5b8bd test: revert "Fix test" and "Sleep longer"
This reverts commit 5174495963.
This reverts commit 33ceec07d8.
2023-12-24 00:16:40 +01:00
Nicolas Duchon db27a07741
Merge pull request #2355 from SchoNie/fix-test_restart_while_missing_cert.py-xfails-xpass
Fix xpass and xfails test_restart_while_missing_cert.py
2023-12-23 22:27:46 +01:00
Niek 33ceec07d8
Sleep longer 2023-12-22 17:50:09 +01:00
Niek 5174495963
Fix test 2023-12-22 17:19:42 +01:00
Nicolas Duchon 39db465e65
Merge pull request #2354 from SchoNie/Pytest-color
Pytest color terminal output
2023-12-22 15:21:49 +01:00
Niek c338a7cf22
Color terminal output 2023-12-22 14:37:20 +01:00
Nicolas Duchon 4f85eefa46
Merge pull request #2349 from pini-gh/pini-support-docker-compose-v1
Tests: support custom 'docker compose' command
2023-12-20 10:04:07 +01:00
Gilles Filippini 9e77e81e7d Tests: support custom 'docker compose' command
Enable overriding default 'docker compose' command with environment variable
'DOCKER_COMPOSE'. This way docker compose v1 is still supported with:

  $ DOCKER_COMPOSE=docker-compose pytest

This is important because people using the Debian packaged docker compose
are stuck to v1.
2023-12-20 09:30:06 +01:00
Nicolas Duchon a8478d10da
Merge pull request #2350 from pini-gh/pini-support-more-python-versions
Fix test case assertion depending on python version
2023-12-19 22:54:42 +01:00
Gilles Filippini 5d2f51dfe2 Fix test case assertion depending on python version 2023-12-19 21:31:19 +01:00
Nicolas Duchon 980470377a
ci: Docker Hub description update 2023-12-19 20:33:51 +01:00
Nicolas Duchon 81798c4d51
Merge pull request #2348 from nginx-proxy/dependabot/docker/nginxproxy/forego-0.17.3-debian
build: bump nginxproxy/forego from 0.17.2-debian to 0.17.3-debian
2023-12-19 20:17:02 +01:00
Nicolas Duchon 478940420e
Merge pull request #2347 from pini-gh/pini-2310
fix #2310
2023-12-19 20:08:31 +01:00
dependabot[bot] 2c3883ca81
build: bump nginxproxy/forego from 0.17.2-debian to 0.17.3-debian
Bumps nginxproxy/forego from 0.17.2-debian to 0.17.3-debian.

---
updated-dependencies:
- dependency-name: nginxproxy/forego
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-19 19:07:02 +00:00
Nicolas Duchon 5d37cab19b
ci: add explicit provenance and enable sbom 2023-12-19 19:26:13 +01:00
Gilles Filippini a2ade38abb fix #2310
Check the '.Internal' network property, because the .Gateway property is
defined for internal networks as well.
2023-12-19 19:21:00 +01:00
Nicolas Duchon 57a350364d
Merge pull request #2245 from nginx-proxy/build-workflow
ci: image build and publish workflow update
2023-12-19 18:48:14 +01:00
Nicolas Duchon e2997d9fb9
ci: enable gha caching on docker/build-push-action 2023-12-19 18:39:23 +01:00
Nicolas Duchon db55ddcab4
ci: use build matrix rather than separate jobs 2023-12-19 18:39:20 +01:00
Nicolas Duchon 41c7646d8c
Merge pull request #2346 from nginx-proxy/dependabot/docker/nginxproxy/docker-gen-0.11.0
build: bump nginxproxy/docker-gen from 0.10.7 to 0.11.0
2023-12-19 14:00:12 +01:00
dependabot[bot] 005488886d
build: bump nginxproxy/docker-gen from 0.10.7 to 0.11.0
Bumps nginxproxy/docker-gen from 0.10.7 to 0.11.0.

---
updated-dependencies:
- dependency-name: nginxproxy/docker-gen
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-19 12:40:22 +00:00
Nicolas Duchon 7d44f98e4f
test: remove unused import 2023-12-12 22:16:32 +01:00
dependabot[bot] 1f17a55366
Merge pull request #2340 from nginx-proxy/dependabot/pip/test/requirements/docker-7.0.0 2023-12-12 21:16:15 +00:00
dependabot[bot] c1617a6fac
ci: bump docker from 6.1.3 to 7.0.0 in /test/requirements
Bumps [docker](https://github.com/docker/docker-py) from 6.1.3 to 7.0.0.
- [Release notes](https://github.com/docker/docker-py/releases)
- [Commits](https://github.com/docker/docker-py/compare/6.1.3...7.0.0)

---
updated-dependencies:
- dependency-name: docker
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-12 21:07:53 +00:00
Nicolas Duchon f044423e4e
Merge pull request #2343 from nginx-proxy/docker-compose-upgrade
test: replace python docker-compose with docker compose
2023-12-12 22:07:14 +01:00
Nicolas Duchon c4cf0af373 test: fix failing tests 2023-12-12 21:56:27 +01:00
Nicolas Duchon 060f09cfce ci: ensure all compose files are valid compose v2 + formatting 2023-12-12 21:56:27 +01:00
Nicolas Duchon b5cac06305 ci: remove python docker-compose 2023-12-12 21:56:24 +01:00
Nicolas Duchon 4fb876ed41
Merge pull request #2341 from nginx-proxy/dependabot/github_actions/actions/setup-python-5
ci: bump actions/setup-python from 4 to 5
2023-12-11 12:27:12 +01:00
dependabot[bot] c06593bdcb
ci: bump actions/setup-python from 4 to 5
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4 to 5.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 04:09:41 +00:00
Nicolas Duchon 9380db5e8e
Merge pull request #2338 from nginx-proxy/aws-ssl-policies
fix: TLS 1.3 security policies
2023-12-08 23:15:04 +01:00
Nicolas Duchon 4c556290f9
fix: enforce TLSv1.3 on Mozilla-Modern SSL policy 2023-12-08 22:41:29 +01:00
Nicolas Duchon c6868ed6be
fix: SSL cipher suites / TLSv1.3 2023-12-08 22:06:07 +01:00
Nicolas Duchon ec0d908a44
feat: add AWS TLS 1.3 security policies 2023-12-08 17:59:26 +01:00
Nicolas Duchon 2ed32974e0
Merge pull request #2274 from nginx-proxy/ssl-policies
New AWS SSL policies
2023-12-08 17:15:21 +01:00
Nicolas Duchon 99aa94aa32
docs: HTML anchors fix 2023-12-08 16:53:27 +01:00
Nicolas Duchon 664ba246fd
fix: remove unsupported TLSv1.3 from new AWS SSL policies 2023-12-08 16:44:48 +01:00
Nicolas Duchon 34655618a6
docs: cleanup SSL policies section 2023-12-08 16:44:47 +01:00
Nicolas Duchon 1535227c78
docs: up to date link to AWS ELB SSL policies 2023-12-08 16:44:47 +01:00
patrickdk 099ac04576
feat: add new SSL policies 2023-12-08 16:44:47 +01:00
Nicolas Duchon d05175d1d6
Merge pull request #2278 from nginx-proxy/http3
feat: experimental HTTP/3 support + optional HTTP/2 disabling
2023-12-08 01:40:36 +01:00
Nicolas Duchon 3b075e7eed
Merge pull request #2336 from nginx-proxy/dependabot/docker/nginxproxy/docker-gen-0.10.7
build: bump nginxproxy/docker-gen from 0.10.6 to 0.10.7
2023-12-08 01:40:23 +01:00
dependabot[bot] d37eff8329
build: bump nginxproxy/docker-gen from 0.10.6 to 0.10.7
Bumps nginxproxy/docker-gen from 0.10.6 to 0.10.7.

---
updated-dependencies:
- dependency-name: nginxproxy/docker-gen
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-08 00:32:19 +00:00
Nicolas Duchon c4cb1c3797
test: tests for HTTP/3
Co-authored-by: Nicolas Duchon <nicolas.duchon@gmail.com>
Co-authored-by: Niek <100143256+SchoNie@users.noreply.github.com>
2023-12-08 00:48:08 +01:00
Nicolas Duchon ae5beca0fe
docs: documentation for HTTP/2 and HTTP/3 support
Co-authored-by: Nicolas Duchon <nicolas.duchon@gmail.com>
Co-authored-by: Patrick Domack <patrickdk@patrickdk.com>
2023-12-08 00:48:08 +01:00
Nicolas Duchon 018db70367
refactor: re-organise template for HTTP/3 feature
Co-authored-by: Nicolas Duchon <nicolas.duchon@gmail.com>
Co-authored-by: Niek <100143256+SchoNie@users.noreply.github.com>
2023-12-08 00:48:08 +01:00
Nicolas Duchon b5cc9b1aa2
feat: experimental http3 support
Co-authored-by: Nicolas Duchon <nicolas.duchon@gmail.com>
Co-authored-by: Knapoc <Knapoc@users.noreply.github.com>
2023-12-08 00:48:08 +01:00
Nicolas Duchon 5af973b193
feat: optionally disable HTTP/2 2023-12-08 00:48:08 +01:00
Nicolas Duchon 7ca3769a39
Merge pull request #2322 from nginx-proxy/dependabot/docker/nginx-1.25.3-alpine
build: bump nginx from 1.25.2-alpine to 1.25.3-alpine
2023-12-08 00:47:06 +01:00
Nicolas Duchon 43692bb495
Merge pull request #2306 from nginx-proxy/dependabot/github_actions/docker/build-push-action-5
ci: bump docker/build-push-action from 4 to 5
2023-12-08 00:29:56 +01:00
dependabot[bot] 3f764a5f84
build: bump nginx from 1.25.2-alpine to 1.25.3-alpine
Bumps nginx from 1.25.2-alpine to 1.25.3-alpine.

---
updated-dependencies:
- dependency-name: nginx
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-08 00:28:25 +01:00
Nicolas Duchon a8f5682397
Merge pull request #2324 from nginx-proxy/dependabot/pip/test/requirements/pytest-7.4.3
ci: bump pytest from 7.4.1 to 7.4.3 in /test/requirements
2023-12-08 00:23:29 +01:00
Nicolas Duchon 272b6d37e6
Merge pull request #2307 from nginx-proxy/dependabot/github_actions/docker/login-action-3
ci: bump docker/login-action from 2 to 3
2023-12-08 00:22:13 +01:00
dependabot[bot] 67369c16c5
ci: bump docker/build-push-action from 4 to 5
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 4 to 5.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v4...v5)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-07 23:22:02 +00:00
Nicolas Duchon 8fb137cf8b
Merge pull request #2305 from nginx-proxy/dependabot/github_actions/docker/metadata-action-5
ci: bump docker/metadata-action from 4 to 5
2023-12-08 00:20:55 +01:00
Nicolas Duchon 08abc53bbc
Merge pull request #2304 from nginx-proxy/dependabot/github_actions/docker/setup-qemu-action-3
ci: bump docker/setup-qemu-action from 2 to 3
2023-12-08 00:20:23 +01:00
Nicolas Duchon 2bbc3e575f
Merge pull request #2303 from nginx-proxy/dependabot/github_actions/docker/setup-buildx-action-3
ci: bump docker/setup-buildx-action from 2 to 3
2023-12-08 00:20:05 +01:00
Nicolas Duchon 32288f3caa
Merge pull request #2296 from nginx-proxy/dependabot/github_actions/actions/checkout-4
ci: bump actions/checkout from 3 to 4
2023-12-08 00:17:20 +01:00
dependabot[bot] 94259dd22c
ci: bump pytest from 7.4.1 to 7.4.3 in /test/requirements
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.4.1 to 7.4.3.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.4.1...7.4.3)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 04:38:05 +00:00
Francesco Cattoni a5566f5e8f
Added support for grpcs protocol 2023-10-22 00:34:32 +02:00
Daniel Carrera 29d4f31815 Merge branch 'main' into feature/virtual_host_alias 2023-10-16 13:02:42 -04:00
dependabot[bot] 4464afa219
ci: bump docker/login-action from 2 to 3
Bumps [docker/login-action](https://github.com/docker/login-action) from 2 to 3.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-18 04:08:20 +00:00
dependabot[bot] 00dbe25e19
ci: bump docker/metadata-action from 4 to 5
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 4 to 5.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Upgrade guide](https://github.com/docker/metadata-action/blob/master/UPGRADE.md)
- [Commits](https://github.com/docker/metadata-action/compare/v4...v5)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-18 04:08:13 +00:00
dependabot[bot] 9a162ba384
ci: bump docker/setup-qemu-action from 2 to 3
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 2 to 3.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-18 04:08:10 +00:00
dependabot[bot] 1ea872051e
ci: bump docker/setup-buildx-action from 2 to 3
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2 to 3.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-18 04:08:08 +00:00
dependabot[bot] 3b32dff071
ci: bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-11 04:10:00 +00:00
Nicolas Duchon 67ab97ed64
Merge pull request #2292 from nginx-proxy/dependabot/pip/test/requirements/pytest-7.4.1
ci: bump pytest from 7.4.0 to 7.4.1 in /test/requirements
2023-09-04 09:05:03 +02:00
Nicolas Duchon 6332fabe37
Merge pull request #2285 from nginx-proxy/dependabot/docker/nginx-1.25.2-alpine
build: bump nginx from 1.25.1-alpine to 1.25.2-alpine
2023-09-04 08:38:45 +02:00
dependabot[bot] 39fb91675f
ci: bump pytest from 7.4.0 to 7.4.1 in /test/requirements
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.4.0 to 7.4.1.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.4.0...7.4.1)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-04 04:53:51 +00:00
dependabot[bot] e623b68eb3
build: bump nginx from 1.25.1-alpine to 1.25.2-alpine
Bumps nginx from 1.25.1-alpine to 1.25.2-alpine.

---
updated-dependencies:
- dependency-name: nginx
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-16 04:34:23 +00:00
Nicolas Duchon 6f0be586b9
Merge pull request #2283 from SchoNie/certificate_bump
Bump create_server_certificate.sh to nginx:1.25.1
2023-07-31 19:07:36 +02:00
Niek 0cbc998381
Bump create_server_certificate.sh to nginx:1.25.1 2023-07-31 13:04:19 +02:00
Nicolas Duchon c430825733
Merge pull request #2273 from nginx-proxy/dependabot/docker/nginxproxy/docker-gen-0.10.6-debian
build: bump nginxproxy/docker-gen from 0.10.5 to 0.10.6
2023-07-12 14:25:33 +02:00
dependabot[bot] cff658a28e
build: bump nginxproxy/docker-gen from 0.10.5-debian to 0.10.6-debian
Bumps nginxproxy/docker-gen from 0.10.5-debian to 0.10.6-debian.

---
updated-dependencies:
- dependency-name: nginxproxy/docker-gen
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-12 11:58:05 +00:00
Nicolas Duchon 8ee5afec33
Merge pull request #2266 from nginx-proxy/dependabot/docker/nginxproxy/forego-0.17.2-debian
build: bump nginxproxy/forego from 0.17.1 to 0.17.2
2023-07-05 06:05:55 +02:00
dependabot[bot] 19f8d7e375
build: bump nginxproxy/forego from 0.17.1-debian to 0.17.2-debian
Bumps nginxproxy/forego from 0.17.1-debian to 0.17.2-debian.

---
updated-dependencies:
- dependency-name: nginxproxy/forego
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-04 06:27:05 +00:00
Nicolas Duchon 6329ea9963
Merge pull request #2267 from nginx-proxy/dependabot/docker/nginxproxy/docker-gen-0.10.5-debian
build: bump nginxproxy/docker-gen from 0.10.4 to 0.10.5
2023-07-04 08:26:32 +02:00
dependabot[bot] 1e02cb7486
build: bump nginxproxy/docker-gen from 0.10.4-debian to 0.10.5-debian
Bumps nginxproxy/docker-gen from 0.10.4-debian to 0.10.5-debian.

---
updated-dependencies:
- dependency-name: nginxproxy/docker-gen
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-04 06:13:58 +00:00
Nicolas Duchon d6234b9b7a
docs: update nginx version badge 2023-07-04 08:06:22 +02:00
Nicolas Duchon f2be3c3915
Merge pull request #2261 from nginx-proxy/dependabot/docker/nginx-1.25.1-alpine
build: bump nginx from 1.25.0-alpine to 1.25.1-alpine
2023-07-04 08:04:14 +02:00
Nicolas Duchon 45c181b972 build: update template for nginx 1.25.1
http2 on the listen directive have been deprecated and replaced by the server level http2 directive.
2023-07-04 07:54:38 +02:00
Nicolas Duchon 104d3fc503
Merge pull request #2263 from nginx-proxy/dependabot/pip/test/requirements/pytest-7.4.0
ci: bump pytest from 7.3.2 to 7.4.0 in /test/requirements
2023-07-04 07:19:29 +02:00
dependabot[bot] f878cd8c04
ci: bump pytest from 7.3.2 to 7.4.0 in /test/requirements
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.3.2 to 7.4.0.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.3.2...7.4.0)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-26 04:58:03 +00:00
dependabot[bot] f9e0cd4f68
build: bump nginx from 1.25.0-alpine to 1.25.1-alpine
Bumps nginx from 1.25.0-alpine to 1.25.1-alpine.

---
updated-dependencies:
- dependency-name: nginx
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-15 04:57:37 +00:00
Nicolas Duchon 4304dcd11d
Merge pull request #2259 from nginx-proxy/dependabot/pip/test/requirements/pytest-7.3.2
ci: bump pytest from 7.3.1 to 7.3.2 in /test/requirements
2023-06-13 07:52:26 +02:00
dependabot[bot] 893eefc99d
ci: bump pytest from 7.3.1 to 7.3.2 in /test/requirements
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.3.1 to 7.3.2.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.3.1...7.3.2)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-12 04:57:57 +00:00
Nicolas Duchon af62e14bb1
docs: fix typo 2023-06-07 20:21:44 +02:00
Nicolas Duchon c1a2b31f35
Merge pull request #2222 from rot169/support-hostnet-containers
Support containers running --net=host (#1537)
2023-06-07 07:55:28 +02:00
Nicolas Duchon e22caf7df9 doc: typo in documentation 2023-06-07 07:45:01 +02:00
Nicolas Duchon a81d03c555
Merge pull request #2255 from nginx-proxy/dependabot/pip/test/requirements/docker-6.1.3
ci: bump docker from 6.1.2 to 6.1.3 in /test/requirements
2023-06-05 07:25:01 +02:00
dependabot[bot] bebb3bba86
ci: bump docker from 6.1.2 to 6.1.3 in /test/requirements
Bumps [docker](https://github.com/docker/docker-py) from 6.1.2 to 6.1.3.
- [Release notes](https://github.com/docker/docker-py/releases)
- [Commits](https://github.com/docker/docker-py/compare/6.1.2...6.1.3)

---
updated-dependencies:
- dependency-name: docker
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-05 04:57:33 +00:00
Nicolas Duchon b382d0bbb6
Merge pull request #2250 from SaturnIC-Forks/main
fix: Replace mDNS .local domain with .internal domain
2023-05-30 07:28:13 +02:00
Nicolas Duchon edb58755c9
docs: nginx badge 1.25.0 2023-05-30 07:09:23 +02:00
Nicolas Duchon 34751eb148
Merge pull request #2251 from nginx-proxy/dependabot/docker/nginx-1.25.0-alpine
build: bump nginx from 1.23.4-alpine to 1.25.0-alpine
2023-05-30 07:02:20 +02:00
Nicolas Duchon f63e239827
Merge pull request #2252 from nginx-proxy/dependabot/pip/test/requirements/requests-2.31.0
ci: bump requests from 2.30.0 to 2.31.0 in /test/requirements
2023-05-30 06:57:07 +02:00
dependabot[bot] e34d00f42c
ci: bump requests from 2.30.0 to 2.31.0 in /test/requirements
Bumps [requests](https://github.com/psf/requests) from 2.30.0 to 2.31.0.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.30.0...v2.31.0)

---
updated-dependencies:
- dependency-name: requests
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-29 04:57:57 +00:00
dependabot[bot] 3a66659e63
build: bump nginx from 1.23.4-alpine to 1.25.0-alpine
Bumps nginx from 1.23.4-alpine to 1.25.0-alpine.

---
updated-dependencies:
- dependency-name: nginx
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-25 04:57:50 +00:00
SaturnIC 13eb61a639 fix: Replace mDNS .local domain with .example domain
See RFC 6762 for details on mDNS .local domain: https://datatracker.ietf.org/doc/html/rfc6762
And RFC 6761 for details on .example domain: https://datatracker.ietf.org/doc/html/rfc6761
2023-05-23 09:43:30 +02:00
azlux a06bb9e68b
fix: add missing cipher suite to Mozilla-Intermediate (#2247) 2023-05-22 12:21:35 +02:00
Nicolas Duchon ffc8b27c6a
Merge pull request #2244 from nginx-proxy/dependabot/pip/test/requirements/docker-6.1.2
ci: bump docker from 6.1.1 to 6.1.2 in /test/requirements
2023-05-15 13:35:30 +02:00
dependabot[bot] bd5816b705
ci: bump docker from 6.1.1 to 6.1.2 in /test/requirements
Bumps [docker](https://github.com/docker/docker-py) from 6.1.1 to 6.1.2.
- [Release notes](https://github.com/docker/docker-py/releases)
- [Commits](https://github.com/docker/docker-py/compare/6.1.1...6.1.2)

---
updated-dependencies:
- dependency-name: docker
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-15 04:58:28 +00:00
Nicolas Duchon 87108892f6
Merge pull request #2238 from nginx-proxy/prebuilt-forego
build: get forego from pre-built image
2023-05-11 10:36:35 +02:00
Nicolas Duchon 5d237b7a0a build: get Forego from pre-built image 2023-05-11 01:07:09 -04:00
Richard Hansen 068bf91e83
Merge pull request #2239 from nginx-proxy/fix-rfc-5746
fix: always on session cache on HTTPS fallback listener
2023-05-11 00:43:24 -04:00
Nicolas Duchon 27f6cebb05
docs: host networking support documentation 2023-05-09 21:08:10 +02:00
Nicolas Duchon 35b1493e16
feat: support proxy + container in host network mode 2023-05-09 19:31:42 +02:00
Nicolas Duchon b88d33d2f3
feat: handle multiple proxy networks 2023-05-09 00:58:05 +02:00
Nicolas Duchon e2539b04f5
fix: always on session cache on HTTPS fallback listener 2023-05-08 23:14:09 +02:00
Nicolas Duchon 9ff197d721
Merge pull request #2237 from nginx-proxy/dependabot/pip/test/requirements/requests-2.30.0
ci: bump requests from 2.29.0 to 2.30.0 in /test/requirements
2023-05-08 21:30:46 +02:00
Nicolas Duchon 2b621599ff test: fix wildcard_certs_and_nohttps test 2023-05-08 21:20:47 +02:00
Nicolas Duchon 6e5e8f4c9d
ci: fix image version labelling 2023-05-08 15:36:04 +02:00
dependabot[bot] faad1cc29e
ci: bump requests from 2.29.0 to 2.30.0 in /test/requirements
Bumps [requests](https://github.com/psf/requests) from 2.29.0 to 2.30.0.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.29.0...v2.30.0)

---
updated-dependencies:
- dependency-name: requests
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-08 10:48:18 +00:00
Nicolas Duchon 7679665d99
Merge pull request #2236 from nginx-proxy/dependabot/pip/test/requirements/docker-6.1.1
ci: bump docker from 6.0.1 to 6.1.1 in /test/requirements
2023-05-08 12:47:22 +02:00
dependabot[bot] 28fef687ad
ci: bump docker from 6.0.1 to 6.1.1 in /test/requirements
Bumps [docker](https://github.com/docker/docker-py) from 6.0.1 to 6.1.1.
- [Release notes](https://github.com/docker/docker-py/releases)
- [Commits](https://github.com/docker/docker-py/compare/6.0.1...6.1.1)

---
updated-dependencies:
- dependency-name: docker
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-08 04:58:23 +00:00
Nicolas Duchon 7dd32e3ed3
Merge pull request #2232 from nginx-proxy/dependabot/docker/golang-1.20.4-alpine
build: bump golang from 1.20.3-alpine to 1.20.4-alpine
2023-05-03 19:54:13 +02:00
Nicolas Duchon d2e62c2013
Merge pull request #2231 from nginx-proxy/remove-wget
build: don't install wget inside images
2023-05-03 07:36:25 +02:00
dependabot[bot] 442e577c0e
build: bump golang from 1.20.3-alpine to 1.20.4-alpine
Bumps golang from 1.20.3-alpine to 1.20.4-alpine.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-03 04:57:51 +00:00
Nicolas Duchon 64e21100d3 build: don't install wget 2023-05-02 05:33:39 +02:00
Nicolas Duchon 0501c54002
build: get docker-gen from pre-built image (#2230)
* build: get docker-gen from pre-built image

* build: requested changes
2023-05-02 05:21:41 +02:00
Nicolas Duchon c337a13847
Merge pull request #2229 from nginx-proxy/workflow-rename
ci: rename build / publish workflow
2023-04-30 16:34:23 +02:00
Nicolas Duchon eabb808b85
ci: rename build / publish workflow 2023-04-30 15:51:46 +02:00
Nicolas Duchon 0853fada32
Merge pull request #2228 from nginx-proxy/dependabot/github_actions/docker/build-push-action-4
ci: bump docker/build-push-action from 3 to 4
2023-04-30 15:41:13 +02:00
Nicolas Duchon 2218f98af2
Merge pull request #2227 from nginx-proxy/dependabot/github_actions/actions/setup-python-4
ci: bump actions/setup-python from 2 to 4
2023-04-30 15:40:59 +02:00
dependabot[bot] 70c9ea6ccc ci: bump actions/setup-python from 2 to 4
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 2 to 4.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v2...v4)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-30 15:31:43 +02:00
Nicolas Duchon 4655ba9f51
ci: only trigger test workflow on push for main branch 2023-04-30 15:30:29 +02:00
dependabot[bot] edb6c5dfd8
ci: bump docker/build-push-action from 3 to 4
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 3 to 4.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-30 13:17:20 +00:00
Nicolas Duchon 4a096a25a8
Merge pull request #2226 from nginx-proxy/dependabot-actions
ci: maintain GitHub Actions with Dependabot
2023-04-30 15:16:53 +02:00
Nicolas Duchon 43eed7d0df
ci: check test suite dependencies weekly 2023-04-30 15:02:44 +02:00
Nicolas Duchon 21321a4495
ci: add GitHub Actions to Dependabot config 2023-04-30 15:02:09 +02:00
Nicolas Duchon 882e9a3b3c
test: add tests for host mode fix 2023-04-28 22:43:20 +02:00
Nicolas Duchon 6ef3196d30
Merge pull request #2225 from nginx-proxy/dependabot/pip/test/requirements/requests-2.29.0
ci: bump requests from 2.28.2 to 2.29.0 in /test/requirements
2023-04-27 18:41:07 +02:00
dependabot[bot] 00a1e5ef5c
ci: bump requests from 2.28.2 to 2.29.0 in /test/requirements
Bumps [requests](https://github.com/psf/requests) from 2.28.2 to 2.29.0.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.28.2...v2.29.0)

---
updated-dependencies:
- dependency-name: requests
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-27 05:00:28 +00:00
Andy 325fd01ebb Support containers running --net=host (#1537)
Detect if a target container is running host networking, and if so, use the IP address of the first bridge net gateway.
2023-04-23 14:09:33 +01:00
Nicolas Duchon b4efff04b7
Merge pull request #2220 from nginx-proxy/docker-gen-0.10.4
build: dockergen 0.10.3 -> 0.10.4
2023-04-18 08:10:11 +02:00
Nicolas Duchon 9f735aab82
build: dockergen 0.10.3 -> 0.10.4 2023-04-18 07:58:38 +02:00
Nicolas Duchon ff676b519e
Merge pull request #2219 from nginx-proxy/dependabot/pip/test/requirements/pytest-7.3.1
ci: bump pytest from 7.3.0 to 7.3.1 in /test/requirements
2023-04-18 07:20:04 +02:00
Richard Hansen 89c3c89f60
Merge pull request #2214 from rhansen/default_server
fix: Remove `default_server` listen option from fallback server
2023-04-17 13:34:14 -04:00
dependabot[bot] b34c917977
ci: bump pytest from 7.3.0 to 7.3.1 in /test/requirements
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.3.0 to 7.3.1.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.3.0...7.3.1)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-17 05:01:01 +00:00
Richard Hansen 035bd2b5ac fix: Remove `default_server` listen option from fallback server
This fixes a bug introduced in commit
9b4bb07b34.
2023-04-13 01:16:54 -04:00
Nicolas Duchon 1f3508e6df
Merge pull request #2216 from nginx-proxy/dependabot/pip/test/requirements/pytest-7.3.0
ci: bump pytest from 7.2.2 to 7.3.0 in /test/requirements
2023-04-10 07:35:41 +02:00
dependabot[bot] 695ad54dcf
ci: bump pytest from 7.2.2 to 7.3.0 in /test/requirements
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.2.2 to 7.3.0.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.2.2...7.3.0)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-10 05:00:55 +00:00
Nicolas Duchon 7322a2d542
Merge pull request #2213 from nginx-proxy/dependabot/docker/golang-1.20.3-alpine
build: bump golang from 1.20.2-alpine to 1.20.3-alpine
2023-04-05 07:19:43 +02:00
dependabot[bot] a3d3baf259
build: bump golang from 1.20.2-alpine to 1.20.3-alpine
Bumps golang from 1.20.2-alpine to 1.20.3-alpine.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-05 04:58:03 +00:00
Nicolas Duchon 130fd908fb
docs: update nginx version badge 2023-03-30 20:58:56 +02:00
Nicolas Duchon 3039d85ee7
Merge pull request #2206 from nginx-proxy/dependabot/docker/nginx-1.23.4-alpine
build: bump nginx from 1.23.3-alpine to 1.23.4-alpine
2023-03-30 20:58:00 +02:00
Nicolas Duchon c35368007e
Merge pull request #2207 from nginx-proxy/docker-gen-0.10.3
build: docker-gen 0.10.2 -> 0.10.3
2023-03-30 01:25:27 +02:00
Nicolas Duchon 2056dc4429
build: dockergen 0.10.2 -> 0.10.3 2023-03-30 01:10:05 +02:00
dependabot[bot] 87ffa7a5a8
build: bump nginx from 1.23.3-alpine to 1.23.4-alpine
Bumps nginx from 1.23.3-alpine to 1.23.4-alpine.

---
updated-dependencies:
- dependency-name: nginx
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-29 04:58:26 +00:00
Nicolas Duchon 0d9cd2b45c
Merge pull request #2186 from rhansen/fallback
fix: Improve handling of unknown hosts and missing certs
2023-03-24 14:18:52 +01:00
Niek 7ca1da8358
feat: Add support for HTTP load balancing between the proxy and upstream server groups (#2173)
Add initial tests

Newlines

Remove unused variable

Co-authored-by: Richard Hansen <rhansen@rhansen.org>

Change comment value

Co-authored-by: Richard Hansen <rhansen@rhansen.org>

add missing services line

Co-authored-by: Richard Hansen <rhansen@rhansen.org>

Use deploy.replicas

Remove details about choosing a load balancing method

Feedback note

Co-authored-by: Nicolas Duchon <nicolas.duchon@gmail.com>
2023-03-21 07:49:27 +01:00
Nicolas Duchon 55d53e6659
Merge pull request #1934 from rhansen/keepalive
feat: Add support for HTTP keep-alive between the proxy and upstream
2023-03-21 07:31:13 +01:00
Nicolas Duchon 6c2d17586b
Merge pull request #2200 from nginx-proxy/docker-gen-0.10.2
build: dockergen 0.10.1 -> 0.10.2
2023-03-21 07:27:48 +01:00
Nicolas Duchon 4696944245
build: dockergen 0.10.1 -> 0.10.2 2023-03-21 07:15:34 +01:00
Richard Hansen 49bb37dfdb feat: Add support for HTTP keep-alive between the proxy and upstream 2023-03-14 04:20:17 -04:00
Nicolas Duchon 1f855fc7b3
Merge pull request #2191 from rhansen/nil-currentcontainer
fix: Don't error if `$globals.CurrentContainer` is `nil`
2023-03-14 06:49:21 +01:00
Richard Hansen 364beed773 fix: Don't error if `$globals.CurrentContainer` is `nil`
Also:
  * Note when there are no networks.
  * Fix "networks available" comment.
2023-03-10 15:23:44 -05:00
Richard Hansen 51fd6918ca
Merge pull request #2188 from nginx-proxy/dependabot/docker/golang-1.20.2-alpine
build: bump golang from 1.20.1-alpine to 1.20.2-alpine
2023-03-08 15:00:19 -05:00
dependabot[bot] 9906ccda42
build: bump golang from 1.20.1-alpine to 1.20.2-alpine
Bumps golang from 1.20.1-alpine to 1.20.2-alpine.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-08 04:58:06 +00:00
Richard Hansen d990354e3d
Merge pull request #2187 from nginx-proxy/dependabot/pip/test/requirements/pytest-7.2.2
ci: bump pytest from 7.2.1 to 7.2.2 in /test/requirements
2023-03-06 15:50:46 -05:00
dependabot[bot] 2fc3e6c28c
ci: bump pytest from 7.2.1 to 7.2.2 in /test/requirements
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.2.1 to 7.2.2.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.2.1...7.2.2)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-06 05:04:42 +00:00
Nicolas Duchon abcef6be86
Merge pull request #2184 from nginx-proxy/dockergen-0.10.1
build: dockergen 0.10.0 -> 0.10.1
2023-02-28 08:50:19 +01:00
Nicolas Duchon 6e9d46e672
Merge pull request #2164 from rhansen/tests
chore: minor test improvements
2023-02-28 08:49:12 +01:00
Nicolas Duchon 16b8cde8e4
build: dockergen 0.10.0 -> 0.10.1 2023-02-28 08:36:27 +01:00
Nicolas Duchon afd6544702
Merge pull request #2179 from rhansen/swarm
fix: Partially revert "chore: Remove support for legacy swarm"
2023-02-28 07:40:16 +01:00
Richard Hansen 4fc17d6139
Merge pull request #2183 from JanMalte/patch-1
fix: Sort networks and ports before iterating
2023-02-21 00:56:06 -05:00
Jan Malte Gerth 37134c44d7 fix: Sort networks and ports before iterating
This avoids unnecessary nginx restarts caused by config file churn.
2023-02-21 00:22:47 -05:00
Richard Hansen b5a54ac219 tests: Reduce scope of `docker_compose` fixture (and friends)
This makes it possible to bring up different compose files for
different tests in the same test module.

This change does not negatively affect performance because the fixture
is a no-op if the docker compose filename is unchanged between tests.
2023-02-17 02:34:08 -05:00
Richard Hansen 4d8f878ba7 tests: Fixture that simplifies Docker compose file changes 2023-02-17 02:34:08 -05:00
Richard Hansen f5a3492926 tests: Factor out DNS monkey patching to its own fixture 2023-02-17 02:34:08 -05:00
Richard Hansen 09a2f40633 tests: Turn helper function into `docker_compose_file` fixture
This makes it easier for tests to override the filename.
2023-02-17 02:34:08 -05:00
Richard Hansen 01745a836f tests: Fix path to `ca-root.crt`
`os.getcwd()` is not guaranteed to always return the `test/`
directory.
2023-02-17 02:34:08 -05:00
Richard Hansen 6207be5f8f fix: Partially revert "chore: Remove support for legacy swarm"
This partially reverts commit 2494e20784
by ignoring any network named "ingress" when searching for a
container's IP address.

That commit was technically a backwards-incompatible change: Some
users use nginx-proxy with Swarm mode even though it is not fully
supported.  In such cases nginx-proxy should ignore the `ingress`
network, otherwise nginx will not be able to reach the
server (container-to-container traffic apparently doesn't work over
the Swarm `ingress` network).

The parts of that commit that examine the `SwarmNode` structure are
not reverted here because docker-gen does not currently populate that
structure -- not even when both docker-gen and the service task
container are running on the same manager node.
2023-02-17 01:52:05 -05:00
Richard Hansen 6f2a549ef1
Merge pull request #2175 from nginx-proxy/dependabot/docker/golang-1.20.1
build: bump golang from 1.20.0 to 1.20.1
2023-02-15 03:47:19 -05:00
dependabot[bot] de4386e440
build: bump golang from 1.20.0 to 1.20.1
Bumps golang from 1.20.0 to 1.20.1.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-15 04:57:57 +00:00
Nicolas Duchon bc2ada1f44
Merge pull request #2163 from nginx-proxy/dockergen-0.10.0
build: dockergen 0.9.4 -> 0.10.0
2023-02-09 08:28:09 +01:00
Nicolas Duchon c10c7bcbe9
build: dockergen 0.9.4 -> 0.10.0 2023-02-09 08:10:43 +01:00
Nicolas Duchon 41e025f0f0
Merge pull request #2159 from rhansen/refactor
chore: Factor out container IP:port lookup
2023-02-09 08:01:26 +01:00
Richard Hansen 9b4bb07b34
fix: Don't create fallback http(s) server when http(s) disabled
Before, a fallback http server was created to handle requests for
unknown virtual hosts even when `HTTPS_METHOD=nohttp`.  (In this case,
all http vhosts would be unknown.)  Likewise, a catch-all fallback
https server was still created even if `HTTPS_METHOD=nohttps`.

Now the fallback servers are created only if needed.  This brings the
behavior in line with the documentation and user expectation.  It will
also make it easier to implement a planned feature: different servers
on different ports.
2023-02-04 18:59:38 -05:00
Richard Hansen 9297e94389
fix: Emit TLS error if there are no certs available
Before, if neither the vhost-specific cert nor `default.crt` existed,
nginx-proxy would not create the https vhost.  This resulted in nginx
either refusing the connection or serving the wrong vhost depending on
whether there was another https vhost with a certificate.

Now nginx-proxy always creates an https server for a vhost, even if
the vhost-specific certificate and the default certificate are both
missing.  When both certs are missing, nginx is given empty
certificate data to make it possible for it to start up without an
error.  The empty certificate data causes the user to see a TLS error,
which is much easier to troubleshoot than a connection refused error
or serving the wrong vhost.
2023-02-02 22:02:06 -05:00
Richard Hansen 16066cab61
fix: Don't create cert error https server if https is not enabled 2023-02-02 17:17:00 -05:00
Richard Hansen ee8d2cede4
Merge pull request #2162 from nginx-proxy/dependabot/docker/golang-1.20.0
build: bump golang from 1.19.5 to 1.20.0
2023-02-02 02:20:26 -05:00
dependabot[bot] 7b6b2f773d
build: bump golang from 1.19.5 to 1.20.0
Bumps golang from 1.19.5 to 1.20.0.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-02 04:01:39 +00:00
Richard Hansen 18d0671312
chore: Factor out duplicate checks for `default.crt`
for improved readability.
2023-02-01 18:56:16 -05:00
Richard Hansen 7a2b1f8833
chore: Split `$is_https` variable into two separate checks
for improved readability.
2023-02-01 18:17:43 -05:00
Richard Hansen 11a46f728c chore: Factor out container IP:port lookup
This will make planned future changes easier.
2023-02-01 03:06:39 -05:00
Richard Hansen 2494e20784 chore: Remove support for legacy swarm
It doesn't work with the newer Docker Swarm mode so it doesn't have
much value anymore.
2023-02-01 03:04:37 -05:00
Nicolas Duchon 1462ff019d
Merge pull request #1179 from harvdogg/master
Allow complete override of location blocks
2023-02-01 07:42:42 +01:00
Richard Hansen 2115974e93 feat: Add ability to completely override location blocks
Co-authored-by: Trent Harvey <trent@harvdog.net>
2023-01-31 04:53:12 -05:00
Nicolas Duchon 8ac8b021b8
Merge pull request #2155 from rhansen/docker-pull
chore: Pass `--pull` to `docker build` to get fresh images
2023-01-30 07:57:44 +01:00
Nicolas Duchon 926bd43cff
Merge pull request #2153 from rhansen/upstream-cleanup
fix: Generate at most one `server` directive per container
2023-01-30 07:56:50 +01:00
Richard Hansen 912a065406 chore: Pass `--pull` to `docker build` to get fresh images
This is a no-op if the images are already up to date, and it prevents
puzzling problems when the images are old.
2023-01-28 18:17:40 -05:00
Richard Hansen 6162427c45 fix: Generate at most one `server` directive per container 2023-01-28 18:01:19 -05:00
Richard Hansen bcec2d9075 chore: Refactor `upstream` template for readability
In particular, reduce the nesting depth to make it easier to
understand what the code is doing by:

  * converting an $O(nm)$ nested loop into two serial $O(n)+O(m)$
    loops, and
  * consolidating similar nested `if` cases.
2023-01-28 18:01:19 -05:00
Richard Hansen daeed502cb feat: Add a warning comment if the container port is published 2023-01-28 18:01:19 -05:00
Richard Hansen 5a8a6ceae2 chore: Improve debug comments in `upstream` template 2023-01-28 18:01:19 -05:00
Richard Hansen 2760ead490 chore: Remove warning comment when port is not exposed
Exposing ports is largely deprecated because it doesn't actually do
anything in Docker.
2023-01-28 18:01:19 -05:00
Richard Hansen e97bf606c8 chore: Move version comment to the top of the template
to ensure that the version is always the first output line.

Also, always output `# nginx-proxy`, even if the version isn't known.
This makes it easier to find the start of the generated config in the
output of `nginx -T`.
2023-01-28 18:01:19 -05:00
Richard Hansen d6d53893e8
Merge pull request #2152 from vincent-herlemont/documentation-log-format
Documentation custom log format.
2023-01-28 03:32:21 -05:00
Vincent Herlemont aa50116272 Documentation custom log format. 2023-01-27 23:16:49 +01:00
Vincent Herlemont 07cc80ac6b
feat: Support LOG_FORMAT env variable (#2151) 2023-01-27 12:28:40 -05:00
Richard Hansen 8346b68a28 fix: Ignore `VIRTUAL_HOST` set to the empty string
Fixes #2144
2023-01-23 20:48:16 -05:00
Richard Hansen f8ae0a4b00 feat: `DEFAULT_ROOT=none` disables the default `location /` block 2023-01-23 20:47:00 -05:00
Nicolas Duchon d3ded293ac
Merge pull request #2147 from nginx-proxy/dockergen-0.9.4
build: dockergen 0.9.3 -> 0.9.4
2023-01-24 00:27:54 +01:00
Nicolas Duchon fa52426d54
ci: set Dependabot commit prefixs 2023-01-23 23:24:58 +01:00
Nicolas Duchon 8df67cdde8
build: dockergen 0.9.3 -> 0.9.4 2023-01-23 23:14:42 +01:00
Richard Hansen 98b6473c84
Merge pull request #2141 from rhansen/debug
feat: Unconditionally produce debug comments
2023-01-21 19:02:27 -05:00
Richard Hansen 8fbc8514ef feat: Unconditionally produce debug comments
Rationale for eliminating the check to see if the `DEBUG` environment
variable holds a true value:
  * The `DEBUG` environment variable might be set on a container (for
    purposes specific to that container, not `nginx-proxy`) to a value
    that cannot be parsed as a bool, which would break `nginx-proxy`.
  * It simplifies the template.
  * It eliminates a cold code path.
  * It avoids heisenbugs.
  * It makes debugging easier for users.

Also delete the debug info tests, as they are fragile and they provide
limited value.

Alternatively, we could avoid collision with the container's use of
the `DEBUG` environment variable by using a container label [1] such
as `com.google.nginx-proxy.nginx-proxy.debug`.  I think doing so has
dubious value, especially if we want to attempt backwards
compatibility with the `DEBUG` environment variable.

Fixes #2139

[1] https://docs.docker.com/engine/reference/commandline/run/#-set-metadata-on-container--l---label---label-file

Co-authored-by: Nicolas Duchon <nicolas.duchon@gmail.com>
2023-01-18 17:27:04 -05:00
Nicolas Duchon 1775420592
Merge pull request #2140 from rhansen/tests
Minor test fixes
2023-01-18 08:02:02 +01:00
Richard Hansen 92e1a6567e tests: Remove extraction of `nginx.tmpl` (now unnecessary) 2023-01-17 18:02:30 -05:00
Richard Hansen 486addd144 tests: Bind-mount the entire nginx-proxy directory in the container 2023-01-17 18:02:30 -05:00
Richard Hansen 569953521a tests: Exit non-zero if creation of nginx-proxy-tester image fails 2023-01-17 18:02:30 -05:00
Richard Hansen 55cfae9636 tests: Avoid unnecessary bashisms 2023-01-17 18:02:30 -05:00
Richard Hansen d56b5b370d tests: Whitespace fixes 2023-01-17 18:02:30 -05:00
Richard Hansen 26b0b05f73 tests: Fix `test_debug/*` tests when IPv6 is enabled 2023-01-17 18:02:29 -05:00
Nicolas Duchon 5d22134ee6
Merge pull request #2137 from nginx-proxy/dockergen-0.9.3
build: dockergen 0.9.2 -> 0.9.3
2023-01-17 08:35:18 +01:00
Nicolas Duchon b16ad27878
build: dockergen 0.9.2 -> 0.9.3 2023-01-17 08:17:02 +01:00
Nicolas Duchon 017a731302
Merge pull request #2127 from rhansen/chores
Various code health chores
2023-01-17 07:44:57 +01:00
Richard Hansen 2427b383b5 chore: Move global variables to a `$globals` dict
Planned future changes will introduce more embedded templates, and the ability
to pass the globals to the templates will be useful.
2023-01-17 00:42:20 -05:00
Richard Hansen 1b253cd908 chore: Wrap long comments 2023-01-17 00:42:20 -05:00
Richard Hansen 0da38122bd chore: Consistent indentation 2023-01-17 00:42:20 -05:00
Richard Hansen f20662eeaa chore: Use `{{-` instead of `{{` to clean up whitespace 2023-01-17 00:42:20 -05:00
Richard Hansen d6d8b2205f chore: Fix comment terminators 2023-01-17 00:42:20 -05:00
Richard Hansen 4651bf411d chore: Fix comment for `$proxy_connection` variable 2023-01-17 00:42:20 -05:00
Richard Hansen 744bd82c54 chore: Combine identical HTTP and HTTPS servers 2023-01-17 00:42:20 -05:00
Richard Hansen 491642b1e9 chore: Factor out duplicate virtual path code 2023-01-17 00:42:20 -05:00
Richard Hansen 14d0f3f222 chore: Rename `$container` to `$containers`
The value is actually a slice/array of containers so it should be
pluralized.
2023-01-17 00:42:20 -05:00
Richard Hansen 05423c681a fix: Use `parseBool` to parse boolean strings 2023-01-17 00:42:20 -05:00
Richard Hansen c117ae8fd8 chore: Use boolean for `$server_found` variable 2023-01-17 00:42:20 -05:00
Richard Hansen 05eee4b7a3
Merge pull request #2136 from nginx-proxy/dependabot/pip/test/requirements/pytest-7.2.1
chore(deps): bump pytest from 7.2.0 to 7.2.1 in /test/requirements
2023-01-16 23:28:47 -05:00
dependabot[bot] 9c9545bf7f
chore(deps): bump pytest from 7.2.0 to 7.2.1 in /test/requirements
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.2.0 to 7.2.1.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.2.0...7.2.1)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-16 04:12:49 +00:00
Richard Hansen cc9edec1c6
Merge pull request #2134 from nginx-proxy/dependabot/pip/test/requirements/requests-2.28.2
chore(deps): bump requests from 2.28.1 to 2.28.2 in /test/requirements
2023-01-13 16:35:16 -05:00
dependabot[bot] 831615fdd4
chore(deps): bump requests from 2.28.1 to 2.28.2 in /test/requirements
Bumps [requests](https://github.com/psf/requests) from 2.28.1 to 2.28.2.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.28.1...v2.28.2)

---
updated-dependencies:
- dependency-name: requests
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-13 04:04:20 +00:00
Richard Hansen 3531fa4d37
Merge pull request #2132 from nginx-proxy/dependabot/docker/golang-1.19.5
chore(deps): bump golang from 1.19.4 to 1.19.5
2023-01-11 14:10:23 -05:00
dependabot[bot] 146b7933a9
chore(deps): bump golang from 1.19.4 to 1.19.5
Bumps golang from 1.19.4 to 1.19.5.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-11 04:03:07 +00:00
Hannes Happle 1614afeaf4
don't redirect http aliases in final config 2020-07-31 15:32:40 +02:00
Hannes Happle 70acecaa4f
avoid duplicate acme location include in alias 2020-07-31 15:09:30 +02:00
Hannes Happle 663a79bfa9
all aliases in same server block (don't split >=3) 2020-07-31 14:32:41 +02:00
Hannes Happle 72e96ab0c6
replaced two numeric ports with variables 2020-07-31 14:31:36 +02:00
shiz0 5b69849b46
Merge pull request #2 from dannycarrera/feature/virtual_host_alias
Feature/virtual host alias
2020-07-31 09:16:27 +02:00
Daniel Carrera 2d860b04fc Do not HTTPS redirect Let'sEncrypt ACME challenge 2020-06-25 18:35:15 -04:00
Daniel Carrera 5108e8e313 Merge http & https server blocks 2020-06-25 18:05:26 -04:00
Daniel Carrera b4b5d63fe8 virtual_host_alias & ssl redirects with single 301 2020-06-24 16:59:11 -04:00
Daniel Carrera 1e344897a2 Added VIRTUAL_HOST_ALIAS to template
Updated README
2020-06-24 16:59:10 -04:00
167 changed files with 4615 additions and 2240 deletions

View File

@ -5,6 +5,8 @@ updates:
directory: "/"
schedule:
interval: "daily"
commit-message:
prefix: "build"
labels:
- "type/build"
- "scope/dockerfile"
@ -13,6 +15,18 @@ updates:
- package-ecosystem: "pip"
directory: "/test/requirements"
schedule:
interval: "daily"
interval: "weekly"
commit-message:
prefix: "ci"
labels:
- "type/ci"
# Maintain GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "ci"
labels:
- "type/ci"

101
.github/workflows/build-publish.yml vendored Normal file
View File

@ -0,0 +1,101 @@
name: Build and publish Docker images
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * 1"
push:
branches:
- main
tags:
- "*.*.*"
paths-ignore:
- "test/*"
- ".gitignore"
- "docker-compose-separate-containers.yml"
- "docker-compose.yml"
- "LICENSE"
- "Makefile"
- "*.md"
jobs:
multiarch-build:
name: Build and publish image
strategy:
matrix:
base: [alpine, debian]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Retrieve nginx-proxy version
id: nginx-proxy_version
run: echo "VERSION=$(git describe --tags)" >> "$GITHUB_OUTPUT"
- name: Retrieve docker-gen version
id: docker-gen_version
run: sed -n -e 's;^FROM nginxproxy/docker-gen:\([0-9.]*\).*;VERSION=\1;p' Dockerfile.${{ matrix.base }} >> "$GITHUB_OUTPUT"
- name: Get Docker tags
id: docker_meta
uses: docker/metadata-action@v5
with:
images: |
ghcr.io/nginx-proxy/nginx-proxy
nginxproxy/nginx-proxy
jwilder/nginx-proxy
tags: |
type=semver,pattern={{version}},enable=${{ matrix.base == 'debian' }}
type=semver,pattern={{major}}.{{minor}},enable=${{ matrix.base == 'debian' }}
type=semver,suffix=-alpine,pattern={{version}},enable=${{ matrix.base == 'alpine' }}
type=semver,suffix=-alpine,pattern={{major}}.{{minor}},enable=${{ matrix.base == 'alpine' }}
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' && matrix.base == 'debian' }}
type=raw,value=alpine,enable=${{ github.ref == 'refs/heads/main' && matrix.base == 'alpine' }}
labels: |
org.opencontainers.image.authors=Nicolas Duchon <nicolas.duchon@gmail.com> (@buchdag), Jason Wilder
org.opencontainers.image.version=${{ steps.nginx-proxy_version.outputs.VERSION }}
flavor: |
latest=false
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push the image
id: docker_build
uses: docker/build-push-action@v5
with:
context: .
file: Dockerfile.${{ matrix.base }}
build-args: |
NGINX_PROXY_VERSION=${{ steps.nginx-proxy_version.outputs.VERSION }}
DOCKER_GEN_VERSION=${{ steps.docker-gen_version.outputs.VERSION }}
platforms: linux/amd64,linux/arm64,linux/s390x,linux/arm/v7
sbom: true
push: true
provenance: mode=max
tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.docker_meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Images digests
run: echo ${{ steps.docker_build.outputs.digest }}

View File

@ -0,0 +1,27 @@
name: Update Docker Hub Description
on:
push:
branches:
- main
paths:
- README.md
- .github/workflows/dockerhub-description.yml
jobs:
dockerHubDescription:
name: Update Docker Hub Description
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Docker Hub Description
uses: peter-evans/dockerhub-description@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN_RWD }}
repository: nginxproxy/nginx-proxy
short-description: ${{ github.event.repository.description }}
enable-url-completion: true

View File

@ -1,143 +0,0 @@
name: DockerHub
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * 1"
push:
branches:
- main
tags:
- "*.*.*"
paths-ignore:
- "test/*"
- ".gitignore"
- "docker-compose-separate-containers.yml"
- "docker-compose.yml"
- "LICENSE"
- "Makefile"
- "*.md"
jobs:
multiarch-build-debian:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Retrieve version
run: echo "GIT_DESCRIBE=$(git describe --tags)" >> $GITHUB_ENV
- name: Get Docker tags for Debian based image
id: docker_meta_debian
uses: docker/metadata-action@v4
with:
images: |
ghcr.io/nginx-proxy/nginx-proxy
nginxproxy/nginx-proxy
jwilder/nginx-proxy
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest,enable={{is_default_branch}}
labels: |
org.opencontainers.image.authors=Nicolas Duchon <nicolas.duchon@gmail.com> (@buchdag), Jason Wilder
org.opencontainers.image.version=${{ env.GIT_DESCRIBE }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Log in to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push the Debian based image
id: docker_build_debian
uses: docker/build-push-action@v3
with:
context: .
file: Dockerfile
build-args: NGINX_PROXY_VERSION=${{ env.GIT_DESCRIBE }}
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
tags: ${{ steps.docker_meta_debian.outputs.tags }}
labels: ${{ steps.docker_meta_debian.outputs.labels }}
- name: Images digests
run: echo ${{ steps.docker_build_debian.outputs.digest }}
multiarch-build-alpine:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Retrieve version
run: echo "GIT_DESCRIBE=$(git describe --tags)" >> $GITHUB_ENV
- name: Get Docker tags for Alpine based image
id: docker_meta_alpine
uses: docker/metadata-action@v4
with:
images: |
ghcr.io/nginx-proxy/nginx-proxy
nginxproxy/nginx-proxy
jwilder/nginx-proxy
tags: |
type=semver,suffix=-alpine,pattern={{version}}
type=semver,suffix=-alpine,pattern={{major}}.{{minor}}
type=raw,value=alpine,enable={{is_default_branch}}
labels: |
org.opencontainers.image.authors=Nicolas Duchon <nicolas.duchon@gmail.com> (@buchdag), Jason Wilder
org.opencontainers.image.version=${{ env.GIT_DESCRIBE }}
flavor: latest=false
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Log in to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push the Alpine based image
id: docker_build_alpine
uses: docker/build-push-action@v3
with:
context: .
file: Dockerfile.alpine
build-args: NGINX_PROXY_VERSION=${{ env.GIT_DESCRIBE }}
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
tags: ${{ steps.docker_meta_alpine.outputs.tags }}
labels: ${{ steps.docker_meta_alpine.outputs.labels }}
- name: Images digests
run: echo ${{ steps.docker_build_alpine.outputs.digest }}

View File

@ -3,6 +3,8 @@ name: Tests
on:
workflow_dispatch:
push:
branches:
- main
paths-ignore:
- "LICENSE"
- "**.md"
@ -21,10 +23,10 @@ jobs:
base_docker_image: [alpine, debian]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python 3.9
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: 3.9

View File

@ -1,74 +0,0 @@
# setup build arguments for version of dependencies to use
ARG DOCKER_GEN_VERSION=0.9.2
ARG FOREGO_VERSION=v0.17.0
# Use a specific version of golang to build both binaries
FROM golang:1.19.4 as gobuilder
# Build docker-gen from scratch
FROM gobuilder as dockergen
ARG DOCKER_GEN_VERSION
RUN git clone https://github.com/nginx-proxy/docker-gen \
&& cd /go/docker-gen \
&& git -c advice.detachedHead=false checkout $DOCKER_GEN_VERSION \
&& go mod download \
&& CGO_ENABLED=0 GOOS=linux go build -ldflags "-X main.buildVersion=${DOCKER_GEN_VERSION}" ./cmd/docker-gen \
&& go clean -cache \
&& mv docker-gen /usr/local/bin/ \
&& cd - \
&& rm -rf /go/docker-gen
# Build forego from scratch
FROM gobuilder as forego
ARG FOREGO_VERSION
RUN git clone https://github.com/nginx-proxy/forego/ \
&& cd /go/forego \
&& git -c advice.detachedHead=false checkout $FOREGO_VERSION \
&& go mod download \
&& CGO_ENABLED=0 GOOS=linux go build -o forego . \
&& go clean -cache \
&& mv forego /usr/local/bin/ \
&& cd - \
&& rm -rf /go/forego
# Build the final image
FROM nginx:1.23.3
ARG NGINX_PROXY_VERSION
# Add DOCKER_GEN_VERSION environment variable
# Because some external projects rely on it
ARG DOCKER_GEN_VERSION
ENV NGINX_PROXY_VERSION=${NGINX_PROXY_VERSION} \
DOCKER_GEN_VERSION=${DOCKER_GEN_VERSION} \
DOCKER_HOST=unix:///tmp/docker.sock
# Install wget and install/updates certificates
RUN apt-get update \
&& apt-get install -y -q --no-install-recommends \
ca-certificates \
wget \
&& apt-get clean \
&& rm -r /var/lib/apt/lists/*
# Configure Nginx
RUN echo "daemon off;" >> /etc/nginx/nginx.conf \
&& sed -i 's/worker_processes 1/worker_processes auto/' /etc/nginx/nginx.conf \
&& sed -i 's/worker_connections 1024/worker_connections 10240/' /etc/nginx/nginx.conf \
&& mkdir -p '/etc/nginx/dhparam'
# Install Forego + docker-gen
COPY --from=forego /usr/local/bin/forego /usr/local/bin/forego
COPY --from=dockergen /usr/local/bin/docker-gen /usr/local/bin/docker-gen
COPY network_internal.conf /etc/nginx/
COPY app nginx.tmpl LICENSE /app/
WORKDIR /app/
ENTRYPOINT ["/app/docker-entrypoint.sh"]
CMD ["forego", "start", "-r"]

View File

@ -1,66 +1,30 @@
# setup build arguments for version of dependencies to use
ARG DOCKER_GEN_VERSION=0.9.2
ARG FOREGO_VERSION=v0.17.0
FROM nginxproxy/docker-gen:0.12.0 AS docker-gen
# Use a specific version of golang to build both binaries
FROM golang:1.19.4-alpine as gobuilder
RUN apk add --no-cache git musl-dev
# Build docker-gen from scratch
FROM gobuilder as dockergen
ARG DOCKER_GEN_VERSION
RUN git clone https://github.com/nginx-proxy/docker-gen \
&& cd /go/docker-gen \
&& git -c advice.detachedHead=false checkout $DOCKER_GEN_VERSION \
&& go mod download \
&& CGO_ENABLED=0 go build -ldflags "-X main.buildVersion=${DOCKER_GEN_VERSION}" ./cmd/docker-gen \
&& go clean -cache \
&& mv docker-gen /usr/local/bin/ \
&& cd - \
&& rm -rf /go/docker-gen
# Build forego from scratch
FROM gobuilder as forego
ARG FOREGO_VERSION
RUN git clone https://github.com/nginx-proxy/forego/ \
&& cd /go/forego \
&& git -c advice.detachedHead=false checkout $FOREGO_VERSION \
&& go mod download \
&& CGO_ENABLED=0 go build -o forego . \
&& go clean -cache \
&& mv forego /usr/local/bin/ \
&& cd - \
&& rm -rf /go/forego
FROM nginxproxy/forego:0.18.1 AS forego
# Build the final image
FROM nginx:1.23.3-alpine
FROM nginx:1.25.4-alpine
ARG NGINX_PROXY_VERSION
# Add DOCKER_GEN_VERSION environment variable
# Because some external projects rely on it
ARG DOCKER_GEN_VERSION
# Add DOCKER_GEN_VERSION environment variable because
# acme-companion rely on it (but the actual value is not important)
ARG DOCKER_GEN_VERSION="unknown"
ENV NGINX_PROXY_VERSION=${NGINX_PROXY_VERSION} \
DOCKER_GEN_VERSION=${DOCKER_GEN_VERSION} \
DOCKER_HOST=unix:///tmp/docker.sock
# Install wget and install/updates certificates
RUN apk add --no-cache --virtual .run-deps \
ca-certificates bash wget openssl \
&& update-ca-certificates
# Install dependencies
RUN apk add --no-cache --virtual .run-deps bash openssl
# Configure Nginx
RUN echo "daemon off;" >> /etc/nginx/nginx.conf \
&& sed -i 's/worker_processes 1/worker_processes auto/' /etc/nginx/nginx.conf \
&& sed -i 's/worker_connections 1024/worker_connections 10240/' /etc/nginx/nginx.conf \
&& mkdir -p '/etc/nginx/dhparam'
RUN sed -i 's/worker_connections.*;$/worker_connections 10240;/' /etc/nginx/nginx.conf \
&& sed -i -e '/^\}$/{s//\}\nworker_rlimit_nofile 20480;/;:a' -e '$!N;$!ba' -e '}' /etc/nginx/nginx.conf \
&& mkdir -p '/etc/nginx/dhparam' \
&& mkdir -p '/etc/nginx/certs'
# Install Forego + docker-gen
COPY --from=forego /usr/local/bin/forego /usr/local/bin/forego
COPY --from=dockergen /usr/local/bin/docker-gen /usr/local/bin/docker-gen
COPY --from=docker-gen /usr/local/bin/docker-gen /usr/local/bin/docker-gen
COPY network_internal.conf /etc/nginx/

32
Dockerfile.debian Normal file
View File

@ -0,0 +1,32 @@
FROM nginxproxy/docker-gen:0.12.0-debian AS docker-gen
FROM nginxproxy/forego:0.18.1-debian AS forego
# Build the final image
FROM nginx:1.25.4
ARG NGINX_PROXY_VERSION
# Add DOCKER_GEN_VERSION environment variable because
# acme-companion rely on it (but the actual value is not important)
ARG DOCKER_GEN_VERSION="unknown"
ENV NGINX_PROXY_VERSION=${NGINX_PROXY_VERSION} \
DOCKER_GEN_VERSION=${DOCKER_GEN_VERSION} \
DOCKER_HOST=unix:///tmp/docker.sock
# Configure Nginx
RUN sed -i 's/worker_connections.*;$/worker_connections 10240;/' /etc/nginx/nginx.conf \
&& sed -i -e '/^\}$/{s//\}\nworker_rlimit_nofile 20480;/;:a' -e '$!N;$!ba' -e '}' /etc/nginx/nginx.conf \
&& mkdir -p '/etc/nginx/dhparam' \
&& mkdir -p '/etc/nginx/certs'
# Install Forego + docker-gen
COPY --from=forego /usr/local/bin/forego /usr/local/bin/forego
COPY --from=docker-gen /usr/local/bin/docker-gen /usr/local/bin/docker-gen
COPY network_internal.conf /etc/nginx/
COPY app nginx.tmpl LICENSE /app/
WORKDIR /app/
ENTRYPOINT ["/app/docker-entrypoint.sh"]
CMD ["forego", "start", "-r"]

View File

@ -3,13 +3,13 @@
build-webserver:
docker build -t web test/requirements/web
docker build --pull -t web test/requirements/web
build-nginx-proxy-test-debian:
docker build --build-arg NGINX_PROXY_VERSION="test" -t nginxproxy/nginx-proxy:test .
docker build --pull --build-arg NGINX_PROXY_VERSION="test" -f Dockerfile.debian -t nginxproxy/nginx-proxy:test .
build-nginx-proxy-test-alpine:
docker build --build-arg NGINX_PROXY_VERSION="test" -f Dockerfile.alpine -t nginxproxy/nginx-proxy:test .
docker build --pull --build-arg NGINX_PROXY_VERSION="test" -f Dockerfile.alpine -t nginxproxy/nginx-proxy:test .
test-debian: build-webserver build-nginx-proxy-test-debian
test/pytest.sh

555
README.md
View File

@ -1,10 +1,9 @@
[![Test](https://github.com/nginx-proxy/nginx-proxy/actions/workflows/test.yml/badge.svg)](https://github.com/nginx-proxy/nginx-proxy/actions/workflows/test.yml)
[![GitHub release](https://img.shields.io/github/v/release/nginx-proxy/nginx-proxy)](https://github.com/nginx-proxy/nginx-proxy/releases)
![nginx 1.23.3](https://img.shields.io/badge/nginx-1.23.3-brightgreen.svg)
![nginx 1.25.4](https://img.shields.io/badge/nginx-1.25.4-brightgreen.svg)
[![Docker Image Size](https://img.shields.io/docker/image-size/nginxproxy/nginx-proxy?sort=semver)](https://hub.docker.com/r/nginxproxy/nginx-proxy "Click to view the image on Docker Hub")
[![Docker stars](https://img.shields.io/docker/stars/nginxproxy/nginx-proxy.svg)](https://hub.docker.com/r/nginxproxy/nginx-proxy 'DockerHub')
[![Docker pulls](https://img.shields.io/docker/pulls/nginxproxy/nginx-proxy.svg)](https://hub.docker.com/r/nginxproxy/nginx-proxy 'DockerHub')
[![Docker stars](https://img.shields.io/docker/stars/nginxproxy/nginx-proxy.svg)](https://hub.docker.com/r/nginxproxy/nginx-proxy "DockerHub")
[![Docker pulls](https://img.shields.io/docker/pulls/nginxproxy/nginx-proxy.svg)](https://hub.docker.com/r/nginxproxy/nginx-proxy "DockerHub")
nginx-proxy sets up a container running nginx and [docker-gen](https://github.com/nginx-proxy/docker-gen). docker-gen generates reverse proxy configs for nginx and reloads nginx when containers are started and stopped.
@ -15,526 +14,82 @@ See [Automated Nginx Reverse Proxy for Docker](http://jasonwilder.com/blog/2014/
To run it:
```console
docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy
docker run --detach \
--name nginx-proxy \
--publish 80:80 \
--volume /var/run/docker.sock:/tmp/docker.sock:ro \
nginxproxy/nginx-proxy:1.5
```
Then start any containers you want proxied with an env var `VIRTUAL_HOST=subdomain.youdomain.com`
Then start any containers (here an nginx container) you want proxied with an env var `VIRTUAL_HOST=subdomain.yourdomain.com`
```console
docker run -e VIRTUAL_HOST=foo.bar.com ...
docker run --detach \
--name your-proxied-app \
--env VIRTUAL_HOST=foo.bar.com \
nginx
```
The containers being proxied must [expose](https://docs.docker.com/engine/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` and be in the same network. 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.
Provided your DNS is setup to resolve `foo.bar.com` to the host running nginx-proxy, a request to `http://foo.bar.com` will then be routed to a container with the `VIRTUAL_HOST` env var set to `foo.bar.com` (in this case, the **your-proxied-app** container).
Provided your DNS is setup to forward foo.bar.com to the host running nginx-proxy, the request will be routed to a container with the `VIRTUAL_HOST` env var set.
The containers being proxied must :
Note: providing a port number in `VIRTUAL_HOST` isn't suported, please see [virtual ports](https://github.com/nginx-proxy/nginx-proxy#virtual-ports) or [custom external HTTP/HTTPS ports](https://github.com/nginx-proxy/nginx-proxy#custom-external-httphttps-ports) depending on what you want to achieve.
- [expose](https://docs.docker.com/engine/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`.
- share at least one Docker network with the nginx-proxy container: 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.
Note: providing a port number in `VIRTUAL_HOST` isn't suported, please see [virtual ports](https://github.com/nginx-proxy/nginx-proxy/tree/main/docs#virtual-ports) or [custom external HTTP/HTTPS ports](https://github.com/nginx-proxy/nginx-proxy/tree/main/docs#custom-external-httphttps-ports) depending on what you want to achieve.
### Image variants
The nginx-proxy images are available in two flavors.
#### nginxproxy/nginx-proxy:latest
#### Debian based version
### Virtual Host Aliases
This image uses the debian:buster based nginx image.
You can add aliases that will redirect (301) to the first entry in `VIRTUAL_HOST` by adding the `VIRTUAL_HOST_ALIAS` env var:
$ docker run -e VIRTUAL_HOST=example.com -e VIRTUAL_HOST_ALIAS=www.example.com,old.example.com ...
This will setup the following redirects:
- `http://www.example.com` &#8594; `http://example.com`
- `http://old.example.com` &#8594; `http://example.com`
If you are using [letsencrypt-nginx-proxy-companion](https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion) for SSL support, then you would run:
$ docker run -e VIRTUAL_HOST=example.com \
-e VIRTUAL_HOST_ALIAS=www.example.com,old.example.com
-e LETSENCRYPT_HOST=example.com,www.example.com,old.example.com
...
This will setup the following redirects:
- `http://example.com` &#8594; `https://example.com`
- `http://www.example.com` &#8594; `https://example.com`
- `http://old.example.com` &#8594; `https://example.com`
- `https://www.example.com` &#8594; `https://example.com`
- `https://old.example.com` &#8594; `https://example.com`
This image is based on the nginx:mainline image, itself based on the debian slim image.
```console
docker pull nginxproxy/nginx-proxy:latest
docker pull nginxproxy/nginx-proxy:1.5
```
#### nginxproxy/nginx-proxy:alpine
#### Alpine based version (`-alpine` suffix)
This image is based on the nginx:alpine image. Use this image to fully support HTTP/2 (including ALPN required by recent Chrome versions). A valid certificate is required as well (see eg. below "SSL Support using an ACME CA" for more info).
This image is based on the nginx:alpine image.
```console
docker pull nginxproxy/nginx-proxy:alpine
docker pull nginxproxy/nginx-proxy:1.5-alpine
```
### Docker Compose
#### :warning: a note on `latest` and `alpine`:
```yaml
version: '2'
It is not recommended to use the `latest` (`nginxproxy/nginx-proxy`, `nginxproxy/nginx-proxy:latest`) or `alpine` (`nginxproxy/nginx-proxy:alpine`) tag for production setups.
services:
nginx-proxy:
image: nginxproxy/nginx-proxy
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
[Those tags point](https://hub.docker.com/r/nginxproxy/nginx-proxy/tags) to the latest commit in the `main` branch. They do not carry any promise of stability, and using them will probably put your nginx-proxy setup at risk of experiencing uncontrolled updates to non backward compatible versions (or versions with breaking changes). You should always specify the version you want to use explicitly to ensure your setup doesn't break when the image is updated.
whoami:
image: jwilder/whoami
expose:
- "8000"
environment:
- VIRTUAL_HOST=whoami.local
- VIRTUAL_PORT=8000
```
### Additional documentation
```console
docker-compose up
curl -H "Host: whoami.local" localhost
```
Example output:
```console
I'm 5b129ab83266
```
### IPv6 support
You can activate the IPv6 support for the nginx-proxy container by passing the value `true` to the `ENABLE_IPV6` environment variable:
```console
docker run -d -p 80:80 -e ENABLE_IPV6=true -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy
```
#### Scoped IPv6 Resolvers
NginX does not support scoped IPv6 resolvers. In [docker-entrypoint.sh](./docker-entrypoint.sh) the resolvers are parsed from resolv.conf, but any scoped IPv6 addreses will be removed.
#### IPv6 NAT
By default, docker uses IPv6-to-IPv4 NAT. This means all client connections from IPv6 addresses will show docker's internal IPv4 host address. To see true IPv6 client IP addresses, you must [enable IPv6](https://docs.docker.com/config/daemon/ipv6/) and use [ipv6nat](https://github.com/robbertkl/docker-ipv6nat). You must also disable the userland proxy by adding `"userland-proxy": false` to `/etc/docker/daemon.json` and restarting the daemon.
### Multiple Hosts
If you need to support multiple virtual hosts for a container, you can separate each entry with commas. For example, `foo.bar.com,baz.bar.com,bar.com` and each host will be setup the same.
### Virtual Ports
When your container exposes only one port, nginx-proxy will default to this port, else to port 80.
If you need to specify a different port, you can set a `VIRTUAL_PORT` env var to select a different one. This variable cannot be set to more than one port.
For each host defined into `VIRTUAL_HOST`, the associated virtual port is retrieved by order of precedence:
1. From the `VIRTUAL_PORT` environment variable
1. From the container's exposed port if there is only one
1. From the default port 80 when none of the above methods apply
### Wildcard Hosts
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 [nip.io](https://nip.io) or [sslip.io](https://sslip.io), using `~^foo\.bar\..*\.nip\.io` will match `foo.bar.127.0.0.1.nip.io`, `foo.bar.10.0.2.2.nip.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).
### Path-based Routing
You can have multiple containers proxied by the same `VIRTUAL_HOST` by adding a `VIRTUAL_PATH` environment variable containing the absolute path to where the container should be mounted. For example with `VIRTUAL_HOST=foo.example.com` and `VIRTUAL_PATH=/api/v2/service`, then requests to http://foo.example.com/api/v2/service will be routed to the container. If you wish to have a container serve the root while other containers serve other paths, give the root container a `VIRTUAL_PATH` of `/`. Unmatched paths will be served by the container at `/` or will return the default nginx error page if no container has been assigned `/`.
It is also possible to specify multiple paths with regex locations like `VIRTUAL_PATH=~^/(app1|alternative1)/`. For further details see the nginx documentation on location blocks. This is not compatible with `VIRTUAL_DEST`.
The full request URI will be forwarded to the serving container in the `X-Original-URI` header.
**NOTE**: Your application needs to be able to generate links starting with `VIRTUAL_PATH`. This can be achieved by it being natively on this path or having an option to prepend this path. The application does not need to expect this path in the request.
#### VIRTUAL_DEST
This environment variable can be used to rewrite the `VIRTUAL_PATH` part of the requested URL to proxied application. The default value is empty (off).
Make sure that your settings won't result in the slash missing or being doubled. Both these versions can cause troubles.
If the application runs natively on this sub-path or has a setting to do so, `VIRTUAL_DEST` should not be set or empty.
If the requests are expected to not contain a sub-path and the generated links contain the sub-path, `VIRTUAL_DEST=/` should be used.
```console
$ docker run -d -e VIRTUAL_HOST=example.tld -e VIRTUAL_PATH=/app1/ -e VIRTUAL_DEST=/ --name app1 app
```
In this example, the incoming request `http://example.tld/app1/foo` will be proxied as `http://app1/foo` instead of `http://app1/app1/foo`.
#### Per-VIRTUAL_PATH location configuration
The same options as from [Per-VIRTUAL_HOST location configuration](#Per-VIRTUAL_HOST-location-configuration) are available on a `VIRTUAL_PATH` basis.
The only difference is that the filename gets an additional block `HASH=$(echo -n $VIRTUAL_PATH | sha1sum | awk '{ print $1 }')`. This is the sha1-hash of the `VIRTUAL_PATH` (no newline). This is done filename sanitization purposes.
The used filename is `${VIRTUAL_HOST}_${HASH}_location`
The filename of the previous example would be `example.tld_8610f6c344b4096614eab6e09d58885349f42faf_location`.
#### DEFAULT_ROOT
This environment variable of the nginx proxy container can be used to customize the return error page if no matching path is found. Furthermore it is possible to use anything which is compatible with the `return` statement of nginx.
For example `DEFAULT_ROOT=418` will return a 418 error page instead of the normal 404 one.
Another example is `DEFAULT_ROOT="301 https://github.com/nginx-proxy/nginx-proxy/blob/main/README.md"` which would redirect an invalid request to this documentation.
Nginx variables such as $scheme, $host, and $request_uri can be used. However, care must be taken to make sure the $ signs are escaped properly.
If you want to use `301 $scheme://$host/myapp1$request_uri` you should use:
* Bash: `DEFAULT_ROOT='301 $scheme://$host/myapp1$request_uri'`
* Docker Compose yaml: `- DEFAULT_ROOT: 301 $$scheme://$$host/myapp1$$request_uri`
### 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 nginxproxy/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.
### Custom external HTTP/HTTPS ports
If you want to use `nginx-proxy` with different external ports that the default ones of `80` for `HTTP` traffic and `443` for `HTTPS` traffic, you'll have to use the environment variable(s) `HTTP_PORT` and/or `HTTPS_PORT` in addition to the changes to the Docker port mapping. If you change the `HTTPS` port, the redirect for `HTTPS` traffic will also be configured to redirect to the custom port. Typical usage, here with the custom ports `1080` and `10443`:
```console
docker run -d -p 1080:1080 -p 10443:10443 -e HTTP_PORT=1080 -e HTTPS_PORT=10443 -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy
```
### Internet vs. Local Network Access
If you allow traffic from the public internet to access your `nginx-proxy` container, you may want to restrict some containers to the internal network only, so they cannot be accessed from the public internet. On containers that should be restricted to the internal network, you should set the environment variable `NETWORK_ACCESS=internal`. By default, the *internal* network is defined as `127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16`. To change the list of networks considered internal, mount a file on the `nginx-proxy` at `/etc/nginx/network_internal.conf` with these contents, edited to suit your needs:
```Nginx
# These networks are considered "internal"
allow 127.0.0.0/8;
allow 10.0.0.0/8;
allow 192.168.0.0/16;
allow 172.16.0.0/12;
# Traffic from all other networks will be rejected
deny all;
```
When internal-only access is enabled, external clients will be denied with an `HTTP 403 Forbidden`
> If there is a load-balancer / reverse proxy in front of `nginx-proxy` that hides the client IP (example: AWS Application/Elastic Load Balancer), you will need to use the nginx `realip` module (already installed) to extract the client's IP from the HTTP request headers. Please see the [nginx realip module configuration](http://nginx.org/en/docs/http/ngx_http_realip_module.html) for more details. This configuration can be added to a new config file and mounted in `/etc/nginx/conf.d/`.
### SSL Backends
If you would like the reverse proxy to connect to your backend using HTTPS instead of HTTP, set `VIRTUAL_PROTO=https` on the backend container.
> Note: If you use `VIRTUAL_PROTO=https` and your backend container exposes port 80 and 443, `nginx-proxy` will use HTTPS on port 80. This is almost certainly not what you want, so you should also include `VIRTUAL_PORT=443`.
### uWSGI Backends
If you would like to connect to uWSGI backend, set `VIRTUAL_PROTO=uwsgi` on the backend container. Your backend container should then listen on a port rather than a socket and expose that port.
### FastCGI Backends
If you would like to connect to FastCGI backend, set `VIRTUAL_PROTO=fastcgi` on the backend container. Your backend container should then listen on a port rather than a socket and expose that port.
### FastCGI File Root Directory
If you use fastcgi,you can set `VIRTUAL_ROOT=xxx` for your root directory
### Default Host
To set the default host for nginx use the env var `DEFAULT_HOST=foo.bar.com` for example
```console
docker run -d -p 80:80 -e DEFAULT_HOST=foo.bar.com -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy
```
nginx-proxy will then redirect all requests to a container where `VIRTUAL_HOST` is set to `DEFAULT_HOST`, if they don't match any (other) `VIRTUAL_HOST`. Using the example above requests without matching `VIRTUAL_HOST` will be redirected to a plain nginx instance after running the following command:
```console
docker run -d -e VIRTUAL_HOST=foo.bar.com nginx
```
### Separate Containers
nginx-proxy can also be run as two separate containers using the [nginxproxy/docker-gen](https://hub.docker.com/r/nginxproxy/docker-gen) image and the official [nginx](https://registry.hub.docker.com/_/nginx/) image.
You may want to do this to prevent having the docker socket bound to a publicly exposed container service.
You can demo this pattern with docker-compose:
```console
docker-compose --file docker-compose-separate-containers.yml up
curl -H "Host: whoami.local" localhost
```
Example output:
```console
I'm 5b129ab83266
```
To run nginx proxy as a separate container you'll need to have [nginx.tmpl](https://github.com/nginx-proxy/nginx-proxy/blob/main/nginx.tmpl) on your host system.
First start nginx with a volume:
```console
docker run -d -p 80:80 --name nginx -v /tmp/nginx:/etc/nginx/conf.d -t nginx
```
Then start the docker-gen container with the shared volume and template:
```console
docker run --volumes-from nginx \
-v /var/run/docker.sock:/tmp/docker.sock:ro \
-v $(pwd):/etc/docker-gen/templates \
-t nginxproxy/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.
```console
docker run -e VIRTUAL_HOST=foo.bar.com ...
```
### SSL Support using an ACME CA
[acme-companion](https://github.com/nginx-proxy/acme-companion) is a lightweight companion container for the nginx-proxy. It allows the automated creation/renewal of SSL certificates using the ACME protocol.
### SSL Support
SSL is supported using single host, wildcard and SNI certificates using naming conventions for certificates or optionally specifying a cert name (for SNI) as an environment variable.
To enable SSL:
```console
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 nginxproxy/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 `.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.
If you are running the container in a virtualized environment (Hyper-V, VirtualBox, etc...), /path/to/certs must exist in that environment or be made accessible to that environment. By default, Docker is not able to mount directories on the host machine to containers running in a virtual machine.
#### Diffie-Hellman Groups
[RFC7919 groups](https://datatracker.ietf.org/doc/html/rfc7919#appendix-A) with key lengths of 2048, 3072, and 4096 bits are [provided by `nginx-proxy`](https://github.com/nginx-proxy/nginx-proxy/dhparam). The ENV `DHPARAM_BITS` can be set to `2048` or `3072` to change from the default 4096-bit key. The DH key file will be located in the container at `/etc/nginx/dhparam/dhparam.pem`. Mounting a different `dhparam.pem` file at that location will override the RFC7919 key.
To use custom `dhparam.pem` files per-virtual-host, the files should be named after the virtual host with a `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 `/etc/nginx/certs` directory.
> COMPATIBILITY WARNING: The default generated `dhparam.pem` key is 4096 bits for A+ security. Some older clients (like Java 6 and 7) do not support DH keys with over 1024 bits. In order to support these clients, you must provide your own `dhparam.pem`.
In the separate container setup, no pre-generated key will be available and neither the [nginxproxy/docker-gen](https://hub.docker.com/r/nginxproxy/docker-gen) image, nor the offical [nginx](https://registry.hub.docker.com/_/nginx/) image will provide one. If you still want A+ security in a separate container setup, you should mount an RFC7919 DH key file to the nginx container at `/etc/nginx/dhparam/dhparam.pem`.
Set `DHPARAM_SKIP` environment variable to `true` to disable using default Diffie-Hellman parameters. The default value is `false`.
```console
docker run -e DHPARAM_SKIP=true ....
```
#### Wildcard Certificates
Wildcard certificates and keys should be named after the domain name with a `.crt` and `.key` extension. For example `VIRTUAL_HOST=foo.bar.com` would use cert name `bar.com.crt` and `bar.com.key`.
#### SNI
If your certificate(s) supports multiple domain names, you can start a container with `CERT_NAME=<name>` to identify the certificate to be used. For example, a certificate for `*.foo.com` and `*.bar.com` could be named `shared.crt` and `shared.key`. A container running with `VIRTUAL_HOST=foo.bar.com` and `CERT_NAME=shared` will then use this shared cert.
#### OCSP Stapling
To enable OCSP Stapling for a domain, `nginx-proxy` looks for a PEM certificate containing the trusted CA certificate chain at `/etc/nginx/certs/<domain>.chain.pem`, where `<domain>` is the domain name in the `VIRTUAL_HOST` directive. The format of this file is a concatenation of the public PEM CA certificates starting with the intermediate CA most near the SSL certificate, down to the root CA. This is often referred to as the "SSL Certificate Chain". If found, this filename is passed to the NGINX [`ssl_trusted_certificate` directive](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_trusted_certificate) and OCSP Stapling is enabled.
#### How SSL Support Works
The default SSL cipher configuration is based on the [Mozilla intermediate profile](https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29) version 5.0 which should provide compatibility with clients back to Firefox 27, Android 4.4.2, Chrome 31, Edge, IE 11 on Windows 7, Java 8u31, OpenSSL 1.0.1, Opera 20, and Safari 9. Note that the DES-based TLS ciphers were removed for security. The configuration also enables HSTS, PFS, OCSP stapling and SSL session caches. Currently TLS 1.2 and 1.3 are supported.
If you don't require backward compatibility, you can use the [Mozilla modern profile](https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility) profile instead by including the environment variable `SSL_POLICY=Mozilla-Modern` to the nginx-proxy container or to your container. This profile is compatible with clients back to Firefox 63, Android 10.0, Chrome 70, Edge 75, Java 11, OpenSSL 1.1.1, Opera 57, and Safari 12.1. Note that this profile is **not** compatible with any version of Internet Explorer.
Other policies available through the `SSL_POLICY` environment variable are [`Mozilla-Old`](https://wiki.mozilla.org/Security/Server_Side_TLS#Old_backward_compatibility) and the [AWS ELB Security Policies](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-security-policy-table.html) `AWS-TLS-1-2-2017-01`, `AWS-TLS-1-1-2017-01`, `AWS-2016-08`, `AWS-2015-05`, `AWS-2015-03` and `AWS-2015-02`.
Note that the `Mozilla-Old` policy should use a 1024 bits DH key for compatibility but this container provides a 4096 bits key. The [Diffie-Hellman Groups](#diffie-hellman-groups) section details different methods of bypassing this, either globally or per virtual-host.
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.
* If the container does not have a usable cert, a 503 will be returned.
Note that in the latter case, a browser may get an connection error as no certificate is available to establish a connection. A self-signed or generic cert named `default.crt` and `default.key` will allow a client browser to make a SSL connection (likely w/ a warning) and subsequently receive a 500.
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`, or disable the HTTPS site with `HTTPS_METHOD=nohttps`. `HTTPS_METHOD` can be specified on each container for which you want to override the default behavior or on the proxy container to set it globally. 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.
By default, [HTTP Strict Transport Security (HSTS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security) is enabled with `max-age=31536000` for HTTPS sites. You can disable HSTS with the environment variable `HSTS=off` or use a custom HSTS configuration like `HSTS=max-age=31536000; includeSubDomains; preload`.
*WARNING*: HSTS will force your users to visit the HTTPS version of your site for the `max-age` time - even if they type in `http://` manually. The only way to get to an HTTP site after receiving an HSTS response is to clear your browser's HSTS cache.
### 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
/etc/nginx/htpasswd/$VIRTUAL_HOST
```console
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:ro \
nginxproxy/nginx-proxy
```
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)
### Headers
By default, `nginx-proxy` forwards all incoming request headers from the client to the backend server unmodified, with the following exceptions:
* `Connection`: Set to `upgrade` if the client sets the `Upgrade` header, otherwise set to `close`. (Keep-alive between `nginx-proxy` and the backend server is not supported.)
* `Proxy`: Always removed if present. This prevents attackers from using the so-called [httpoxy attack](http://httpoxy.org). There is no legitimate reason for a client to send this header, and there are many vulnerable languages / platforms (`CVE-2016-5385`, `CVE-2016-5386`, `CVE-2016-5387`, `CVE-2016-5388`, `CVE-2016-1000109`, `CVE-2016-1000110`, `CERT-VU#797896`).
* `X-Real-IP`: Set to the client's IP address.
* `X-Forwarded-For`: The client's IP address is appended to the value provided by the client. (If the client did not provide this header, it is set to the client's IP address.)
* `X-Forwarded-Host`: If the client did not provide this header or if the `TRUST_DOWNSTREAM_PROXY` environment variable is set to `false` (see below), this is set to the value of the `Host` header provided by the client. Otherwise, the header is forwarded to the backend server unmodified.
* `X-Forwarded-Proto`: If the client did not provide this header or if the `TRUST_DOWNSTREAM_PROXY` environment variable is set to `false` (see below), this is set to `http` for plain HTTP connections and `https` for TLS connections. Otherwise, the header is forwarded to the backend server unmodified.
* `X-Forwarded-Ssl`: Set to `on` if the `X-Forwarded-Proto` header sent to the backend server is `https`, otherwise set to `off`.
* `X-Forwarded-Port`: If the client did not provide this header or if the `TRUST_DOWNSTREAM_PROXY` environment variable is set to `false` (see below), this is set to the port of the server that accepted the client's request. Otherwise, the header is forwarded to the backend server unmodified.
* `X-Original-URI`: Set to the original request URI.
#### Trusting Downstream Proxy Headers
For legacy compatibility reasons, `nginx-proxy` forwards any client-supplied `X-Forwarded-Proto` (which affects the value of `X-Forwarded-Ssl`), `X-Forwarded-Host`, and `X-Forwarded-Port` headers unchecked and unmodified. To prevent malicious clients from spoofing the protocol, hostname, or port that is perceived by your backend server, you are encouraged to set the `TRUST_DOWNSTREAM_PROXY` value to `false` if:
* you do not operate a second reverse proxy downstream of `nginx-proxy`, or
* you do operate a second reverse proxy downstream of `nginx-proxy` but that proxy forwards those headers unchecked from untrusted clients.
The default for `TRUST_DOWNSTREAM_PROXY` may change to `false` in a future version of `nginx-proxy`. If you require it to be enabled, you are encouraged to explicitly set it to `true` to avoid compatibility problems when upgrading.
### Custom Nginx Configuration
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.
#### Replacing default proxy settings
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
# 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-Host $proxy_x_forwarded_host;
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl;
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
proxy_set_header X-Original-URI $request_uri;
# Mitigate httpoxy attack (see README for details)
proxy_set_header Proxy "";
```
***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`.
This can be done in a derived image by creating the file in a `RUN` command or by `COPY`ing the file into `conf.d`:
```Dockerfile
FROM nginxproxy/nginx-proxy
RUN { \
echo 'server_tokens off;'; \
echo 'client_max_body_size 100m;'; \
} > /etc/nginx/conf.d/my_proxy.conf
```
Or it can be done by mounting in your custom configuration in your `docker run` command:
```console
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 nginxproxy/nginx-proxy
```
#### 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 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.
For example, if you have a virtual host named `app.example.com`, you could provide a custom configuration for that host as follows:
```console
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 nginxproxy/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:
```console
{ 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.
#### 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:
```console
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 nginxproxy/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:
```console
{ 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}_location` file associated with it.
#### Per-VIRTUAL_HOST `server_tokens` configuration
Per virtual-host `servers_tokens` directive can be configured by passing appropriate value to the `SERVER_TOKENS` environment variable. Please see the [nginx http_core module configuration](https://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens) for more details.
### Unhashed vs SHA1 upstream names
By default the nginx configuration `upstream` blocks will use this block's corresponding hostname as a predictable name. However, this can cause issues in some setups (see [this issue](https://github.com/nginx-proxy/nginx-proxy/issues/1162)). In those cases you might want to switch to SHA1 names for the `upstream` blocks by setting the `SHA1_UPSTREAM_NAME` environment variable to `true` on the nginx-proxy container.
Please note that using regular expressions in `VIRTUAL_HOST` will always result in a corresponding `upstream` block with an SHA1 name.
### Troubleshooting
In case you can't access your VIRTUAL_HOST, set `DEBUG=true` in the client container's environment and have a look at the generated nginx configuration file `/etc/nginx/conf.d/default.conf`:
```console
docker exec <nginx-proxy-instance> cat /etc/nginx/conf.d/default.conf
```
Especially at `upstream` definition blocks which should look like:
```Nginx
# foo.example.com
upstream foo.example.com {
## Can be connected with "my_network" network
# Exposed ports: [{ <exposed_port1> tcp } { <exposed_port2> tcp } ...]
# Default virtual port: <exposed_port|80>
# VIRTUAL_PORT: <VIRTUAL_PORT>
# foo
server 172.18.0.9:<Port>;
# Fallback entry
server 127.0.0.1 down;
}
```
The effective `Port` is retrieved by order of precedence:
1. From the `VIRTUAL_PORT` environment variable
1. From the container's exposed port if there is only one
1. From the default port 80 when none of the above methods apply
### Contributing
Before submitting pull requests or issues, please check github to make sure an existing issue or pull request is not already open.
#### Running Tests Locally
To run tests, you just need to run the command below:
```console
make test
```
This commands run tests on two variants of the nginx-proxy docker image: Debian and Alpine.
You can run the tests for each of these images with their respective commands:
```console
make test-debian
make test-alpine
```
You can learn more about how the test suite works and how to write new tests in the [test/README.md](test/README.md) file.
Please check the [docs section](https://github.com/nginx-proxy/nginx-proxy/tree/main/docs).

View File

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

View File

@ -1,4 +1,5 @@
version: '2'
version: "2"
services:
nginx:
image: nginx
@ -21,4 +22,4 @@ services:
whoami:
image: jwilder/whoami
environment:
- VIRTUAL_HOST=whoami.local
- VIRTUAL_HOST=whoami.example

View File

@ -1,4 +1,5 @@
version: '2'
version: "2"
services:
nginx-proxy:
image: nginxproxy/nginx-proxy
@ -8,7 +9,10 @@ services:
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
# if you want to proxy based on host ports, you'll want to use the host network
# network_mode: "host"
whoami:
image: jwilder/whoami
environment:
- VIRTUAL_HOST=whoami.local
- VIRTUAL_HOST=whoami.example

781
docs/README.md Normal file
View File

@ -0,0 +1,781 @@
### Docker Compose
```yaml
version: '2'
services:
nginx-proxy:
image: nginxproxy/nginx-proxy
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
whoami:
image: jwilder/whoami
expose:
- "8000"
environment:
- VIRTUAL_HOST=whoami.example
- VIRTUAL_PORT=8000
```
```console
docker compose up
curl -H "Host: whoami.example" localhost
```
Example output:
```console
I'm 5b129ab83266
```
### IPv6 support
You can activate the IPv6 support for the nginx-proxy container by passing the value `true` to the `ENABLE_IPV6` environment variable:
```console
docker run -d -p 80:80 -e ENABLE_IPV6=true -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy
```
#### Scoped IPv6 Resolvers
NginX does not support scoped IPv6 resolvers. In [docker-entrypoint.sh](https://github.com/nginx-proxy/nginx-proxy/tree/main/docker-entrypoint.sh) the resolvers are parsed from resolv.conf, but any scoped IPv6 addreses will be removed.
#### IPv6 NAT
By default, docker uses IPv6-to-IPv4 NAT. This means all client connections from IPv6 addresses will show docker's internal IPv4 host address. To see true IPv6 client IP addresses, you must [enable IPv6](https://docs.docker.com/config/daemon/ipv6/) and use [ipv6nat](https://github.com/robbertkl/docker-ipv6nat). You must also disable the userland proxy by adding `"userland-proxy": false` to `/etc/docker/daemon.json` and restarting the daemon.
### Multiple Hosts
If you need to support multiple virtual hosts for a container, you can separate each entry with commas. For example, `foo.bar.com,baz.bar.com,bar.com` and each host will be setup the same.
### Virtual Ports
When your container exposes only one port, nginx-proxy will default to this port, else to port 80.
If you need to specify a different port, you can set a `VIRTUAL_PORT` env var to select a different one. This variable cannot be set to more than one port.
For each host defined into `VIRTUAL_HOST`, the associated virtual port is retrieved by order of precedence:
1. From the `VIRTUAL_PORT` environment variable
1. From the container's exposed port if there is only one
1. From the default port 80 when none of the above methods apply
### Wildcard Hosts
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 [nip.io](https://nip.io) or [sslip.io](https://sslip.io), using `~^foo\.bar\..*\.nip\.io` will match `foo.bar.127.0.0.1.nip.io`, `foo.bar.10.0.2.2.nip.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).
### Path-based Routing
You can have multiple containers proxied by the same `VIRTUAL_HOST` by adding a `VIRTUAL_PATH` environment variable containing the absolute path to where the container should be mounted. For example with `VIRTUAL_HOST=foo.example.com` and `VIRTUAL_PATH=/api/v2/service`, then requests to http://foo.example.com/api/v2/service will be routed to the container. If you wish to have a container serve the root while other containers serve other paths, give the root container a `VIRTUAL_PATH` of `/`. Unmatched paths will be served by the container at `/` or will return the default nginx error page if no container has been assigned `/`.
It is also possible to specify multiple paths with regex locations like `VIRTUAL_PATH=~^/(app1|alternative1)/`. For further details see the nginx documentation on location blocks. This is not compatible with `VIRTUAL_DEST`.
The full request URI will be forwarded to the serving container in the `X-Original-URI` header.
**NOTE**: Your application needs to be able to generate links starting with `VIRTUAL_PATH`. This can be achieved by it being natively on this path or having an option to prepend this path. The application does not need to expect this path in the request.
#### VIRTUAL_DEST
This environment variable can be used to rewrite the `VIRTUAL_PATH` part of the requested URL to proxied application. The default value is empty (off).
Make sure that your settings won't result in the slash missing or being doubled. Both these versions can cause troubles.
If the application runs natively on this sub-path or has a setting to do so, `VIRTUAL_DEST` should not be set or empty.
If the requests are expected to not contain a sub-path and the generated links contain the sub-path, `VIRTUAL_DEST=/` should be used.
```console
$ docker run -d -e VIRTUAL_HOST=example.tld -e VIRTUAL_PATH=/app1/ -e VIRTUAL_DEST=/ --name app1 app
```
In this example, the incoming request `http://example.tld/app1/foo` will be proxied as `http://app1/foo` instead of `http://app1/app1/foo`.
#### Per-VIRTUAL_PATH location configuration
The same options as from [Per-VIRTUAL_HOST location configuration](#Per-VIRTUAL_HOST-location-configuration) are available on a `VIRTUAL_PATH` basis.
The only difference is that the filename gets an additional block `HASH=$(echo -n $VIRTUAL_PATH | sha1sum | awk '{ print $1 }')`. This is the sha1-hash of the `VIRTUAL_PATH` (no newline). This is done filename sanitization purposes.
The used filename is `${VIRTUAL_HOST}_${HASH}_location`
The filename of the previous example would be `example.tld_8610f6c344b4096614eab6e09d58885349f42faf_location`.
#### DEFAULT_ROOT
This environment variable of the nginx proxy container can be used to customize the return error page if no matching path is found. Furthermore it is possible to use anything which is compatible with the `return` statement of nginx.
Exception: If this is set to the string `none`, no default `location /` directive will be generated. This makes it possible for you to provide your own `location /` directive in your [`/etc/nginx/vhost.d/VIRTUAL_HOST`](#per-virtual_host) or [`/etc/nginx/vhost.d/default`](#per-virtual_host-default-configuration) files.
If unspecified, `DEFAULT_ROOT` defaults to `404`.
Examples (YAML syntax):
* `DEFAULT_ROOT: "none"` prevents `nginx-proxy` from generating a default `location /` directive.
* `DEFAULT_ROOT: "418"` returns a 418 error page instead of the normal 404 one.
* `DEFAULT_ROOT: "301 https://github.com/nginx-proxy/nginx-proxy/blob/main/README.md"` redirects the client to this documentation.
Nginx variables such as `$scheme`, `$host`, and `$request_uri` can be used. However, care must be taken to make sure the `$` signs are escaped properly. For example, if you want to use `301 $scheme://$host/myapp1$request_uri` you should use:
* Bash: `DEFAULT_ROOT='301 $scheme://$host/myapp1$request_uri'`
* Docker Compose yaml: `- DEFAULT_ROOT: 301 $$scheme://$$host/myapp1$$request_uri`
### 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 nginxproxy/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.
### Host networking
`nginx-proxy` is compatible with containers using Docker's [host networking](https://docs.docker.com/network/host/), both with the proxy connected to one or more [bridge network](https://docs.docker.com/network/bridge/) (default or user created) or running in host network mode itself.
Proxyed containers running in host network mode **must** use the [`VIRTUAL_PORT`](#virtual-ports) environment variable, as this is the only way for `nginx-proxy` to get the correct port (or a port at all) for those containers.
### Custom external HTTP/HTTPS ports
If you want to use `nginx-proxy` with different external ports that the default ones of `80` for `HTTP` traffic and `443` for `HTTPS` traffic, you'll have to use the environment variable(s) `HTTP_PORT` and/or `HTTPS_PORT` in addition to the changes to the Docker port mapping. If you change the `HTTPS` port, the redirect for `HTTPS` traffic will also be configured to redirect to the custom port. Typical usage, here with the custom ports `1080` and `10443`:
```console
docker run -d -p 1080:1080 -p 10443:10443 -e HTTP_PORT=1080 -e HTTPS_PORT=10443 -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy
```
### Internet vs. Local Network Access
If you allow traffic from the public internet to access your `nginx-proxy` container, you may want to restrict some containers to the internal network only, so they cannot be accessed from the public internet. On containers that should be restricted to the internal network, you should set the environment variable `NETWORK_ACCESS=internal`. By default, the *internal* network is defined as `127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16`. To change the list of networks considered internal, mount a file on the `nginx-proxy` at `/etc/nginx/network_internal.conf` with these contents, edited to suit your needs:
```Nginx
# These networks are considered "internal"
allow 127.0.0.0/8;
allow 10.0.0.0/8;
allow 192.168.0.0/16;
allow 172.16.0.0/12;
# Traffic from all other networks will be rejected
deny all;
```
When internal-only access is enabled, external clients will be denied with an `HTTP 403 Forbidden`
> If there is a load-balancer / reverse proxy in front of `nginx-proxy` that hides the client IP (example: AWS Application/Elastic Load Balancer), you will need to use the nginx `realip` module (already installed) to extract the client's IP from the HTTP request headers. Please see the [nginx realip module configuration](http://nginx.org/en/docs/http/ngx_http_realip_module.html) for more details. This configuration can be added to a new config file and mounted in `/etc/nginx/conf.d/`.
### SSL Backends
If you would like the reverse proxy to connect to your backend using HTTPS instead of HTTP, set `VIRTUAL_PROTO=https` on the backend container.
> Note: If you use `VIRTUAL_PROTO=https` and your backend container exposes port 80 and 443, `nginx-proxy` will use HTTPS on port 80. This is almost certainly not what you want, so you should also include `VIRTUAL_PORT=443`.
### uWSGI Backends
If you would like to connect to uWSGI backend, set `VIRTUAL_PROTO=uwsgi` on the backend container. Your backend container should then listen on a port rather than a socket and expose that port.
### FastCGI Backends
If you would like to connect to FastCGI backend, set `VIRTUAL_PROTO=fastcgi` on the backend container. Your backend container should then listen on a port rather than a socket and expose that port.
### FastCGI File Root Directory
If you use fastcgi,you can set `VIRTUAL_ROOT=xxx` for your root directory
### Logging
The default nginx access log format is
```
$host $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$upstream_addr"
```
#### Custom log format
If you want to use a custom access log format, you can set `LOG_FORMAT=xxx` on the proxy container.
With docker compose take care to escape the `$` character with `$$` to avoid variable interpolation. Example: `$remote_addr` becomes `$$remote_addr`.
#### JSON log format
If you want access logs in JSON format, you can set `LOG_JSON=true`. This will correctly set the escape character to `json` and the log format to :
```json
{
"time_local": "$time_iso8601",
"client_ip": "$http_x_forwarded_for",
"remote_addr": "$remote_addr",
"request": "$request",
"status": "$status",
"body_bytes_sent": "$body_bytes_sent",
"request_time": "$request_time",
"upstream_response_time": "$upstream_response_time",
"upstream_addr": "$upstream_addr",
"http_referrer": "$http_referer",
"http_user_agent": "$http_user_agent",
"request_id": "$request_id"
}
```
#### Log format escaping
If you want to manually set nginx `log_format`'s `escape`, set the `LOG_FORMAT_ESCAPE` variable to [a value supported by nginx](https://nginx.org/en/docs/http/ngx_http_log_module.html#log_format).
#### Disable access logs
To disable nginx access logs entirely, set the `DISABLE_ACCESS_LOGS` environment variable to any value.
#### Disabling colors in the container log output
To remove colors from the container log output, set the [`NO_COLOR` environment variable to any value other than an empty string](https://no-color.org/) on the nginx-proxy container.
```console
docker run --detach \
--publish 80:80 \
--env NO_COLOR=1 \
--volume /var/run/docker.sock:/tmp/docker.sock:ro \
nginxproxy/nginx-proxy
```
### Default Host
To set the default host for nginx use the env var `DEFAULT_HOST=foo.bar.com` for example
```console
docker run -d -p 80:80 -e DEFAULT_HOST=foo.bar.com -v /var/run/docker.sock:/tmp/docker.sock:ro nginxproxy/nginx-proxy
```
nginx-proxy will then redirect all requests to a container where `VIRTUAL_HOST` is set to `DEFAULT_HOST`, if they don't match any (other) `VIRTUAL_HOST`. Using the example above requests without matching `VIRTUAL_HOST` will be redirected to a plain nginx instance after running the following command:
```console
docker run -d -e VIRTUAL_HOST=foo.bar.com nginx
```
### Separate Containers
nginx-proxy can also be run as two separate containers using the [nginxproxy/docker-gen](https://hub.docker.com/r/nginxproxy/docker-gen) image and the official [nginx](https://registry.hub.docker.com/_/nginx/) image.
You may want to do this to prevent having the docker socket bound to a publicly exposed container service.
You can demo this pattern with docker compose:
```console
docker compose --file docker-compose-separate-containers.yml up
curl -H "Host: whoami.example" localhost
```
Example output:
```console
I'm 5b129ab83266
```
To run nginx proxy as a separate container you'll need to have [nginx.tmpl](https://github.com/nginx-proxy/nginx-proxy/blob/main/nginx.tmpl) on your host system.
First start nginx with a volume:
```console
docker run -d -p 80:80 --name nginx -v /tmp/nginx:/etc/nginx/conf.d -t nginx
```
Then start the docker-gen container with the shared volume and template:
```console
docker run --volumes-from nginx \
-v /var/run/docker.sock:/tmp/docker.sock:ro \
-v $(pwd):/etc/docker-gen/templates \
-t nginxproxy/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.
```console
docker run -e VIRTUAL_HOST=foo.bar.com ...
```
### SSL Support using an ACME CA
[acme-companion](https://github.com/nginx-proxy/acme-companion) is a lightweight companion container for the nginx-proxy. It allows the automated creation/renewal of SSL certificates using the ACME protocol.
### SSL Support
SSL is supported using single host, wildcard and SNI certificates using naming conventions for certificates or optionally specifying a cert name (for SNI) as an environment variable.
To enable SSL:
```console
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 nginxproxy/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 `.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.
If you are running the container in a virtualized environment (Hyper-V, VirtualBox, etc...), /path/to/certs must exist in that environment or be made accessible to that environment. By default, Docker is not able to mount directories on the host machine to containers running in a virtual machine.
#### Diffie-Hellman Groups
[RFC7919 groups](https://datatracker.ietf.org/doc/html/rfc7919#appendix-A) with key lengths of 2048, 3072, and 4096 bits are [provided by `nginx-proxy`](https://github.com/nginx-proxy/nginx-proxy/dhparam). The ENV `DHPARAM_BITS` can be set to `2048` or `3072` to change from the default 4096-bit key. The DH key file will be located in the container at `/etc/nginx/dhparam/dhparam.pem`. Mounting a different `dhparam.pem` file at that location will override the RFC7919 key.
To use custom `dhparam.pem` files per-virtual-host, the files should be named after the virtual host with a `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 `/etc/nginx/certs` directory.
> COMPATIBILITY WARNING: The default generated `dhparam.pem` key is 4096 bits for A+ security. Some older clients (like Java 6 and 7) do not support DH keys with over 1024 bits. In order to support these clients, you must provide your own `dhparam.pem`.
In the separate container setup, no pre-generated key will be available and neither the [nginxproxy/docker-gen](https://hub.docker.com/r/nginxproxy/docker-gen) image, nor the offical [nginx](https://registry.hub.docker.com/_/nginx/) image will provide one. If you still want A+ security in a separate container setup, you should mount an RFC7919 DH key file to the nginx container at `/etc/nginx/dhparam/dhparam.pem`.
Set `DHPARAM_SKIP` environment variable to `true` to disable using default Diffie-Hellman parameters. The default value is `false`.
```console
docker run -e DHPARAM_SKIP=true ....
```
#### Wildcard Certificates
Wildcard certificates and keys should be named after the domain name with a `.crt` and `.key` extension. For example `VIRTUAL_HOST=foo.bar.com` would use cert name `bar.com.crt` and `bar.com.key`.
#### SNI
If your certificate(s) supports multiple domain names, you can start a container with `CERT_NAME=<name>` to identify the certificate to be used. For example, a certificate for `*.foo.com` and `*.bar.com` could be named `shared.crt` and `shared.key`. A container running with `VIRTUAL_HOST=foo.bar.com` and `CERT_NAME=shared` will then use this shared cert.
#### OCSP Stapling
To enable OCSP Stapling for a domain, `nginx-proxy` looks for a PEM certificate containing the trusted CA certificate chain at `/etc/nginx/certs/<domain>.chain.pem`, where `<domain>` is the domain name in the `VIRTUAL_HOST` directive. The format of this file is a concatenation of the public PEM CA certificates starting with the intermediate CA most near the SSL certificate, down to the root CA. This is often referred to as the "SSL Certificate Chain". If found, this filename is passed to the NGINX [`ssl_trusted_certificate` directive](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_trusted_certificate) and OCSP Stapling is enabled.
#### How SSL Support Works
The default SSL cipher configuration is based on the [Mozilla intermediate profile](https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29) version 5.0 which should provide compatibility with clients back to Firefox 27, Android 4.4.2, Chrome 31, Edge, IE 11 on Windows 7, Java 8u31, OpenSSL 1.0.1, Opera 20, and Safari 9. Note that the DES-based TLS ciphers were removed for security. The configuration also enables HSTS, PFS, OCSP stapling and SSL session caches. Currently TLS 1.2 and 1.3 are supported.
If you don't require backward compatibility, you can use the [Mozilla modern profile](https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility) profile instead by including the environment variable `SSL_POLICY=Mozilla-Modern` to the nginx-proxy container or to your container. This profile is compatible with clients back to Firefox 63, Android 10.0, Chrome 70, Edge 75, Java 11, OpenSSL 1.1.1, Opera 57, and Safari 12.1. Note that this profile is **not** compatible with any version of Internet Explorer.
Complete list of policies available through the `SSL_POLICY` environment variable, including the [AWS ELB Security Policies](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html#describe-ssl-policies) and [AWS Classic ELB security policies](https://docs.aws.amazon.com/fr_fr/elasticloadbalancing/latest/classic/elb-security-policy-table.html):
<details>
<summary>Mozilla policies</summary>
<ul>
<li>
<a href="https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility" target="_blank">
<code>Mozilla-Modern</code>
</a>
</li>
<li>
<a href="https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29" target="_blank">
<code>Mozilla-Intermediate</code>
</a>
</li>
<li>
<a href="https://wiki.mozilla.org/Security/Server_Side_TLS#Old_backward_compatibility" target="_blank">
<code>Mozilla-Old</code>
</a>
</li>
</ul>
</details>
<details>
<summary>AWS ELB TLS 1.3 security policies</summary>
<ul>
<li>
<code>AWS-TLS13-1-3-2021-06</code>
</li>
<li>
<code>AWS-TLS13-1-2-2021-06</code>
</li>
<li>
<code>AWS-TLS13-1-2-Res-2021-06</code>
</li>
<li>
<code>AWS-TLS13-1-2-Ext1-2021-06</code>
</li>
<li>
<code>AWS-TLS13-1-2-Ext2-2021-06</code>
</li>
<li>
<code>AWS-TLS13-1-1-2021-06</code>
</li>
<li>
<code>AWS-TLS13-1-0-2021-06</code>
</li>
</ul>
</details>
<details>
<summary>AWS ELB FS supported policies</summary>
<ul>
<li>
<code>AWS-FS-1-2-Res-2020-10</code>
</li>
<li>
<code>AWS-FS-1-2-Res-2019-08</code>
</li>
<li>
<code>AWS-FS-1-2-2019-08</code>
</li>
<li>
<code>AWS-FS-1-1-2019-08</code>
</li>
<li>
<code>AWS-FS-2018-06</code>
</li>
</ul>
</details>
<details>
<summary>AWS ELB TLS 1.0 - 1.2 security policies</summary>
<ul>
<li>
<code>AWS-TLS-1-2-Ext-2018-06</code>
</li>
<li>
<code>AWS-TLS-1-2-2017-01</code>
</li>
<li>
<code>AWS-TLS-1-1-2017-01</code>
</li>
<li>
<code>AWS-2016-08</code>
</li>
</ul>
</details>
<details>
<summary>AWS Classic ELB security policies</summary>
<ul>
<li>
<code>AWS-2015-05</code>
</li>
<li>
<code>AWS-2015-03</code>
</li>
<li>
<code>AWS-2015-02</code>
</li>
</ul>
</details>
</br>
Note that the `Mozilla-Old` policy should use a 1024 bits DH key for compatibility but this container provides a 4096 bits key. The [Diffie-Hellman Groups](#diffie-hellman-groups) section details different methods of bypassing this, either globally or per virtual-host.
The default behavior for the proxy when port 80 and 443 are exposed is as follows:
* If a virtual host has a usable cert, port 80 will redirect to 443 for that virtual host so that HTTPS is always preferred when available.
* If the virtual host does not have a usable cert, but `default.crt` and `default.key` exist, those will be used as the virtual host's certificate and the client browser will receive a 500 error.
* If the virtual host does not have a usable cert, and `default.crt` and `default.key` do not exist, TLS negotiation will fail (see [Missing Certificate](#missing-certificate) below).
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`, or disable the HTTPS site with `HTTPS_METHOD=nohttps`. `HTTPS_METHOD` can be specified on each container for which you want to override the default behavior or on the proxy container to set it globally. 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.
By default, [HTTP Strict Transport Security (HSTS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security) is enabled with `max-age=31536000` for HTTPS sites. You can disable HSTS with the environment variable `HSTS=off` or use a custom HSTS configuration like `HSTS=max-age=31536000; includeSubDomains; preload`.
*WARNING*: HSTS will force your users to visit the HTTPS version of your site for the `max-age` time - even if they type in `http://` manually. The only way to get to an HTTP site after receiving an HSTS response is to clear your browser's HSTS cache.
#### Missing Certificate
If HTTPS is enabled for a virtual host but its certificate is missing, nginx-proxy will configure nginx to use the default certificate (`default.crt` with `default.key`) and return a 500 error.
If the default certificate is also missing, nginx-proxy will configure nginx to accept HTTPS connections but fail the TLS negotiation. Client browsers will render a TLS error page. As of March 2023, web browsers display the following error messages:
* Chrome:
> This site can't provide a secure connection
>
> example.test sent an invalid response.
>
> Try running Connectivity Diagnostics.
>
> `ERR_SSL_PROTOCOL_ERROR`
* Firefox:
> Secure Connection Failed
>
> An error occurred during a connection to example.test.
> Peer reports it experienced an internal error.
>
> Error code: `SSL_ERROR_INTERNAL_ERROR_ALERT` "TLS error".
### HTTP/2 support
HTTP/2 is enabled by default and can be disabled if necessary either per-proxied container or globally:
To disable HTTP/2 for a single proxied container, set the `com.github.nginx-proxy.nginx-proxy.http2.enable` label to `false` on this container.
To disable HTTP/2 globally set the environment variable `ENABLE_HTTP2` to `false` on the nginx-proxy container.
More reading on the potential TCP head-of-line blocking issue with HTTP/2: [HTTP/2 Issues](https://www.twilio.com/blog/2017/10/http2-issues.html), [Comparing HTTP/3 vs HTTP/2](https://blog.cloudflare.com/http-3-vs-http-2/)
### HTTP/3 support
> **Warning**
> HTTP/3 support [is still considered experimental in nginx](https://www.nginx.com/blog/binary-packages-for-preview-nginx-quic-http3-implementation/) and as such is considered experimental in nginx-proxy too and is disabled by default. [Feedbacks for the HTTP/3 support are welcome in #2271.](https://github.com/nginx-proxy/nginx-proxy/discussions/2271)
HTTP/3 use the QUIC protocol over UDP (unlike HTTP/1.1 and HTTP/2 which work over TCP), so if you want to use HTTP/3 you'll have to explicitely publish the 443/udp port of the proxy in addition to the 443/tcp port:
```console
docker run -d -p 80:80 -p 443:443/tcp -p 443:443/udp \
-v /var/run/docker.sock:/tmp/docker.sock:ro \
nginxproxy/nginx-proxy
```
HTTP/3 can be enabled either per-proxied container or globally:
To enable HTTP/3 for a single proxied container, set the `com.github.nginx-proxy.nginx-proxy.http3.enable` label to `true` on this container.
To enable HTTP/3 globally set the environment variable `ENABLE_HTTP3` to `true` on the nginx-proxy container.
### 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 in directory
`/etc/nginx/htpasswd/{$VIRTUAL_HOST}`
```console
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:ro \
nginxproxy/nginx-proxy
```
If you want to define basic authentication for a `VIRTUAL_PATH`, you have to create a file named as `/etc/nginx/htpasswd/${VIRTUAL_HOST}_${VIRTUAL_PATH_SHA1}`
(where `$VIRTUAL_PATH_SHA1` is the SHA1 hash for the virtual path, you can use any SHA1 online generator to calculate it).
You'll need apache2-utils on the machine where you plan to create the htpasswd file. Follow these [instructions](http://httpd.apache.org/docs/programs/htpasswd.html)
### Upstream (Backend) Server HTTP Load Balancing Support
> **Warning**
> This feature is experimental. The behavior may change (or the feature may be removed entirely) without warning in a future release, even if the release is not a new major version. If you use this feature, or if you would like to use this feature but you require changes to it first, please [provide feedback in #2195](https://github.com/nginx-proxy/nginx-proxy/discussions/2195). Once we have collected enough feedback we will promote this feature to officially supported.
If you have multiple containers with the same `VIRTUAL_HOST` and `VIRTUAL_PATH` settings, nginx will spread the load across all of them. To change the load balancing algorithm from nginx's default (round-robin), set the `com.github.nginx-proxy.nginx-proxy.loadbalance` label on one or more of your application containers to the desired load balancing directive. See the [`ngx_http_upstream_module` documentation](https://nginx.org/en/docs/http/ngx_http_upstream_module.html) for available directives.
> **Note**
> * Don't forget the terminating semicolon (`;`).
> * If you are using Docker Compose, remember to escape any dollar sign (`$`) characters (`$` becomes `$$`).
Docker Compose example:
```yaml
services:
nginx-proxy:
image: nginxproxy/nginx-proxy
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTPS_METHOD: nohttps
myapp:
image: jwilder/whoami
expose:
- "8000"
environment:
VIRTUAL_HOST: myapp.example
VIRTUAL_PORT: "8000"
labels:
com.github.nginx-proxy.nginx-proxy.loadbalance: "hash $$remote_addr;"
deploy:
replicas: 4
```
### Upstream (Backend) Server HTTP Keep-Alive Support
> **Warning**
> This feature is experimental. The behavior may change (or the feature may be removed entirely) without warning in a future release, even if the release is not a new major version. If you use this feature, or if you would like to use this feature but you require changes to it first, please [provide feedback in #2194](https://github.com/nginx-proxy/nginx-proxy/discussions/2194). Once we have collected enough feedback we will promote this feature to officially supported.
To enable HTTP keep-alive between `nginx-proxy` and backend server(s), set the `com.github.nginx-proxy.nginx-proxy.keepalive` label on the server's container either to `auto` or to the desired maximum number of idle connections. The `auto` setting will dynamically set the maximum number of idle connections to twice the number of servers listed in the corresponding `upstream{}` block, [per nginx recommendation](https://www.nginx.com/blog/avoiding-top-10-nginx-configuration-mistakes/#no-keepalives).
See the [nginx keepalive documentation](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive) and the [Docker label documentation](https://docs.docker.com/config/labels-custom-metadata/) for details.
### Headers
By default, `nginx-proxy` forwards all incoming request headers from the client to the backend server unmodified, with the following exceptions:
* `Connection`: Set to `upgrade` if the client sets the `Upgrade` header, otherwise set to `close`. (Keep-alive between `nginx-proxy` and the backend server is not supported.)
* `Proxy`: Always removed if present. This prevents attackers from using the so-called [httpoxy attack](http://httpoxy.org). There is no legitimate reason for a client to send this header, and there are many vulnerable languages / platforms (`CVE-2016-5385`, `CVE-2016-5386`, `CVE-2016-5387`, `CVE-2016-5388`, `CVE-2016-1000109`, `CVE-2016-1000110`, `CERT-VU#797896`).
* `X-Real-IP`: Set to the client's IP address.
* `X-Forwarded-For`: The client's IP address is appended to the value provided by the client. (If the client did not provide this header, it is set to the client's IP address.)
* `X-Forwarded-Host`: If the client did not provide this header or if the `TRUST_DOWNSTREAM_PROXY` environment variable is set to `false` (see below), this is set to the value of the `Host` header provided by the client. Otherwise, the header is forwarded to the backend server unmodified.
* `X-Forwarded-Proto`: If the client did not provide this header or if the `TRUST_DOWNSTREAM_PROXY` environment variable is set to `false` (see below), this is set to `http` for plain HTTP connections and `https` for TLS connections. Otherwise, the header is forwarded to the backend server unmodified.
* `X-Forwarded-Ssl`: Set to `on` if the `X-Forwarded-Proto` header sent to the backend server is `https`, otherwise set to `off`.
* `X-Forwarded-Port`: If the client did not provide this header or if the `TRUST_DOWNSTREAM_PROXY` environment variable is set to `false` (see below), this is set to the port of the server that accepted the client's request. Otherwise, the header is forwarded to the backend server unmodified.
* `X-Original-URI`: Set to the original request URI.
#### Trusting Downstream Proxy Headers
For legacy compatibility reasons, `nginx-proxy` forwards any client-supplied `X-Forwarded-Proto` (which affects the value of `X-Forwarded-Ssl`), `X-Forwarded-Host`, and `X-Forwarded-Port` headers unchecked and unmodified. To prevent malicious clients from spoofing the protocol, hostname, or port that is perceived by your backend server, you are encouraged to set the `TRUST_DOWNSTREAM_PROXY` value to `false` if:
* you do not operate a second reverse proxy downstream of `nginx-proxy`, or
* you do operate a second reverse proxy downstream of `nginx-proxy` but that proxy forwards those headers unchecked from untrusted clients.
The default for `TRUST_DOWNSTREAM_PROXY` may change to `false` in a future version of `nginx-proxy`. If you require it to be enabled, you are encouraged to explicitly set it to `true` to avoid compatibility problems when upgrading.
### Custom Nginx Configuration
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.
#### Replacing default proxy settings
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
# HTTP 1.1 support
proxy_http_version 1.1;
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-Host $proxy_x_forwarded_host;
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl;
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
proxy_set_header X-Original-URI $request_uri;
# Mitigate httpoxy attack (see README for details)
proxy_set_header Proxy "";
```
***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`.
This can be done in a derived image by creating the file in a `RUN` command or by `COPY`ing the file into `conf.d`:
```Dockerfile
FROM nginxproxy/nginx-proxy
RUN { \
echo 'server_tokens off;'; \
echo 'client_max_body_size 100m;'; \
} > /etc/nginx/conf.d/my_proxy.conf
```
Or it can be done by mounting in your custom configuration in your `docker run` command:
```console
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 nginxproxy/nginx-proxy
```
#### 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 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.
For example, if you have a virtual host named `app.example.com`, you could provide a custom configuration for that host as follows:
```console
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 nginxproxy/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:
```console
{ 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.
#### 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:
```console
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 nginxproxy/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:
```console
{ 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}_location` file associated with it.
#### Overriding `location` blocks
The `${VIRTUAL_HOST}_${PATH_HASH}_location`, `${VIRTUAL_HOST}_location`, and `default_location` files documented above make it possible to *augment* the generated [`location` block(s)](https://nginx.org/en/docs/http/ngx_http_core_module.html#location) in a virtual host. In some circumstances, you may need to *completely override* the `location` block for a particular combination of virtual host and path. To do this, create a file whose name follows this pattern:
```
/etc/nginx/vhost.d/${VIRTUAL_HOST}_${PATH_HASH}_location_override
```
where `${VIRTUAL_HOST}` is the name of the virtual host (the `VIRTUAL_HOST` environment variable) and `${PATH_HASH}` is the SHA-1 hash of the path, as [described above](#per-virtual_path-location-configuration).
For convenience, the `_${PATH_HASH}` part can be omitted if the path is `/`:
```
/etc/nginx/vhost.d/${VIRTUAL_HOST}_location_override
```
When an override file exists, the `location` block that is normally created by `nginx-proxy` is not generated. Instead, the override file is included via the [nginx `include` directive](https://nginx.org/en/docs/ngx_core_module.html#include).
You are responsible for providing a suitable `location` block in your override file as required for your service. By default, `nginx-proxy` uses the `VIRTUAL_HOST` name as the upstream name for your application's Docker container; see [here](#unhashed-vs-sha1-upstream-names) for details. As an example, if your container has a `VIRTUAL_HOST` value of `app.example.com`, then to override the location block for `/` you would create a file named `/etc/nginx/vhost.d/app.example.com_location_override` that contains something like this:
```
location / {
proxy_pass http://app.example.com;
}
```
#### Per-VIRTUAL_HOST `server_tokens` configuration
Per virtual-host `servers_tokens` directive can be configured by passing appropriate value to the `SERVER_TOKENS` environment variable. Please see the [nginx http_core module configuration](https://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens) for more details.
### Unhashed vs SHA1 upstream names
By default the nginx configuration `upstream` blocks will use this block's corresponding hostname as a predictable name. However, this can cause issues in some setups (see [this issue](https://github.com/nginx-proxy/nginx-proxy/issues/1162)). In those cases you might want to switch to SHA1 names for the `upstream` blocks by setting the `SHA1_UPSTREAM_NAME` environment variable to `true` on the nginx-proxy container.
Please note that using regular expressions in `VIRTUAL_HOST` will always result in a corresponding `upstream` block with an SHA1 name.
### Troubleshooting
If you can't access your `VIRTUAL_HOST`, inspect the generated nginx configuration:
```console
docker exec <nginx-proxy-instance> nginx -T
```
Pay attention to the `upstream` definition blocks, which should look like this:
```Nginx
# foo.example.com
upstream foo.example.com {
## Can be connected with "my_network" network
# Exposed ports: [{ <exposed_port1> tcp } { <exposed_port2> tcp } ...]
# Default virtual port: <exposed_port|80>
# VIRTUAL_PORT: <VIRTUAL_PORT>
# foo
server 172.18.0.9:<Port>;
# Fallback entry
server 127.0.0.1 down;
}
```
The effective `Port` is retrieved by order of precedence:
1. From the `VIRTUAL_PORT` environment variable
1. From the container's exposed port if there is only one
1. From the default port 80 when none of the above methods apply
### Contributing
Before submitting pull requests or issues, please check github to make sure an existing issue or pull request is not already open.
#### Running Tests Locally
To run tests, you just need to run the command below:
```console
make test
```
This commands run tests on two variants of the nginx-proxy docker image: Debian and Alpine.
You can run the tests for each of these images with their respective commands:
```console
make test-debian
make test-alpine
```
You can learn more about how the test suite works and how to write new tests in the [test/README.md](https://github.com/nginx-proxy/nginx-proxy/tree/main/test/README.md) file.

1129
nginx.tmpl
View File

@ -1,218 +1,491 @@
{{ $CurrentContainer := where $ "ID" .Docker.CurrentContainerID | first }}
# nginx-proxy{{ if $.Env.NGINX_PROXY_VERSION }} version : {{ $.Env.NGINX_PROXY_VERSION }}{{ end }}
{{ $nginx_proxy_version := coalesce $.Env.NGINX_PROXY_VERSION "" }}
{{ $external_http_port := coalesce $.Env.HTTP_PORT "80" }}
{{ $external_https_port := coalesce $.Env.HTTPS_PORT "443" }}
{{ $debug_all := $.Env.DEBUG }}
{{ $sha1_upstream_name := parseBool (coalesce $.Env.SHA1_UPSTREAM_NAME "false") }}
{{ $default_root_response := coalesce $.Env.DEFAULT_ROOT "404" }}
{{ $trust_downstream_proxy := parseBool (coalesce $.Env.TRUST_DOWNSTREAM_PROXY "true") }}
{{- /*
* Global values. Values are stored in this map rather than in individual
* global variables so that the values can be easily passed to embedded
* templates. (Go templates cannot access variables outside of their own
* scope.)
*/}}
{{- $globals := dict }}
{{- $_ := set $globals "containers" $ }}
{{- $_ := set $globals "Env" $.Env }}
{{- $_ := set $globals "Docker" $.Docker }}
{{- $_ := set $globals "CurrentContainer" (where $globals.containers "ID" $globals.Docker.CurrentContainerID | first) }}
{{- $_ := set $globals "default_cert_ok" (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }}
{{- $_ := set $globals "external_http_port" (coalesce $globals.Env.HTTP_PORT "80") }}
{{- $_ := set $globals "external_https_port" (coalesce $globals.Env.HTTPS_PORT "443") }}
{{- $_ := set $globals "sha1_upstream_name" (parseBool (coalesce $globals.Env.SHA1_UPSTREAM_NAME "false")) }}
{{- $_ := set $globals "default_root_response" (coalesce $globals.Env.DEFAULT_ROOT "404") }}
{{- $_ := set $globals "trust_downstream_proxy" (parseBool (coalesce $globals.Env.TRUST_DOWNSTREAM_PROXY "true")) }}
{{- $_ := set $globals "access_log" (or (and (not $globals.Env.DISABLE_ACCESS_LOGS) "access_log /var/log/nginx/access.log vhost;") "") }}
{{- $_ := set $globals "enable_ipv6" (parseBool (coalesce $globals.Env.ENABLE_IPV6 "false")) }}
{{- $_ := set $globals "ssl_policy" (or ($globals.Env.SSL_POLICY) "Mozilla-Intermediate") }}
{{- $_ := set $globals "vhosts" (dict) }}
{{- $_ := set $globals "networks" (dict) }}
# Networks available to the container running docker-gen (which are assumed to
# match the networks available to the container running nginx):
{{- /*
* Note: $globals.CurrentContainer may be nil in some circumstances due to
* <https://github.com/nginx-proxy/docker-gen/issues/458>. For more context
* see <https://github.com/nginx-proxy/nginx-proxy/issues/2189>.
*/}}
{{- if $globals.CurrentContainer }}
{{- range sortObjectsByKeysAsc $globals.CurrentContainer.Networks "Name" }}
{{- $_ := set $globals.networks .Name . }}
# {{ .Name }}
{{- else }}
# (none)
{{- end }}
{{- else }}
# /!\ WARNING: Failed to find the Docker container running docker-gen. All
# upstream (backend) application containers will appear to be
# unreachable. Try removing the -only-exposed and -only-published
# arguments to docker-gen if you pass either of those. See
# <https://github.com/nginx-proxy/docker-gen/issues/458>.
{{- end }}
{{ define "ssl_policy" }}
{{ if eq .ssl_policy "Mozilla-Modern" }}
ssl_protocols TLSv1.3;
{{/* nginx currently lacks ability to choose ciphers in TLS 1.3 in configuration, see https://trac.nginx.org/nginx/ticket/1529 /*}}
{{/* a possible workaround can be modify /etc/ssl/openssl.cnf to change it globally (see https://trac.nginx.org/nginx/ticket/1529#comment:12 ) /*}}
{{/* explicitly set ngnix default value in order to allow single servers to override the global http value */}}
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers off;
{{ else if eq .ssl_policy "Mozilla-Intermediate" }}
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers off;
{{ else if eq .ssl_policy "Mozilla-Old" }}
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA';
ssl_prefer_server_ciphers on;
{{ else if eq .ssl_policy "AWS-TLS-1-2-2017-01" }}
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:AES128-GCM-SHA256:AES128-SHA256:AES256-GCM-SHA384:AES256-SHA256';
ssl_prefer_server_ciphers on;
{{ else if eq .ssl_policy "AWS-TLS-1-1-2017-01" }}
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA';
ssl_prefer_server_ciphers on;
{{ else if eq .ssl_policy "AWS-2016-08" }}
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA';
ssl_prefer_server_ciphers on;
{{ else if eq .ssl_policy "AWS-2015-05" }}
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DES-CBC3-SHA';
ssl_prefer_server_ciphers on;
{{ else if eq .ssl_policy "AWS-2015-03" }}
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DHE-DSS-AES128-SHA:DES-CBC3-SHA';
ssl_prefer_server_ciphers on;
{{ else if eq .ssl_policy "AWS-2015-02" }}
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DHE-DSS-AES128-SHA';
ssl_prefer_server_ciphers on;
{{ end }}
{{ end }}
{{- /*
* Template used as a function to get a container's IP address. This
* template only outputs debug comments; the IP address is "returned" by
* storing the value in the provided dot dict.
*
* The provided dot dict is expected to have the following entries:
* - "globals": Global values.
* - "container": The container's RuntimeContainer struct.
*
* The return value will be added to the dot dict with key "ip".
*/}}
{{- define "container_ip" }}
{{- $ip := "" }}
# networks:
{{- range sortObjectsByKeysAsc $.container.Networks "Name" }}
{{- /*
* TODO: Only ignore the "ingress" network for Swarm tasks (in case
* the user is not using Swarm mode and names a network "ingress").
*/}}
{{- if eq .Name "ingress" }}
# {{ .Name }} (ignored)
{{- continue }}
{{- end }}
{{- if eq .Name "host" }}
{{- /* Handle containers in host nework mode */}}
{{- if (index $.globals.networks "host") }}
# both container and proxy are in host network mode, using localhost IP
{{- $ip = "127.0.0.1" }}
{{- continue }}
{{- end }}
{{- range sortObjectsByKeysAsc $.globals.CurrentContainer.Networks "Name" }}
{{- if and . .Gateway (not .Internal) }}
# container is in host network mode, using {{ .Name }} gateway IP
{{- $ip = .Gateway }}
{{- break }}
{{- end }}
{{- end }}
{{- if $ip }}
{{- continue }}
{{- end }}
{{- end }}
{{- if and (not (index $.globals.networks .Name)) (not $.globals.networks.host) }}
# {{ .Name }} (unreachable)
{{- continue }}
{{- end }}
{{- /*
* Do not emit multiple `server` directives for this container if it
* is reachable over multiple networks. This avoids accidentally
* inflating the effective round-robin weight of a server due to the
* redundant upstream addresses that nginx sees as belonging to
* distinct servers.
*/}}
{{- if $ip }}
# {{ .Name }} (ignored; reachable but redundant)
{{- continue }}
{{- end }}
# {{ .Name }} (reachable)
{{- if and . .IP }}
{{- $ip = .IP }}
{{- else }}
# /!\ No IP for this network!
{{- end }}
{{- else }}
# (none)
{{- end }}
# IP address: {{ if $ip }}{{ $ip }}{{ else }}(none usable){{ end }}
{{- $_ := set $ "ip" $ip }}
{{- end }}
{{ define "location" }}
location {{ .Path }} {
{{ if eq .NetworkTag "internal" }}
# Only allow traffic from internal clients
include /etc/nginx/network_internal.conf;
{{ end }}
{{- /*
* Template used as a function to get the port of the server in the given
* container. This template only outputs debug comments; the port is
* "returned" by storing the value in the provided dot dict.
*
* The provided dot dict is expected to have the following entries:
* - "container": The container's RuntimeContainer struct.
*
* The return value will be added to the dot dict with key "port".
*/}}
{{- define "container_port" }}
{{- /* If only 1 port exposed, use that as a default, else 80. */}}
# exposed ports:{{ range sortObjectsByKeysAsc $.container.Addresses "Port" }} {{ .Port }}/{{ .Proto }}{{ else }} (none){{ end }}
{{- $default_port := when (eq (len $.container.Addresses) 1) (first $.container.Addresses).Port "80" }}
# default port: {{ $default_port }}
{{- $port := when (eq $.port "legacy") (or $.container.Env.VIRTUAL_PORT $default_port) $.port }}
# using port: {{ $port }}
{{- $addr_obj := where $.container.Addresses "Port" $port | first }}
{{- if and $addr_obj $addr_obj.HostPort }}
# /!\ WARNING: Virtual port published on host. Clients
# might be able to bypass nginx-proxy and
# access the container's server directly.
{{- end }}
{{- $_ := set $ "port" $port }}
{{- end }}
{{ if eq .Proto "uwsgi" }}
include uwsgi_params;
uwsgi_pass {{ trim .Proto }}://{{ trim .Upstream }};
{{ else if eq .Proto "fastcgi" }}
root {{ trim .VhostRoot }};
include fastcgi_params;
fastcgi_pass {{ trim .Upstream }};
{{ else if eq .Proto "grpc" }}
grpc_pass {{ trim .Proto }}://{{ trim .Upstream }};
{{ else }}
proxy_pass {{ trim .Proto }}://{{ trim .Upstream }}{{ trim .Dest }};
{{ end }}
{{- define "ssl_policy" }}
{{- if eq .ssl_policy "Mozilla-Modern" }}
ssl_protocols TLSv1.3;
{{- /*
* This ssl_ciphers directive is not used but necessary to get TLSv1.3 only.
* see https://serverfault.com/questions/1023766/nginx-with-only-tls1-3-cipher-suites
*/}}
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384;
ssl_conf_command Ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;
ssl_prefer_server_ciphers off;
{{- else if eq .ssl_policy "Mozilla-Intermediate" }}
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305';
ssl_prefer_server_ciphers off;
{{- else if eq .ssl_policy "Mozilla-Old" }}
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA';
ssl_prefer_server_ciphers on;
{{- else if eq .ssl_policy "AWS-TLS13-1-3-2021-06" }}
ssl_protocols TLSv1.3;
{{- /*
* This ssl_ciphers directive is not used but necessary to get TLSv1.3 only.
* see https://serverfault.com/questions/1023766/nginx-with-only-tls1-3-cipher-suites
*/}}
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384;
ssl_conf_command Ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;
ssl_prefer_server_ciphers on;
{{- else if eq .ssl_policy "AWS-TLS13-1-2-2021-06" }}
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384';
ssl_prefer_server_ciphers on;
{{- else if eq .ssl_policy "AWS-TLS13-1-2-Res-2021-06" }}
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;
{{- else if eq .ssl_policy "AWS-TLS13-1-2-Ext1-2021-06" }}
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:AES128-GCM-SHA256:AES128-SHA256:AES256-GCM-SHA384:AES256-SHA256';
ssl_prefer_server_ciphers on;
{{- else if eq .ssl_policy "AWS-TLS13-1-2-Ext2-2021-06" }}
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA';
ssl_prefer_server_ciphers on;
{{- else if eq .ssl_policy "AWS-TLS13-1-1-2021-06" }}
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA';
ssl_prefer_server_ciphers on;
{{- else if eq .ssl_policy "AWS-TLS13-1-0-2021-06" }}
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA';
ssl_prefer_server_ciphers on;
{{- else if eq .ssl_policy "AWS-FS-1-2-Res-2020-10" }}
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;
{{- else if eq .ssl_policy "AWS-FS-1-2-Res-2019-08" }}
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384';
ssl_prefer_server_ciphers on;
{{- else if eq .ssl_policy "AWS-FS-1-2-2019-08" }}
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA';
ssl_prefer_server_ciphers on;
{{- else if eq .ssl_policy "AWS-FS-1-1-2019-08" }}
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA';
ssl_prefer_server_ciphers on;
{{- else if eq .ssl_policy "AWS-FS-2018-06" }}
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA';
ssl_prefer_server_ciphers on;
{{- else if eq .ssl_policy "AWS-TLS-1-2-Ext-2018-06" }}
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA';
ssl_prefer_server_ciphers on;
{{- else if eq .ssl_policy "AWS-TLS-1-2-2017-01" }}
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:AES128-GCM-SHA256:AES128-SHA256:AES256-GCM-SHA384:AES256-SHA256';
ssl_prefer_server_ciphers on;
{{- else if eq .ssl_policy "AWS-TLS-1-1-2017-01" }}
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA';
ssl_prefer_server_ciphers on;
{{- else if eq .ssl_policy "AWS-2016-08" }}
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA';
ssl_prefer_server_ciphers on;
{{- else if eq .ssl_policy "AWS-2015-05" }}
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DES-CBC3-SHA';
ssl_prefer_server_ciphers on;
{{- else if eq .ssl_policy "AWS-2015-03" }}
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DHE-DSS-AES128-SHA:DES-CBC3-SHA';
ssl_prefer_server_ciphers on;
{{- else if eq .ssl_policy "AWS-2015-02" }}
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DHE-DSS-AES128-SHA';
ssl_prefer_server_ciphers on;
{{- end }}
{{- end }}
{{ if (exists (printf "/etc/nginx/htpasswd/%s" .Host)) }}
auth_basic "Restricted {{ .Host }}";
auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" .Host) }};
{{ end }}
{{- define "location" }}
{{- $vpath := .VPath }}
{{- $override := printf "/etc/nginx/vhost.d/%s_%s_location_override" .Host (sha1 .Path) }}
{{- if and (eq .Path "/") (not (exists $override)) }}
{{- $override = printf "/etc/nginx/vhost.d/%s_location_override" .Host }}
{{- end }}
{{- if exists $override }}
include {{ $override }};
{{- else }}
{{- $keepalive := $vpath.keepalive }}
location {{ .Path }} {
{{- if eq $vpath.network_tag "internal" }}
# Only allow traffic from internal clients
include /etc/nginx/network_internal.conf;
{{- end }}
{{ if (exists (printf "/etc/nginx/vhost.d/%s_%s_location" .Host (sha1 .Path) )) }}
include {{ printf "/etc/nginx/vhost.d/%s_%s_location" .Host (sha1 .Path) }};
{{ else if (exists (printf "/etc/nginx/vhost.d/%s_location" .Host)) }}
include {{ printf "/etc/nginx/vhost.d/%s_location" .Host}};
{{ else if (exists "/etc/nginx/vhost.d/default_location") }}
include /etc/nginx/vhost.d/default_location;
{{ end }}
{{ $proto := $vpath.proto }}
{{ $upstream := $vpath.upstream }}
{{ $dest := $vpath.dest }}
{{- if eq $proto "uwsgi" }}
include uwsgi_params;
uwsgi_pass {{ trim $proto }}://{{ trim $upstream }};
{{- else if eq $proto "fastcgi" }}
root {{ trim .VhostRoot }};
include fastcgi_params;
fastcgi_pass {{ trim $upstream }};
{{- if ne $keepalive "disabled" }}
fastcgi_keep_conn on;
{{- end }}
{{- else if eq $proto "grpc" }}
grpc_pass {{ trim $proto }}://{{ trim $upstream }};
{{- else if eq $proto "grpcs" }}
grpc_pass {{ trim $proto }}://{{ trim $upstream }};
{{- else }}
proxy_pass {{ trim $proto }}://{{ trim $upstream }}{{ trim $dest }};
set $upstream_keepalive {{ if ne $keepalive "disabled" }}true{{ else }}false{{ end }};
{{- end }}
{{- if (exists (printf "/etc/nginx/htpasswd/%s_%s" .Host (sha1 .Path) )) }}
auth_basic "Restricted {{ .Host }}{{ .Path }}";
auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s_%s" .Host (sha1 .Path)) }};
{{- else if (exists (printf "/etc/nginx/htpasswd/%s" .Host)) }}
auth_basic "Restricted {{ .Host }}";
auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" .Host) }};
{{- end }}
{{- if (exists (printf "/etc/nginx/vhost.d/%s_%s_location" .Host (sha1 .Path) )) }}
include {{ printf "/etc/nginx/vhost.d/%s_%s_location" .Host (sha1 .Path) }};
{{- else if (exists (printf "/etc/nginx/vhost.d/%s_location" .Host)) }}
include {{ printf "/etc/nginx/vhost.d/%s_location" .Host}};
{{- else if (exists "/etc/nginx/vhost.d/default_location") }}
include /etc/nginx/vhost.d/default_location;
{{- end }}
}
{{- end }}
{{- end }}
{{- define "upstream" }}
{{- $path := .Path }}
{{- $vpath := .VPath }}
upstream {{ $vpath.upstream }} {
{{- $servers := 0 }}
{{- $loadbalance := $vpath.loadbalance }}
{{- if $loadbalance }}
# From the container's loadbalance label:
{{ $loadbalance }}
{{- end }}
{{- range $port, $containers := $vpath.ports }}
{{- range $container := $containers }}
# Container: {{ $container.Name }}
{{- $args := dict "globals" $.globals "container" $container }}
{{- template "container_ip" $args }}
{{- $ip := $args.ip }}
{{- $args = dict "container" $container "path" $path "port" $port }}
{{- template "container_port" $args }}
{{- if $ip }}
{{- $servers = add1 $servers }}
server {{ $ip }}:{{ $args.port }};
{{- end }}
{{- end }}
{{- end }}
{{- /* nginx-proxy/nginx-proxy#1105 */}}
{{- if lt $servers 1 }}
# Fallback entry
server 127.0.0.1 down;
{{- end }}
{{- $keepalive := $vpath.keepalive }}
{{- if and (ne $keepalive "disabled") (gt $servers 0) }}
{{- if eq $keepalive "auto" }}
keepalive {{ mul $servers 2 }};
{{- else }}
keepalive {{ $keepalive }};
{{- end }}
{{- end }}
}
{{ end }}
{{- end }}
{{ define "upstream" }}
{{ $networks := .Networks }}
{{ $debug_all := .Debug }}
upstream {{ .Upstream }} {
{{ $server_found := "false" }}
{{ range $container := .Containers }}
{{ $debug := (eq (coalesce $container.Env.DEBUG $debug_all "false") "true") }}
{{/* If only 1 port exposed, use that as a default, else 80 */}}
{{ $defaultPort := (when (eq (len $container.Addresses) 1) (first $container.Addresses) (dict "Port" "80")).Port }}
{{ $port := (coalesce $container.Env.VIRTUAL_PORT $defaultPort) }}
{{ $address := where $container.Addresses "Port" $port | first }}
{{ if $debug }}
# Exposed ports: {{ $container.Addresses }}
# Default virtual port: {{ $defaultPort }}
# VIRTUAL_PORT: {{ $container.Env.VIRTUAL_PORT }}
{{ if not $address }}
# /!\ Virtual port not exposed
{{ end }}
{{ end }}
{{ range $knownNetwork := $networks }}
{{ range $containerNetwork := sortObjectsByKeysAsc $container.Networks "Name" }}
{{ if (and (ne $containerNetwork.Name "ingress") (or (eq $knownNetwork.Name $containerNetwork.Name) (eq $knownNetwork.Name "host"))) }}
## Can be connected with "{{ $containerNetwork.Name }}" network
{{ 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 }}
{{ $server_found = "true" }}
# {{ $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 if $containerNetwork }}
{{ $server_found = "true" }}
# {{ $container.Name }}
server {{ $containerNetwork.IP }}:{{ $address.Port }};
{{ end }}
{{ else if $containerNetwork }}
# {{ $container.Name }}
{{ if $containerNetwork.IP }}
{{ $server_found = "true" }}
server {{ $containerNetwork.IP }}:{{ $port }};
{{ else }}
# /!\ No IP for this network!
{{ end }}
{{ end }}
{{ else }}
# Cannot connect to network '{{ $containerNetwork.Name }}' of this container
{{ end }}
{{ end }}
{{ end }}
{{ end }}
{{/* nginx-proxy/nginx-proxy#1105 */}}
{{ if (eq $server_found "false") }}
# Fallback entry
server 127.0.0.1 down;
{{ end }}
}
{{ end }}
{{- /*
* Template used as a function to collect virtual path properties from
* the given containers. These properties are "returned" by storing their
* values into the provided dot dict.
*
* The provided dot dict is expected to have the following entries:
* - "Containers": List of container's RuntimeContainer struct.
* - "Upstream_name"
* - "Has_virtual_paths": boolean
* - "Path"
*
* The return values will be added to the dot dict with keys:
* - "dest"
* - "proto"
* - "network_tag"
* - "upstream"
* - "loadbalance"
* - "keepalive"
*/}}
{{- define "get_path_info" }}
{{- /* Get the VIRTUAL_PROTO defined by containers w/ the same vhost-vpath, falling back to "http". */}}
{{- $proto := trim (or (first (groupByKeys $.Containers "Env.VIRTUAL_PROTO")) "http") }}
{{- /* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external". */}}
{{- $network_tag := or (first (groupByKeys $.Containers "Env.NETWORK_ACCESS")) "external" }}
{{ if ne $nginx_proxy_version "" }}
# nginx-proxy version : {{ $nginx_proxy_version }}
{{ end }}
{{- $loadbalance := first (keys (groupByLabel $.Containers "com.github.nginx-proxy.nginx-proxy.loadbalance")) }}
{{- $keepalive := coalesce (first (keys (groupByLabel $.Containers "com.github.nginx-proxy.nginx-proxy.keepalive"))) "disabled" }}
{{- $upstream := $.Upstream_name }}
{{- $dest := "" }}
{{- if $.Has_virtual_paths }}
{{- $sum := sha1 $.Path }}
{{- $upstream = printf "%s-%s" $upstream $sum }}
{{- $dest = or (first (groupByKeys $.Containers "Env.VIRTUAL_DEST")) "" }}
{{- end }}
{{- $_ := set $ "proto" $proto }}
{{- $_ := set $ "network_tag" $network_tag }}
{{- $_ := set $ "upstream" $upstream }}
{{- $_ := set $ "dest" $dest }}
{{- $_ := set $ "loadbalance" $loadbalance }}
{{- $_ := set $ "keepalive" $keepalive }}
{{- 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 {
default {{ if $trust_downstream_proxy }}$http_x_forwarded_proto{{ else }}$scheme{{ end }};
'' $scheme;
default {{ if $globals.trust_downstream_proxy }}$http_x_forwarded_proto{{ else }}$scheme{{ end }};
'' $scheme;
}
map $http_x_forwarded_host $proxy_x_forwarded_host {
default {{ if $trust_downstream_proxy }}$http_x_forwarded_host{{ else }}$http_host{{ end }};
'' $http_host;
default {{ if $globals.trust_downstream_proxy }}$http_x_forwarded_host{{ else }}$host{{ end }};
'' $host;
}
# If we receive X-Forwarded-Port, pass it through; otherwise, pass along the
# server port the client connected to
map $http_x_forwarded_port $proxy_x_forwarded_port {
default {{ if $trust_downstream_proxy }}$http_x_forwarded_port{{ else }}$server_port{{ end }};
'' $server_port;
default {{ if $globals.trust_downstream_proxy }}$http_x_forwarded_port{{ else }}$server_port{{ end }};
'' $server_port;
}
# If we receive Upgrade, set Connection to "upgrade"; otherwise, delete any
# Connection header that may have been passed to this server
# Include the port in the Host header sent to the container if it is non-standard
map $server_port $host_port {
default :$server_port;
80 '';
443 '';
}
# If the request from the downstream client has an "Upgrade:" header (set to any
# non-empty value), pass "Connection: upgrade" to the upstream (backend) server.
# Otherwise, the value for the "Connection" header depends on whether the user
# has enabled keepalive to the upstream server.
map $http_upgrade $proxy_connection {
default upgrade;
'' close;
default upgrade;
'' $proxy_connection_noupgrade;
}
map $upstream_keepalive $proxy_connection_noupgrade {
# Preserve nginx's default behavior (send "Connection: close").
default close;
# Use an empty string to cancel nginx's default behavior.
true '';
}
# Abuse the map directive (see <https://stackoverflow.com/q/14433309>) to ensure
# that $upstream_keepalive is always defined. This is necessary because:
# - The $proxy_connection variable is indirectly derived from
# $upstream_keepalive, so $upstream_keepalive must be defined whenever
# $proxy_connection is resolved.
# - The $proxy_connection variable is used in a proxy_set_header directive in
# the http block, so it is always fully resolved for every request -- even
# those where proxy_pass is not used (e.g., unknown virtual host).
map "" $upstream_keepalive {
# The value here should not matter because it should always be overridden in
# a location block (see the "location" template) for all requests where the
# value actually matters.
default false;
}
# Apply fix for very long server names
server_names_hash_bucket_size 128;
# Default dhparam
{{ if (exists "/etc/nginx/dhparam/dhparam.pem") }}
{{- if (exists "/etc/nginx/dhparam/dhparam.pem") }}
ssl_dhparam /etc/nginx/dhparam/dhparam.pem;
{{ end }}
{{- end }}
# Set appropriate X-Forwarded-Ssl header based on $proxy_x_forwarded_proto
map $proxy_x_forwarded_proto $proxy_x_forwarded_ssl {
default off;
https on;
default off;
https on;
}
gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
log_format vhost '$host $remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$upstream_addr"';
{{- /* See https://nginx.org/en/docs/http/ngx_http_log_module.html#log_format for details and variables
* LOG_FORMAT_ESCAPE sets the escape part of the log format
* LOG_FORMAT sets the log format
*/}}
{{- $logEscape := printf "escape=%s" (or $globals.Env.LOG_FORMAT_ESCAPE "default") }}
{{- $logFormat := or $globals.Env.LOG_FORMAT `$host $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$upstream_addr"` }}
{{- if parseBool (or $globals.Env.LOG_JSON "false") }}
{{- /* LOG_JSON is a shorthand
* that sets logging defaults to JSON format
*/}}
# JSON Logging enabled (via LOG_JSON env variable)
{{- $logEscape = printf "escape=%s" (or $globals.Env.LOG_FORMAT_ESCAPE "json") }}
{{- $logFormat = or $globals.Env.LOG_FORMAT `{"time_local":"$time_iso8601","client_ip":"$http_x_forwarded_for","remote_addr":"$remote_addr","request":"$request","status":"$status","body_bytes_sent":"$body_bytes_sent","request_time":"$request_time","upstream_response_time":"$upstream_response_time","upstream_addr":"$upstream_addr","http_referrer":"$http_referer","http_user_agent":"$http_user_agent","request_id":"$request_id"}` }}
{{- end }}
log_format vhost {{ $logEscape }} '{{ or $globals.Env.LOG_FORMAT $logFormat }}';
access_log off;
{{/* Get the SSL_POLICY defined by this container, falling back to "Mozilla-Intermediate" */}}
{{ $ssl_policy := or ($.Env.SSL_POLICY) "Mozilla-Intermediate" }}
{{ template "ssl_policy" (dict "ssl_policy" $ssl_policy) }}
{{- template "ssl_policy" (dict "ssl_policy" $globals.ssl_policy) }}
error_log /dev/stderr;
{{ if $.Env.RESOLVERS }}
resolver {{ $.Env.RESOLVERS }};
{{ end }}
{{- if $globals.Env.RESOLVERS }}
resolver {{ $globals.Env.RESOLVERS }};
{{- end }}
{{ if (exists "/etc/nginx/proxy.conf") }}
{{- if (exists "/etc/nginx/proxy.conf") }}
include /etc/nginx/proxy.conf;
{{ else }}
{{- else }}
# HTTP 1.1 support
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Host $http_host;
proxy_set_header Host $host$host_port;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
proxy_set_header X-Real-IP $remote_addr;
@ -225,86 +498,356 @@ proxy_set_header X-Original-URI $request_uri;
# Mitigate httpoxy attack (see README for details)
proxy_set_header Proxy "";
{{ end }}
{{- end }}
{{ $access_log := (or (and (not $.Env.DISABLE_ACCESS_LOGS) "access_log /var/log/nginx/access.log vhost;") "") }}
{{- /* Precompute some information about each vhost. */}}
{{- range $hostname, $containers := groupByMulti $globals.containers "Env.VIRTUAL_HOST" "," }}
{{- $hostname = trim $hostname }}
{{- if not $hostname }}
{{- /* Ignore containers with VIRTUAL_HOST set to the empty string. */}}
{{- continue }}
{{- end }}
{{ $enable_ipv6 := eq (or ($.Env.ENABLE_IPV6) "") "true" }}
{{- $certName := first (groupByKeys $containers "Env.CERT_NAME") }}
{{- $vhostCert := closest (dir "/etc/nginx/certs") (printf "%s.crt" $hostname) }}
{{- $vhostCert = trimSuffix ".crt" $vhostCert }}
{{- $vhostCert = trimSuffix ".key" $vhostCert }}
{{- $cert := or $certName $vhostCert }}
{{- $cert_ok := and (ne $cert "") (exists (printf "/etc/nginx/certs/%s.crt" $cert)) (exists (printf "/etc/nginx/certs/%s.key" $cert)) }}
{{- $default := eq $globals.Env.DEFAULT_HOST $hostname }}
{{- $https_method := or (first (groupByKeys $containers "Env.HTTPS_METHOD")) $globals.Env.HTTPS_METHOD "redirect" }}
{{- $http2_enabled := parseBool (or (first (keys (groupByLabel $containers "com.github.nginx-proxy.nginx-proxy.http2.enable"))) $globals.Env.ENABLE_HTTP2 "true")}}
{{- $http3_enabled := parseBool (or (first (keys (groupByLabel $containers "com.github.nginx-proxy.nginx-proxy.http3.enable"))) $globals.Env.ENABLE_HTTP3 "false")}}
{{- $is_regexp := hasPrefix "~" $hostname }}
{{- $upstream_name := when (or $is_regexp $globals.sha1_upstream_name) (sha1 $hostname) $hostname }}
{{- /* Get the SERVER_TOKENS defined by containers w/ the same vhost, falling back to "". */}}
{{- $server_tokens := trim (or (first (groupByKeys $containers "Env.SERVER_TOKENS")) "") }}
{{- /* Get the SSL_POLICY defined by containers w/ the same vhost, falling back to empty string (use default). */}}
{{- $ssl_policy := or (first (groupByKeys $containers "Env.SSL_POLICY")) "" }}
{{- /* Get the HSTS defined by containers w/ the same vhost, falling back to "max-age=31536000". */}}
{{- $hsts := or (first (groupByKeys $containers "Env.HSTS")) (or $globals.Env.HSTS "max-age=31536000") }}
{{- /* Get the VIRTUAL_ROOT By containers w/ use fastcgi root */}}
{{- $vhost_root := or (first (groupByKeys $containers "Env.VIRTUAL_ROOT")) "/var/www/public" }}
{{- $tmp_paths := groupBy $containers "Env.VIRTUAL_PATH" }}
{{- $has_virtual_paths := gt (len $tmp_paths) 0}}
{{- if not $has_virtual_paths }}
{{- $tmp_paths = dict "/" $containers }}
{{- end }}
{{- $paths := dict }}
{{- range $path, $containers := $tmp_paths }}
{{- $args := dict "Containers" $containers "Path" $path "Upstream_name" $upstream_name "Has_virtual_paths" $has_virtual_paths }}
{{- template "get_path_info" $args }}
{{- $_ := set $paths $path (dict
"ports" (dict "legacy" $containers)
"dest" $args.dest
"proto" $args.proto
"network_tag" $args.network_tag
"upstream" $args.upstream
"loadbalance" $args.loadbalance
"keepalive" $args.keepalive
) }}
{{- end }}
{{- $_ := set $globals.vhosts $hostname (dict
"cert" $cert
"cert_ok" $cert_ok
"default" $default
"hsts" $hsts
"https_method" $https_method
"http2_enabled" $http2_enabled
"http3_enabled" $http3_enabled
"paths" $paths
"server_tokens" $server_tokens
"ssl_policy" $ssl_policy
"vhost_root" $vhost_root
) }}
{{- end }}
{{- /*
* If needed, create a catch-all fallback server to send an error code to
* clients that request something from an unknown vhost.
*
* This server must appear first in the generated config because nginx uses
* the first `server` directive to handle requests that don't match any of
* the other `server` directives. An alternative approach would be to add
* the `default_server` option to the `listen` directives inside this
* `server`, but some users inject a custom `server` directive that uses
* `default_server`. Using `default_server` here would cause nginx to fail
* to start for those users. See
* <https://github.com/nginx-proxy/nginx-proxy/issues/2212>.
*/}}
{{- block "fallback_server" $globals }}
{{- $globals := . }}
{{- $http_exists := false }}
{{- $https_exists := false }}
{{- $default_http_exists := false }}
{{- $default_https_exists := false }}
{{- $http3_enabled := false }}
{{- range $vhost := $globals.vhosts }}
{{- $http := or (ne $vhost.https_method "nohttp") (not $vhost.cert_ok) }}
{{- $https := ne $vhost.https_method "nohttps" }}
{{- $http_exists = or $http_exists $http }}
{{- $https_exists = or $https_exists $https }}
{{- $default_http_exists = or $default_http_exists (and $http $vhost.default) }}
{{- $default_https_exists = or $default_https_exists (and $https $vhost.default) }}
{{- $http3_enabled = or $http3_enabled $vhost.http3_enabled }}
{{- end }}
{{- $fallback_http := and $http_exists (not $default_http_exists) }}
{{- $fallback_https := and $https_exists (not $default_https_exists) }}
{{- /*
* If there are no vhosts at all, create fallbacks for both plain http
* and https so that clients get something more useful than a connection
* refused error.
*/}}
{{- if and (not $http_exists) (not $https_exists) }}
{{- $fallback_http = true }}
{{- $fallback_https = true }}
{{- end }}
{{- if or $fallback_http $fallback_https }}
server {
server_name _; # This is just an invalid value which will never trigger on a real hostname.
server_tokens off;
listen {{ $external_http_port }};
{{ if $enable_ipv6 }}
listen [::]:{{ $external_http_port }};
{{ end }}
{{ $access_log }}
return 503;
server_name _; # This is just an invalid value which will never trigger on a real hostname.
server_tokens off;
{{ $globals.access_log }}
http2 on;
{{- if $fallback_http }}
listen {{ $globals.external_http_port }}; {{- /* Do not add `default_server` (see comment above). */}}
{{- if $globals.enable_ipv6 }}
listen [::]:{{ $globals.external_http_port }}; {{- /* Do not add `default_server` (see comment above). */}}
{{- end }}
{{- end }}
{{- if $fallback_https }}
listen {{ $globals.external_https_port }} ssl; {{- /* Do not add `default_server` (see comment above). */}}
{{- if $globals.enable_ipv6 }}
listen [::]:{{ $globals.external_https_port }} ssl; {{- /* Do not add `default_server` (see comment above). */}}
{{- end }}
{{- if $http3_enabled }}
http3 on;
listen {{ $globals.external_https_port }} quic reuseport; {{- /* Do not add `default_server` (see comment above). */}}
{{- if $globals.enable_ipv6 }}
listen [::]:{{ $globals.external_https_port }} quic reuseport; {{- /* Do not add `default_server` (see comment above). */}}
{{- end }}
{{- end }}
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
{{- end }}
{{- if $globals.default_cert_ok }}
ssl_certificate /etc/nginx/certs/default.crt;
ssl_certificate_key /etc/nginx/certs/default.key;
{{- else }}
# No default.crt certificate found for this vhost, so force nginx to emit a
# TLS error if the client connects via https.
{{- /* See the comment in the main `server` directive for rationale. */}}
ssl_ciphers aNULL;
set $empty "";
ssl_certificate data:$empty;
ssl_certificate_key data:$empty;
if ($https) {
return 444;
}
{{- end }}
return 503;
}
{{- end }}
{{- end }}
{{ if (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }}
{{- range $hostname, $vhost := $globals.vhosts }}
{{- $default_server := when $vhost.default "default_server" "" }}
{{- range $path, $vpath := $vhost.paths }}
# {{ $hostname }}{{ $path }}
{{ template "upstream" (dict "globals" $globals "Path" $path "VPath" $vpath) }}
{{- end }}
{{- if and $vhost.cert_ok (eq $vhost.https_method "redirect") }}
server {
server_name _; # This is just an invalid value which will never trigger on a real hostname.
server_tokens off;
listen {{ $external_https_port }} ssl http2;
{{ if $enable_ipv6 }}
listen [::]:{{ $external_https_port }} ssl http2;
{{ end }}
{{ $access_log }}
return 503;
server_name {{ $hostname }};
{{- if $vhost.server_tokens }}
server_tokens {{ $vhost.server_tokens }};
{{- end }}
{{ $globals.access_log }}
listen {{ $globals.external_http_port }} {{ $default_server }};
{{- if $globals.enable_ipv6 }}
listen [::]:{{ $globals.external_http_port }} {{ $default_server }};
{{- end }}
# Do not HTTPS redirect Let's Encrypt ACME challenge
location ^~ /.well-known/acme-challenge/ {
auth_basic off;
auth_request off;
allow all;
root /usr/share/nginx/html;
try_files $uri =404;
break;
}
location / {
{{- if eq $globals.external_https_port "443" }}
return 301 https://$host$request_uri;
{{- else }}
return 301 https://$host:{{ $globals.external_https_port }}$request_uri;
{{- end }}
}
}
{{- end }}
server {
server_name {{ $hostname }};
{{- if $vhost.server_tokens }}
server_tokens {{ $vhost.server_tokens }};
{{- end }}
{{ $globals.access_log }}
{{- if $vhost.http2_enabled }}
http2 on;
{{- end }}
{{- if or (eq $vhost.https_method "nohttps") (not $vhost.cert_ok) (eq $vhost.https_method "noredirect") }}
listen {{ $globals.external_http_port }} {{ $default_server }};
{{- if $globals.enable_ipv6 }}
listen [::]:{{ $globals.external_http_port }} {{ $default_server }};
{{- end }}
{{- end }}
{{- if ne $vhost.https_method "nohttps" }}
listen {{ $globals.external_https_port }} ssl {{ $default_server }};
{{- if $globals.enable_ipv6 }}
listen [::]:{{ $globals.external_https_port }} ssl {{ $default_server }};
{{- end }}
{{- if $vhost.http3_enabled }}
http3 on;
add_header alt-svc 'h3=":{{ $globals.external_https_port }}"; ma=86400;';
listen {{ $globals.external_https_port }} quic {{ $default_server }};
{{- if $globals.enable_ipv6 }}
listen [::]:{{ $globals.external_https_port }} quic {{ $default_server }};
{{- end }}
{{- end }}
{{- if $vhost.cert_ok }}
{{- template "ssl_policy" (dict "ssl_policy" $vhost.ssl_policy) }}
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_certificate /etc/nginx/certs/{{ (printf "%s.crt" $vhost.cert) }};
ssl_certificate_key /etc/nginx/certs/{{ (printf "%s.key" $vhost.cert) }};
{{- if (exists (printf "/etc/nginx/certs/%s.dhparam.pem" $vhost.cert)) }}
ssl_dhparam {{ printf "/etc/nginx/certs/%s.dhparam.pem" $vhost.cert }};
{{- end }}
{{- if (exists (printf "/etc/nginx/certs/%s.chain.pem" $vhost.cert)) }}
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate {{ printf "/etc/nginx/certs/%s.chain.pem" $vhost.cert }};
{{- end }}
{{- if (not (or (eq $vhost.https_method "noredirect") (eq $vhost.hsts "off"))) }}
set $sts_header "";
if ($https) {
set $sts_header "{{ trim $vhost.hsts }}";
}
add_header Strict-Transport-Security $sts_header always;
{{- end }}
{{- else if $globals.default_cert_ok }}
# No certificate found for this vhost, so use the default certificate and
# return an error code if the user connects via https.
ssl_certificate /etc/nginx/certs/default.crt;
ssl_certificate_key /etc/nginx/certs/default.key;
if ($https) {
return 500;
}
{{- else }}
# No certificate found for this vhost, so force nginx to emit a TLS error if
# the client connects via https.
{{- /*
* The alternative is to not provide an https server for this
* vhost, which would either cause the user to see the wrong
* vhost (if there is another vhost with a certificate) or a
* connection refused error (if there is no other vhost with a
* certificate). A TLS error is easier to troubleshoot, and is
* safer than serving the wrong vhost. Also see
* <https://serverfault.com/a/1044022>.
*/}}
ssl_ciphers aNULL;
set $empty "";
ssl_certificate data:$empty;
ssl_certificate_key data:$empty;
if ($https) {
return 444;
}
{{- end }}
{{- end }}
{{- if (exists (printf "/etc/nginx/vhost.d/%s" $hostname)) }}
include {{ printf "/etc/nginx/vhost.d/%s" $hostname }};
{{- else if (exists "/etc/nginx/vhost.d/default") }}
include /etc/nginx/vhost.d/default;
{{- end }}
{{- range $path, $vpath := $vhost.paths }}
{{- template "location" (dict
"Path" $path
"Host" $hostname
"VhostRoot" $vhost.vhost_root
"VPath" $vpath
) }}
{{- end }}
{{- if and (not (contains $vhost.paths "/")) (ne $globals.default_root_response "none")}}
location / {
return {{ $globals.default_root_response }};
}
{{- end }}
return 500;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_certificate /etc/nginx/certs/default.crt;
ssl_certificate_key /etc/nginx/certs/default.key;
}
{{ end }}
{{ range $host, $containers := groupByMulti $ "Env.VIRTUAL_HOST" "," }}
{{ $host := trim $host }}
{{ $is_regexp := hasPrefix "~" $host }}
{{ $upstream_name := when (or $is_regexp $sha1_upstream_name) (sha1 $host) $host }}
{{ $paths := groupBy $containers "Env.VIRTUAL_PATH" }}
{{ $nPaths := len $paths }}
{{ if eq $nPaths 0 }}
# {{ $host }}
{{ template "upstream" (dict "Upstream" $upstream_name "Containers" $containers "Networks" $CurrentContainer.Networks "Debug" $debug_all) }}
{{ else }}
{{ range $path, $containers := $paths }}
{{ $sum := sha1 $path }}
{{ $upstream := printf "%s-%s" $upstream_name $sum }}
# {{ $host }}{{ $path }}
{{ template "upstream" (dict "Upstream" $upstream "Containers" $containers "Networks" $CurrentContainer.Networks "Debug" $debug_all) }}
{{ end }}
{{ end }}
{{ end }}
# VIRTUAL_HOST_ALIAS
{{ range $host_alias, $containers := groupBy $ "Env.VIRTUAL_HOST_ALIAS" }}
{{ $host_alias := replace $host_alias "," " " 99 }}
{{ $first_host := (first (groupByKeys $containers "Env.VIRTUAL_HOST")) }}
{{ $first_host := trim $first_host }}
# First Host {{ $first_host }}
#Alias: {{ $host_alias }}
{{ $default_host := or ($.Env.DEFAULT_HOST) "" }}
{{ $default_server := index (dict $host "" $default_host "default_server") $host }}
{{/* Get the SERVER_TOKENS defined by containers w/ the same vhost, falling back to "" */}}
{{ $server_tokens := trim (or (first (groupByKeys $containers "Env.SERVER_TOKENS")) "") }}
{{ $default_server := index (dict $host_alias "" $default_host "default_server") $host_alias }}
{{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external" */}}
{{ $network_tag := or (first (groupByKeys $containers "Env.NETWORK_ACCESS")) "external" }}
{{/* Get the HTTPS_METHOD defined by containers w/ the same vhost, falling back to "redirect" */}}
{{ $https_method := or (first (groupByKeys $containers "Env.HTTPS_METHOD")) (or $.Env.HTTPS_METHOD "redirect") }}
{{ $https_method := or (first (groupByKeys $containers "Env.HTTPS_METHOD")) "redirect" }}
{{/* Get the SSL_POLICY defined by containers w/ the same vhost, falling back to empty string (use default) */}}
{{ $ssl_policy := or (first (groupByKeys $containers "Env.SSL_POLICY")) "" }}
{{/* Get the HSTS defined by containers w/ the same vhost, falling back to "max-age=31536000" */}}
{{ $hsts := or (first (groupByKeys $containers "Env.HSTS")) (or $.Env.HSTS "max-age=31536000") }}
{{/* Get the VIRTUAL_ROOT By containers w/ use fastcgi root */}}
{{ $vhost_root := or (first (groupByKeys $containers "Env.VIRTUAL_ROOT")) "/var/www/public" }}
{{ $hsts := or (first (groupByKeys $containers "Env.HSTS")) "max-age=31536000" }}
{{/* Get the first cert name defined by containers w/ the same vhost */}}
{{ $certName := (first (groupByKeys $containers "Env.CERT_NAME")) }}
{{/* Get the best matching cert by name for the vhost. */}}
{{ $vhostCert := (closest (dir "/etc/nginx/certs") (printf "%s.crt" $host))}}
{{ $vhostCert := (closest (dir "/etc/nginx/certs") (printf "%s.crt" $host_alias))}}
{{/* vhostCert is actually a filename so remove any suffixes since they are added later */}}
{{ $vhostCert := trimSuffix ".crt" $vhostCert }}
@ -317,48 +860,19 @@ server {
{{ if $is_https }}
{{ if eq $https_method "redirect" }}
server {
server_name {{ $host }};
{{ if $server_tokens }}
server_tokens {{ $server_tokens }};
{{ end }}
server_name {{ $host_alias }};
{{ if eq $https_method "redirect" }}
listen {{ $external_http_port }} {{ $default_server }};
{{ if $enable_ipv6 }}
listen [::]:{{ $external_http_port }} {{ $default_server }};
{{ end }}
{{ $access_log }}
# Do not HTTPS redirect Let'sEncrypt ACME challenge
location ^~ /.well-known/acme-challenge/ {
auth_basic off;
auth_request off;
allow all;
root /usr/share/nginx/html;
try_files $uri =404;
break;
}
location / {
{{ if eq $external_https_port "443" }}
return 301 https://$host$request_uri;
{{ else }}
return 301 https://$host:{{ $external_https_port }}$request_uri;
{{ end }}
}
}
{{ end }}
server {
server_name {{ $host }};
{{ if $server_tokens }}
server_tokens {{ $server_tokens }};
{{ end }}
listen {{ $external_https_port }} ssl http2 {{ $default_server }};
{{ if $enable_ipv6 }}
{{ if eq $https_method "redirect" }}
listen [::]:{{ $external_http_port }} {{ $default_server }};
{{ end }}
listen [::]:{{ $external_https_port }} ssl http2 {{ $default_server }};
{{ end }}
{{ $access_log }}
access_log /var/log/nginx/access.log vhost;
{{ template "ssl_policy" (dict "ssl_policy" $ssl_policy) }}
@ -383,37 +897,15 @@ server {
add_header Strict-Transport-Security "{{ trim $hsts }}" always;
{{ end }}
{{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }}
include {{ printf "/etc/nginx/vhost.d/%s" $host }};
{{ if (exists (printf "/etc/nginx/vhost.d/%s" $host_alias)) }}
include {{ printf "/etc/nginx/vhost.d/%s" $host_alias }};
{{ else if (exists "/etc/nginx/vhost.d/default") }}
include /etc/nginx/vhost.d/default;
{{ end }}
{{ if eq $nPaths 0 }}
{{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost, falling back to "http" */}}
{{ $proto := trim (or (first (groupByKeys $containers "Env.VIRTUAL_PROTO")) "http") }}
{{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external" */}}
{{ $network_tag := or (first (groupByKeys $containers "Env.NETWORK_ACCESS")) "external" }}
{{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $upstream_name "Host" $host "VhostRoot" $vhost_root "Dest" "" "NetworkTag" $network_tag) }}
{{ else }}
{{ range $path, $container := $paths }}
{{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost-vpath, falling back to "http" */}}
{{ $proto := trim (or (first (groupByKeys $container "Env.VIRTUAL_PROTO")) "http") }}
{{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external" */}}
{{ $network_tag := or (first (groupByKeys $container "Env.NETWORK_ACCESS")) "external" }}
{{ $sum := sha1 $path }}
{{ $upstream := printf "%s-%s" $upstream_name $sum }}
{{ $dest := (or (first (groupByKeys $container "Env.VIRTUAL_DEST")) "") }}
{{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host "VhostRoot" $vhost_root "Dest" $dest "NetworkTag" $network_tag) }}
{{ end }}
{{ if (not (contains $paths "/")) }}
location / {
return {{ $default_root_response }};
}
{{ end }}
{{ end }}
location / {
return 301 https://{{ $first_host }}$request_uri;
}
}
{{ end }}
@ -421,66 +913,47 @@ server {
{{ if or (not $is_https) (eq $https_method "noredirect") }}
server {
server_name {{ $host }};
{{ if $server_tokens }}
server_tokens {{ $server_tokens }};
{{ end }}
server_name {{ $host_alias }};
listen {{ $external_http_port }} {{ $default_server }};
{{ if $enable_ipv6 }}
listen [::]:{{ $external_http_port }} {{ $default_server }};
listen [::]:80 {{ $default_server }};
{{ end }}
{{ $access_log }}
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 }};
{{ if eq $network_tag "internal" }}
# Only allow traffic from internal clients
include /etc/nginx/network_internal.conf;
{{ end }}
{{ if (exists (printf "/etc/nginx/vhost.d/%s" $host_alias)) }}
include {{ printf "/etc/nginx/vhost.d/%s" $host_alias }};
{{ else if (exists "/etc/nginx/vhost.d/default") }}
include /etc/nginx/vhost.d/default;
{{ end }}
{{ if eq $nPaths 0 }}
{{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost, falling back to "http" */}}
{{ $proto := trim (or (first (groupByKeys $containers "Env.VIRTUAL_PROTO")) "http") }}
{{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external" */}}
{{ $network_tag := or (first (groupByKeys $containers "Env.NETWORK_ACCESS")) "external" }}
{{ template "location" (dict "Path" "/" "Proto" $proto "Upstream" $upstream_name "Host" $host "VhostRoot" $vhost_root "Dest" "" "NetworkTag" $network_tag) }}
{{ else }}
{{ range $path, $container := $paths }}
{{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost-vpath, falling back to "http" */}}
{{ $proto := trim (or (first (groupByKeys $container "Env.VIRTUAL_PROTO")) "http") }}
{{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external" */}}
{{ $network_tag := or (first (groupByKeys $container "Env.NETWORK_ACCESS")) "external" }}
{{ $sum := sha1 $path }}
{{ $upstream := printf "%s-%s" $upstream_name $sum }}
{{ $dest := (or (first (groupByKeys $container "Env.VIRTUAL_DEST")) "") }}
{{ template "location" (dict "Path" $path "Proto" $proto "Upstream" $upstream "Host" $host "VhostRoot" $vhost_root "Dest" $dest "NetworkTag" $network_tag) }}
{{ end }}
{{ if (not (contains $paths "/")) }}
location / {
return {{ $default_root_response }};
}
{{ end }}
{{ if not (exists "/etc/nginx/vhost.d/default") }}
# Do not HTTPS redirect Let'sEncrypt ACME challenge
location /.well-known/acme-challenge/ {
auth_basic off;
allow all;
root /usr/share/nginx/html;
try_files $uri =404;
break;
}
{{ end }}
location / {
return 301 https://{{ $first_host }}$request_uri;
}
}
{{ if (and (not $is_https) (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }}
server {
server_name {{ $host }};
{{ if $server_tokens }}
server_tokens {{ $server_tokens }};
{{ end }}
server_name {{ $host_alias }};
listen {{ $external_https_port }} ssl http2 {{ $default_server }};
{{ if $enable_ipv6 }}
listen [::]:{{ $external_https_port }} ssl http2 {{ $default_server }};
listen [::]:443 ssl http2 {{ $default_server }};
{{ end }}
{{ $access_log }}
return 500;
ssl_certificate /etc/nginx/certs/default.crt;
ssl_certificate_key /etc/nginx/certs/default.key;
access_log /var/log/nginx/access.log vhost;
}
{{ end }}
{{ end }}
{{ end }}
{{- end }}

View File

@ -4,12 +4,10 @@ Nginx proxy test suite
Install requirements
--------------------
You need [python 3.9](https://www.python.org/) and [pip](https://pip.pypa.io/en/stable/installing/) installed. Then run the commands:
You need [Docker Compose v2](https://docs.docker.com/compose/install/linux/), [python 3.9](https://www.python.org/) and [pip](https://pip.pypa.io/en/stable/installation/) installed. Then run the commands:
pip install -r requirements/python-requirements.txt
Prepare the nginx-proxy test image
----------------------------------
@ -28,12 +26,25 @@ need more verbosity ?
pytest -s
Note: By default this test suite relies on Docker Compose v2 with the command `docker compose`. It still supports Docker Compose v1 via the `DOCKER_COMPOSE` environment variable:
DOCKER_COMPOSE=docker-compose pytest
Run one single test module
--------------------------
pytest test_nominal.py
Run the test suite from a Docker container
------------------------------------------
If you cannot (or don't want to) install pytest and its requirements on your computer. You can use the nginx-proxy-tester docker image to run the test suite from a Docker container.
make test-debian
or if you want to test the alpine flavor:
make test-alpine
Write a test module
-------------------
@ -48,11 +59,11 @@ This test suite uses [pytest](http://doc.pytest.org/en/latest/). The [conftest.p
When using the `docker_compose` fixture in a test, pytest will try to find a yml file named after your test module filename. For instance, if your test module is `test_example.py`, then the `docker_compose` fixture will try to load a `test_example.yml` [docker compose file](https://docs.docker.com/compose/compose-file/).
Once the docker compose file found, the fixture will remove all containers, run `docker-compose up`, and finally your test will be executed.
Once the docker compose file found, the fixture will remove all containers, run `docker compose up`, and finally your test will be executed.
The fixture will run the _docker-compose_ command with the `-f` option to load the given compose file. So you can test your docker compose file syntax by running it yourself with:
The fixture will run the _docker compose_ command with the `-f` option to load the given compose file. So you can test your docker compose file syntax by running it yourself with:
docker-compose -f test_example.yml up -d
docker compose -f test_example.yml up -d
In the case you are running pytest from within a docker container, the `docker_compose` fixture will make sure the container running pytest is attached to all docker networks. That way, your test will be able to reach any of them.

View File

@ -24,7 +24,7 @@ fi
# Create a nginx container (which conveniently provides the `openssl` command)
###############################################################################
CONTAINER=$(docker run -d -v $DIR:/work -w /work -e SAN="$ALTERNATE_DOMAINS" nginx:1.19.10)
CONTAINER=$(docker run -d -v $DIR:/work -w /work -e SAN="$ALTERNATE_DOMAINS" nginx:1.25.3)
# Configure openssl
docker exec $CONTAINER bash -c '
mkdir -p /ca/{certs,crl,private,newcerts} 2>/dev/null

View File

@ -26,6 +26,7 @@ CA_ROOT_CERTIFICATE = os.path.join(os.path.dirname(__file__), 'certs/ca-root.crt
PYTEST_RUNNING_IN_CONTAINER = os.environ.get('PYTEST_RUNNING_IN_CONTAINER') == "1"
FORCE_CONTAINER_IPV6 = False # ugly global state to consider containers' IPv6 address instead of IPv4
DOCKER_COMPOSE = os.environ.get('DOCKER_COMPOSE', 'docker compose')
docker_client = docker.from_env()
@ -45,10 +46,10 @@ def ipv6(force_ipv6=True):
Meant to be used as a context manager to force IPv6 sockets:
with ipv6():
nginxproxy.get("http://something.nginx-proxy.local") # force use of IPv6
nginxproxy.get("http://something.nginx-proxy.example") # force use of IPv6
with ipv6(False):
nginxproxy.get("http://something.nginx-proxy.local") # legacy behavior
nginxproxy.get("http://something.nginx-proxy.example") # legacy behavior
"""
@ -160,6 +161,10 @@ def container_ip(container: Container):
net_info = container.attrs["NetworkSettings"]["Networks"]
if "bridge" in net_info:
return net_info["bridge"]["IPAddress"]
# container is running in host network mode
if "host" in net_info:
return "127.0.0.1"
# not default bridge network, fallback on first network defined
network_name = list(net_info.keys())[0]
@ -173,6 +178,10 @@ def container_ipv6(container):
net_info = container.attrs["NetworkSettings"]["Networks"]
if "bridge" in net_info:
return net_info["bridge"]["GlobalIPv6Address"]
# container is running in host network mode
if "host" in net_info:
return "::1"
# not default bridge network, fallback on first network defined
network_name = list(net_info.keys())[0]
@ -293,19 +302,19 @@ def get_nginx_conf_from_container(container):
def docker_compose_up(compose_file='docker-compose.yml'):
logging.info(f'docker-compose -f {compose_file} up -d')
logging.info(f'{DOCKER_COMPOSE} -f {compose_file} up -d')
try:
subprocess.check_output(shlex.split(f'docker-compose -f {compose_file} up -d'), stderr=subprocess.STDOUT)
subprocess.check_output(shlex.split(f'{DOCKER_COMPOSE} -f {compose_file} up -d'), stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
pytest.fail(f"Error while runninng 'docker-compose -f {compose_file} up -d':\n{e.output}", pytrace=False)
pytest.fail(f"Error while runninng '{DOCKER_COMPOSE} -f {compose_file} up -d':\n{e.output}", pytrace=False)
def docker_compose_down(compose_file='docker-compose.yml'):
logging.info(f'docker-compose -f {compose_file} down -v')
logging.info(f'{DOCKER_COMPOSE} -f {compose_file} down -v')
try:
subprocess.check_output(shlex.split(f'docker-compose -f {compose_file} down -v'), stderr=subprocess.STDOUT)
subprocess.check_output(shlex.split(f'{DOCKER_COMPOSE} -f {compose_file} down -v'), stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
pytest.fail(f"Error while runninng 'docker-compose -f {compose_file} down -v':\n{e.output}", pytrace=False)
pytest.fail(f"Error while runninng '{DOCKER_COMPOSE} -f {compose_file} down -v':\n{e.output}", pytrace=False)
def wait_for_nginxproxy_to_be_ready():
@ -322,34 +331,31 @@ def wait_for_nginxproxy_to_be_ready():
logging.debug("nginx-proxy ready")
break
def find_docker_compose_file(request):
"""
helper for fixture functions to figure out the name of the docker-compose file to consider.
- if the test module provides a `docker_compose_file` variable, take that
- else, if a yaml file exists with the same name as the test module (but for the `.yml` extension), use that
- otherwise use `docker-compose.yml`.
@pytest.fixture
def docker_compose_file(request):
"""Fixture naming the docker compose file to consider.
If a YAML file exists with the same name as the test module (with the `.py` extension replaced
with `.yml` or `.yaml`), use that. Otherwise, use `docker-compose.yml` in the same directory
as the test module.
Tests can override this fixture to specify a custom location.
"""
test_module_dir = os.path.dirname(request.module.__file__)
yml_file = os.path.join(test_module_dir, request.module.__name__ + '.yml')
yaml_file = os.path.join(test_module_dir, request.module.__name__ + '.yaml')
default_file = os.path.join(test_module_dir, 'docker-compose.yml')
docker_compose_file_module_variable = getattr(request.module, "docker_compose_file", None)
if docker_compose_file_module_variable is not None:
docker_compose_file = os.path.join( test_module_dir, docker_compose_file_module_variable)
if not os.path.isfile(docker_compose_file):
raise ValueError(f"docker compose file {docker_compose_file!r} could not be found. Check your test module `docker_compose_file` variable value.")
if os.path.isfile(yml_file):
docker_compose_file = yml_file
elif os.path.isfile(yaml_file):
docker_compose_file = yaml_file
else:
if os.path.isfile(yml_file):
docker_compose_file = yml_file
elif os.path.isfile(yaml_file):
docker_compose_file = yaml_file
else:
docker_compose_file = default_file
docker_compose_file = default_file
if not os.path.isfile(docker_compose_file):
logging.error("Could not find any docker-compose file named either '{0}.yml', '{0}.yaml' or 'docker-compose.yml'".format(request.module.__name__))
logging.error("Could not find any docker compose file named either '{0}.yml', '{0}.yaml' or 'docker-compose.yml'".format(request.module.__name__))
logging.debug(f"using docker compose file {docker_compose_file}")
return docker_compose_file
@ -419,34 +425,72 @@ def connect_to_all_networks():
return [connect_to_network(network) for network in networks]
class DockerComposer(contextlib.AbstractContextManager):
def __init__(self):
self._docker_compose_file = None
def __exit__(self, *exc_info):
self._down()
def _down(self):
if self._docker_compose_file is None:
return
for network in self._networks:
disconnect_from_network(network)
docker_compose_down(self._docker_compose_file)
self._docker_compose_file = None
def compose(self, docker_compose_file):
if docker_compose_file == self._docker_compose_file:
return
self._down()
if docker_compose_file is None:
return
remove_all_containers()
docker_compose_up(docker_compose_file)
self._networks = connect_to_all_networks()
wait_for_nginxproxy_to_be_ready()
time.sleep(3) # give time to containers to be ready
self._docker_compose_file = docker_compose_file
###############################################################################
#
# Py.test fixtures
#
###############################################################################
@pytest.fixture(scope="module")
def docker_compose(request):
"""
pytest fixture providing containers described in a docker compose file. After the tests, remove the created containers
A custom docker compose file name can be defined in a variable named `docker_compose_file`.
@pytest.fixture(scope="module")
def docker_composer():
with DockerComposer() as d:
yield d
@pytest.fixture
def ca_root_certificate():
return CA_ROOT_CERTIFICATE
@pytest.fixture
def monkey_patched_dns():
original_dns_resolver = monkey_patch_urllib_dns_resolver()
yield
restore_urllib_dns_resolver(original_dns_resolver)
@pytest.fixture
def docker_compose(monkey_patched_dns, docker_composer, docker_compose_file):
"""Ensures containers described in a docker compose file are started.
A custom docker compose file name can be specified by overriding the `docker_compose_file`
fixture.
Also, in the case where pytest is running from a docker container, this fixture makes sure
our container will be attached to all the docker networks.
"""
docker_compose_file = find_docker_compose_file(request)
original_dns_resolver = monkey_patch_urllib_dns_resolver()
remove_all_containers()
docker_compose_up(docker_compose_file)
networks = connect_to_all_networks()
wait_for_nginxproxy_to_be_ready()
time.sleep(3) # give time to containers to be ready
docker_composer.compose(docker_compose_file)
yield docker_client
for network in networks:
disconnect_from_network(network)
docker_compose_down(docker_compose_file)
restore_urllib_dns_resolver(original_dns_resolver)
@pytest.fixture()

View File

@ -1,5 +1,5 @@
[pytest]
# disable the creation of the `.cache` folders
addopts = -p no:cacheprovider --ignore=requirements --ignore=certs -r s -v
addopts = -p no:cacheprovider --ignore=requirements --ignore=certs --color=yes -v
markers =
incremental: mark a test as incremental.
incremental: mark a test as incremental.

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/sh
###############################################################################
# #
# This script is meant to run the test suite from a Docker container. #
@ -9,17 +9,20 @@
###############################################################################
# Returns the absolute directory path to this script
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
ARGS=("$@")
TESTDIR=$(cd "${0%/*}" && pwd) || exit 1
DIR=$(cd "${TESTDIR}/.." && pwd) || exit 1
# check requirements
echo "> Building nginx-proxy-tester image..."
docker build -t nginx-proxy-tester -f "${DIR}/requirements/Dockerfile-nginx-proxy-tester" "${DIR}/requirements"
docker build --pull -t nginx-proxy-tester \
-f "${TESTDIR}/requirements/Dockerfile-nginx-proxy-tester" \
"${TESTDIR}/requirements" \
|| exit 1
# run the nginx-proxy-tester container setting the correct value for the working dir in order for
# docker-compose to work properly when run from within that container.
# run the nginx-proxy-tester container setting the correct value for the working dir
# in order for docker compose to work properly when run from within that container.
exec docker run --rm -it --name "nginx-proxy-pytest" \
--volume "/var/run/docker.sock:/var/run/docker.sock" \
--volume "${DIR}:${DIR}" \
--workdir "${DIR}" \
nginx-proxy-tester "${ARGS[@]}"
--workdir "${TESTDIR}" \
nginx-proxy-tester "$@"

View File

@ -5,5 +5,32 @@ ENV PYTEST_RUNNING_IN_CONTAINER=1
COPY python-requirements.txt /requirements.txt
RUN pip install -r /requirements.txt
# Add Docker's official GPG key
RUN apt-get update \
&& apt-get install -y \
ca-certificates \
curl \
gnupg \
&& install -m 0755 -d /etc/apt/keyrings \
&& curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg \
&& chmod a+r /etc/apt/keyrings/docker.gpg
# Add the Docker repository to Apt sources
RUN echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install docker-ce-cli and docker-compose-plugin requirements for Pytest docker_compose fixture
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
docker-ce-cli \
docker-compose-plugin \
&& apt-get clean \
&& rm -r /var/lib/apt/lists/*
# Check if docker compose is available
RUN docker compose version
WORKDIR /test
ENTRYPOINT ["pytest"]

View File

@ -1,5 +1,4 @@
backoff==2.2.1
docker-compose==1.29.2
docker==6.0.1
pytest==7.2.0
requests==2.28.1
docker==7.0.0
pytest==8.1.1
requests==2.31.0

View File

@ -1,5 +0,0 @@
Test the behavior of nginx-proxy when restarted after deleting a certificate file is was using.
1. nginx-proxy is created with a virtual host having a certificate
1. while nginx-proxy is running, the certificate file is deleted
1. nginx-proxy is then restarted (without removing the container)

View File

@ -1,70 +0,0 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4096 (0x1000)
Signature Algorithm: sha256WithRSAEncryption
Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld
Validity
Not Before: Feb 17 23:20:54 2017 GMT
Not After : Jul 5 23:20:54 2044 GMT
Subject: CN=web.nginx-proxy
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:b6:27:63:a5:c6:e8:f4:7a:94:0e:cc:a2:62:76:
6d:5d:33:6f:cf:19:fc:e7:e5:bb:0e:0e:d0:7c:4f:
73:4c:48:2b:17:d1:4d:d5:9f:42:08:73:84:54:8c:
86:d2:c5:da:59:01:3f:42:22:e0:36:f0:dc:ab:de:
0a:bd:26:2b:22:13:87:a6:1f:23:ef:0e:99:27:8b:
15:4a:1b:ef:93:c9:6b:91:de:a0:02:0c:62:bb:cc:
56:37:e8:25:92:c3:1f:f1:69:d8:7c:a8:33:e0:89:
ce:14:67:a0:39:77:88:91:e6:a3:07:97:90:22:88:
d0:79:18:63:fb:6f:7e:ee:2b:42:7e:23:f5:e7:da:
e9:ee:6a:fa:96:65:9f:e1:2b:15:49:c8:cd:2d:ce:
86:4f:2c:2a:67:79:bf:41:30:14:cc:f6:0f:14:74:
9e:b6:d3:d0:3b:f0:1b:b8:e8:19:2a:fd:d6:fd:dc:
4b:4e:65:7d:9b:bf:37:7e:2d:35:22:2e:74:90:ce:
41:35:3d:41:a0:99:db:97:1f:bf:3e:18:3c:48:fb:
da:df:c6:4e:4e:b9:67:b8:10:d5:a5:13:03:c4:b7:
65:e7:aa:f0:14:4b:d3:4d:ea:fe:8f:69:cf:50:21:
63:27:cf:9e:4c:67:15:7b:3f:3b:da:cb:17:80:61:
1e:25
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:web.nginx-proxy
Signature Algorithm: sha256WithRSAEncryption
09:31:be:db:4e:b0:b6:68:da:ae:5b:16:51:29:fc:9f:61:b6:
5a:2f:3c:35:ef:67:76:97:b0:34:4e:3b:b4:d6:88:19:4f:84:
2e:73:d3:c0:3a:4c:41:54:6c:bb:67:89:67:ad:25:55:d7:d4:
80:fe:a7:3f:3d:9e:f1:34:96:d8:da:5a:78:51:c0:63:f1:52:
29:35:55:f4:7d:70:1c:d3:96:62:7f:64:86:81:52:27:c4:c6:
10:13:c6:73:56:4d:32:d0:b3:c3:c8:2c:25:83:e4:2b:1d:d4:
74:30:e5:85:af:2d:b6:a5:6b:fe:5d:d3:3c:00:58:94:f4:6a:
f5:a6:1d:cf:f9:ed:d5:27:ed:13:24:b2:4f:2b:f3:b8:e4:af:
0c:1d:fe:e0:6a:01:5e:a2:44:ff:3e:96:fa:6c:39:a3:51:37:
f3:72:55:d8:2d:29:6e:de:95:b9:d8:e3:1e:65:a5:9c:0d:79:
2d:39:ab:c7:ac:16:b6:a5:71:4b:35:a4:6c:72:47:1b:72:9c:
67:58:c1:fc:f6:7f:a7:73:50:7b:d6:27:57:74:a1:31:38:a7:
31:e3:b9:d4:c9:45:33:ec:ed:16:cf:c5:bd:d0:03:b1:45:3f:
68:0d:91:5c:26:4e:37:05:74:ed:3e:75:5e:ca:5e:ee:e2:51:
4b:da:08:99
-----BEGIN CERTIFICATE-----
MIIC8zCCAdugAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp
bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs
ZDAeFw0xNzAyMTcyMzIwNTRaFw00NDA3MDUyMzIwNTRaMBoxGDAWBgNVBAMMD3dl
Yi5uZ2lueC1wcm94eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALYn
Y6XG6PR6lA7MomJ2bV0zb88Z/Ofluw4O0HxPc0xIKxfRTdWfQghzhFSMhtLF2lkB
P0Ii4Dbw3KveCr0mKyITh6YfI+8OmSeLFUob75PJa5HeoAIMYrvMVjfoJZLDH/Fp
2HyoM+CJzhRnoDl3iJHmoweXkCKI0HkYY/tvfu4rQn4j9efa6e5q+pZln+ErFUnI
zS3Ohk8sKmd5v0EwFMz2DxR0nrbT0DvwG7joGSr91v3cS05lfZu/N34tNSIudJDO
QTU9QaCZ25cfvz4YPEj72t/GTk65Z7gQ1aUTA8S3Zeeq8BRL003q/o9pz1AhYyfP
nkxnFXs/O9rLF4BhHiUCAwEAAaMeMBwwGgYDVR0RBBMwEYIPd2ViLm5naW54LXBy
b3h5MA0GCSqGSIb3DQEBCwUAA4IBAQAJMb7bTrC2aNquWxZRKfyfYbZaLzw172d2
l7A0Tju01ogZT4Quc9PAOkxBVGy7Z4lnrSVV19SA/qc/PZ7xNJbY2lp4UcBj8VIp
NVX0fXAc05Zif2SGgVInxMYQE8ZzVk0y0LPDyCwlg+QrHdR0MOWFry22pWv+XdM8
AFiU9Gr1ph3P+e3VJ+0TJLJPK/O45K8MHf7gagFeokT/Ppb6bDmjUTfzclXYLSlu
3pW52OMeZaWcDXktOavHrBa2pXFLNaRsckcbcpxnWMH89n+nc1B71idXdKExOKcx
47nUyUUz7O0Wz8W90AOxRT9oDZFcJk43BXTtPnVeyl7u4lFL2giZ
-----END CERTIFICATE-----

View File

@ -1,27 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAtidjpcbo9HqUDsyiYnZtXTNvzxn85+W7Dg7QfE9zTEgrF9FN
1Z9CCHOEVIyG0sXaWQE/QiLgNvDcq94KvSYrIhOHph8j7w6ZJ4sVShvvk8lrkd6g
Agxiu8xWN+glksMf8WnYfKgz4InOFGegOXeIkeajB5eQIojQeRhj+29+7itCfiP1
59rp7mr6lmWf4SsVScjNLc6GTywqZ3m/QTAUzPYPFHSettPQO/AbuOgZKv3W/dxL
TmV9m783fi01Ii50kM5BNT1BoJnblx+/Phg8SPva38ZOTrlnuBDVpRMDxLdl56rw
FEvTTer+j2nPUCFjJ8+eTGcVez872ssXgGEeJQIDAQABAoIBAGQCMFW+ZfyEqHGP
rMA+oUEAkqy0agSwPwky3QjDXlxNa0uCYSeebtTRB6CcHxHuCzm+04puN4gyqhW6
rU64fAoTivCMPGBuNWxekmvD9r+/YM4P2u4E+th9EgFT9f0kII+dO30FpKXtQzY0
xuWGWXcxl+T9M+eiEkPKPmq4BoqgTDo5ty7qDv0ZqksGotKFmdYbtSvgBAueJdwu
VWJvenI9F42ExBRKOW1aldiRiaYBCLiCVPKJtOg9iuOP9RHUL1SE8xy5I5mm78g3
a13ji3BNq3yS+VhGjQ7zDy1V1jGupLoJw4I7OThu8hy+B8Vt8EN/iqakufOkjlTN
xTJ33CkCgYEA5Iymg0NTjWk6aEkFa9pERjfUWqdVp9sWSpFFZZgi55n7LOx6ohi3
vuLim3is/gYfK2kU/kHGZZLPnT0Rdx0MbOB4XK0CAUlqtUd0IyO4jMZ06g4/kn3N
e2jLdCCIBoEQuLk4ELxj2mHsLQhEvDrg7nzU2WpTHHhvJbIbDWOAxhsCgYEAzAgv
rKpanF+QDf4yeKHxAj2rrwRksTw4Pe7ZK/bog/i+HIVDA70vMapqftHbual/IRrB
JL7hxskoJ/h9c1w4xkWDjqkSKz8/Ihr4dyPfWyGINWbx/rarT/m5MU5SarScoK7o
Xgb25x+W+61rtI+2JhVRGO86+JiAeT4LkAX88L8CgYAwHHug/jdEeXZWJakCfzwI
HBCT1M3vO+uBXvtg25ndb0i0uENIhDOJ93EEkW65Osis9r34mBgPocwaqZRXosHO
2aH8wF6/rpjL+HK2QvrCh7Rs4Pr494qeA/1wQLjhxaGjgToQK9hJTHvPLwJpLWvU
SGr2Ka+9Oo0LPmb7dorRKQKBgQCLsNcjOodLJMp2KiHYIdfmlt6itzlRd09yZ8Nc
rHHJWVagJEUbnD1hnbHIHlp3pSqbObwfMmlWNoc9xo3tm6hrZ1CJLgx4e5b3/Ms8
ltznge/F0DPDFsH3wZwfu+YFlJ7gDKCfL9l/qEsxCS0CtJobPOEHV1NivNbJK8ey
1ca19QKBgDTdMOUsobAmDEkPQIpxfK1iqYAB7hpRLi79OOhLp23NKeyRNu8FH9fo
G3DZ4xUi6hP2bwiYugMXDyLKfvxbsXwQC84kGF8j+bGazKNhHqEC1OpYwmaTB3kg
qL9cHbjWySeRdIsRY/eWmiKjUwmiO54eAe1HWUdcsuz8yM3xf636
-----END RSA PRIVATE KEY-----

View File

@ -1,17 +0,0 @@
web:
image: web
expose:
- "81"
environment:
WEB_PORTS: 81
VIRTUAL_HOST: web.nginx-proxy
reverseproxy:
image: nginxproxy/nginx-proxy:test
container_name: reverseproxy
environment:
DEBUG: "true"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./tmp_certs:/etc/nginx/certs:ro

View File

@ -1,72 +0,0 @@
import logging
import os
from os.path import join, isfile
from shutil import copy
from time import sleep
import pytest
from requests import ConnectionError
script_dir = os.path.dirname(__file__)
pytestmark = pytest.mark.xfail() # TODO delete this marker once those issues are fixed
@pytest.fixture(scope="module", autouse=True)
def certs():
"""
pytest fixture that provides cert and key files into the tmp_certs directory
"""
file_names = ("web.nginx-proxy.crt", "web.nginx-proxy.key")
logging.info("copying server cert and key files into tmp_certs")
for f_name in file_names:
copy(join(script_dir, "certs", f_name), join(script_dir, "tmp_certs"))
yield
logging.info("cleaning up the tmp_cert directory")
for f_name in file_names:
if isfile(join(script_dir, "tmp_certs", f_name)):
os.remove(join(script_dir, "tmp_certs", f_name))
###############################################################################
def test_unknown_virtual_host_is_503(docker_compose, nginxproxy):
r = nginxproxy.get("http://foo.nginx-proxy/")
assert r.status_code == 503
def test_http_web_is_301(docker_compose, nginxproxy):
r = nginxproxy.get("http://web.nginx-proxy/port", allow_redirects=False)
assert r.status_code == 301
def test_https_web_is_200(docker_compose, nginxproxy):
r = nginxproxy.get("https://web.nginx-proxy/port")
assert r.status_code == 200
assert "answer from port 81\n" in r.text
@pytest.mark.incremental
def test_delete_cert_and_restart_reverseproxy(docker_compose):
os.remove(join(script_dir, "tmp_certs", "web.nginx-proxy.crt"))
docker_compose.containers.get("reverseproxy").restart()
sleep(3) # give time for the container to initialize
assert "running" == docker_compose.containers.get("reverseproxy").status
@pytest.mark.incremental
def test_unknown_virtual_host_is_still_503(nginxproxy):
r = nginxproxy.get("http://foo.nginx-proxy/")
assert r.status_code == 503
@pytest.mark.incremental
def test_http_web_is_now_200(nginxproxy):
r = nginxproxy.get("http://web.nginx-proxy/port", allow_redirects=False)
assert r.status_code == 200
assert "answer from port 81\n" == r.text
@pytest.mark.incremental
def test_https_web_is_now_broken_since_there_is_no_cert(nginxproxy):
with pytest.raises(ConnectionError):
nginxproxy.get("https://web.nginx-proxy/port")

View File

@ -1,2 +0,0 @@
*
!.gitignore

View File

@ -32,4 +32,3 @@ services:
environment:
WEB_PORTS: 82
VIRTUAL_HOST: webB.nginx-proxy

View File

@ -1,23 +1,25 @@
web1:
image: web
expose:
- "81"
environment:
WEB_PORTS: 81
VIRTUAL_HOST: web1.nginx-proxy.tld
version: "2"
web2:
image: web
expose:
- "82"
environment:
WEB_PORTS: 82
VIRTUAL_HOST: web2.nginx-proxy.tld
services:
web1:
image: web
expose:
- "81"
environment:
WEB_PORTS: 81
VIRTUAL_HOST: web1.nginx-proxy.tld
web2:
image: web
expose:
- "82"
environment:
WEB_PORTS: 82
VIRTUAL_HOST: web2.nginx-proxy.tld
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/f00.sock:ro
environment:
DOCKER_HOST: unix:///f00.sock
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/f00.sock:ro
environment:
DOCKER_HOST: unix:///f00.sock

View File

@ -5,6 +5,6 @@ def test_unknown_virtual_host(docker_compose, nginxproxy):
assert r.status_code == 503
def test_forwards_to_whoami(docker_compose, nginxproxy):
r = nginxproxy.get("http://web.nginx-proxy.local/port")
r = nginxproxy.get("http://web.nginx-proxy.example/port")
assert r.status_code == 200
assert r.text == "answer from port 81\n"

View File

@ -1,4 +1,5 @@
version: '2'
version: "2"
services:
nginx-proxy:
image: nginxproxy/nginx-proxy:test
@ -11,4 +12,4 @@ services:
- "81"
environment:
WEB_PORTS: 81
VIRTUAL_HOST: web.nginx-proxy.local
VIRTUAL_HOST: web.nginx-proxy.example

View File

@ -6,14 +6,14 @@ def test_custom_default_conf_does_not_apply_to_unknown_vhost(docker_compose, ngi
assert "X-test" not in r.headers
def test_custom_default_conf_applies_to_web1(docker_compose, nginxproxy):
r = nginxproxy.get("http://web1.nginx-proxy.local/port")
r = nginxproxy.get("http://web1.nginx-proxy.example/port")
assert r.status_code == 200
assert r.text == "answer from port 81\n"
assert "X-test" in r.headers
assert "f00" == r.headers["X-test"]
def test_custom_default_conf_applies_to_web2(docker_compose, nginxproxy):
r = nginxproxy.get("http://web2.nginx-proxy.local/port")
r = nginxproxy.get("http://web2.nginx-proxy.example/port")
assert r.status_code == 200
assert r.text == "answer from port 82\n"
assert "X-test" in r.headers
@ -21,7 +21,7 @@ def test_custom_default_conf_applies_to_web2(docker_compose, nginxproxy):
def test_custom_default_conf_is_overriden_for_web3(docker_compose, nginxproxy):
r = nginxproxy.get("http://web3.nginx-proxy.local/port")
r = nginxproxy.get("http://web3.nginx-proxy.example/port")
assert r.status_code == 200
assert r.text == "answer from port 83\n"
assert "X-test" in r.headers

View File

@ -1,30 +1,33 @@
nginx-proxy:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./my_custom_proxy_settings.conf:/etc/nginx/vhost.d/default_location:ro
- ./my_custom_proxy_settings_bar.conf:/etc/nginx/vhost.d/web3.nginx-proxy.local_location:ro
version: "2"
web1:
image: web
expose:
- "81"
environment:
WEB_PORTS: 81
VIRTUAL_HOST: web1.nginx-proxy.local
services:
nginx-proxy:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./my_custom_proxy_settings.conf:/etc/nginx/vhost.d/default_location:ro
- ./my_custom_proxy_settings_bar.conf:/etc/nginx/vhost.d/web3.nginx-proxy.example_location:ro
web2:
image: web
expose:
- "82"
environment:
WEB_PORTS: 82
VIRTUAL_HOST: web2.nginx-proxy.local
web1:
image: web
expose:
- "81"
environment:
WEB_PORTS: 81
VIRTUAL_HOST: web1.nginx-proxy.example
web3:
image: web
expose:
- "83"
environment:
WEB_PORTS: 83
VIRTUAL_HOST: web3.nginx-proxy.local
web2:
image: web
expose:
- "82"
environment:
WEB_PORTS: 82
VIRTUAL_HOST: web2.nginx-proxy.example
web3:
image: web
expose:
- "83"
environment:
WEB_PORTS: 83
VIRTUAL_HOST: web3.nginx-proxy.example

View File

@ -6,14 +6,14 @@ def test_custom_conf_does_not_apply_to_unknown_vhost(docker_compose, nginxproxy)
assert "X-test" not in r.headers
def test_custom_conf_applies_to_web1(docker_compose, nginxproxy):
r = nginxproxy.get("http://web1.nginx-proxy.local/port")
r = nginxproxy.get("http://web1.nginx-proxy.example/port")
assert r.status_code == 200
assert r.text == "answer from port 81\n"
assert "X-test" in r.headers
assert "f00" == r.headers["X-test"]
def test_custom_conf_applies_to_web2(docker_compose, nginxproxy):
r = nginxproxy.get("http://web2.nginx-proxy.local/port")
r = nginxproxy.get("http://web2.nginx-proxy.example/port")
assert r.status_code == 200
assert r.text == "answer from port 82\n"
assert "X-test" in r.headers

View File

@ -1,4 +1,5 @@
version: '2'
version: "2"
services:
nginx-proxy:
image: nginxproxy/nginx-proxy:test
@ -12,7 +13,7 @@ services:
- "81"
environment:
WEB_PORTS: 81
VIRTUAL_HOST: web1.nginx-proxy.local
VIRTUAL_HOST: web1.nginx-proxy.example
web2:
image: web
@ -20,4 +21,4 @@ services:
- "82"
environment:
WEB_PORTS: 82
VIRTUAL_HOST: web2.nginx-proxy.local
VIRTUAL_HOST: web2.nginx-proxy.example

View File

@ -6,17 +6,17 @@ def test_custom_conf_does_not_apply_to_unknown_vhost(docker_compose, nginxproxy)
assert "X-test" not in r.headers
def test_custom_conf_applies_to_web1(docker_compose, nginxproxy):
r = nginxproxy.get("http://web1.nginx-proxy.local/port")
r = nginxproxy.get("http://web1.nginx-proxy.example/port")
assert r.status_code == 200
assert r.text == "answer from port 81\n"
assert "X-test" in r.headers
assert "f00" == r.headers["X-test"]
def test_custom_conf_does_not_apply_to_web2(docker_compose, nginxproxy):
r = nginxproxy.get("http://web2.nginx-proxy.local/port")
r = nginxproxy.get("http://web2.nginx-proxy.example/port")
assert r.status_code == 200
assert r.text == "answer from port 82\n"
assert "X-test" not in r.headers
def test_custom_block_is_present_in_nginx_generated_conf(docker_compose, nginxproxy):
assert b"include /etc/nginx/vhost.d/web1.nginx-proxy.local_location;" in nginxproxy.get_conf()
assert b"include /etc/nginx/vhost.d/web1.nginx-proxy.example_location;" in nginxproxy.get_conf()

View File

@ -1,10 +1,11 @@
version: '2'
version: "2"
services:
nginx-proxy:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./my_custom_proxy_settings.conf:/etc/nginx/vhost.d/web1.nginx-proxy.local_location:ro
- ./my_custom_proxy_settings.conf:/etc/nginx/vhost.d/web1.nginx-proxy.example_location:ro
web1:
image: web
@ -12,7 +13,7 @@ services:
- "81"
environment:
WEB_PORTS: 81
VIRTUAL_HOST: web1.nginx-proxy.local
VIRTUAL_HOST: web1.nginx-proxy.example
web2:
image: web
@ -20,4 +21,4 @@ services:
- "82"
environment:
WEB_PORTS: 82
VIRTUAL_HOST: web2.nginx-proxy.local
VIRTUAL_HOST: web2.nginx-proxy.example

View File

@ -6,14 +6,14 @@ def test_custom_conf_does_not_apply_to_unknown_vhost(docker_compose, nginxproxy)
assert "X-test" not in r.headers
def test_custom_conf_applies_to_web1(docker_compose, nginxproxy):
r = nginxproxy.get("http://web1.nginx-proxy.local/port")
r = nginxproxy.get("http://web1.nginx-proxy.example/port")
assert r.status_code == 200
assert r.text == "answer from port 81\n"
assert "X-test" in r.headers
assert "f00" == r.headers["X-test"]
def test_custom_conf_does_not_apply_to_web2(docker_compose, nginxproxy):
r = nginxproxy.get("http://web2.nginx-proxy.local/port")
r = nginxproxy.get("http://web2.nginx-proxy.example/port")
assert r.status_code == 200
assert r.text == "answer from port 82\n"
assert "X-test" not in r.headers

View File

@ -1,10 +1,11 @@
version: '2'
version: "2"
services:
nginx-proxy:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./my_custom_proxy_settings.conf:/etc/nginx/vhost.d/web1.nginx-proxy.local:ro
- ./my_custom_proxy_settings.conf:/etc/nginx/vhost.d/web1.nginx-proxy.example:ro
web1:
image: web
@ -12,7 +13,7 @@ services:
- "81"
environment:
WEB_PORTS: 81
VIRTUAL_HOST: web1.nginx-proxy.local
VIRTUAL_HOST: web1.nginx-proxy.example
web2:
image: web
@ -20,4 +21,4 @@ services:
- "82"
environment:
WEB_PORTS: 82
VIRTUAL_HOST: web2.nginx-proxy.local
VIRTUAL_HOST: web2.nginx-proxy.example

View File

@ -6,14 +6,14 @@ def test_custom_conf_does_not_apply_to_unknown_vhost(docker_compose, nginxproxy)
assert "X-test" not in r.headers
def test_custom_conf_applies_to_web1(docker_compose, nginxproxy):
r = nginxproxy.get("http://web1.nginx-proxy.local/port")
r = nginxproxy.get("http://web1.nginx-proxy.example/port")
assert r.status_code == 200
assert r.text == "answer from port 81\n"
assert "X-test" in r.headers
assert "f00" == r.headers["X-test"]
def test_custom_conf_applies_to_web2(docker_compose, nginxproxy):
r = nginxproxy.get("http://web2.nginx-proxy.local/port")
r = nginxproxy.get("http://web2.nginx-proxy.example/port")
assert r.status_code == 200
assert r.text == "answer from port 82\n"
assert "X-test" in r.headers

View File

@ -1,4 +1,5 @@
version: '2'
version: "2"
services:
nginx-proxy:
image: nginxproxy/nginx-proxy:test
@ -12,7 +13,7 @@ services:
- "81"
environment:
WEB_PORTS: 81
VIRTUAL_HOST: web1.nginx-proxy.local
VIRTUAL_HOST: web1.nginx-proxy.example
web2:
image: web
@ -20,4 +21,4 @@ services:
- "82"
environment:
WEB_PORTS: 82
VIRTUAL_HOST: web2.nginx-proxy.local
VIRTUAL_HOST: web2.nginx-proxy.example

View File

@ -1,12 +0,0 @@
import pytest
import re
def test_debug_info_is_present_in_nginx_generated_conf(docker_compose, nginxproxy):
conf = nginxproxy.get_conf().decode('ASCII')
assert re.search(r"# Exposed ports: \[\{\d+\.\d+\.\d+\.\d+\s+80\s+tcp \} \{\d+\.\d+\.\d+\.\d+\s+81\s+tcp \}\]", conf) or \
re.search(r"# Exposed ports: \[\{\d+\.\d+\.\d+\.\d+\s+81\s+tcp \} \{\d+\.\d+\.\d+\.\d+\s+80\s+tcp \}\]", conf)
assert re.search(r"# Exposed ports: \[\{\d+\.\d+\.\d+\.\d+\s+82\s+tcp \} \{\d+\.\d+\.\d+\.\d+\s+83\s+tcp \}\]", conf) or \
re.search(r"# Exposed ports: \[\{\d+\.\d+\.\d+\.\d+\s+83\s+tcp \} \{\d+\.\d+\.\d+\.\d+\s+82\s+tcp \}\]", conf)
assert "# Default virtual port: 80" in conf
assert "# VIRTUAL_PORT: 82" in conf
assert conf.count("# /!\\ Virtual port not exposed") == 1

View File

@ -1,26 +0,0 @@
web1:
image: web
expose:
- "80"
- "81"
environment:
WEB_PORTS: "80 81"
VIRTUAL_HOST: "web1.nginx-proxy.tld"
VIRTUAL_PORT: "82"
web2:
image: web
expose:
- "82"
- "83"
environment:
WEB_PORTS: "82 83"
VIRTUAL_HOST: "web2.nginx-proxy.tld"
VIRTUAL_PORT: "82"
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
DEBUG: "true"

View File

@ -1,8 +0,0 @@
import pytest
import re
def test_debug_info_is_present_in_nginx_generated_conf(docker_compose, nginxproxy):
conf = nginxproxy.get_conf().decode('ASCII')
assert re.search(r"# Exposed ports: \[\{\d+\.\d+\.\d+\.\d+\s+80\s+tcp \} \{\d+\.\d+\.\d+\.\d+\s+81\s+tcp \}\]", conf) or \
re.search(r"# Exposed ports: \[\{\d+\.\d+\.\d+\.\d+\s+81\s+tcp \} \{\d+\.\d+\.\d+\.\d+\s+80\s+tcp \}\]", conf)
assert conf.count("# Exposed ports: [{") == 1

View File

@ -1,25 +0,0 @@
web1:
image: web
expose:
- "80"
- "81"
environment:
WEB_PORTS: "80 81"
VIRTUAL_HOST: "web1.nginx-proxy.tld"
VIRTUAL_PORT: "82"
DEBUG: "true"
web2:
image: web
expose:
- "82"
- "83"
environment:
WEB_PORTS: "82 83"
VIRTUAL_HOST: "web2.nginx-proxy.tld"
VIRTUAL_PORT: "82"
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro

View File

@ -1,17 +1,19 @@
# GIVEN a webserver with VIRTUAL_HOST set to web1.tld
web1:
image: web
expose:
- "81"
environment:
WEB_PORTS: 81
VIRTUAL_HOST: web1.tld
version: "2"
services:
# GIVEN a webserver with VIRTUAL_HOST set to web1.tld
web1:
image: web
expose:
- "81"
environment:
WEB_PORTS: 81
VIRTUAL_HOST: web1.tld
# WHEN nginx-proxy runs with DEFAULT_HOST set to web1.tld
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
DEFAULT_HOST: web1.tld
# WHEN nginx-proxy runs with DEFAULT_HOST set to web1.tld
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
DEFAULT_HOST: web1.tld

View File

@ -0,0 +1,8 @@
import re
def test_default_root_none(docker_compose, nginxproxy):
conf = nginxproxy.get_conf().decode()
assert re.search(r"(?m)^\s*location\s+/path\s+\{", conf)
assert not re.search(r"(?m)^\s*location\s+/\s+\{", conf)

View File

@ -0,0 +1,18 @@
version: "2"
services:
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
DEFAULT_ROOT: none
web:
image: web
expose:
- "80"
environment:
WEB_PORTS: "80"
VIRTUAL_HOST: web.nginx-proxy.test
VIRTUAL_PATH: /path

View File

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

View File

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

View File

@ -1,8 +1,5 @@
import os
import docker
import logging
import pytest
import re
from distutils.version import LooseVersion
@ -13,38 +10,12 @@ pytestmark = pytest.mark.skipif(
)
@pytest.fixture(scope="module")
def nginx_tmpl():
"""
pytest fixture which extracts the the nginx config template from
the nginxproxy/nginx-proxy:test image
"""
script_dir = os.path.dirname(__file__)
logging.info("extracting nginx.tmpl from nginxproxy/nginx-proxy:test")
docker_client = docker.from_env()
print(
docker_client.containers.run(
image="nginxproxy/nginx-proxy:test",
remove=True,
volumes=["{current_dir}:{current_dir}".format(current_dir=script_dir)],
entrypoint="sh",
command='-xc "cp /app/nginx.tmpl {current_dir} && chmod 777 {current_dir}/nginx.tmpl"'.format(
current_dir=script_dir
),
stderr=True,
)
)
yield
logging.info("removing nginx.tmpl")
os.remove(os.path.join(script_dir, "nginx.tmpl"))
def test_unknown_virtual_host_is_503(nginx_tmpl, docker_compose, nginxproxy):
def test_unknown_virtual_host_is_503(docker_compose, nginxproxy):
r = nginxproxy.get("http://unknown.nginx.container.docker/")
assert r.status_code == 503
def test_forwards_to_whoami(nginx_tmpl, docker_compose, nginxproxy):
def test_forwards_to_whoami(docker_compose, nginxproxy):
r = nginxproxy.get("http://whoami.nginx.container.docker/")
assert r.status_code == 200
whoami_container = docker_compose.containers.get("whoami")

View File

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

View File

@ -22,6 +22,7 @@ def web1(docker_compose):
},
ports={"81/tcp": None}
)
docker_compose.networks.get("test_default").connect(container)
sleep(2) # give it some time to initialize and for docker-gen to detect it
yield container
try:
@ -46,6 +47,7 @@ def web2(docker_compose):
},
ports={"82/tcp": None}
)
docker_compose.networks.get("test_default").connect(container)
sleep(2) # give it some time to initialize and for docker-gen to detect it
yield container
try:

View File

@ -1,4 +1,7 @@
nginxproxy:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
version: "2"
services:
nginxproxy:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro

View File

@ -0,0 +1,5 @@
server {
server_name __;
listen 80 default_server;
return 418;
}

View File

@ -0,0 +1,17 @@
version: "2"
services:
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./custom-fallback.conf:/etc/nginx/conf.d/zzz-custom-fallback.conf:ro
http-only:
image: web
expose:
- "83"
environment:
WEB_PORTS: "83"
VIRTUAL_HOST: http-only.nginx-proxy.test
HTTPS_METHOD: nohttps

View File

@ -0,0 +1,71 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4096 (0x1000)
Signature Algorithm: sha256WithRSAEncryption
Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld
Validity
Not Before: Feb 7 21:54:16 2023 GMT
Not After : Jun 25 21:54:16 2050 GMT
Subject: CN=http-only.nginx-proxy.test
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:b4:62:61:07:54:2e:6d:55:83:2d:24:b7:e2:15:
34:13:bd:79:21:e9:10:75:3f:4c:f8:ba:60:29:87:
e5:8e:2a:1e:fd:33:51:5a:8a:3a:6f:60:ff:24:f1:
1b:27:30:8c:ac:43:04:b7:79:cb:7a:ec:c6:08:a4:
a0:15:b0:0f:ee:6b:15:84:24:11:bc:85:2b:48:06:
04:0a:58:bb:8c:e8:4d:48:f5:06:c5:91:fe:5d:99:
0a:29:31:8a:f1:9b:0c:e0:39:75:a1:06:9b:d4:f5:
06:74:8f:46:5e:64:ba:2f:d0:3d:7c:3d:30:03:e9:
7c:35:17:69:04:f6:2e:29:d4:93:d6:d6:d2:6c:04:
38:06:21:06:05:30:8a:b9:9d:05:8d:12:6e:48:39:
bb:f6:93:4f:ba:a5:84:c7:96:2f:be:92:25:e9:d0:
95:2a:d9:23:8a:b3:28:0b:b6:19:1c:3b:be:a2:91:
70:44:a8:77:18:94:4b:df:61:f4:5c:c9:78:76:34:
b5:87:0f:c0:92:04:26:b6:ca:62:cd:9b:5d:eb:bf:
10:ac:df:af:72:5f:af:09:38:b1:dc:e1:3d:13:db:
a0:ac:b7:2e:ca:39:5c:4c:f1:1e:81:a8:b4:44:a2:
72:d5:3b:c0:71:cc:dc:16:0d:fa:38:96:44:b3:00:
d6:65
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:http-only.nginx-proxy.test
Signature Algorithm: sha256WithRSAEncryption
3b:54:95:48:4d:f6:93:38:42:40:02:ab:b7:17:3b:50:3b:ca:
c7:12:69:b0:da:cb:d7:3e:0e:1f:bf:a2:59:c7:fe:c2:5c:43:
84:92:b9:3a:be:8f:7e:2e:81:3c:ed:f3:a9:77:21:c2:35:f1:
da:cf:3a:1e:e2:ee:a2:ce:72:55:97:87:0e:ad:59:61:f7:75:
46:c0:2b:d4:88:b7:36:97:11:fb:5e:28:89:e9:2a:92:f1:15:
f1:43:8e:c1:38:85:8d:3a:26:7d:25:72:93:17:96:8d:5a:ed:
e8:73:3a:d5:8d:80:f2:af:38:84:ff:85:2e:d1:36:7d:2e:e1:
f0:2c:d8:15:5f:fc:c5:70:5d:25:6a:22:f3:2a:cd:0f:25:ad:
d4:93:d3:9a:3e:50:bc:da:a5:6c:86:ea:1d:d9:b9:c5:90:db:
f5:02:c8:c9:77:5c:ef:77:fe:74:60:41:33:d9:3c:a2:e1:73:
aa:14:18:5d:36:58:c8:41:63:4c:59:0e:4b:3d:c5:65:5a:01:
b0:16:50:0f:d0:4f:0d:ca:97:f6:11:47:06:6b:b1:ae:bb:26:
30:34:8b:7a:91:5d:8a:22:c7:f9:05:0d:bb:a5:b7:60:c0:20:
ce:d0:0e:c0:66:b3:e7:c4:61:ec:c5:40:e6:52:11:41:c3:11:
18:04:c7:1e
-----BEGIN CERTIFICATE-----
MIIDCzCCAfOgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp
bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs
ZDAgFw0yMzAyMDcyMTU0MTZaGA8yMDUwMDYyNTIxNTQxNlowJTEjMCEGA1UEAwwa
aHR0cC1vbmx5Lm5naW54LXByb3h5LnRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQC0YmEHVC5tVYMtJLfiFTQTvXkh6RB1P0z4umAph+WOKh79M1Fa
ijpvYP8k8RsnMIysQwS3ect67MYIpKAVsA/uaxWEJBG8hStIBgQKWLuM6E1I9QbF
kf5dmQopMYrxmwzgOXWhBpvU9QZ0j0ZeZLov0D18PTAD6Xw1F2kE9i4p1JPW1tJs
BDgGIQYFMIq5nQWNEm5IObv2k0+6pYTHli++kiXp0JUq2SOKsygLthkcO76ikXBE
qHcYlEvfYfRcyXh2NLWHD8CSBCa2ymLNm13rvxCs369yX68JOLHc4T0T26Csty7K
OVxM8R6BqLREonLVO8BxzNwWDfo4lkSzANZlAgMBAAGjKTAnMCUGA1UdEQQeMByC
Gmh0dHAtb25seS5uZ2lueC1wcm94eS50ZXN0MA0GCSqGSIb3DQEBCwUAA4IBAQA7
VJVITfaTOEJAAqu3FztQO8rHEmmw2svXPg4fv6JZx/7CXEOEkrk6vo9+LoE87fOp
dyHCNfHazzoe4u6iznJVl4cOrVlh93VGwCvUiLc2lxH7XiiJ6SqS8RXxQ47BOIWN
OiZ9JXKTF5aNWu3oczrVjYDyrziE/4Uu0TZ9LuHwLNgVX/zFcF0laiLzKs0PJa3U
k9OaPlC82qVshuod2bnFkNv1AsjJd1zvd/50YEEz2Tyi4XOqFBhdNljIQWNMWQ5L
PcVlWgGwFlAP0E8Nypf2EUcGa7GuuyYwNIt6kV2KIsf5BQ27pbdgwCDO0A7AZrPn
xGHsxUDmUhFBwxEYBMce
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAtGJhB1QubVWDLSS34hU0E715IekQdT9M+LpgKYfljioe/TNR
Woo6b2D/JPEbJzCMrEMEt3nLeuzGCKSgFbAP7msVhCQRvIUrSAYECli7jOhNSPUG
xZH+XZkKKTGK8ZsM4Dl1oQab1PUGdI9GXmS6L9A9fD0wA+l8NRdpBPYuKdST1tbS
bAQ4BiEGBTCKuZ0FjRJuSDm79pNPuqWEx5YvvpIl6dCVKtkjirMoC7YZHDu+opFw
RKh3GJRL32H0XMl4djS1hw/AkgQmtspizZtd678QrN+vcl+vCTix3OE9E9ugrLcu
yjlcTPEegai0RKJy1TvAcczcFg36OJZEswDWZQIDAQABAoIBAAfDA/HQyX6i41YZ
8l+kEe2XhZLT+IVTB/jb7C9dTZ9kaJj0kFeZAxKv1cq9JTH2gNcYuyc58muDrLHK
g6jrPoQ/z1k0RB8ci9Q5jgrz7n4NsOWmxXfS5GMaprlHDHeA+HjdgBZBtorfUDvL
vndpVimgiETETUCd115hd39jKHFcRcdV6yCix7ObywK3dMgLVpagCcnlyCWffS/r
nhhMfJ+VstW0nUtfZ7JEYwT6Cg7lLAVtDkqPX8zGjJiRwUKH808bUyqEw1y5Cc8U
U5hbmMgPWfXsKxsEC6FSVHBG9ZX2jymOMQXijLFcBSuWvADHmyU+ZxXcbtd1rv4E
cGFj3wECgYEA5cNrr5WjrpEin6MYYVWxiQ+xEWPU2R17eApagrDRLM41JJpv7a5m
TYuZRfIxb59CBPi718Gi168P3T2KMvo2/BTh9Lq5ZBYHx3aDqW2QvMFn7/tgamj8
0DBxccd2QWfGIBrT1rAF7lD8TC86wtDDVKrvhucRSEXVKF/jWFFRGfUCgYEAyPt6
48khr7sfNMVdkDLjQjZVV6H7ZUMoSn0FGybgKWxW+b0XCBPObUQWIpyCNTRr1+4A
1TAUS+F/OVVfwnLNgemeE2wd6CaduxwiK1U4pHbyXCElH1ifonHWV3MoXOefYsiY
q5z2jfJzUi0JZVUKsveu9rQsFLsc//1s/I5T1LECgYEAldY6fNg2VVp63OZsuNU8
oSiljbSwEyMh6Oe/nOkYkIKtr4AzrCoGt11piG7ohGW0lS9suMijnMqiquI+JP5+
KyinLoUy761aR17nf+9e62mpkZw6hUqQTGi7Irs0SHUXhMpaCfDi/Ua9MiW+yVuB
ds6+xBgeciZwWxMlXOwy2p0CgYEAm+YWiSK3Mq0fo7uEvBn9Fps2z+ciLoZNdppL
n6gkMX2MaeQ3PVi/wxoRYX+tsL+c973yf2vwEnw0R7Dlutt6dc9VgxNWj4GE0GMe
Tiao7Uom7Tf4p7wC9+r9rI/zOz2f8OxRIK18wtbShWfR5fx1dCWUXmGb3+jUse1O
4Qk2FcECgYAvSvGFoJb8tuHFEYYHBbjficmvTUsrTE+EhxPqWKFhKfF19fFFIupy
XBCrN6nwrh+/YMxZXeIRbbTTf814cOO7PjLeNhnfhJZkaJq1HzbYe3bOurna3qrm
Ra3xiM8Ld2PyGnZPXf8+AWhMhuPkLX1KFVTCAxwCpmTZCHtiGCmXMA==
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,71 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4096 (0x1000)
Signature Algorithm: sha256WithRSAEncryption
Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld
Validity
Not Before: Feb 7 21:53:19 2023 GMT
Not After : Jun 25 21:53:19 2050 GMT
Subject: CN=https-and-http.nginx-proxy.test
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:b7:97:85:d1:7f:6b:50:29:f3:87:b7:4e:f5:25:
40:6a:d8:fa:a1:63:3c:4a:2e:68:4a:c6:8b:38:df:
07:81:d0:08:9d:fc:17:f5:37:28:7f:31:e6:f3:81:
28:4e:22:b6:bd:a2:4e:f2:2f:e5:0f:dd:55:3c:e1:
04:84:4c:45:1b:1a:ae:b7:f0:2a:da:43:05:71:91:
92:b8:d1:49:fe:80:0a:53:b9:66:da:54:60:9a:fc:
e1:b2:e8:28:48:7f:96:94:3c:92:a3:b2:37:f6:7a:
c2:de:0b:12:f0:ae:4e:92:fe:2d:c1:b2:95:28:1f:
88:8d:79:99:81:19:ae:22:a4:95:f5:9f:db:25:8e:
1d:cf:43:cd:6f:85:93:5f:79:ee:f8:f3:d4:82:e1:
e9:4d:c9:ad:ae:5b:92:43:3a:3c:71:51:70:f7:3e:
bd:1b:24:52:6a:a3:cf:54:72:57:ed:fe:72:ea:96:
9b:5a:02:02:a7:df:85:b7:68:ae:1e:07:77:9f:59:
a5:a0:8b:28:c2:c8:b7:bb:8a:42:50:df:05:73:bf:
9c:55:13:b5:82:79:77:40:57:a4:8f:88:a5:71:50:
d7:70:b0:4d:0c:d9:86:b3:9b:db:8a:20:bd:19:68:
10:52:2d:53:ba:0e:2e:1c:ad:80:54:bb:b6:c9:ab:
11:39
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:https-and-http.nginx-proxy.test
Signature Algorithm: sha256WithRSAEncryption
2c:f3:e5:47:3f:8e:5a:28:b1:df:e5:95:50:85:6f:27:2f:a6:
8d:f1:5e:cf:df:e2:52:66:97:61:36:59:81:26:25:19:99:c9:
93:e5:85:cb:ca:69:af:4b:21:a3:d2:7a:bf:b5:5e:2d:42:fb:
99:f8:22:58:e5:bf:79:b8:8a:74:7e:c6:94:14:d9:f2:27:63:
b6:e5:74:21:5b:59:fb:f6:c8:a9:28:fb:60:f7:5e:bd:c2:e6:
74:24:14:96:61:95:6c:c2:66:b4:52:25:a1:85:5a:97:e5:68:
5c:62:cf:69:3b:b0:a9:56:d8:e3:5f:74:dc:84:18:d5:3e:4f:
c9:35:39:26:88:dc:9b:80:d9:40:e1:4f:09:27:8d:d2:89:55:
30:91:02:86:35:04:95:1e:1d:58:14:5b:c6:e0:2e:a7:bf:a8:
f6:2b:76:8a:4e:71:79:bc:c0:04:cd:db:81:73:46:ce:68:ed:
25:b0:0e:42:8d:96:64:77:3b:f4:9d:1a:c9:f6:78:4c:56:4f:
92:17:29:3d:80:50:71:77:4b:a8:29:c2:12:fc:ad:0a:37:81:
38:4c:fb:54:99:4d:12:5f:98:dc:d1:a9:7b:08:45:c4:6f:7e:
fe:00:e0:db:79:fe:d1:28:e3:8e:82:d1:fb:bc:0a:c4:42:93:
c9:5e:eb:ba
-----BEGIN CERTIFICATE-----
MIIDFTCCAf2gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp
bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs
ZDAgFw0yMzAyMDcyMTUzMTlaGA8yMDUwMDYyNTIxNTMxOVowKjEoMCYGA1UEAwwf
aHR0cHMtYW5kLWh0dHAubmdpbngtcHJveHkudGVzdDCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBALeXhdF/a1Ap84e3TvUlQGrY+qFjPEouaErGizjfB4HQ
CJ38F/U3KH8x5vOBKE4itr2iTvIv5Q/dVTzhBIRMRRsarrfwKtpDBXGRkrjRSf6A
ClO5ZtpUYJr84bLoKEh/lpQ8kqOyN/Z6wt4LEvCuTpL+LcGylSgfiI15mYEZriKk
lfWf2yWOHc9DzW+Fk1957vjz1ILh6U3Jra5bkkM6PHFRcPc+vRskUmqjz1RyV+3+
cuqWm1oCAqffhbdorh4Hd59ZpaCLKMLIt7uKQlDfBXO/nFUTtYJ5d0BXpI+IpXFQ
13CwTQzZhrOb24ogvRloEFItU7oOLhytgFS7tsmrETkCAwEAAaMuMCwwKgYDVR0R
BCMwIYIfaHR0cHMtYW5kLWh0dHAubmdpbngtcHJveHkudGVzdDANBgkqhkiG9w0B
AQsFAAOCAQEALPPlRz+OWiix3+WVUIVvJy+mjfFez9/iUmaXYTZZgSYlGZnJk+WF
y8ppr0sho9J6v7VeLUL7mfgiWOW/ebiKdH7GlBTZ8idjtuV0IVtZ+/bIqSj7YPde
vcLmdCQUlmGVbMJmtFIloYVal+VoXGLPaTuwqVbY41903IQY1T5PyTU5Jojcm4DZ
QOFPCSeN0olVMJEChjUElR4dWBRbxuAup7+o9it2ik5xebzABM3bgXNGzmjtJbAO
Qo2WZHc79J0ayfZ4TFZPkhcpPYBQcXdLqCnCEvytCjeBOEz7VJlNEl+Y3NGpewhF
xG9+/gDg23n+0SjjjoLR+7wKxEKTyV7rug==
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAt5eF0X9rUCnzh7dO9SVAatj6oWM8Si5oSsaLON8HgdAInfwX
9TcofzHm84EoTiK2vaJO8i/lD91VPOEEhExFGxqut/Aq2kMFcZGSuNFJ/oAKU7lm
2lRgmvzhsugoSH+WlDySo7I39nrC3gsS8K5Okv4twbKVKB+IjXmZgRmuIqSV9Z/b
JY4dz0PNb4WTX3nu+PPUguHpTcmtrluSQzo8cVFw9z69GyRSaqPPVHJX7f5y6pab
WgICp9+Ft2iuHgd3n1mloIsowsi3u4pCUN8Fc7+cVRO1gnl3QFekj4ilcVDXcLBN
DNmGs5vbiiC9GWgQUi1Tug4uHK2AVLu2yasROQIDAQABAoIBACT4KSVHoEdzOyvw
GME6sB8T9Fw9TG2vrKaqFmzsVGmqh6Gwmu5xHgGG/fe44XHigaPsJDOWu2yXaEur
ECrH5P6RP++gODDdYCI/ayk2U80g4XN8mR6L8Swkkhphr4Lx1lOhYvH9uFE05Tqr
RjQbFY16C6K+oFSFDQ1YGDYsAqnM3RD7PH+lHpo8UN1TO/vogdSQEpMYZDwLAYnW
uD5G3c0u2PsGu9YLuz2p8hcs3chh+cqKJWXOeW0JLrNGx1bqeQWkn6nXRDdRYi9V
cJlTgDqGuF54bieSyq9ABDZQP4Ol+moYKDoIz5PwurNjcYSklrT1tw0gqHZoQK1L
fDjw3QECgYEA7QMRU1AFKTvO7/8WLHLN5BT63n31wm0e9PYpz/XVLWEfxBcp9Xmf
xAIhXZ/U9P4dfNqxTjN9mVGzCHh5KfDJnUFqOXFy/zvfMeRzJf6dJo6/4OX9Bijr
Tgd454vyGXYQP2t+F14UAwl6vlGOAjttiP5qY5Ef1gllBEeIPe9Ts9kCgYEAxkzZ
pq4HJ/5/iDquMEHXNXzpNPavSvgxQdl1ILvJ49LJImmQFBCP9PqiOTIfePz1OqUI
C4baFuc0FEDJ3x9CUNmMY1lEi2ZUq2agPSXaQNsMcKtEJH8SoJlJIRpkQA7unX09
zb4dam6g79OaGmb8scePuezXMLv1Ee6WWtXbzGECgYEA6PYn9Gzl9cacu9dOUzgw
2ewpPcIvawDY+cxwAsHO3MDneVWPX4JBoGa7pwvwRTL1hwBqYMRJwwbD5CKObcQI
V/KxV28Eqo2N77tt1z2x9/E99u/4yTI1P0gm9ejfeVlL1RpyIMPPBcEujZ0Z6WXC
X3I63k0KLtajHRa2erIf4tkCgYAfunAgwTuX5JqXO3xfcEl033WY6deGUUvgU2Dw
Sdu1viY8gVNyQmwmMGwAZsquWxsJtRoibgM7IucsTml+b8v2j7hstP3IqCjn+9Wr
swDG28WTyXNvu31JgP04dLaRoVIAlOdsofym6OiLNvozO0M3VsziXMjZnVlK8zfP
dORkQQKBgQDXAJEJPygxVA+bF104dzCMWGmU7K8ShEWC5eOdKK4KWf9bNDpY6M6c
i6zga/xBbj7e3Bxqprpp8Wy2gIsnYiVo4V9EQethbLdomPxOpBMNMARw81rL1CpO
jbHB7bIDcKs2tQoZEXUW86ZxC8sdaDaWTJTfUO0RpJow6ZO3yvxVIQ==
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,71 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4096 (0x1000)
Signature Algorithm: sha256WithRSAEncryption
Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld
Validity
Not Before: Feb 7 21:53:49 2023 GMT
Not After : Jun 25 21:53:49 2050 GMT
Subject: CN=https-only.nginx-proxy.test
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:d9:87:48:02:85:f4:5f:0d:90:7e:4c:4f:13:89:
41:ca:41:15:c2:6f:fd:a8:c7:17:83:c6:dd:8c:fe:
19:a4:b2:6b:0b:35:4f:b4:3d:7c:40:0a:04:33:2a:
fd:10:72:f7:63:63:99:5b:3d:ec:78:ee:c6:4d:c8:
0e:4c:be:f2:3f:e3:02:74:57:9a:c1:fe:15:95:63:
4e:e7:2c:eb:70:f2:6b:c8:ba:01:a2:ca:a1:c7:76:
ff:38:e4:c2:b0:66:fc:85:d2:af:0f:22:81:d4:82:
eb:d5:b0:e6:69:14:37:dd:8d:ad:29:ce:93:68:5a:
ce:f4:77:76:6f:78:13:b6:c8:2f:fe:e0:b6:7e:fb:
29:16:be:e2:f5:45:3b:39:5b:52:dc:26:b7:ca:0c:
b6:1c:fc:a8:38:0b:dd:c1:f4:04:9b:2d:38:c9:a5:
2d:3e:f1:42:88:53:a2:3b:17:cf:d5:3c:2b:d6:6a:
7f:6f:05:8d:c5:b7:5d:64:1e:83:1b:e7:ec:80:3d:
6d:34:c1:66:b2:e6:5d:d9:a7:6e:46:75:14:bf:10:
16:c5:fc:47:8e:63:fa:e5:b4:bd:f2:b9:e0:cb:ea:
75:f9:68:ee:7d:8f:ea:8f:1a:9f:34:27:7a:4a:9f:
85:fd:3e:17:a7:96:c3:d0:4e:50:a2:a2:e0:45:92:
d0:b5
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:https-only.nginx-proxy.test
Signature Algorithm: sha256WithRSAEncryption
8a:52:46:42:a9:74:18:6a:52:90:ef:a4:e9:c5:54:d5:97:3a:
ff:8b:c2:76:4f:9e:47:aa:e1:ea:e5:b9:af:9d:33:e3:85:17:
54:7d:32:bd:ac:90:3f:5c:d2:a1:42:17:52:2b:b1:83:e5:c3:
bf:81:f0:e7:38:e2:88:67:7b:d8:59:fe:f9:94:99:ba:be:f4:
3c:24:b2:c7:9e:f0:98:21:c6:2d:c2:e8:f3:67:bd:62:00:aa:
ce:34:fa:b4:53:6d:c1:09:5e:55:bd:43:aa:86:c6:f8:c5:83:
46:3a:49:12:a2:ec:30:36:0c:99:44:74:09:9d:cc:4b:98:1f:
7e:c9:9b:68:a0:f8:1e:00:14:d0:da:2a:bf:c8:ca:a8:1c:10:
b5:68:a2:f1:41:93:0c:f3:3f:c0:c6:53:3c:8d:a7:dd:a5:7b:
35:cc:44:e0:5b:6d:c5:cb:33:6f:c1:43:7e:06:df:21:99:11:
b3:91:41:b4:5e:f0:37:1e:8e:e5:73:85:dc:4a:21:d5:41:f9:
4e:b8:f5:ed:21:93:09:91:c2:8c:6b:04:a4:84:ab:3a:fe:35:
64:fa:6b:a7:8d:40:a6:64:89:30:84:ac:28:99:5a:01:79:77:
c0:df:88:da:a9:75:5f:c4:51:ae:a8:45:7b:d2:e1:a2:81:29:
60:cd:7b:cd
-----BEGIN CERTIFICATE-----
MIIDDTCCAfWgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp
bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs
ZDAgFw0yMzAyMDcyMTUzNDlaGA8yMDUwMDYyNTIxNTM0OVowJjEkMCIGA1UEAwwb
aHR0cHMtb25seS5uZ2lueC1wcm94eS50ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEA2YdIAoX0Xw2QfkxPE4lBykEVwm/9qMcXg8bdjP4ZpLJrCzVP
tD18QAoEMyr9EHL3Y2OZWz3seO7GTcgOTL7yP+MCdFeawf4VlWNO5yzrcPJryLoB
osqhx3b/OOTCsGb8hdKvDyKB1ILr1bDmaRQ33Y2tKc6TaFrO9Hd2b3gTtsgv/uC2
fvspFr7i9UU7OVtS3Ca3ygy2HPyoOAvdwfQEmy04yaUtPvFCiFOiOxfP1Twr1mp/
bwWNxbddZB6DG+fsgD1tNMFmsuZd2aduRnUUvxAWxfxHjmP65bS98rngy+p1+Wju
fY/qjxqfNCd6Sp+F/T4Xp5bD0E5QoqLgRZLQtQIDAQABoyowKDAmBgNVHREEHzAd
ghtodHRwcy1vbmx5Lm5naW54LXByb3h5LnRlc3QwDQYJKoZIhvcNAQELBQADggEB
AIpSRkKpdBhqUpDvpOnFVNWXOv+LwnZPnkeq4erlua+dM+OFF1R9Mr2skD9c0qFC
F1IrsYPlw7+B8Oc44ohne9hZ/vmUmbq+9Dwkssee8Jghxi3C6PNnvWIAqs40+rRT
bcEJXlW9Q6qGxvjFg0Y6SRKi7DA2DJlEdAmdzEuYH37Jm2ig+B4AFNDaKr/Iyqgc
ELVoovFBkwzzP8DGUzyNp92lezXMROBbbcXLM2/BQ34G3yGZEbORQbRe8DcejuVz
hdxKIdVB+U649e0hkwmRwoxrBKSEqzr+NWT6a6eNQKZkiTCErCiZWgF5d8DfiNqp
dV/EUa6oRXvS4aKBKWDNe80=
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA2YdIAoX0Xw2QfkxPE4lBykEVwm/9qMcXg8bdjP4ZpLJrCzVP
tD18QAoEMyr9EHL3Y2OZWz3seO7GTcgOTL7yP+MCdFeawf4VlWNO5yzrcPJryLoB
osqhx3b/OOTCsGb8hdKvDyKB1ILr1bDmaRQ33Y2tKc6TaFrO9Hd2b3gTtsgv/uC2
fvspFr7i9UU7OVtS3Ca3ygy2HPyoOAvdwfQEmy04yaUtPvFCiFOiOxfP1Twr1mp/
bwWNxbddZB6DG+fsgD1tNMFmsuZd2aduRnUUvxAWxfxHjmP65bS98rngy+p1+Wju
fY/qjxqfNCd6Sp+F/T4Xp5bD0E5QoqLgRZLQtQIDAQABAoIBAAWs//YA5MVuJy0E
dLO/yxWp6RVvsqCqwTRRBgrdvnGLrjtWosPDLvDE0iM7peq99TKEsMWusfLd2BLD
e4wJF20PUUsT1hflt050juR9SY9i4+kS4WQMAXig5DvpzCKqLUCYpLSyY8zVta2X
tgtb2bFQNwp2N2ZrqCa8zzxNV8ZXGoW+ZlvBJEDtBwt1DCDhY39/pqHfIhFl4Vwk
YhhbVjID145D1j/fP6vLceM2YA4uRmF1itj1iQ6YNNpXRspUGE4DXdqR6HcbduiX
trZjmdtKXY8mJg6jyLZxYbjFlKV/LvqKRYF3Jb9K0vdd4juBdZoy7DQzoLhcnzui
pEnPLakCgYEA9tN6KdQGKGBXGuF+ZqhXfB/XSkKUf8o/5j62cbu11ZIJ+iEBx+d6
lQAxTz5hHUL6a3c5qiM+AWBxYuFD6oqptIlTlBfIXI978neDNvEWWffivPvQLbt9
o9ohOirfK1iGPvtrpAwjv5ylE5SiTmJ/6wDvQWjNGAnJ3aaxkesJUSMCgYEA4Z0K
UHZVtnKLtzzIY7KfLbuKF/fJEDfMNr4Wgl6ny21vqO9kJGmA7SaoNdhx8RDcKmeV
/Vey4ug6YlOG48eapKLTthdRz5mx+jIkUfdOhj81m28xm/OPTqCrviTHCNOHeYDy
NKAIlJMo2z0vTKJn5eP6CsYmDWLpHQNyXY5qcEcCgYAzDBWt5O3JF/Or2Yr8zEAb
qbIq544yx69jfQDakMnQe72Yf48Quuz9N+b6zpnjJWEJLMU+TL+cJUgN/SzAqyDh
96zTaf/ENOCbiuAWUtIelUfNcf7iFm6rnodUsl0pZ8uL5w+iA+i4zjrNy+WtdG2k
OrNAwd345L1dHAaJeSSaJQKBgQCUnF3r7Fa/TCpt87LHwSQK+sqWyRf+/9IbiRDI
pVL/s8FmVPHw7jIHhHwuo7lCImnz4LGy5C6oOnIizIRAy/04Ty0Hd8ri5YmPlbHI
8A8gbMiB7zeNU1zlXP5jzFPyo2tMhLyGH5gnTdwOtfnPD/dCPe45ZJYyISIOg3O0
3peMBwKBgH20cskAOCNclfoG+Nis52h8FqmDlflJ8waUarvk26JhO1e009kOytw8
x/qSuttpGtTG+4fdc2wJvFNczr4h9ZlftBdgZXj8PKgRpcIe8q97Xg8PUj+Xfu/t
vD/QV+tVcGoAMsQq4NeFxiTbPfwVyXdYFT1XVCu6JEdLL+gpWh5W
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,42 @@
version: "2"
services:
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./nodefault.certs:/etc/nginx/certs:ro
https-and-http:
image: web
expose:
- "81"
environment:
WEB_PORTS: "81"
VIRTUAL_HOST: https-and-http.nginx-proxy.test
https-only:
image: web
expose:
- "82"
environment:
WEB_PORTS: "82"
VIRTUAL_HOST: https-only.nginx-proxy.test
HTTPS_METHOD: nohttp
http-only:
image: web
expose:
- "83"
environment:
WEB_PORTS: "83"
VIRTUAL_HOST: http-only.nginx-proxy.test
HTTPS_METHOD: nohttps
missing-cert:
image: web
expose:
- "84"
environment:
WEB_PORTS: "84"
VIRTUAL_HOST: missing-cert.nginx-proxy.test

View File

@ -0,0 +1,19 @@
version: "2"
services:
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./withdefault.certs:/etc/nginx/certs:ro
environment:
HTTPS_METHOD: redirect
https-only:
image: web
expose:
- "82"
environment:
WEB_PORTS: "82"
HTTPS_METHOD: nohttp
VIRTUAL_HOST: https-only.nginx-proxy.test

View File

@ -0,0 +1,26 @@
version: "2"
services:
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./withdefault.certs:/etc/nginx/certs:ro
environment:
HTTPS_METHOD: nohttp
https-only:
image: web
expose:
- "82"
environment:
WEB_PORTS: "82"
VIRTUAL_HOST: https-only.nginx-proxy.test
missing-cert:
image: web
expose:
- "84"
environment:
WEB_PORTS: "84"
VIRTUAL_HOST: missing-cert.nginx-proxy.test

View File

@ -0,0 +1,18 @@
version: "2"
services:
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./withdefault.certs:/etc/nginx/certs:ro
environment:
HTTPS_METHOD: nohttp
https-only:
image: web
expose:
- "82"
environment:
WEB_PORTS: "82"
VIRTUAL_HOST: https-only.nginx-proxy.test

View File

@ -0,0 +1,18 @@
version: "2"
services:
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTPS_METHOD: redirect
http-only:
image: web
expose:
- "83"
environment:
WEB_PORTS: "83"
HTTPS_METHOD: nohttps
VIRTUAL_HOST: http-only.nginx-proxy.test

View File

@ -0,0 +1,17 @@
version: "2"
services:
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTPS_METHOD: nohttps
http-only:
image: web
expose:
- "83"
environment:
WEB_PORTS: "83"
VIRTUAL_HOST: http-only.nginx-proxy.test

View File

@ -0,0 +1,70 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4096 (0x1000)
Signature Algorithm: sha256WithRSAEncryption
Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld
Validity
Not Before: Feb 9 04:02:23 2023 GMT
Not After : Jun 27 04:02:23 2050 GMT
Subject: CN=*.nginx-proxy.test
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:db:bd:54:de:01:7e:82:4e:c0:f1:5d:12:fd:3a:
fb:21:19:4d:44:25:47:ea:ad:d8:11:5c:d1:65:88:
af:49:fc:8e:4b:c3:01:c1:0d:6d:22:67:bd:31:66:
9f:4a:50:17:9e:47:b3:3b:b3:21:73:1f:81:55:73:
52:47:9b:fb:85:6b:e8:d8:09:cc:e1:7d:1c:14:03:
1c:ae:84:b4:5b:e5:e5:c7:71:fc:1f:74:33:4f:ae:
f7:8d:21:1f:55:8d:93:c7:84:4d:93:01:a1:1c:37:
ae:85:5c:70:2c:21:ec:87:35:c3:86:d3:b3:0f:9a:
b0:9d:8a:cd:0e:49:e8:99:c5:4c:50:bd:a8:6e:a7:
01:3e:a7:dc:cf:c3:48:37:8e:c6:8a:89:b0:41:01:
58:ee:45:94:fa:90:eb:df:c8:0e:b7:dd:79:75:13:
1e:07:69:ee:54:47:92:18:9d:e0:a9:ee:4e:22:d1:
f4:a2:4d:a1:47:ed:9b:35:2a:70:cc:66:fb:3e:f0:
49:f7:ee:62:2a:27:a1:d3:52:7b:ff:e9:12:d9:5b:
6b:f6:18:bf:9c:9d:5f:00:29:d2:54:b5:f8:a4:a2:
9b:3f:fe:a6:ed:14:ae:a0:fe:13:33:18:33:17:a9:
8b:fe:fc:75:65:0c:fb:c2:d1:1e:81:ca:43:89:bd:
78:dd
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:*.nginx-proxy.test
Signature Algorithm: sha256WithRSAEncryption
43:a7:1f:4b:ec:ff:1d:70:c7:f8:6e:eb:fd:15:25:27:b2:54:
c7:92:cf:ed:51:31:28:56:76:5c:da:8b:17:31:55:8c:a1:c2:
37:95:27:7b:b6:58:e5:92:ef:1e:fe:35:f1:44:ca:c7:1b:7b:
75:bf:e1:91:61:6d:8a:6f:35:8b:73:f4:d9:08:60:25:07:7a:
3e:c2:79:e7:ae:b4:70:cc:8a:30:cb:80:aa:47:1a:40:82:00:
a0:5e:01:67:d1:95:21:3c:b1:52:7d:f5:87:b6:43:41:df:b2:
a7:ee:3b:73:17:c4:19:2c:6b:7b:3c:26:9e:4c:00:e3:e8:07:
f2:e1:a1:31:79:57:be:b6:b1:a7:93:70:4e:e1:7d:bf:08:c5:
e7:a0:de:7d:82:20:24:f7:b0:3f:c2:94:36:88:ef:7b:7d:c0:
7f:8a:78:a1:8e:56:42:82:ce:82:e6:8e:3d:1b:b7:ca:dd:a9:
a8:e6:f9:a3:f4:4a:a4:a0:9c:15:6f:44:8c:48:20:e5:85:ed:
6f:85:22:41:1d:1f:fe:58:e5:43:ad:f2:c4:10:5a:10:ed:36:
10:98:ad:73:97:6a:e0:19:18:d6:32:26:03:3d:dd:84:5c:2e:
97:ca:a2:f5:63:f2:7a:16:f1:55:ca:d2:a1:54:09:8a:bb:23:
f0:53:36:51
-----BEGIN CERTIFICATE-----
MIIC+zCCAeOgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp
bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs
ZDAgFw0yMzAyMDkwNDAyMjNaGA8yMDUwMDYyNzA0MDIyM1owHTEbMBkGA1UEAwwS
Ki5uZ2lueC1wcm94eS50ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEA271U3gF+gk7A8V0S/Tr7IRlNRCVH6q3YEVzRZYivSfyOS8MBwQ1tIme9MWaf
SlAXnkezO7Mhcx+BVXNSR5v7hWvo2AnM4X0cFAMcroS0W+Xlx3H8H3QzT673jSEf
VY2Tx4RNkwGhHDeuhVxwLCHshzXDhtOzD5qwnYrNDknomcVMUL2obqcBPqfcz8NI
N47GiomwQQFY7kWU+pDr38gOt915dRMeB2nuVEeSGJ3gqe5OItH0ok2hR+2bNSpw
zGb7PvBJ9+5iKieh01J7/+kS2Vtr9hi/nJ1fACnSVLX4pKKbP/6m7RSuoP4TMxgz
F6mL/vx1ZQz7wtEegcpDib143QIDAQABoyEwHzAdBgNVHREEFjAUghIqLm5naW54
LXByb3h5LnRlc3QwDQYJKoZIhvcNAQELBQADggEBAEOnH0vs/x1wx/hu6/0VJSey
VMeSz+1RMShWdlzaixcxVYyhwjeVJ3u2WOWS7x7+NfFEyscbe3W/4ZFhbYpvNYtz
9NkIYCUHej7CeeeutHDMijDLgKpHGkCCAKBeAWfRlSE8sVJ99Ye2Q0HfsqfuO3MX
xBksa3s8Jp5MAOPoB/LhoTF5V762saeTcE7hfb8Ixeeg3n2CICT3sD/ClDaI73t9
wH+KeKGOVkKCzoLmjj0bt8rdqajm+aP0SqSgnBVvRIxIIOWF7W+FIkEdH/5Y5UOt
8sQQWhDtNhCYrXOXauAZGNYyJgM93YRcLpfKovVj8noW8VXK0qFUCYq7I/BTNlE=
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA271U3gF+gk7A8V0S/Tr7IRlNRCVH6q3YEVzRZYivSfyOS8MB
wQ1tIme9MWafSlAXnkezO7Mhcx+BVXNSR5v7hWvo2AnM4X0cFAMcroS0W+Xlx3H8
H3QzT673jSEfVY2Tx4RNkwGhHDeuhVxwLCHshzXDhtOzD5qwnYrNDknomcVMUL2o
bqcBPqfcz8NIN47GiomwQQFY7kWU+pDr38gOt915dRMeB2nuVEeSGJ3gqe5OItH0
ok2hR+2bNSpwzGb7PvBJ9+5iKieh01J7/+kS2Vtr9hi/nJ1fACnSVLX4pKKbP/6m
7RSuoP4TMxgzF6mL/vx1ZQz7wtEegcpDib143QIDAQABAoIBAGUd9QXMTjkMoIDx
QaHCGHocuI+ZUETQBtPGkJ1WjsNPMvPuIsqBsSzZ7Bflj3uU66lseTAJuGTPpKZ7
0Ose/llhVN7Fc8B34AndfL9aVdzMKDblXw3iXRJYA5awHUkzQ0PWwBPb9hWUEf1Q
klXcrolx1i4fEREnMArvKnlezWikpXcqDYRcmUfEvVozaq75heavHpOcOq2dg7vo
N/gcJmfG4aDOhrZC1f22u5cNePvbVj+DdXOUHMEEfXOFbxk97VhmcIaH75ugvVh4
EMMg87mcGLZiqPO5k6SYcuGyquc32Tf5sK80mpt/+SAEHCvSmUt9c1ynQrS9IhNp
OGfZhQkCgYEA+LonwScVGVEgHg1A9E7BKhIrgUOlwWNM43s+o8Uuz1T72VUVZ6N/
aO0+2Panw1qjsb0CUC2zft3zZTiZd81gWRmBYQ0R9dHWyWHbJlOv8rAmJ+60Gr2a
UVTLHEdZKx6svSDNhL0HfxxfWwePgHB4NVa2RUA3KQ5y5C96EXb8WbsCgYEA4iow
nIIbRZ9ILDz1oThxE+dFifKWXWFOwa58EFBY+/y34itL7kXRu2+4ZIltwL0L8m5j
GUALUabuoOASKg4CFBhCvoAAlWZRr6L6EOecrElUnrefUrKuCWPCVo3MnCMuLXDp
p1mEGIwEZBCY+jrSBMrRCawsMRkcymLJhEBFYkcCgYB6xIey0vObF2ve6XPSIr09
YtKObzF1jun4rnBwrXc5Zx0YXOK/0PemdtO6i6SqzCZYKI7nvGcIi80DfThi5cBU
uj4eBTGEQBrgM6jT9iK2izOKKkxDlqqA0nWec6kTm4Rvpa1Lg3Ibz4lRiR3Pq7Pp
v+8fp16SqUsUTkrWLADK2QKBgCRIhHf3X4yx2xBNz1JIDcwVpFBXPMxKWio0Ze7w
FPaIOq/sJkhZpyYc7EYkzhjHu2zvTLK2VZqJ32qrx/47NRYoNjz9qBpPyfcVfGzN
25LASPUVnFfWFpmnCXx9T0AVXMkpfjK857ZQcDvldcVfPmZKa3LTzlsqHjZR1uaC
sR7tAoGBANBfInPZVZRJfqqkPN1K8j4P7uCGjTIBmys/vxoilh1d0scTgZrdqt92
EKi/3UsJW2ndqQNDLbvi5kcW8a6UU3UB1LLvpyQ5zuS81x3+kKfv+5cDM8rt/M4A
MXnJA5eDZZ4SlHFzdblUv/MZdT+1x0tivMn3zFKNNj2SmaSGkQ0m
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,71 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4096 (0x1000)
Signature Algorithm: sha256WithRSAEncryption
Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld
Validity
Not Before: Feb 7 21:54:16 2023 GMT
Not After : Jun 25 21:54:16 2050 GMT
Subject: CN=http-only.nginx-proxy.test
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:b4:62:61:07:54:2e:6d:55:83:2d:24:b7:e2:15:
34:13:bd:79:21:e9:10:75:3f:4c:f8:ba:60:29:87:
e5:8e:2a:1e:fd:33:51:5a:8a:3a:6f:60:ff:24:f1:
1b:27:30:8c:ac:43:04:b7:79:cb:7a:ec:c6:08:a4:
a0:15:b0:0f:ee:6b:15:84:24:11:bc:85:2b:48:06:
04:0a:58:bb:8c:e8:4d:48:f5:06:c5:91:fe:5d:99:
0a:29:31:8a:f1:9b:0c:e0:39:75:a1:06:9b:d4:f5:
06:74:8f:46:5e:64:ba:2f:d0:3d:7c:3d:30:03:e9:
7c:35:17:69:04:f6:2e:29:d4:93:d6:d6:d2:6c:04:
38:06:21:06:05:30:8a:b9:9d:05:8d:12:6e:48:39:
bb:f6:93:4f:ba:a5:84:c7:96:2f:be:92:25:e9:d0:
95:2a:d9:23:8a:b3:28:0b:b6:19:1c:3b:be:a2:91:
70:44:a8:77:18:94:4b:df:61:f4:5c:c9:78:76:34:
b5:87:0f:c0:92:04:26:b6:ca:62:cd:9b:5d:eb:bf:
10:ac:df:af:72:5f:af:09:38:b1:dc:e1:3d:13:db:
a0:ac:b7:2e:ca:39:5c:4c:f1:1e:81:a8:b4:44:a2:
72:d5:3b:c0:71:cc:dc:16:0d:fa:38:96:44:b3:00:
d6:65
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:http-only.nginx-proxy.test
Signature Algorithm: sha256WithRSAEncryption
3b:54:95:48:4d:f6:93:38:42:40:02:ab:b7:17:3b:50:3b:ca:
c7:12:69:b0:da:cb:d7:3e:0e:1f:bf:a2:59:c7:fe:c2:5c:43:
84:92:b9:3a:be:8f:7e:2e:81:3c:ed:f3:a9:77:21:c2:35:f1:
da:cf:3a:1e:e2:ee:a2:ce:72:55:97:87:0e:ad:59:61:f7:75:
46:c0:2b:d4:88:b7:36:97:11:fb:5e:28:89:e9:2a:92:f1:15:
f1:43:8e:c1:38:85:8d:3a:26:7d:25:72:93:17:96:8d:5a:ed:
e8:73:3a:d5:8d:80:f2:af:38:84:ff:85:2e:d1:36:7d:2e:e1:
f0:2c:d8:15:5f:fc:c5:70:5d:25:6a:22:f3:2a:cd:0f:25:ad:
d4:93:d3:9a:3e:50:bc:da:a5:6c:86:ea:1d:d9:b9:c5:90:db:
f5:02:c8:c9:77:5c:ef:77:fe:74:60:41:33:d9:3c:a2:e1:73:
aa:14:18:5d:36:58:c8:41:63:4c:59:0e:4b:3d:c5:65:5a:01:
b0:16:50:0f:d0:4f:0d:ca:97:f6:11:47:06:6b:b1:ae:bb:26:
30:34:8b:7a:91:5d:8a:22:c7:f9:05:0d:bb:a5:b7:60:c0:20:
ce:d0:0e:c0:66:b3:e7:c4:61:ec:c5:40:e6:52:11:41:c3:11:
18:04:c7:1e
-----BEGIN CERTIFICATE-----
MIIDCzCCAfOgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp
bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs
ZDAgFw0yMzAyMDcyMTU0MTZaGA8yMDUwMDYyNTIxNTQxNlowJTEjMCEGA1UEAwwa
aHR0cC1vbmx5Lm5naW54LXByb3h5LnRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQC0YmEHVC5tVYMtJLfiFTQTvXkh6RB1P0z4umAph+WOKh79M1Fa
ijpvYP8k8RsnMIysQwS3ect67MYIpKAVsA/uaxWEJBG8hStIBgQKWLuM6E1I9QbF
kf5dmQopMYrxmwzgOXWhBpvU9QZ0j0ZeZLov0D18PTAD6Xw1F2kE9i4p1JPW1tJs
BDgGIQYFMIq5nQWNEm5IObv2k0+6pYTHli++kiXp0JUq2SOKsygLthkcO76ikXBE
qHcYlEvfYfRcyXh2NLWHD8CSBCa2ymLNm13rvxCs369yX68JOLHc4T0T26Csty7K
OVxM8R6BqLREonLVO8BxzNwWDfo4lkSzANZlAgMBAAGjKTAnMCUGA1UdEQQeMByC
Gmh0dHAtb25seS5uZ2lueC1wcm94eS50ZXN0MA0GCSqGSIb3DQEBCwUAA4IBAQA7
VJVITfaTOEJAAqu3FztQO8rHEmmw2svXPg4fv6JZx/7CXEOEkrk6vo9+LoE87fOp
dyHCNfHazzoe4u6iznJVl4cOrVlh93VGwCvUiLc2lxH7XiiJ6SqS8RXxQ47BOIWN
OiZ9JXKTF5aNWu3oczrVjYDyrziE/4Uu0TZ9LuHwLNgVX/zFcF0laiLzKs0PJa3U
k9OaPlC82qVshuod2bnFkNv1AsjJd1zvd/50YEEz2Tyi4XOqFBhdNljIQWNMWQ5L
PcVlWgGwFlAP0E8Nypf2EUcGa7GuuyYwNIt6kV2KIsf5BQ27pbdgwCDO0A7AZrPn
xGHsxUDmUhFBwxEYBMce
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAtGJhB1QubVWDLSS34hU0E715IekQdT9M+LpgKYfljioe/TNR
Woo6b2D/JPEbJzCMrEMEt3nLeuzGCKSgFbAP7msVhCQRvIUrSAYECli7jOhNSPUG
xZH+XZkKKTGK8ZsM4Dl1oQab1PUGdI9GXmS6L9A9fD0wA+l8NRdpBPYuKdST1tbS
bAQ4BiEGBTCKuZ0FjRJuSDm79pNPuqWEx5YvvpIl6dCVKtkjirMoC7YZHDu+opFw
RKh3GJRL32H0XMl4djS1hw/AkgQmtspizZtd678QrN+vcl+vCTix3OE9E9ugrLcu
yjlcTPEegai0RKJy1TvAcczcFg36OJZEswDWZQIDAQABAoIBAAfDA/HQyX6i41YZ
8l+kEe2XhZLT+IVTB/jb7C9dTZ9kaJj0kFeZAxKv1cq9JTH2gNcYuyc58muDrLHK
g6jrPoQ/z1k0RB8ci9Q5jgrz7n4NsOWmxXfS5GMaprlHDHeA+HjdgBZBtorfUDvL
vndpVimgiETETUCd115hd39jKHFcRcdV6yCix7ObywK3dMgLVpagCcnlyCWffS/r
nhhMfJ+VstW0nUtfZ7JEYwT6Cg7lLAVtDkqPX8zGjJiRwUKH808bUyqEw1y5Cc8U
U5hbmMgPWfXsKxsEC6FSVHBG9ZX2jymOMQXijLFcBSuWvADHmyU+ZxXcbtd1rv4E
cGFj3wECgYEA5cNrr5WjrpEin6MYYVWxiQ+xEWPU2R17eApagrDRLM41JJpv7a5m
TYuZRfIxb59CBPi718Gi168P3T2KMvo2/BTh9Lq5ZBYHx3aDqW2QvMFn7/tgamj8
0DBxccd2QWfGIBrT1rAF7lD8TC86wtDDVKrvhucRSEXVKF/jWFFRGfUCgYEAyPt6
48khr7sfNMVdkDLjQjZVV6H7ZUMoSn0FGybgKWxW+b0XCBPObUQWIpyCNTRr1+4A
1TAUS+F/OVVfwnLNgemeE2wd6CaduxwiK1U4pHbyXCElH1ifonHWV3MoXOefYsiY
q5z2jfJzUi0JZVUKsveu9rQsFLsc//1s/I5T1LECgYEAldY6fNg2VVp63OZsuNU8
oSiljbSwEyMh6Oe/nOkYkIKtr4AzrCoGt11piG7ohGW0lS9suMijnMqiquI+JP5+
KyinLoUy761aR17nf+9e62mpkZw6hUqQTGi7Irs0SHUXhMpaCfDi/Ua9MiW+yVuB
ds6+xBgeciZwWxMlXOwy2p0CgYEAm+YWiSK3Mq0fo7uEvBn9Fps2z+ciLoZNdppL
n6gkMX2MaeQ3PVi/wxoRYX+tsL+c973yf2vwEnw0R7Dlutt6dc9VgxNWj4GE0GMe
Tiao7Uom7Tf4p7wC9+r9rI/zOz2f8OxRIK18wtbShWfR5fx1dCWUXmGb3+jUse1O
4Qk2FcECgYAvSvGFoJb8tuHFEYYHBbjficmvTUsrTE+EhxPqWKFhKfF19fFFIupy
XBCrN6nwrh+/YMxZXeIRbbTTf814cOO7PjLeNhnfhJZkaJq1HzbYe3bOurna3qrm
Ra3xiM8Ld2PyGnZPXf8+AWhMhuPkLX1KFVTCAxwCpmTZCHtiGCmXMA==
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,71 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4096 (0x1000)
Signature Algorithm: sha256WithRSAEncryption
Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld
Validity
Not Before: Feb 7 21:53:19 2023 GMT
Not After : Jun 25 21:53:19 2050 GMT
Subject: CN=https-and-http.nginx-proxy.test
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:b7:97:85:d1:7f:6b:50:29:f3:87:b7:4e:f5:25:
40:6a:d8:fa:a1:63:3c:4a:2e:68:4a:c6:8b:38:df:
07:81:d0:08:9d:fc:17:f5:37:28:7f:31:e6:f3:81:
28:4e:22:b6:bd:a2:4e:f2:2f:e5:0f:dd:55:3c:e1:
04:84:4c:45:1b:1a:ae:b7:f0:2a:da:43:05:71:91:
92:b8:d1:49:fe:80:0a:53:b9:66:da:54:60:9a:fc:
e1:b2:e8:28:48:7f:96:94:3c:92:a3:b2:37:f6:7a:
c2:de:0b:12:f0:ae:4e:92:fe:2d:c1:b2:95:28:1f:
88:8d:79:99:81:19:ae:22:a4:95:f5:9f:db:25:8e:
1d:cf:43:cd:6f:85:93:5f:79:ee:f8:f3:d4:82:e1:
e9:4d:c9:ad:ae:5b:92:43:3a:3c:71:51:70:f7:3e:
bd:1b:24:52:6a:a3:cf:54:72:57:ed:fe:72:ea:96:
9b:5a:02:02:a7:df:85:b7:68:ae:1e:07:77:9f:59:
a5:a0:8b:28:c2:c8:b7:bb:8a:42:50:df:05:73:bf:
9c:55:13:b5:82:79:77:40:57:a4:8f:88:a5:71:50:
d7:70:b0:4d:0c:d9:86:b3:9b:db:8a:20:bd:19:68:
10:52:2d:53:ba:0e:2e:1c:ad:80:54:bb:b6:c9:ab:
11:39
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:https-and-http.nginx-proxy.test
Signature Algorithm: sha256WithRSAEncryption
2c:f3:e5:47:3f:8e:5a:28:b1:df:e5:95:50:85:6f:27:2f:a6:
8d:f1:5e:cf:df:e2:52:66:97:61:36:59:81:26:25:19:99:c9:
93:e5:85:cb:ca:69:af:4b:21:a3:d2:7a:bf:b5:5e:2d:42:fb:
99:f8:22:58:e5:bf:79:b8:8a:74:7e:c6:94:14:d9:f2:27:63:
b6:e5:74:21:5b:59:fb:f6:c8:a9:28:fb:60:f7:5e:bd:c2:e6:
74:24:14:96:61:95:6c:c2:66:b4:52:25:a1:85:5a:97:e5:68:
5c:62:cf:69:3b:b0:a9:56:d8:e3:5f:74:dc:84:18:d5:3e:4f:
c9:35:39:26:88:dc:9b:80:d9:40:e1:4f:09:27:8d:d2:89:55:
30:91:02:86:35:04:95:1e:1d:58:14:5b:c6:e0:2e:a7:bf:a8:
f6:2b:76:8a:4e:71:79:bc:c0:04:cd:db:81:73:46:ce:68:ed:
25:b0:0e:42:8d:96:64:77:3b:f4:9d:1a:c9:f6:78:4c:56:4f:
92:17:29:3d:80:50:71:77:4b:a8:29:c2:12:fc:ad:0a:37:81:
38:4c:fb:54:99:4d:12:5f:98:dc:d1:a9:7b:08:45:c4:6f:7e:
fe:00:e0:db:79:fe:d1:28:e3:8e:82:d1:fb:bc:0a:c4:42:93:
c9:5e:eb:ba
-----BEGIN CERTIFICATE-----
MIIDFTCCAf2gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp
bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs
ZDAgFw0yMzAyMDcyMTUzMTlaGA8yMDUwMDYyNTIxNTMxOVowKjEoMCYGA1UEAwwf
aHR0cHMtYW5kLWh0dHAubmdpbngtcHJveHkudGVzdDCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBALeXhdF/a1Ap84e3TvUlQGrY+qFjPEouaErGizjfB4HQ
CJ38F/U3KH8x5vOBKE4itr2iTvIv5Q/dVTzhBIRMRRsarrfwKtpDBXGRkrjRSf6A
ClO5ZtpUYJr84bLoKEh/lpQ8kqOyN/Z6wt4LEvCuTpL+LcGylSgfiI15mYEZriKk
lfWf2yWOHc9DzW+Fk1957vjz1ILh6U3Jra5bkkM6PHFRcPc+vRskUmqjz1RyV+3+
cuqWm1oCAqffhbdorh4Hd59ZpaCLKMLIt7uKQlDfBXO/nFUTtYJ5d0BXpI+IpXFQ
13CwTQzZhrOb24ogvRloEFItU7oOLhytgFS7tsmrETkCAwEAAaMuMCwwKgYDVR0R
BCMwIYIfaHR0cHMtYW5kLWh0dHAubmdpbngtcHJveHkudGVzdDANBgkqhkiG9w0B
AQsFAAOCAQEALPPlRz+OWiix3+WVUIVvJy+mjfFez9/iUmaXYTZZgSYlGZnJk+WF
y8ppr0sho9J6v7VeLUL7mfgiWOW/ebiKdH7GlBTZ8idjtuV0IVtZ+/bIqSj7YPde
vcLmdCQUlmGVbMJmtFIloYVal+VoXGLPaTuwqVbY41903IQY1T5PyTU5Jojcm4DZ
QOFPCSeN0olVMJEChjUElR4dWBRbxuAup7+o9it2ik5xebzABM3bgXNGzmjtJbAO
Qo2WZHc79J0ayfZ4TFZPkhcpPYBQcXdLqCnCEvytCjeBOEz7VJlNEl+Y3NGpewhF
xG9+/gDg23n+0SjjjoLR+7wKxEKTyV7rug==
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAt5eF0X9rUCnzh7dO9SVAatj6oWM8Si5oSsaLON8HgdAInfwX
9TcofzHm84EoTiK2vaJO8i/lD91VPOEEhExFGxqut/Aq2kMFcZGSuNFJ/oAKU7lm
2lRgmvzhsugoSH+WlDySo7I39nrC3gsS8K5Okv4twbKVKB+IjXmZgRmuIqSV9Z/b
JY4dz0PNb4WTX3nu+PPUguHpTcmtrluSQzo8cVFw9z69GyRSaqPPVHJX7f5y6pab
WgICp9+Ft2iuHgd3n1mloIsowsi3u4pCUN8Fc7+cVRO1gnl3QFekj4ilcVDXcLBN
DNmGs5vbiiC9GWgQUi1Tug4uHK2AVLu2yasROQIDAQABAoIBACT4KSVHoEdzOyvw
GME6sB8T9Fw9TG2vrKaqFmzsVGmqh6Gwmu5xHgGG/fe44XHigaPsJDOWu2yXaEur
ECrH5P6RP++gODDdYCI/ayk2U80g4XN8mR6L8Swkkhphr4Lx1lOhYvH9uFE05Tqr
RjQbFY16C6K+oFSFDQ1YGDYsAqnM3RD7PH+lHpo8UN1TO/vogdSQEpMYZDwLAYnW
uD5G3c0u2PsGu9YLuz2p8hcs3chh+cqKJWXOeW0JLrNGx1bqeQWkn6nXRDdRYi9V
cJlTgDqGuF54bieSyq9ABDZQP4Ol+moYKDoIz5PwurNjcYSklrT1tw0gqHZoQK1L
fDjw3QECgYEA7QMRU1AFKTvO7/8WLHLN5BT63n31wm0e9PYpz/XVLWEfxBcp9Xmf
xAIhXZ/U9P4dfNqxTjN9mVGzCHh5KfDJnUFqOXFy/zvfMeRzJf6dJo6/4OX9Bijr
Tgd454vyGXYQP2t+F14UAwl6vlGOAjttiP5qY5Ef1gllBEeIPe9Ts9kCgYEAxkzZ
pq4HJ/5/iDquMEHXNXzpNPavSvgxQdl1ILvJ49LJImmQFBCP9PqiOTIfePz1OqUI
C4baFuc0FEDJ3x9CUNmMY1lEi2ZUq2agPSXaQNsMcKtEJH8SoJlJIRpkQA7unX09
zb4dam6g79OaGmb8scePuezXMLv1Ee6WWtXbzGECgYEA6PYn9Gzl9cacu9dOUzgw
2ewpPcIvawDY+cxwAsHO3MDneVWPX4JBoGa7pwvwRTL1hwBqYMRJwwbD5CKObcQI
V/KxV28Eqo2N77tt1z2x9/E99u/4yTI1P0gm9ejfeVlL1RpyIMPPBcEujZ0Z6WXC
X3I63k0KLtajHRa2erIf4tkCgYAfunAgwTuX5JqXO3xfcEl033WY6deGUUvgU2Dw
Sdu1viY8gVNyQmwmMGwAZsquWxsJtRoibgM7IucsTml+b8v2j7hstP3IqCjn+9Wr
swDG28WTyXNvu31JgP04dLaRoVIAlOdsofym6OiLNvozO0M3VsziXMjZnVlK8zfP
dORkQQKBgQDXAJEJPygxVA+bF104dzCMWGmU7K8ShEWC5eOdKK4KWf9bNDpY6M6c
i6zga/xBbj7e3Bxqprpp8Wy2gIsnYiVo4V9EQethbLdomPxOpBMNMARw81rL1CpO
jbHB7bIDcKs2tQoZEXUW86ZxC8sdaDaWTJTfUO0RpJow6ZO3yvxVIQ==
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,71 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4096 (0x1000)
Signature Algorithm: sha256WithRSAEncryption
Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld
Validity
Not Before: Feb 7 21:53:49 2023 GMT
Not After : Jun 25 21:53:49 2050 GMT
Subject: CN=https-only.nginx-proxy.test
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:d9:87:48:02:85:f4:5f:0d:90:7e:4c:4f:13:89:
41:ca:41:15:c2:6f:fd:a8:c7:17:83:c6:dd:8c:fe:
19:a4:b2:6b:0b:35:4f:b4:3d:7c:40:0a:04:33:2a:
fd:10:72:f7:63:63:99:5b:3d:ec:78:ee:c6:4d:c8:
0e:4c:be:f2:3f:e3:02:74:57:9a:c1:fe:15:95:63:
4e:e7:2c:eb:70:f2:6b:c8:ba:01:a2:ca:a1:c7:76:
ff:38:e4:c2:b0:66:fc:85:d2:af:0f:22:81:d4:82:
eb:d5:b0:e6:69:14:37:dd:8d:ad:29:ce:93:68:5a:
ce:f4:77:76:6f:78:13:b6:c8:2f:fe:e0:b6:7e:fb:
29:16:be:e2:f5:45:3b:39:5b:52:dc:26:b7:ca:0c:
b6:1c:fc:a8:38:0b:dd:c1:f4:04:9b:2d:38:c9:a5:
2d:3e:f1:42:88:53:a2:3b:17:cf:d5:3c:2b:d6:6a:
7f:6f:05:8d:c5:b7:5d:64:1e:83:1b:e7:ec:80:3d:
6d:34:c1:66:b2:e6:5d:d9:a7:6e:46:75:14:bf:10:
16:c5:fc:47:8e:63:fa:e5:b4:bd:f2:b9:e0:cb:ea:
75:f9:68:ee:7d:8f:ea:8f:1a:9f:34:27:7a:4a:9f:
85:fd:3e:17:a7:96:c3:d0:4e:50:a2:a2:e0:45:92:
d0:b5
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:https-only.nginx-proxy.test
Signature Algorithm: sha256WithRSAEncryption
8a:52:46:42:a9:74:18:6a:52:90:ef:a4:e9:c5:54:d5:97:3a:
ff:8b:c2:76:4f:9e:47:aa:e1:ea:e5:b9:af:9d:33:e3:85:17:
54:7d:32:bd:ac:90:3f:5c:d2:a1:42:17:52:2b:b1:83:e5:c3:
bf:81:f0:e7:38:e2:88:67:7b:d8:59:fe:f9:94:99:ba:be:f4:
3c:24:b2:c7:9e:f0:98:21:c6:2d:c2:e8:f3:67:bd:62:00:aa:
ce:34:fa:b4:53:6d:c1:09:5e:55:bd:43:aa:86:c6:f8:c5:83:
46:3a:49:12:a2:ec:30:36:0c:99:44:74:09:9d:cc:4b:98:1f:
7e:c9:9b:68:a0:f8:1e:00:14:d0:da:2a:bf:c8:ca:a8:1c:10:
b5:68:a2:f1:41:93:0c:f3:3f:c0:c6:53:3c:8d:a7:dd:a5:7b:
35:cc:44:e0:5b:6d:c5:cb:33:6f:c1:43:7e:06:df:21:99:11:
b3:91:41:b4:5e:f0:37:1e:8e:e5:73:85:dc:4a:21:d5:41:f9:
4e:b8:f5:ed:21:93:09:91:c2:8c:6b:04:a4:84:ab:3a:fe:35:
64:fa:6b:a7:8d:40:a6:64:89:30:84:ac:28:99:5a:01:79:77:
c0:df:88:da:a9:75:5f:c4:51:ae:a8:45:7b:d2:e1:a2:81:29:
60:cd:7b:cd
-----BEGIN CERTIFICATE-----
MIIDDTCCAfWgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp
bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs
ZDAgFw0yMzAyMDcyMTUzNDlaGA8yMDUwMDYyNTIxNTM0OVowJjEkMCIGA1UEAwwb
aHR0cHMtb25seS5uZ2lueC1wcm94eS50ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEA2YdIAoX0Xw2QfkxPE4lBykEVwm/9qMcXg8bdjP4ZpLJrCzVP
tD18QAoEMyr9EHL3Y2OZWz3seO7GTcgOTL7yP+MCdFeawf4VlWNO5yzrcPJryLoB
osqhx3b/OOTCsGb8hdKvDyKB1ILr1bDmaRQ33Y2tKc6TaFrO9Hd2b3gTtsgv/uC2
fvspFr7i9UU7OVtS3Ca3ygy2HPyoOAvdwfQEmy04yaUtPvFCiFOiOxfP1Twr1mp/
bwWNxbddZB6DG+fsgD1tNMFmsuZd2aduRnUUvxAWxfxHjmP65bS98rngy+p1+Wju
fY/qjxqfNCd6Sp+F/T4Xp5bD0E5QoqLgRZLQtQIDAQABoyowKDAmBgNVHREEHzAd
ghtodHRwcy1vbmx5Lm5naW54LXByb3h5LnRlc3QwDQYJKoZIhvcNAQELBQADggEB
AIpSRkKpdBhqUpDvpOnFVNWXOv+LwnZPnkeq4erlua+dM+OFF1R9Mr2skD9c0qFC
F1IrsYPlw7+B8Oc44ohne9hZ/vmUmbq+9Dwkssee8Jghxi3C6PNnvWIAqs40+rRT
bcEJXlW9Q6qGxvjFg0Y6SRKi7DA2DJlEdAmdzEuYH37Jm2ig+B4AFNDaKr/Iyqgc
ELVoovFBkwzzP8DGUzyNp92lezXMROBbbcXLM2/BQ34G3yGZEbORQbRe8DcejuVz
hdxKIdVB+U649e0hkwmRwoxrBKSEqzr+NWT6a6eNQKZkiTCErCiZWgF5d8DfiNqp
dV/EUa6oRXvS4aKBKWDNe80=
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA2YdIAoX0Xw2QfkxPE4lBykEVwm/9qMcXg8bdjP4ZpLJrCzVP
tD18QAoEMyr9EHL3Y2OZWz3seO7GTcgOTL7yP+MCdFeawf4VlWNO5yzrcPJryLoB
osqhx3b/OOTCsGb8hdKvDyKB1ILr1bDmaRQ33Y2tKc6TaFrO9Hd2b3gTtsgv/uC2
fvspFr7i9UU7OVtS3Ca3ygy2HPyoOAvdwfQEmy04yaUtPvFCiFOiOxfP1Twr1mp/
bwWNxbddZB6DG+fsgD1tNMFmsuZd2aduRnUUvxAWxfxHjmP65bS98rngy+p1+Wju
fY/qjxqfNCd6Sp+F/T4Xp5bD0E5QoqLgRZLQtQIDAQABAoIBAAWs//YA5MVuJy0E
dLO/yxWp6RVvsqCqwTRRBgrdvnGLrjtWosPDLvDE0iM7peq99TKEsMWusfLd2BLD
e4wJF20PUUsT1hflt050juR9SY9i4+kS4WQMAXig5DvpzCKqLUCYpLSyY8zVta2X
tgtb2bFQNwp2N2ZrqCa8zzxNV8ZXGoW+ZlvBJEDtBwt1DCDhY39/pqHfIhFl4Vwk
YhhbVjID145D1j/fP6vLceM2YA4uRmF1itj1iQ6YNNpXRspUGE4DXdqR6HcbduiX
trZjmdtKXY8mJg6jyLZxYbjFlKV/LvqKRYF3Jb9K0vdd4juBdZoy7DQzoLhcnzui
pEnPLakCgYEA9tN6KdQGKGBXGuF+ZqhXfB/XSkKUf8o/5j62cbu11ZIJ+iEBx+d6
lQAxTz5hHUL6a3c5qiM+AWBxYuFD6oqptIlTlBfIXI978neDNvEWWffivPvQLbt9
o9ohOirfK1iGPvtrpAwjv5ylE5SiTmJ/6wDvQWjNGAnJ3aaxkesJUSMCgYEA4Z0K
UHZVtnKLtzzIY7KfLbuKF/fJEDfMNr4Wgl6ny21vqO9kJGmA7SaoNdhx8RDcKmeV
/Vey4ug6YlOG48eapKLTthdRz5mx+jIkUfdOhj81m28xm/OPTqCrviTHCNOHeYDy
NKAIlJMo2z0vTKJn5eP6CsYmDWLpHQNyXY5qcEcCgYAzDBWt5O3JF/Or2Yr8zEAb
qbIq544yx69jfQDakMnQe72Yf48Quuz9N+b6zpnjJWEJLMU+TL+cJUgN/SzAqyDh
96zTaf/ENOCbiuAWUtIelUfNcf7iFm6rnodUsl0pZ8uL5w+iA+i4zjrNy+WtdG2k
OrNAwd345L1dHAaJeSSaJQKBgQCUnF3r7Fa/TCpt87LHwSQK+sqWyRf+/9IbiRDI
pVL/s8FmVPHw7jIHhHwuo7lCImnz4LGy5C6oOnIizIRAy/04Ty0Hd8ri5YmPlbHI
8A8gbMiB7zeNU1zlXP5jzFPyo2tMhLyGH5gnTdwOtfnPD/dCPe45ZJYyISIOg3O0
3peMBwKBgH20cskAOCNclfoG+Nis52h8FqmDlflJ8waUarvk26JhO1e009kOytw8
x/qSuttpGtTG+4fdc2wJvFNczr4h9ZlftBdgZXj8PKgRpcIe8q97Xg8PUj+Xfu/t
vD/QV+tVcGoAMsQq4NeFxiTbPfwVyXdYFT1XVCu6JEdLL+gpWh5W
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,42 @@
version: "2"
services:
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./withdefault.certs:/etc/nginx/certs:ro
https-and-http:
image: web
expose:
- "81"
environment:
WEB_PORTS: "81"
VIRTUAL_HOST: https-and-http.nginx-proxy.test
https-only:
image: web
expose:
- "82"
environment:
WEB_PORTS: "82"
VIRTUAL_HOST: https-only.nginx-proxy.test
HTTPS_METHOD: nohttp
http-only:
image: web
expose:
- "83"
environment:
WEB_PORTS: "83"
VIRTUAL_HOST: http-only.nginx-proxy.test
HTTPS_METHOD: nohttps
missing-cert:
image: web
expose:
- "84"
environment:
WEB_PORTS: "84"
VIRTUAL_HOST: missing-cert.nginx-proxy.test

104
test/test_fallback.py Normal file
View File

@ -0,0 +1,104 @@
import os.path
import re
import backoff
import pytest
import requests
@pytest.fixture
def data_dir():
return f"{os.path.splitext(__file__)[0]}.data"
@pytest.fixture
def docker_compose_file(data_dir, compose_file):
return os.path.join(data_dir, compose_file)
@pytest.fixture
def get(docker_compose, nginxproxy, want_err_re):
@backoff.on_exception(
backoff.constant,
requests.exceptions.RequestException,
giveup=lambda e: want_err_re and want_err_re.search(str(e)),
interval=.3,
max_tries=30,
jitter=None)
def _get(url):
return nginxproxy.get(url, allow_redirects=False)
return _get
INTERNAL_ERR_RE = re.compile("TLSV1_ALERT_INTERNAL_ERROR")
CONNECTION_REFUSED_RE = re.compile("Connection refused")
@pytest.mark.parametrize("compose_file,url,want_code,want_err_re", [
# Has default.crt.
("withdefault.yml", "http://https-and-http.nginx-proxy.test/", 301, None),
("withdefault.yml", "https://https-and-http.nginx-proxy.test/", 200, None),
("withdefault.yml", "http://https-only.nginx-proxy.test/", 503, None),
("withdefault.yml", "https://https-only.nginx-proxy.test/", 200, None),
("withdefault.yml", "http://http-only.nginx-proxy.test/", 200, None),
("withdefault.yml", "https://http-only.nginx-proxy.test/", 503, None),
("withdefault.yml", "http://missing-cert.nginx-proxy.test/", 200, None),
("withdefault.yml", "https://missing-cert.nginx-proxy.test/", 500, None),
("withdefault.yml", "http://unknown.nginx-proxy.test/", 503, None),
("withdefault.yml", "https://unknown.nginx-proxy.test/", 503, None),
# Same as withdefault.yml, except there is no default.crt.
("nodefault.yml", "http://https-and-http.nginx-proxy.test/", 301, None),
("nodefault.yml", "https://https-and-http.nginx-proxy.test/", 200, None),
("nodefault.yml", "http://https-only.nginx-proxy.test/", 503, None),
("nodefault.yml", "https://https-only.nginx-proxy.test/", 200, None),
("nodefault.yml", "http://http-only.nginx-proxy.test/", 200, None),
("nodefault.yml", "https://http-only.nginx-proxy.test/", None, INTERNAL_ERR_RE),
("nodefault.yml", "http://missing-cert.nginx-proxy.test/", 200, None),
("nodefault.yml", "https://missing-cert.nginx-proxy.test/", None, INTERNAL_ERR_RE),
("nodefault.yml", "http://unknown.nginx-proxy.test/", 503, None),
("nodefault.yml", "https://unknown.nginx-proxy.test/", None, INTERNAL_ERR_RE),
# HTTPS_METHOD=nohttp on nginx-proxy, HTTPS_METHOD unset on the app container.
("nohttp.yml", "http://https-only.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
("nohttp.yml", "https://https-only.nginx-proxy.test/", 200, None),
("nohttp.yml", "http://unknown.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
("nohttp.yml", "https://unknown.nginx-proxy.test/", 503, None),
# HTTPS_METHOD=redirect on nginx-proxy, HTTPS_METHOD=nohttp on the app container.
("nohttp-on-app.yml", "http://https-only.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
("nohttp-on-app.yml", "https://https-only.nginx-proxy.test/", 200, None),
("nohttp-on-app.yml", "http://unknown.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
("nohttp-on-app.yml", "https://unknown.nginx-proxy.test/", 503, None),
# Same as nohttp.yml, except there is a vhost with a missing cert. This causes its
# HTTPS_METHOD=nohttp setting to effectively become HTTPS_METHOD=noredirect. This means that
# there will be a plain http server solely to support that vhost, so http requests to other
# vhosts get a 503, not a connection refused error.
("nohttp-with-missing-cert.yml", "http://https-only.nginx-proxy.test/", 503, None),
("nohttp-with-missing-cert.yml", "https://https-only.nginx-proxy.test/", 200, None),
("nohttp-with-missing-cert.yml", "http://missing-cert.nginx-proxy.test/", 200, None),
("nohttp-with-missing-cert.yml", "https://missing-cert.nginx-proxy.test/", 500, None),
("nohttp-with-missing-cert.yml", "http://unknown.nginx-proxy.test/", 503, None),
("nohttp-with-missing-cert.yml", "https://unknown.nginx-proxy.test/", 503, None),
# HTTPS_METHOD=nohttps on nginx-proxy, HTTPS_METHOD unset on the app container.
("nohttps.yml", "http://http-only.nginx-proxy.test/", 200, None),
("nohttps.yml", "https://http-only.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
("nohttps.yml", "http://unknown.nginx-proxy.test/", 503, None),
("nohttps.yml", "https://unknown.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
# HTTPS_METHOD=redirect on nginx-proxy, HTTPS_METHOD=nohttps on the app container.
("nohttps-on-app.yml", "http://http-only.nginx-proxy.test/", 200, None),
("nohttps-on-app.yml", "https://http-only.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
("nohttps-on-app.yml", "http://unknown.nginx-proxy.test/", 503, None),
("nohttps-on-app.yml", "https://unknown.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
# Custom nginx config that has a `server` directive that uses `default_server` and simply
# returns 418. Nginx should successfully start (in particular, the `default_server` in the
# custom config should not conflict with the fallback server generated by nginx-proxy) and nginx
# should prefer that server for handling requests for unknown vhosts.
("custom-fallback.yml", "http://unknown.nginx-proxy.test/", 418, None),
])
def test_fallback(get, url, want_code, want_err_re):
if want_err_re is None:
r = get(url)
assert r.status_code == want_code
else:
with pytest.raises(requests.exceptions.RequestException, match=want_err_re):
get(url)

View File

@ -1,22 +1,24 @@
web:
image: web
expose:
- "80"
environment:
WEB_PORTS: 80
VIRTUAL_HOST: web.nginx-proxy.tld
version: "2"
web-server-tokens-off:
image: web
expose:
- "80"
environment:
WEB_PORTS: 80
VIRTUAL_HOST: web-server-tokens-off.nginx-proxy.tld
SERVER_TOKENS: "off"
services:
web:
image: web
expose:
- "80"
environment:
WEB_PORTS: 80
VIRTUAL_HOST: web.nginx-proxy.tld
web-server-tokens-off:
image: web
expose:
- "80"
environment:
WEB_PORTS: 80
VIRTUAL_HOST: web-server-tokens-off.nginx-proxy.tld
SERVER_TOKENS: "off"
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro

View File

@ -1,28 +1,30 @@
web:
image: web
expose:
- "80"
environment:
WEB_PORTS: 80
VIRTUAL_HOST: web.nginx-proxy.tld
version: "2"
web-server-tokens-off:
image: web
expose:
- "80"
environment:
WEB_PORTS: 80
VIRTUAL_HOST: web-server-tokens-off.nginx-proxy.tld
SERVER_TOKENS: "off"
services:
web:
image: web
expose:
- "80"
environment:
WEB_PORTS: 80
VIRTUAL_HOST: web.nginx-proxy.tld
web-server-tokens-off:
image: web
expose:
- "80"
environment:
WEB_PORTS: 80
VIRTUAL_HOST: web-server-tokens-off.nginx-proxy.tld
SERVER_TOKENS: "off"
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./certs/web.nginx-proxy.tld.crt:/etc/nginx/certs/default.crt:ro
- ./certs/web.nginx-proxy.tld.key:/etc/nginx/certs/default.key:ro
- ./certs/web.nginx-proxy.tld.crt:/etc/nginx/certs/web.nginx-proxy.tld.crt:ro
- ./certs/web.nginx-proxy.tld.key:/etc/nginx/certs/web.nginx-proxy.tld.key:ro
- ./certs/web-server-tokens-off.nginx-proxy.tld.crt:/etc/nginx/certs/web-server-tokens-off.nginx-proxy.tld.crt:ro
- ./certs/web-server-tokens-off.nginx-proxy.tld.key:/etc/nginx/certs/web-server-tokens-off.nginx-proxy.tld.key:ro
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./certs/web.nginx-proxy.tld.crt:/etc/nginx/certs/default.crt:ro
- ./certs/web.nginx-proxy.tld.key:/etc/nginx/certs/default.key:ro
- ./certs/web.nginx-proxy.tld.crt:/etc/nginx/certs/web.nginx-proxy.tld.crt:ro
- ./certs/web.nginx-proxy.tld.key:/etc/nginx/certs/web.nginx-proxy.tld.key:ro
- ./certs/web-server-tokens-off.nginx-proxy.tld.crt:/etc/nginx/certs/web-server-tokens-off.nginx-proxy.tld.crt:ro
- ./certs/web-server-tokens-off.nginx-proxy.tld.key:/etc/nginx/certs/web-server-tokens-off.nginx-proxy.tld.key:ro

View File

@ -0,0 +1,13 @@
import pytest
def test_forwards_to_bridge_network_container(docker_compose, nginxproxy):
r = nginxproxy.get("http://bridge-network.nginx-proxy.tld/port")
assert r.status_code == 200
assert r.text == "answer from port 80\n"
def test_forwards_to_host_network_container(docker_compose, nginxproxy):
r = nginxproxy.get("http://host-network.nginx-proxy.tld/port")
assert r.status_code == 200
assert r.text == "answer from port 8080\n"

View File

@ -0,0 +1,31 @@
version: "2"
networks:
net1:
internal: true
net2:
services:
bridge-network:
image: web
environment:
WEB_PORTS: "80"
VIRTUAL_HOST: "bridge-network.nginx-proxy.tld"
networks:
- net2
host-network:
image: web
environment:
WEB_PORTS: "8080"
VIRTUAL_HOST: "host-network.nginx-proxy.tld"
VIRTUAL_PORT: "8080"
network_mode: host
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
networks:
- net1
- net2

View File

@ -0,0 +1,13 @@
import pytest
def test_forwards_to_host_network_container_1(docker_compose, nginxproxy):
r = nginxproxy.get("http://host-network-1.nginx-proxy.tld:8888/port")
assert r.status_code == 200
assert r.text == "answer from port 8080\n"
def test_forwards_to_host_network_container_2(docker_compose, nginxproxy):
r = nginxproxy.get("http://host-network-2.nginx-proxy.tld:8888/port")
assert r.status_code == 200
assert r.text == "answer from port 8181\n"

View File

@ -0,0 +1,26 @@
version: "2"
services:
host-network-1:
image: web
environment:
WEB_PORTS: "8080"
VIRTUAL_HOST: "host-network-1.nginx-proxy.tld"
VIRTUAL_PORT: "8080"
network_mode: host
host-network-2:
image: web
environment:
WEB_PORTS: "8181"
VIRTUAL_HOST: "host-network-2.nginx-proxy.tld"
VIRTUAL_PORT: "8181"
network_mode: host
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTP_PORT: 8888
network_mode: host

View File

@ -0,0 +1 @@
vhost:$2a$13$/aPYmoK0mmgyAI4TpKdFY.6441Ugo39MdXjhpm.Pp6D15rbz9tvz.

View File

@ -0,0 +1 @@
vpath:$2a$13$/aPYmoK0mmgyAI4TpKdFY.6441Ugo39MdXjhpm.Pp6D15rbz9tvz.

View File

@ -0,0 +1,13 @@
import pytest
def test_htpasswd_virtual_host_is_restricted(docker_compose, nginxproxy):
r = nginxproxy.get("http://htpasswd.nginx-proxy.tld/port")
assert r.status_code == 401
assert "WWW-Authenticate" in r.headers
assert r.headers["WWW-Authenticate"] == 'Basic realm="Restricted htpasswd.nginx-proxy.tld"'
def test_htpasswd_virtual_host_basic_auth(docker_compose, nginxproxy):
r = nginxproxy.get("http://htpasswd.nginx-proxy.tld/port", auth=("vhost", "password"))
assert r.status_code == 200
assert r.text == "answer from port 80\n"

View File

@ -0,0 +1,17 @@
version: "2"
services:
web:
image: web
expose:
- "80"
environment:
WEB_PORTS: 80
VIRTUAL_HOST: htpasswd.nginx-proxy.tld
sut:
container_name: sut
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./htpasswd:/etc/nginx/htpasswd:ro

View File

@ -0,0 +1,12 @@
import pytest
def test_htpasswd_virtual_path_is_restricted(docker_compose, nginxproxy):
r = nginxproxy.get("http://htpasswd.nginx-proxy.tld/foo/port")
assert r.status_code == 401
assert "WWW-Authenticate" in r.headers
assert r.headers["WWW-Authenticate"] == 'Basic realm="Restricted htpasswd.nginx-proxy.tld/foo/"'
def test_htpasswd_virtual_path_basic_auth(docker_compose, nginxproxy):
r = nginxproxy.get("http://htpasswd.nginx-proxy.tld/foo/port", auth=("vpath", "password"))
assert r.status_code == 200
assert r.text == "answer from port 80\n"

View File

@ -0,0 +1,19 @@
version: "2"
services:
web:
image: web
expose:
- "80"
environment:
WEB_PORTS: 80
VIRTUAL_HOST: htpasswd.nginx-proxy.tld
VIRTUAL_PATH: /foo/
VIRTUAL_DEST: /
sut:
container_name: sut
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./htpasswd:/etc/nginx/htpasswd:ro

View File

@ -0,0 +1,8 @@
import pytest
import re
def test_http2_global_disabled_config(docker_compose, nginxproxy):
conf = nginxproxy.get_conf().decode('ASCII')
r = nginxproxy.get("http://http2-global-disabled.nginx-proxy.tld")
assert r.status_code == 200
assert not re.search(r"(?s)http2-global-disabled\.nginx-proxy\.tld.*http2 on", conf)

View File

@ -0,0 +1,17 @@
version: "2"
services:
http2-global-disabled:
image: web
expose:
- "80"
environment:
WEB_PORTS: 80
VIRTUAL_HOST: http2-global-disabled.nginx-proxy.tld
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
ENABLE_HTTP2: "false"

View File

@ -0,0 +1,19 @@
import pytest
import re
#Python Requests is not able to do native http3 requests.
#We only check for directives which should enable http3.
def test_http3_global_disabled_ALTSVC_header(docker_compose, nginxproxy):
r = nginxproxy.get("http://http3-global-disabled.nginx-proxy.tld/headers")
assert r.status_code == 200
assert "Host: http3-global-disabled.nginx-proxy.tld" in r.text
assert not "alt-svc" in r.headers
def test_http3_global_disabled_config(docker_compose, nginxproxy):
conf = nginxproxy.get_conf().decode('ASCII')
r = nginxproxy.get("http://http3-global-disabled.nginx-proxy.tld")
assert r.status_code == 200
assert not re.search(r"(?s)listen 443 quic", conf)
assert not re.search(r"(?s)http3 on", conf)
assert not re.search(r"(?s)add_header alt-svc \'h3=\":443\"; ma=86400;\'", conf)

View File

@ -0,0 +1,17 @@
version: "2"
services:
http3-global-disabled:
image: web
expose:
- "80"
environment:
WEB_PORTS: 80
VIRTUAL_HOST: http3-global-disabled.nginx-proxy.tld
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
#environment:
#ENABLE_HTTP3: "false" #Disabled by default

View File

@ -0,0 +1,21 @@
import pytest
import re
#Python Requests is not able to do native http3 requests.
#We only check for directives which should enable http3.
def test_http3_global_enabled_ALTSVC_header(docker_compose, nginxproxy):
r = nginxproxy.get("http://http3-global-enabled.nginx-proxy.tld/headers")
assert r.status_code == 200
assert "Host: http3-global-enabled.nginx-proxy.tld" in r.text
assert "alt-svc" in r.headers
assert r.headers["alt-svc"] == 'h3=":443"; ma=86400;'
def test_http3_global_enabled_config(docker_compose, nginxproxy):
conf = nginxproxy.get_conf().decode('ASCII')
r = nginxproxy.get("http://http3-global-enabled.nginx-proxy.tld")
assert r.status_code == 200
assert re.search(r"listen 443 quic reuseport\;", conf)
assert re.search(r"(?s)http3-global-enabled\.nginx-proxy\.tld;.*listen 443 quic", conf)
assert re.search(r"(?s)http3-global-enabled\.nginx-proxy\.tld;.*http3 on\;", conf)
assert re.search(r"(?s)http3-global-enabled\.nginx-proxy\.tld;.*add_header alt-svc \'h3=\":443\"; ma=86400;\'", conf)

View File

@ -0,0 +1,17 @@
version: "2"
services:
http3-global-enabled:
image: web
expose:
- "80"
environment:
WEB_PORTS: 80
VIRTUAL_HOST: http3-global-enabled.nginx-proxy.tld
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
ENABLE_HTTP3: "true"

View File

@ -0,0 +1,49 @@
import pytest
import re
#Python Requests is not able to do native http3 requests.
#We only check for directives which should enable http3.
def test_http3_vhost_enabled_ALTSVC_header(docker_compose, nginxproxy):
r = nginxproxy.get("http://http3-vhost-enabled.nginx-proxy.tld/headers")
assert r.status_code == 200
assert "Host: http3-vhost-enabled.nginx-proxy.tld" in r.text
assert "alt-svc" in r.headers
assert r.headers["alt-svc"] == 'h3=":443"; ma=86400;'
def test_http3_vhost_enabled_config(docker_compose, nginxproxy):
conf = nginxproxy.get_conf().decode('ASCII')
r = nginxproxy.get("http://http3-vhost-enabled.nginx-proxy.tld")
assert r.status_code == 200
assert re.search(r"listen 443 quic reuseport\;", conf)
assert re.search(r"(?s)http3-vhost-enabled\.nginx-proxy\.tld;.*listen 443 quic", conf)
assert re.search(r"(?s)http3-vhost-enabled\.nginx-proxy\.tld;.*http3 on\;", conf)
assert re.search(r"(?s)http3-vhost-enabled\.nginx-proxy\.tld;.*add_header alt-svc \'h3=\":443\"; ma=86400;\'", conf)
def test_http3_vhost_disabled_ALTSVC_header(docker_compose, nginxproxy):
r = nginxproxy.get("http://http3-vhost-disabled.nginx-proxy.tld/headers")
assert r.status_code == 200
assert "Host: http3-vhost-disabled.nginx-proxy.tld" in r.text
assert not "alt-svc" in r.headers
def test_http3_vhost_disabled_config(docker_compose, nginxproxy):
conf = nginxproxy.get_conf().decode('ASCII')
r = nginxproxy.get("http://http3-vhost-disabled.nginx-proxy.tld")
assert r.status_code == 200
assert not re.search(r"(?s)http3-vhost-disabled\.nginx-proxy\.tld.*listen 443 quic.*\# http3-vhost-enabled\.nginx-proxy\.tld", conf)
assert not re.search(r"(?s)http3-vhost-disabled\.nginx-proxy\.tld.*http3 on.*\# http3-vhost-enabled\.nginx-proxy\.tld", conf)
assert not re.search(r"(?s)http3-vhost-disabled\.nginx-proxy\.tld;.*add_header alt-svc \'h3=\":443\"; ma=86400;\'.*\# http3-vhost-enabled\.nginx-proxy\.tld", conf)
def test_http3_vhost_disabledbydefault_ALTSVC_header(docker_compose, nginxproxy):
r = nginxproxy.get("http://http3-vhost-default-disabled.nginx-proxy.tld/headers")
assert r.status_code == 200
assert "Host: http3-vhost-default-disabled.nginx-proxy.tld" in r.text
assert not "alt-svc" in r.headers
def test_http3_vhost_disabledbydefault_config(docker_compose, nginxproxy):
conf = nginxproxy.get_conf().decode('ASCII')
r = nginxproxy.get("http://http3-vhost-default-disabled.nginx-proxy.tld")
assert r.status_code == 200
assert not re.search(r"(?s)http3-vhost-default-disabled\.nginx-proxy\.tld.*listen 443 quic.*\# http3-vhost-disabled\.nginx-proxy\.tld", conf)
assert not re.search(r"(?s)http3-vhost-default-disabled\.nginx-proxy\.tld.*http3 on.*\# http3-vhost-disabled\.nginx-proxy\.tld", conf)
assert not re.search(r"(?s)http3-vhost-default-disabled\.nginx-proxy\.tld;.*add_header alt-svc \'h3=\":443\"; ma=86400;\'.*\# http3-vhost-disabled\.nginx-proxy\.tld", conf)

View File

@ -0,0 +1,35 @@
version: "2"
services:
http3-vhost-enabled:
image: web
expose:
- "80"
environment:
WEB_PORTS: 80
VIRTUAL_HOST: http3-vhost-enabled.nginx-proxy.tld
labels:
com.github.nginx-proxy.nginx-proxy.http3.enable: "true"
http3-vhost-disabled:
image: web
expose:
- "80"
environment:
WEB_PORTS: 80
VIRTUAL_HOST: http3-vhost-disabled.nginx-proxy.tld
labels:
com.github.nginx-proxy.nginx-proxy.http3.enable: "false"
http3-vhost-default-disabled:
image: web
expose:
- "80"
environment:
WEB_PORTS: 80
VIRTUAL_HOST: http3-vhost-default-disabled.nginx-proxy.tld
sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro

View File

@ -5,4 +5,9 @@ import pytest
def test_web1_http_custom_port(docker_compose, nginxproxy, subdomain):
r = nginxproxy.get("http://%s.nginx-proxy.tld:8080/port" % subdomain, allow_redirects=False)
assert r.status_code == 200
assert "answer from port 81\n" in r.text
assert "answer from port 81\n" in r.text
def test_nonstandardport_Host_header(docker_compose, nginxproxy):
r = nginxproxy.get("http://web.nginx-proxy.tld:8080/headers")
assert r.status_code == 200
assert "Host: web.nginx-proxy.tld:8080" in r.text

Some files were not shown because too many files have changed in this diff Show More