Nginx रिवर्स प्रॉक्सी + URL फिर से लिखना


149

Nginx पोर्ट 80 पर चल रहा है, और मैं इसे इस तरह /fooसे पोर्ट करने के लिए पथ के साथ प्रॉक्सी URL रिवर्स करने के लिए उपयोग कर रहा हूं 3200:

location /foo {
                proxy_pass http://localhost:3200;
                proxy_redirect     off;
                proxy_set_header   Host $host;
}

यह ठीक काम करता है, लेकिन मेरे पास पोर्ट पर एक एप्लिकेशन है 3200, जिसके लिए मैं नहीं चाहता कि प्रारंभिक /fooको भेजा जाए। वह है - जब मैं पहुंचता हूं http://localhost/foo/bar, तो मैं चाहता हूं कि केवल /barवह मार्ग हो जैसा कि ऐप द्वारा प्राप्त किया गया है। इसलिए मैंने ऊपर के लोकेशन ब्लॉक में इस लाइन को जोड़ने की कोशिश की:

rewrite ^(.*)foo(.*)$ http://localhost:3200/$2 permanent;

यह 302 रीडायरेक्ट (URL में परिवर्तन) का कारण बनता है, लेकिन मुझे 301 चाहिए। मुझे क्या करना चाहिए?


अगर आपको ग्रेफाना के मामले में कोई समस्या है तो आपको ये नुस्खा इस्तेमाल करना चाहिए: docs.grafana.org/installation/behind_proxy/…
mohsen saeedi

जवाबों:


169

लोकलहोस्ट के लिए कोई भी रीडायरेक्ट रिमोट सिस्टम (जैसे क्लाइंट का वेब ब्राउज़र) से कोई मतलब नहीं रखता है। तो आपके (मामले में) स्थायी (301) या पुनर्निर्देशित (302) फिर से लिखना झंडे आपके मामले में उपयोग करने योग्य नहीं हैं।

कृपया पारदर्शी पुनर्लेखन नियम का उपयोग करते हुए सेटअप करने का प्रयास करें:

location  /foo {
  rewrite /foo/(.*) /$1  break;
  proxy_pass         http://localhost:3200;
  proxy_redirect     off;
  proxy_set_header   Host $host;
}

curl -iअपने पुनर्लेखन का परीक्षण करने के लिए उपयोग करें । नियम में एक बहुत ही सूक्ष्म परिवर्तन nginx को पुनर्निर्देशित करने का कारण बन सकता है।


1
URL पथ अभी भी मेरे ऐप में / foo से शुरू होता है जब मैं ऐसा करता हूं ...
jeffreyveon

एक अलग समस्या होनी चाहिए। मैंने कुछ मिनट पहले ही सफलतापूर्वक इस परिदृश्य को देखा। मूल URL: http: // development / foo / testme / 1234 - एक PHP स्क्रिप्ट का REQUEST_URI प्रॉक्सी बैक-एंड के रूप में जुड़े अपाचे पर चल रहा है: '/ testme / 1234'
जेन्स ब्रैडलर

9
रेगेक्स शायद होना चाहिए /foo(.*), अन्यथा example.com/fooअभ्यस्त मिलान नहीं किया जाना चाहिए । (जो कि शायद जेफ्रीवेवन ने क्या अनुभव किया है)
बेनो

इस तरह के काम करता है, लेकिन मेरे शरीर को प्रॉक्सी_सेट_बॉडी के साथ सेट किया जा रहा है।
जस्टिन थॉमस

rewrite /(.*) /socket.io/ ब्रेक; SOCKET.IO के लिए मेरा दिन बचाएं
user956584

122

जब तक आप प्रॉक्सी_पास निर्देश में एक यूआरआई निर्दिष्ट करते हैं, तब तक एक रीराइट नियम का उपयोग किए बिना इसके लिए सरल स्थान उपसर्ग मिलान कार्य करता है:

location /foo {
  proxy_pass http://localhost:3200/;
}

निर्देश /के अंत में अतिरिक्त सूचना दें proxy_pass। NGINX मिलान किए हुए उपसर्ग को छीन लेगा /fooऔर शेष को URI के बैकएंड सर्वर पर भेज देगा /। इसलिए, http://myserver:80/foo/barबैकएंड पर पोस्ट करेगा http://localhost:3200/bar

से proxy_pass पर nginx डॉक्स :

यदि प्रॉक्सी_पास निर्देश यूआरआई के साथ निर्दिष्ट किया जाता है, तो जब एक अनुरोध सर्वर से पारित हो जाता है, तो सामान्यीकृत अनुरोध यूआरआई के स्थान का मिलान करने वाला हिस्सा यूआरआई द्वारा निर्देश में निर्दिष्ट किया जाता है:


