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 / เอกสารฉันได้รับการเปลี่ยนเส้นทางไปยัง 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 แต่พวกเขาไม่ได้ช่วย


แก้ไข

อ้างอิงจากhttps://forum.nginx.org/read.php?2,261216,261216#msg-261216สิ่งนี้ดูไม่เป็นไปได้ในตอนนี้


ดูที่คอนเทนเนอร์nginx-proxyดังนั้นคุณไม่จำเป็นต้องทำการเขียนพอร์ตขยะใหม่อีกต่อไป
Michael Hampton

ฉันไม่ต้องการให้มีสิ่งใดสร้างความสมดุลต่อหน้าตู้คอนเทนเนอร์เหล่านี้ ฉันมีไฟล์นักเทียบท่าที่ตั้งค่าพอร์ตภายนอกตาม env var และส่วนใหญ่ฉันมักจะ "นักเทียบท่าเขียน -d" ไฟล์นี้หนึ่งครั้ง อย่างไรก็ตามสำหรับเหตุผลในการทดสอบและเพื่อให้ฉันสามารถทำงานในสิ่งอื่น ๆ ฉันต้องการที่จะทำ "PORT = 8080 นักเทียบท่า - เขียน - ทดสอบ p-up -d" เพื่อปั่นชุดคอนเทนเนอร์ใหม่ทั้งหมด (เนื่องจากชื่อโครงการใหม่ ) ที่แมปเข้ากับพอร์ตโฮสต์อื่น
Ibasa

ตอบแค่เจอปัญหานี้เช่นกัน ฉันเดาว่าฉันจะต้องไปวานิลลา nginx หรือย้ายสิ่งของใน 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 / พยายามเพิ่ม server_name_in_redirect off เช่นกัน ยังเปลี่ยนเส้นทางไปยัง localhost / docs /
Ibasa

@Ibasa ใช่ขอโทษด้วย อ่านสองครั้ง - เขียนครั้งเดียว ต้องพยายามจำไว้
Richard Smith

5

ไคลเอนต์ HTTP จะใส่พอร์ตในส่วนหัวของโฮสต์ หากคุณใช้ค่าเดิมของส่วนหัวของโฮสต์เมื่อทำการเปลี่ยนเส้นทางควรทำงานตามที่คาดไว้ ฉันทดสอบโค้ดต่อไปนี้และดูเหมือนว่าจะทำสิ่งที่คุณต้องการอย่างแน่นอน:

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

น่าสนใจ ... ฉันพบปัญหานี้อย่างแม่นยำและสามารถแก้ไขได้มากเท่าที่คำตอบของ Richard Smithแนะนำ:

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

ความแตกต่างเพียงอย่างเดียวคือฉันไม่ได้ระบุindex.html?

ระบุรหัสข้อผิดพลาดเพื่อหลีกเลี่ยงการวนรอบการเปลี่ยนเส้นทาง

ยังคงรอการตอบรับจากการสนับสนุนของ nginx

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.