Nginx कई स्थान मुद्दे


15

मैं वर्तमान में एक रिपॉजिटरी से 3 में 3 एप्लिकेशन को अलग करने की कोशिश कर रहा हूं, लेकिन url संरचना को ध्यान में रखते हुए, इसलिए मूल रूप से एक ही डोमेन के तहत अलग-अलग स्थानों को अलग-अलग अनुप्रयोगों द्वारा वितरित किया जाना है।

जो मैं संघर्ष कर रहा हूं, वह यह है कि किसी एक एप्लिकेशन को गैर-मौजूद urls के लिए कमबैक होना चाहिए, इसलिए यदि पहला मेल नहीं खाता है, और दूसरा नहीं है, तो तीसरे को अनुरोध को संभालना चाहिए

मुझे जो संरचना मिली है वह है:

/ etc / nginx / sites-enable / main_site, यहाँ में, server_name और लॉग के अलावा मुझे मिला है include /etc/nginx/subsites-enabled/*, जहाँ मुझे 3 कॉन्फ़िगरेशन फ़ाइलें मिली हैं, प्रत्येक ऐप के लिए एक।

3 कॉन्फिग फाइलों में से प्रत्येक में एक लोकेशन ब्लॉक होता है।

मैंने रेगेक्स में नकारात्मक रूप देखने की कोशिश की है (मूल रूप से अन्य एप्लिकेशन हैंडल को हार्डकोड करने की कोशिश कर रहा है) लेकिन असफल रहा।

इसलिए, संक्षेप में:

/ / और समुदाय /etc/nginx/subsites-enabled/example.org/home (कुछ पर्ल स्क्रिप्ट) द्वारा दिया जाना चाहिए

/ समाचार /etc/nginx/subsites-enabled/example.org/news (वर्डप्रेस) द्वारा वितरित किया जाना चाहिए

बाकी सब कुछ /etc/nginx/subsites-enabled/example.org/app (केक ऐप) द्वारा दिया जाना चाहिए

पर्ल बिट ठीक काम करता है। मुझे जो समस्या हो रही है, वह यह है कि ऐप समाचार ले रहा है (शायद यह मेल खाता है। *), मैंने विभिन्न विकल्पों की कोशिश की है (मैं 2 दिनों के लिए इस पर रहा हूं) लेकिन उनमें से किसी ने भी सभी समस्याओं को हल नहीं किया (कभी-कभी स्थैतिक संपत्ति काम नहीं करेगी, आदि)।

मेरा विन्यास है:

/etc/nginx/sites-enabled/example.org:

server {
    listen   80;
    server_name example.org;
    error_log /var/log/nginx/example.org.log;

    include /etc/nginx/subsites-enabled/example.org/*;
}

/etc/nginx/subsites-enabled/example.org/home:

location = / {
  rewrite ^.*$ /index.pl last;
}

location ~* /community(.*) {
  rewrite ^.*$ /index.pl last;
}

location ~ \.pl {
  root   /var/www/vhosts/home;
  access_log /var/log/nginx/home/access.log;
  error_log /var/log/nginx/home/error.log;

  include /etc/nginx/fastcgi_params;
  fastcgi_index index.pl;
  fastcgi_param SCRIPT_FILENAME /var/www/vhosts/home$fastcgi_script_name;
  fastcgi_pass  unix:/var/run/fcgiwrap.socket;
}

/ Etc / ngins / सबसाइट सक्षम / समाचार

location /news {
  access_log /var/log/nginx/news/access.log;
  error_log /var/log/nginx/news/error.log debug;

  error_page 404 = /news/index.php;

  root /var/www/vhosts/news;

  index index.php;

  if (!-e $request_filename) {
      rewrite ^.*$ /index.php last;
  }

  location ~ \.php {
    include /etc/nginx/fastcgi_params;
    fastcgi_pass  127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /var/www/vhosts/news$fastcgi_script_name;
  }
}

/ Etc / nginx / सबसाइट सक्षम / ऐप्स:

location ~ .* {
  access_log /var/log/nginx/app/access.log;
  error_log /var/log/nginx/app/error.log;

  rewrite_log on;

  index index.php;
  root /var/www/vhosts/app/app/webroot;

  if (-f $request_filename) {
    expires 30d;
    break;
  }

  if (!-e $request_filename) {
    rewrite ^.*$ /index.php last;
  }

  location ~ \.php {
    include /etc/nginx/fastcgi_params;
    fastcgi_pass  127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /var/www/vhosts/app/app/webroot$fastcgi_script_name;
  }
}

a) अपने कॉन्फिगर को कुछ उदाहरणों के साथ पोस्ट करें जहां विभिन्न रीडायरेक्ट (गैर-मौजूद URL के लिए सहित) को जाना चाहिए। बी) एक नाम स्थान ब्लॉक ( उपसर्ग का उपयोग करके ) के साथ try_files का उपयोग करें @जो आपके डिफ़ॉल्ट एप्लिकेशन को मैप करता है। आप एक एरर_पेज भी सेट कर सकते हैं, जो 404 नाम वाले स्थान पर मैप करता है।
साइबरबरी

@ cyberx86 मैंने और अधिक विवरण और मेरे विन्यास को जोड़ा
आंद्रेई सेर्डेलियुक

एक त्वरित नज़र कुछ बातों का सुझाव देती है: ए) रेगेक्स मैचिंग पारंपरिक तारों पर पूर्वता लेता है - इसलिए आपका ऐप ब्लॉक आपके समाचार ब्लॉक के बजाय मेल खाएगा - प्रयास करें location ^~ /news। बी) आपके ऐप ब्लॉक के लिए, आपको ऐसा करने में सक्षम होना चाहिए location /(यह वैसा नहीं है location = /, बल्कि कुछ मामलों में (विशेष रूप से रेगेक्स) से पहले ही सब कुछ मिलान नहीं करना चाहिए।) आदेश मायने रखता है - आप 3 को संयोजित करना चाह सकते हैं। सही क्रम में ब्लॉक के साथ एक एकल फ़ाइल में फ़ाइलें। इसके अलावा, try_files का उपयोग करें !-e। अंत में wiki.nginx.org/HttpCoreModule#location देखें ।
साइबरबरी cy

मैंने उनमें से हर बदलाव की बहुत कोशिश की, जिसमें उन्हें एक ही फाइल में संयोजित करना (भले ही उन्हें अलग-अलग तैनात होने की आवश्यकता हो), उनमें से कोई भी काम नहीं करता है। समाचार बस एप्लिकेशन द्वारा नियंत्रित किया जाता है।
आंद्रेई सेर्डेलियुच

ठीक है, मुझे लगता है कि इसे हल कर दिया गया है - जैसा कि मैंने शुरू में उम्मीद की थी, उससे थोड़ा मुश्किल - लेकिन निश्चित रूप से खिलाफ मैच के लिए सुखद। पहेली के लिए धन्यवाद।
साइबरएक्स 86

जवाबों:


47

आपके कॉन्फ़िगरेशन में कुछ चीजें गलत हैं, दो प्रासंगिक हैं:

  1. किसी स्थान ब्लॉक के भीतर पथ में अभी भी मिलान पथ शामिल है।
  2. एक मैच के लिए सभी उपलब्ध स्थानों को देखने के माध्यम से 'अंतिम' के साथ जारी है (वे वर्तमान स्थान ब्लॉक से बाहर निकलते हैं)।

उदाहरण के लिए, URL example.org/news/test.htm लें

  • location /newsब्लॉक से मिलान होगा
  • उपयोग किया गया रास्ता तब है /news/test.htm- यह नहीं बदलता है, सिर्फ इसलिए कि यह स्थान ब्लॉक में है
  • डॉक्‍यूमेंट_रूट में पथ जोड़ते हुए, आपको मिलता है: /var/www/vhosts/news/news/test.htm
  • आपके if (!-e $request_filename)कथन को इस गैर-मौजूद फ़ाइल को कैप्चर करना चाहिए
  • आप के लिए पथ को फिर से लिखना /index.php
  • चूंकि आप lastप्रक्रियाओं का उपयोग शुरू कर रहे हैं (स्थान ब्लॉक से बाहर तोड़कर)
  • /index.phpअब द्वारा कब्जा कर लिया है location /app block

जब आप अपने ऐप लोकेशन ब्लॉक में जाते हैं, तो मूल निर्देश के साथ, ऊपर बताई गई समस्या को कंपाउंड किया जाता है। 'समाचार' ब्लॉक के विपरीत, जहाँ आप गर्भधारण कर सकते हैं बस 'समाचार' को पथ से हटा दें (क्योंकि इसे वापस जोड़ा जाएगा), आप इसे ऐप पथ के लिए नहीं कर सकते हैं, जो 'वेबरोट' में समाप्त होता है।

समाधान aliasनिर्देश में निहित है । यह document_root को नहीं बदलता है, लेकिन यह फ़ाइल पथ को परिवर्तित करता है जो अनुरोध की सेवा के लिए उपयोग किया जाता है। दुर्भाग्य से, rewriteऔर try_filesथोड़ा अप्रत्याशित रूप से व्यवहार करते हैं alias

चलिए एक सरल उदाहरण से शुरू करते हैं - कोई PHP नहीं - सिर्फ HTML और आपका पर्ल ब्लॉक - लेकिन एक फ़ोल्डर संरचना के साथ आपका मिलान (Nginx 1.0.12, CentOS 6 पर परीक्षण):

server {
    server_name example.org;
    error_log /var/log/nginx/example.org.error.log notice;
    access_log /var/log/nginx/example.org.access.log;
    rewrite_log on;

    location = / {
        rewrite ^ /index.pl last;
    }

    location ^~ /community {
        rewrite ^ /index.pl last;
    }

    location ~ \.pl {
        root   /var/www/vhosts/home;

        [fastcgi_stuff...]
    }


    location ^~ /news {
        alias /var/www/vhosts/news;
        index index.htm;

        try_files $uri $uri/ /news/index.htm;
    }

    location ^~ /app {
        alias /var/www/vhosts/app/app/webroot;
        index index.htm;

        try_files $uri $uri/ /app/index.htm;
    }

    location / {
        rewrite ^/(.*) /app/$1 last;
    }
}
  • location = / - केवल रूट पथ से मेल खाएगा
  • location ^~ /community - / समुदाय के साथ शुरू होने वाले हर पथ से मेल खाएगा
  • location ~ \.pl - .pl शामिल सभी फ़ाइलों से मेल खाएगा
  • location ^~ /news - / समाचार के साथ शुरू होने वाले हर पथ से मेल खाएगा
  • location ^~ /app - / एप्लिकेशन के साथ शुरू हर पथ से मेल खाएगा
  • location / - ऊपर से मेल नहीं खाने वाले सभी रास्तों का मिलान होगा

आप को हटाने में सक्षम होना चाहिए ^~- लेकिन यह एक मामूली प्रदर्शन सुधार की पेशकश कर सकता है, क्योंकि यह एक मैच मिलते ही खोज बंद कर देता है।

जबकि PHP ब्लाकों को वापस जोड़ने के लिए यह एक साधारण मामला होना चाहिए, दुर्भाग्य से, थोड़ी सी कठिनाई है - try_files(और आपका पुनर्लेखन) नेस्टेड लोकेशन ब्लॉक के लिए वांछित पथ को समाप्त नहीं करता है - और aliasकेवल एक्सटेंशन के उपयोग से स्थान ब्लॉक में निर्दिष्ट काम नहीं करता है।

एक समाधान अलग स्थान ब्लॉक का उपयोग करना है जो उपनाम निर्देश के साथ एक साथ कैप्चर करते हैं - यह काफी सुरुचिपूर्ण नहीं है, लेकिन जहां तक ​​मैं बता सकता हूं, यह काम करता है (फिर से, Nginx 1.0.12, CentOS 6 पर परीक्षण किया गया - बेशक, मैंने CakePHP, Wordpress और पर्ल को सेटअप नहीं किया था - मैंने प्रत्येक फ़ोल्डर में बस PHP और HTML फ़ाइलों के एक जोड़े का उपयोग किया था)

server {
    server_name example.org;
    error_log /var/log/nginx/example.org.error.log notice;
    access_log /var/log/nginx/example.org.access.log;
    rewrite_log on;

    location = / {
        rewrite ^ /index.pl last;
    }

    location ^~ /community {
        rewrite ^ /index.pl last;
    }

    location ~ \.pl {
        root   /var/www/vhosts/home;
        access_log /var/log/nginx/home.access.log;
        error_log /var/log/nginx/home.error.log;
        include /etc/nginx/fastcgi_params;
        fastcgi_index index.pl;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass  unix:/var/run/fcgiwrap.socket;
    }

    location /news {
        access_log /var/log/nginx/news.access.log;
        error_log /var/log/nginx/news.error.log notice;
        alias /var/www/vhosts/news;
        index index.php;
        try_files $uri $uri/ /news/index.php;
    }

    location ~* ^/news/(.*\.php)$ {
        access_log /var/log/nginx/news.php.access.log;
        error_log /var/log/nginx/news.php.error.log notice;
        alias /var/www/vhosts/news/$1;
        try_files "" /news/index.php;
        include /etc/nginx/fastcgi_params;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_NAME $1;
        fastcgi_param SCRIPT_FILENAME /var/www/vhosts/news/$1;
        fastcgi_pass  127.0.0.1:9000;
    }

    location /app {
        alias /var/www/vhosts/app/app/webroot;
        access_log /var/log/nginx/app.access.log;
        error_log /var/log/nginx/app.error.log notice;
        index index.php;
        try_files $uri $uri/ /app/index.php;
    }

    location ~* ^/app/(.*\.php)$ {
        access_log /var/log/nginx/news.access.log;
        error_log /var/log/nginx/news.error.log notice;
        alias /var/www/vhosts/app/app/webroot/$1;
        try_files "" /app/index.php;
        include /etc/nginx/fastcgi_params;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_NAME $1;
        fastcgi_param SCRIPT_FILENAME /var/www/vhosts/app/app/webroot/$1;
        fastcgi_pass  127.0.0.1:9000;
    }

    location / {
        rewrite ^/(.*) /app/$1 last;
    }
}

उपरोक्त विन्यास, सरल को ऊपर ले जाता है, और दो बदलाव करता है:

  • दो स्थान ब्लॉक जोड़ें:
    • location ~* ^/news/(.*\.php)$ - .php में समाप्त होने वाली सभी फाइलों का मिलान, पथ के साथ / समाचार / के साथ शुरू होगा
    • location ~* ^/app/(.*\.php)$ - .php में समाप्त होने वाली सभी फाइलों से मेल खाएगा, पथ / एप्लिकेशन / के साथ शुरू होने वाले
  • ^~मिलान हटाएं - यह आवश्यक है ताकि दो जोड़े गए स्थान ब्लॉक पथों के विरुद्ध मेल कर सकें (अन्यथा मिलान / समाचार / ऐप ऐप पर बंद हो जाएगा)।

यह ध्यान दिया जाना चाहिए कि स्थान मिलान का क्रम यहां बहुत महत्वपूर्ण है:

  • सटीक मिलान पहले (उपयोग करते हुए =)
  • ^~दूसरे के साथ मेल खाता है
  • मिलान रेक्सक्स ब्लॉक
  • परम्परागत तार - केवल अगर कोई मेल नहीं regex पाया जाता है

एक मिलान रेगेक्स एक सीधे स्ट्रिंग को सुपरडेड करेगा!

उल्लेख का एक महत्वपूर्ण बिंदु यह है कि जब कैप्चर का उपयोग उपनाम के साथ किया जाता है, तो पूरे URL को बदल दिया जाता है - न कि केवल प्रमुख फ़ोल्डर। दुर्भाग्य से, इसका मतलब है कि $fastcgi_script_nameखाली छोड़ दिया गया है - इसलिए, मैंने $1इसके बजाय ऊपर उपयोग किया है।

मुझे यकीन है कि आपको कुछ बदलाव करने की आवश्यकता होगी, लेकिन मूल आधार कार्यात्मक होना चाहिए। आपको आवश्यकतानुसार कई फ़ाइलों में ब्लॉकों को अलग करने में सक्षम होना चाहिए - ऑर्डरिंग को कॉन्फ़िगरेशन को प्रभावित नहीं करना चाहिए।


2
यार, काश, मैं तुम्हें 100 बार उखाड़ सकता। तुम शुद्ध भयानक हो। धन्यवाद!
आंद्रेई सेर्डेलिएक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.