Nginx vários problemas de localização

12

Atualmente, estou tentando separar 3 aplicativos de um repositório em 3, mas mantendo a estrutura de URL, portanto, basicamente diferentes locais no mesmo domínio precisam ser entregues por aplicativos diferentes.

O que estou enfrentando é que um dos aplicativos precisa ser o substituto de URLs inexistentes, então, se o primeiro não corresponder e o segundo não, o terceiro deve lidar com o solicitação

A estrutura que eu tenho é:

/ etc / nginx / sites-enabled / main_site, aqui, além de server_name e logs, eu tenho include /etc/nginx/subsites-enabled/* , onde eu tenho 3 arquivos de configuração, um para cada um dos aplicativos.

Cada um dos três arquivos de configuração contém um bloco de localização.

Eu tentei lookahead negativo no regex (basicamente tentando codificar os URLs que os outros aplicativos manipulam), mas falhei.

Então, para resumir:

A comunidade

/ e / deve ser entregue por /etc/nginx/subsites-enabled/example.org/home (alguns scripts perl)

/ news deve ser entregue por /etc/nginx/subsites-enabled/example.org/news (wordpress)

tudo o mais deve ser fornecido por /etc/nginx/subsites-enabled/example.org/app (app cake)

O bit perl funciona bem. O problema que estou tendo é que o aplicativo está assumindo notícias (provavelmente porque coincide com. *), Eu tentei várias opções (eu estive nisso por 2 dias), mas nenhum deles resolveu todos os problemas (às vezes ativos estáticos não funcionariam, etc).

Minha configuração é:

/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 / subsites-enabled / news

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 / subsites-enabled / 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;
  }
}
    
por Andrei Serdeliuc 17.02.2012 / 12:23

1 resposta

42

Existem algumas coisas erradas na sua configuração, sendo as duas mais relevantes:

  1. Os caminhos dentro de um bloco de localização ainda incluem o caminho correspondente.
  2. Reescreve com "last" e analisa todos os locais disponíveis para uma partida (eles quebram o bloco de localização atual).

Por exemplo, use o URL example.org/news/test.htm

  • O bloco location /news corresponderá a ele
  • O caminho usado é, então, /news/test.htm - isso não muda, apenas porque está no bloco de localização
  • Adicionando o caminho para o document_root, você obtém: /var/www/vhosts/news/news/test.htm
  • Sua declaração if (!-e $request_filename) deve capturar este arquivo não existente
  • Você reescreve o caminho para /index.php
  • Como você está usando last , os processos começam de novo (saindo do bloco de localização)
  • /index.php agora é capturado pelo location /app block .

O problema mencionado acima, com a diretiva raiz, é combinado quando você vai para o bloco de localização do seu aplicativo. Ao contrário do bloco "news", onde você poderia simplesmente remover "notícias" do caminho (já que ele será adicionado novamente), você não pode fazer isso para o caminho do aplicativo, que termina em "webroot".

A solução está na diretiva alias . Isso não altera o document_root, mas altera o caminho do arquivo usado para atender à solicitação. Infelizmente, rewrite e try_files tendem a se comportar um pouco inesperadamente com alias .

Vamos começar com um exemplo simples - sem PHP - apenas HTML e seu bloco Perl - mas com uma estrutura de pastas correspondente à sua (testada no 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 = / - corresponderá apenas ao caminho da raiz
  • location ^~ /community - corresponderá a todos os caminhos que começam com / community
  • location ~ \.pl - corresponderá a todos os arquivos que contiverem .pl
  • location ^~ /news - corresponderá a todos os caminhos iniciados por / news
  • location ^~ /app - corresponderá a todos os caminhos que começam com / app
  • location / - corresponderá a todos os caminhos não correspondidos acima

Você deve conseguir remover o ^~ , mas ele pode oferecer uma pequena melhora de desempenho, pois interrompe a pesquisa depois que uma correspondência é encontrada.

Embora deva ser simples adicionar os blocos do PHP de volta, infelizmente há uma pequena dificuldade - try_files (e sua reescrita) não acaba passando o caminho desejado para o bloco de localização aninhado - e usar alias quando somente a extensão é especificada no bloco de localização não funciona.

Uma solução é usar blocos de localização separados que executam uma captura junto com a diretiva de alias - não é muito elegante, mas pelo que eu sei, funciona (novamente, testado no Nginx 1.0.12, CentOS 6 - Claro, eu não configurei o CakePHP, Wordpress e Perl - eu usei apenas alguns arquivos PHP e HTML em cada pasta)

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

A configuração acima, pega a simples acima, e faz duas alterações:

  • Adicione dois blocos de localização:
    • location ~* ^/news/(.*\.php)$ - corresponderá a todos os arquivos terminados em .php, com caminhos começando com / news /
    • location ~* ^/app/(.*\.php)$ - corresponderá a todos os arquivos terminados em .php, com caminhos começando com / app /
  • Remova a ^~ matching - isso é necessário para que os dois blocos de localização adicionados possam corresponder aos caminhos (caso contrário, a correspondência seria interrompida nos blocos / news ou / app).

Deve notar-se que a encomenda da correspondência de localização é muito importante aqui:

  • Correspondências exatas primeiro (usando = )
  • Corresponde a ^~ segundo
  • Correspondência de blocos de expressão regular
  • Strings convencionais - somente se nenhuma regex correspondente for encontrada

Um regex correspondente substituirá uma string reta!

Um ponto importante de menção é que quando as capturas são usadas com alias, a URL inteira é substituída - não apenas a pasta principal. Infelizmente, isso significa que $fastcgi_script_name está vazio - por isso, usei $1 acima.

Tenho certeza de que você precisará fazer algumas alterações, mas a premissa básica deve ser funcional. Você deve ser capaz de separar os blocos em vários arquivos, conforme necessário - a ordenação não deve afetar a configuração.

    
por 18.02.2012 / 08:43

Tags