Перепишіть Nginx на докер-машину, коли порт порту! = Порт контейнера


10

Я намагаюся запустити декілька контейнерів докера, які працюють під час прослуховування nginx на порту 80, але з різними портами хостів, які відображають порт 80 контейнерів.

Здебільшого це працює, за винятком випадків, коли nginx робить переадресацію через відсутність останньої косої риски.

server {
    listen 80;
    root /var/www;
    index index.html;
    location /docs {}
}

Враховуючи вищевказаний конфігурацію nginx та контейнер докера, який працює з портом хоста 8080, відображеним на контейнерний порт 80, я можу отримати localhost: 8080 / docs / через curl ok:

> GET /docs/ HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 200 OK
* Server nginx/1.9.5 is not blacklisted
< Server: nginx/1.9.5
< Date: Sat, 28 Nov 2015 17:27:05 GMT
< Content-Type: text/html
< Content-Length: 6431
< Last-Modified: Sat, 28 Nov 2015 17:17:06 GMT
< Connection: keep-alive
< ETag: "5659e192-191f"
< Accept-Ranges: bytes
<
... html page ...

але якщо я запитую localhost: 8080 / docs, я отримую переспрямування на localhost / docs /

> GET /docs HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
* Server nginx/1.9.5 is not blacklisted
< Server: nginx/1.9.5
< Date: Sat, 28 Nov 2015 17:29:40 GMT
< Content-Type: text/html
< Content-Length: 184
< Location: http://localhost/docs/
< Connection: keep-alive
<
... html redirect page ...

Як я можу отримати nginx для збереження вихідного порту під час переадресації? Я спробував переглянути port_in_redirect та server_name_in_redirect, але вони не допомогли.


EDIT

На основі https://forum.nginx.org/read.php?2,261216,261216#msg-261216 наразі це виглядає неможливо.


Загляньте в контейнер nginx-proxy , щоб вам не довелося робити жодного з цього шаленого сміття для переписування портів.
Майкл Хемптон

Я не хочу дуже балансувати перед цими контейнерами. У мене є файл складання докер-файлів, який встановлює зовнішній порт на основі env var, і більшість часу я просто "docker-compose up -d" цей файл один раз. Однак з причин тестування та щоб дозволити мені працювати над іншими речами, я хочу мати можливість "PORT = 8080 docker-compose -p test up -d", щоб розгорнути цілий новий набір контейнерів (завдяки новій назві проекту ), які відображені в інший хост-порт.
Ібаса

Ек, щойно зіткнувся і з цією проблемою. Напевно, мені доведеться піти на nginx vanilla або перенести матеріал на 8080 на щось інше.
Кен

Відповіді:


2

Найпростіше рішення - видалити indexдирективу, а не покладатися на явні чи неявні $uri/переадресації. Наприклад:

server {
  listen 80;
  root /var/www;
  location /docs {
    try_files $uri $uri/index.html =404;
  }
}

Це не однакова поведінка, оскільки вона взагалі уникає переадресації. Якщо ви хотіли, щоб перенаправлення косою косою рисою, як дає модуль індексу, потрібне більш складне рішення. Наприклад:

server {
  listen 80;
  root /var/www;
  location /docs {
    try_files $uri @redirect;
  }
  location @redirect {
    if ($uri ~* ^(.+)/$) { rewrite ^ $uri/index.html last; }
    if (-d $document_root$uri) { return $scheme://$host:8080$uri/; }
    return 404;
  }
}

Як я вже говорив у запитанні, що я спробував це, я додав port_in_redirect off; до блоку http, того самого результату переспрямування на localhost / docs /, спробував вимкнути серверне ім’я_в_посередку; так само. Досі переспрямовує до localhost / docs /
Ібаса

@Ibasa Так, вибач за це. Прочитайте двічі - напишіть один раз. Потрібно спробувати запам’ятати це.
Річард Сміт

5

Клієнти HTTP розмістять порт у заголовку Host. Якщо ви використовуєте початкове значення заголовка хоста, виконуючи переадресацію, воно повинно працювати як очікувалося. Я перевірив наступний код і, здається, виконує саме те, що ви просили:

location ~ ^.*[^/]$ {
    try_files $uri @rewrite;
}
location @rewrite {
    return 302 $scheme://$http_host$uri/;
}

> GET /bla HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 302 Moved Temporarily
< Server: nginx/1.9.7
< Date: Sun, 29 Nov 2015 06:23:35 GMT
< Content-Type: text/html
< Content-Length: 160
< Connection: keep-alive
< Location: http://localhost:8080/bla/

Це технічно правильна відповідь. Він також працює з IP-адресами, наприклад, запит на 127.0.0.1:8000 матиме 127.0.0.1:8000 як http_host. Це тому, що відповідно до: tools.ietf.org/html/rfc2616#section-14.23 http_host потребує неоднозначності, до якого додасться порт. Якщо порти залишаються поза межами, то значення за замовчуванням маються на увазі (наприклад, 80 або 443). Тож це рішення повинно бути найчистішим для роботи з ...
lifeofguenter

0

Просто дотримуйтесь цього простого виправлення

location /app {
    alias /usr/share/nginx/html/folder;
    if (-d $request_filename) {
        rewrite [^/]$ $scheme://$http_host$uri/ permanent;
    }
}

0

Цікаво ... Я зіткнувся саме з цим питанням і зміг його виправити, як підказує відповідь Річарда Сміта :

root /var/www;
location = /docs {
    try_files $uri $uri/ =404;
}

Різниця лише в тому, що я не вказую index.html?

Вкажіть код помилки, щоб уникнути циклу переадресації.

Ще чекаю на відгуки від підтримки nginx.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.