Nginx çoklu konum sorunları


15

Şu anda 3 uygulamayı bir depodan 3'e ayırmaya çalışıyorum, ancak url yapısını koruyarak, temel olarak aynı alan altındaki farklı konumların farklı uygulamalar tarafından teslim edilmesi gerekiyor.

Mücadele ettiğim şey, uygulamalardan birinin var olmayan URL'ler için geri dönüş olması gerektiğidir, bu yüzden birincisi uyuşmuyorsa ve ikincisi uyuşmuyorsa, üçüncüsü isteği ele almalıdır

Sahip olduğum yapı:

/ etc / nginx / sites özellikli / main_site, burada, sunucu_adı ve sahip olduğum günlükler dışında, include /etc/nginx/subsites-enabled/*her bir uygulama için bir tane olmak üzere 3 yapılandırma dosyam var.

3 yapılandırma dosyasının her biri bir konum bloğu içerir.

Normalde negatif temelde denedim (temelde diğer uygulamalar ele urls sabit kodlamaya çalışıyorum) ama başarısız oldu.

Özetlemek gerekirse:

/ ve / topluluğu /etc/nginx/subsites-enabled/example.org/home (birkaç perl betiği) tarafından teslim edilmelidir

/ haberler /etc/nginx/subsites-enabled/example.org/news (wordpress) tarafından iletilmelidir

diğer her şey /etc/nginx/subsites-enabled/example.org/app (cake app) tarafından teslim edilmelidir

Perl biti iyi çalışıyor. Yaşadığım sorun, uygulamanın haberleri devralması (muhtemelen eşleştiği için. *), Çeşitli seçenekleri denedim (2 gündür bu oldum), ancak hiçbiri tüm sorunları çözmedi (bazen statik varlıklar çalışmaz, vb.).

Yapılandırmam:

/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 / alt siteler etkin / haber

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 / alt siteler etkin / app:

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) çeşitli yönlendirmelerin (var olmayan URL'ler için olanlar da dahil) nereye gitmesi gerektiğine ilişkin bazı örneklerle birlikte yapılandırmanızı yayınlayın. b) varsayılan uygulamanızla eşlenen adlandırılmış bir konum bloğuyla ( @öneki kullanarak ) try_files kullanın . Ayrıca, 404'ü adlandırılmış bir konumla eşleyen bir hata_sayfası da kurabilirsiniz.
cyberx86

@ cyberx86 Daha fazla ayrıntı ekledim ve yapılandırmam
Andrei Serdeliuc

Hızlı bir bakış birkaç şey önerir: a) normal ifade eşleşmesi geleneksel dizelerden önceliklidir - böylece haber bloğunuz yerine uygulama bloğunuz eşleşir - deneyin location ^~ /news. b) uygulama bloğunuz için, bunu yapabilmeniz gerekir location /(bu aynı değildir location = /, ancak önceden eşleşmemiş olan her şeyle eşleşmelidir. c) bazı durumlarda (özellikle normal ifadeler), sipariş önemlidir - 3'ü birleştirmek isteyebilirsiniz dosyaları bloklar doğru sırada olacak şekilde tek bir dosyaya dönüştürün. Ayrıca, yerine try_files kullanın !-e. Son olarak bkz. Wiki.nginx.org/HttpCoreModule#location .
cyberx86

Bunları tek bir dosyada birleştirmek de dahil olmak üzere hemen hemen her varyasyonunu denedim (ayrı olarak dağıtıldıkları için ayrı olmaları gerekse de), hiçbiri çalışmıyor. Haberler sadece uygulama tarafından ele alınır.
Andrei Serdeliuc

Bence, başlangıçta beklediğimden biraz daha zor - ama fikirlere karşı kesinlikle zevkli bir şekilde çözdüğümü düşünüyorum. Bulmaca için teşekkürler.
cyberx86

Yanıtlar:


47

Konfigürasyonunuzda yanlış olan birkaç şey var, ikisi de ilgili:

  1. Konum bloğundaki yollar hala eşleşen yolu içerir.
  2. 'Son' ile yeniden yazarlar, bir eşleşme için mevcut tüm konumları arayarak devam eder (geçerli konum bloğundan çıkarlar).

Örneğin, example.org/news/test.htm URL'sini alın

  • location /newsBlok bunu maç olacak
  • Kullanılan yol o zaman /news/test.htm- bu konum bloğunda olduğu için değişmez
  • Document_root yolunu ekleyerek şunları elde edersiniz: /var/www/vhosts/news/news/test.htm
  • Sizin if (!-e $request_filename)açıklamada bu varolmayan bir dosya yakalamak gerekir
  • Yolunu yeniden yazarsınız /index.php
  • Kullandığınız lastiçin işlemler baştan başlar (konum bloğundan çıkmak)
  • /index.phpartık location /app block.

Kök yönergede yukarıda belirtilen sorun, uygulama konum bloğunuza gittiğinizde birleşir. Muhtemelen 'haberleri' yoldan kaldırabileceğiniz 'haber' bloğunun aksine (geri ekleneceği için) bunu 'webroot' ile biten uygulama yolu için yapamazsınız.

Çözüm aliasdirektifte yatmaktadır . Bu, document_root'u değiştirmez, ancak isteği sunmak için kullanılan dosya yolunu değiştirir. Ne yazık ki rewriteve try_filesbeklenmedik bir şekilde davranma eğilimindedir alias.

Basit bir örnekle başlayalım - PHP yok - sadece HTML ve Perl bloğunuz - ancak sizinkiyle eşleşen bir klasör yapısı ile (Nginx 1.0.12, CentOS 6'da test edilmiştir) başlayalım:

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 = / - yalnızca kök yolu ile eşleşecek
  • location ^~ /community - / community ile başlayan her yolla eşleşecek
  • location ~ \.pl - .pl içeren tüm dosyalarla eşleşir
  • location ^~ /news - / news ile başlayan her yolla eşleşecek
  • location ^~ /app - / app ile başlayan her yolla eşleşir
  • location / - yukarıda eşleşmeyen tüm yollarla eşleşecek

^~- işaretini kaldırabilmeniz gerekir, ancak bir eşleşme bulunduğunda aramayı durdurduğundan hafif bir performans iyileştirmesi sunabilir.

PHP bloklarını tekrar eklemek basit bir mesele olsa da, ne yazık ki, hafif bir zorluk var - try_files(ve yeniden yazmanız) iç içe konum bloğuna istenen yolu geçmiyor - ve aliassadece uzantı olduğunda konum bloğunda belirtilen çalışmaz.

Bir çözüm, takma ad yönergesi ile birlikte bir yakalama gerçekleştiren ayrı konum blokları kullanmaktır - oldukça zarif değil, ancak anlayabildiğim kadarıyla işe yarıyor (tekrar, Nginx 1.0.12, CentOS 6 - üzerinde test edildi tabii ki, CakePHP, Wordpress ve Perl'i kurmadım - her klasörde birkaç PHP ve HTML dosyası kullandım)

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

Yukarıdaki yapılandırma, yukarıdaki basit olanı alır ve iki değişiklik yapar:

  • İki konum bloğu ekleyin:
    • location ~* ^/news/(.*\.php)$ - .php ile biten tüm dosyalarla / news / ile başlayan yollarla eşleşir
    • location ~* ^/app/(.*\.php)$ - .php ile biten tüm dosyalarla / app / ile başlayan yollarla eşleşir
  • ^~Eşleştirmeyi kaldırın - bu, eklenen iki konum bloğunun yollarla eşleşebilmesi için gereklidir (aksi takdirde eşleştirme / news veya / app bloklarında durur).

Konum eşleştirme siparişinin burada çok önemli olduğuna dikkat edilmelidir:

  • İlk olarak tam eşleşmeler (kullanılarak =)
  • ^~Saniye ile eşleşir
  • Normal regex bloklarını eşleştirme
  • Geleneksel dizeler - yalnızca eşleşen normal ifade bulunmuyorsa

Eşleşen bir normal ifade düz bir dizenin yerini alacaktır!

Önemli bir nokta, yakalamalar takma adla kullanıldığında, yalnızca önde gelen klasörün değil, tüm URL'nin değiştirilmesidir. Ne yazık ki, bu $fastcgi_script_nameboş bırakıldığı anlamına geliyor - bu yüzden $1bunun yerine yukarıda kullandım.

Birkaç değişiklik yapmanız gerekeceğinden eminim, ancak temel öncül işlevsel olmalı. Blokları gerektiği gibi birden fazla dosyaya ayırabilmelisiniz - sipariş yapılandırmayı etkilememelidir.


2
Dostum, keşke seni 100 kere vurabilseydim. Sen saf harikasın. Teşekkürler!
Andrei Serdeliuc
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.