Caminho raiz do domínio nginx dinâmico com base no nome do host?

11

Estou tentando configurar meu servidor nginx / PHP de desenvolvimento com uma configuração básica de master / catch-all vhost para que eu possa criar ___.framework.locdomínios ilimitados conforme necessário.

server {
        listen 80;
        index index.html index.htm index.php;

        # Test 1
        server_name ~^(.+)\.frameworks\.loc$;
        set $file_path $1;
        root    /var/www/frameworks/$file_path/public;

        include /etc/nginx/php.conf;
}

No entanto, o nginx responde com um erro 404 nesta configuração. Eu sei que o nginx e o PHP estão funcionando e têm permissão porque a localhostconfiguração que estou usando funciona bem.

server {
        listen 80 default;
        server_name localhost;
        root /var/www/localhost;
        index index.html index.htm index.php;

        include /etc/nginx/php.conf;
}

O que devo verificar para encontrar o problema? Aqui está uma cópia do php.conf que ambos estão carregando.

location / {
        try_files $uri $uri/ /index.php$is_args$args;
}

location ~ \.php$ {

        try_files $uri =404;

        include fastcgi_params;
        fastcgi_index index.php;

        # Keep these parameters for compatibility with old PHP scripts using them.
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        # Some default config
        fastcgi_connect_timeout        20;
        fastcgi_send_timeout          180;
        fastcgi_read_timeout          180;
        fastcgi_buffer_size          128k;
        fastcgi_buffers            4 256k;
        fastcgi_busy_buffers_size    256k;
        fastcgi_temp_file_write_size 256k;
        fastcgi_intercept_errors    on;
        fastcgi_ignore_client_abort off;
        fastcgi_pass 127.0.0.1:9000;

}
Xeoncross
fonte

Respostas:

12

Por que não usar:

server_name *.frameworks.loc;
root /var/www/frameworks/$http_host/public;
Michael Hampton
fonte
Isto é exatamente o que eu estava procurando!
Xeoncross
13

A configuração do Nginx não é um programa, é uma declaração. Quando você estiver usando uma configuração como esta:

server {
        server_name ~^(.+)\.frameworks\.loc$;
        ...
        set $file_path $1;
        root    /var/www/frameworks/$file_path/public;
}

Não há como garantir que sua setdiretiva seja executada antes root.

Mas há um truque com a mapdiretiva que eu gosto de usar. Baseia-se no fato que mapé avaliado anteslocation

http {
  map $http_host $rootpath {
    ~^(.?<mypath>+)\.frameworks\.loc$  $mypath;
    default                            /      ;
  }
  ....
  root /var/www/frameworks/$rootpath
}
DukeLion
fonte
Parece divertido, pretendo jogar mais com o mapa agora. Também não sabia que os arquivos de configuração não foram processados ​​de maneira linear.
Xeoncross
Qual é o objetivo $mypathdaqui? Não é usado em nenhum lugar.
kodeart
@kodeart $mypathé o grupo de resultados para regex ~^(.?<mypath>+)\.frameworks\.loc$e $rootpathé o resultado de todo o truque do mapa.
Fabio Montefuscolo
4

Além da excelente resposta da DukeLion , eu precisava mudar de linha

~^(.?<mypath>+)\.frameworks\.loc$ $mypath;

para

~^(?P<mypath>.+)\.frameworks\.loc$ $mypath;

no meu /etc/nginx/nginx.confarquivo, como sugerido aqui .

Adicionando

root /var/www/frameworks/$rootpath

no /etc/nginx/sites-available/defaultfuncionou bem depois disso.

zub0r
fonte
0

Talvez você possa ver o lighttpd também. Ele tem suporte para exatamente o que você está perguntando aqui. É chamada mod_evhost .

Ativar evhost

Adicione as seguintes linhas ao seu lighttpd.conf. Se você estiver usando a distribuição base Debian / Ubuntu, basta vincular ou copiar de /etc/lighttpd/conf-available/10-evhost.confpara /etc/lighttpd/conf-enabled/.

    # http://redmine.lighttpd.net/wiki/1/Docs:ModEVhost
    server.modules + = ("mod_evhost")
    evhost.path-pattern = "/ home / www /% _"

O %_(curinga) em evhost.path-patten significa usar o nome de domínio completo (por exemplo, www.example.com). Uma solicitação para www.example.com será direcionada automaticamente para a raiz do documento /home/www/www.example.com/.

Adicionar site adicional é tão fácil quanto criar outro diretório /home/wwwcom o nome de domínio completo. Nenhuma alteração no arquivo de configuração Lighttpd.

Existem outros curingas e podem ser usados ​​para criar uma estrutura de diretórios. Eles são os seguintes

    %% => sinal de%
    % 0 => nome de domínio + tld
    % 1 => tld
    % 2 => nome de domínio sem tld
    % 3 => nome do subdomínio 1
    % 4 => nome do subdomínio 2
    % _ => nome completo do domínio

Informações detalhadas estão aqui .

PS: Habilitar o PHP também é fácil se você estiver na plataforma debian / ubuntu. Basta ativar 10-fastcgi.confe 15-fastcgi-php.conf.

John Siu
fonte
0

O NGINX usa a biblioteca de expressões regulares PCRE.
A partir da server_namediretiva NGINX v0.8.25, permite capturas nomeadas .

Capturas nomeadas em expressões regulares criam variáveis ​​( 0.8.25 ) que podem ser usadas posteriormente em outras diretivas. Ao usar parênteses nomeados, o NGINX define automaticamente uma variável para cada parêntese nomeado, durante a avaliação de nomes de servidores (eu acho).

Eu uso o seguinte snippet para "cercar" os ambientes de desenvolvedores. «Usuário» refere-se ao nome de usuário e «proj» ao projeto em que trabalham:

# ...
server_name ~^(?<user>[^.]+)\.(?<proj>[^.]+).dev.local-server.com;
root /home/$user/www/$proj;
# ...

Observe que a configuração do nginx é declarativa e, como tal, as declarações estáticas podem sempre ser mais rápidas em comparação com os valores e variáveis ​​calculados em tempo de execução. A avaliação de expressões regulares é relativamente cara, acho que deve ser usada com parcimônia em ambientes pesados ​​(de produção).

Stphane
fonte