Nginx viết lại trên máy docker khi cổng máy chủ! = Cổng container


10

Tôi đang cố gắng chạy nhiều container docker tất cả đang chạy nginx nghe trên cổng 80, nhưng với các cổng máy chủ khác nhau ánh xạ tới cổng container 80.

Đối với hầu hết các phần này hoạt động, ngoại trừ khi nginx thực hiện chuyển hướng do thiếu dấu gạch chéo.

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

Với cấu hình nginx ở trên và một container docker chạy nó với cổng máy chủ 8080 được ánh xạ tới cổng container 80 Tôi có thể nhận localhost: 8080 / docs / qua 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 ...

nhưng nếu tôi yêu cầu localhost: 8080 / docs tôi sẽ chuyển hướng đến 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 ...

Làm cách nào tôi có thể lấy nginx để bảo vệ cổng ban đầu khi thực hiện chuyển hướng? Tôi đã thử xem port_in_redirect và server_name_in_redirect nhưng họ không giúp được gì.


BIÊN TẬP

Dựa trên https://forum.nginx.org/read.php?2,261216,261216#msg-261216 điều này hiện không thể thực hiện được.


Nhìn vào vùng chứa nginx-proxy , vì vậy bạn không phải thực hiện bất kỳ thao tác viết lại cổng điên rồ nào.
Michael Hampton

Tôi không thực sự muốn bất cứ điều gì cân bằng trước những container này. Tôi đã có một tệp soạn thảo docker đặt cổng ngoài dựa trên var env và hầu hết thời gian tôi chỉ "docker-compose up -d" tệp này một lần. Tuy nhiên vì lý do thử nghiệm và cho phép tôi làm việc với những thứ khác mà tôi muốn có thể thực hiện "PORT = 8080 docker-compose -p test up -d" để quay một bộ container hoàn toàn mới (do tên dự án mới ) được ánh xạ tới một cổng máy chủ khác.
Ibasa

Ack, chỉ cần chạy vào vấn đề này là tốt. Tôi đoán tôi sẽ phải đi vanilla nginx hoặc chuyển thứ trên 8080 sang thứ khác.
Ken

Câu trả lời:


2

Giải pháp đơn giản nhất là loại bỏ indexchỉ thị và không dựa vào các $uri/chuyển hướng rõ ràng hoặc ẩn . Ví dụ:

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

Đây không phải là hành vi giống hệt nhau vì nó tránh hoàn toàn chuyển hướng. Nếu bạn muốn chuyển hướng dấu gạch chéo như mô-đun chỉ mục đưa ra, thì cần một giải pháp phức tạp hơn. Ví dụ:

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;
  }
}

Như tôi đã nói trong câu hỏi tôi đã thử điều này, tôi đã thêm port_in_redirect; đến khối http, cùng kết quả của việc chuyển hướng đến localhost / docs /, đã thử thêm server_name_in_redirect tắt; cũng. Vẫn chuyển hướng đến localhost / docs /
Ibasa

@Ibasa Vâng, xin lỗi về điều đó. Đọc hai lần - viết một lần. Phải cố nhớ điều đó.
Richard Smith

5

Các máy khách HTTP sẽ đặt cổng vào tiêu đề Máy chủ. Nếu bạn sử dụng giá trị ban đầu của tiêu đề máy chủ khi thực hiện chuyển hướng, nó sẽ hoạt động như mong đợi. Tôi đã kiểm tra mã sau đây và có vẻ đang thực hiện chính xác những gì bạn yêu cầu:

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/

Đây là kỹ thuật câu trả lời chính xác. Nó cũng hoạt động với IP, ví dụ: yêu cầu tới 127.0.0.1:8000 sẽ có 127.0.0.1:8000 dưới dạng http_host. Đó là bởi vì theo: tools.ietf.org/html/rfc2616#section-14,23 http_host cần để phục vụ cho sự mơ hồ, mà một cổng sẽ thêm vào. Nếu các cổng bị bỏ đi, thì mặc định được ngụ ý (ví dụ: 80 hoặc 443). Vì vậy, giải pháp này sẽ là sạch nhất để làm việc với ...
lifeofguenter

0

Chỉ cần làm theo cách khắc phục đơn giản này

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

0

Thật thú vị ... Tôi đã gặp chính xác vấn đề này và đã có thể khắc phục nó như câu trả lời của Richard Smith cho thấy:

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

Sự khác biệt duy nhất là tôi không chỉ định index.html?

Chỉ định mã lỗi để tránh vòng lặp chuyển hướng.

Vẫn đang chờ phản hồi từ hỗ trợ của nginx.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.