12
मेरे लिए मेरे द्वारा जोड़े गए स्थान / foo / {
आंद्रेई एन

यह वही था जो मैं देख रहा था!
अनबिनियार

6
यह एक बहुत ही साफ समाधान है, मैं इस सवाल का विहित जवाब देना पसंद करूंगा।
२०:१२ पर रैलीन

2
अनुगामी स्लेश रखने या हटाने के महत्व का एहसास करने के लिए बहुत लंबा समय लिया।
परवेज

5
//xyzयदि आप ऐसा करते हैं तो यह वास्तव में मेजबान के पास जाएगा ।
आर्किमिडीज ट्रैजानो

60

पूर्णतया सबसे सही तरीका और सर्वोत्तम अभ्यास आमतौर पर इस प्रकार है:

location /foo/ {
    proxy_pass http://localhost:3200/; # note the trailing slash!
}

  • पीछे चल रहे स्लैशproxy_pass के गंभीर महत्व पर ध्यान दें , जो बैकएंड पर सामने वाले छोर के अनुरूप $uriहोने वाले चर को स्वचालित रूप से बदल देता है । एक स्पष्ट निर्देश की आवश्यकता नहीं है ।/foo//rewrite

  • साथ ही, ध्यान दें कि अनुगामी /मेंlocation के रूप में अच्छी तरह से काफी महत्वपूर्ण है - इसके बिना, आप एक बिंदु (जैसे, एक काम पर अपनी साइट पर अजीब दिखने यूआरएल होने का जोखिम /fooenके अलावा /foo/en)।

    इसके अतिरिक्त, निर्देशन के दस्तावेज़ीकरण के अनुसार, कुछ विशेष हैंडलिंग भी सुनिश्चित करता है /, locationसाथ ही साथ proxy_passइसमें निहित प्रभाव को भी सुनिश्चित करता है ।locationlocation = /foo {return 301 /foo/;}

    इसलिए, locationऊपर दिए गए अनुगामी स्लैश के साथ परिभाषित करके , आप न केवल यह सुनिश्चित करते हैं कि स्लैश-कम प्रत्यय URL जैसे /fooenमान्य नहीं होंगे, बल्कि यह भी कि /fooबिना अनुगामी स्लैश के भी काम करना जारी रहेगा।


संदर्भ प्रलेखन:


ऐसा लगता है $argsकि खो रहे हैं: के http://frontend/foo?bar=bazलिए अनुमानित हो जाएगा http://backend/। ध्यान दें कि
आर्ग्स

@Vanuan, क्या आप इसके बारे में निश्चित हैं? $argsयदि आप ऊपर दिए गए कोड का उपयोग करते हैं $uri, और जब तक आप अपने में स्पष्ट चर का उपयोग नहीं कर रहे हैं, तो मुझे बहुत निश्चित है कि आपको अभी भी ऊपर दिए कोड का उपयोग करना चाहिए proxy_pass
cnst

@cnst ओह, मैं देख रहा हूँ। मैं मेजबान चर का उपयोग कर रहा हूँ। यह काउंटर सहज है।
18-29 बजे वानुअन

1
@ArchimedesTrajano, आप गलत हैं, क्योंकि /fooपुनर्निर्देशित करने के लिए विशेष हैंडलिंग है /foo/, इसलिए, जब तक कि आप बैकएंड पर कुछ अजीब नहीं कर रहे हैं, तब भी /fooअनुरोध उपरोक्त कोड के साथ काम करेंगे। (यह वास्तव में पहले से ही जवाब का हिस्सा है, BTW।)
cnst

3
हालांकि इन सभी मंचों पर इस समाधान को जीतने के लिए "लगता है", यह जवाब में ही ध्यान दिया जाना चाहिए कि नग्नेक्स यूआरएल को डिकोड करेगा और डीकोड किए गए URL को प्रॉक्सी सर्वर से पास करेगा। यदि आपका URL URL एन्कोडेड भागों को ले जाता है तो यह समाधान काम नहीं करेगा।
कोडिंग

1

प्रयत्न, कोशिश

location /foo {
    proxy_pass http://localhost:3200/;
    ....

या

location ^~ /foo {
    proxy_pass http://localhost:3200/;
    ....

13
यह उत्तर अच्छा होगा यदि आप कुछ स्पष्टीकरण देते हैं कि इसे ऊपर की तरह क्यों कॉन्फ़िगर किया जाना चाहिए।
मसलोगेह

//xyzयदि आप ऐसा करते हैं तो यह वास्तव में मेजबान के पास जाएगा ।
आर्किमिडीज ट्रैजानो

1

@Terabuck अभी तक कोई जवाब नहीं देने के लिए क्षमा करें।

आपको लोकलहोस्ट का उपयोग नहीं करना चाहिए क्योंकि आप इस तथ्य पर निर्भर करते हैं कि एप्लिकेशन किसी होस्ट फ़ाइल के साथ सर्वर पर चल रहा है। स्थानीय होस्ट केवल 127.0.0.1 के लिए डिफ़ॉल्ट अनुवाद है। यह बताते हुए कुछ भी नहीं है कि आपके पास यह होस्ट फ़ाइलें होनी चाहिए। यह सिर्फ एक के लिए बहुत आम है।

लूपबैक इंटरफ़ेस का फिर से निर्भर होना एक और आम बात है लेकिन आप अभी भी नेटवर्किंग स्टैक पर लूपबैक इंटरफ़ेस पर निर्भर हैं। इन दोनों का न होना एक दुर्लभ मामला है। अगर आप कभी इस बारे में चिंता करते हैं। कम से कम यूनिक्स / लिनक्स पर आपके पास सॉकेट्स का विकल्प है। यह लोकलहोस्ट तक पहुंचने के लिए नेटवर्क स्टैक की आवश्यकता को समाप्त कर देगा। इस दृष्टिकोण के साथ सावधानी बरतें क्योंकि कुछ कारक हैं जो मेजबान ओएस पर जगह में आएंगे। जैसे कि खुली हुई फाइलों की संख्या आदि।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.