¿Ruta raíz del dominio nginx dinámico basada en el nombre de host?

11

Estoy tratando de configurar mi servidor nginx / PHP de desarrollo con una configuración vhost master / catch-all básica para que pueda crear ___.framework.locdominios ilimitados según sea necesario.

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

Sin embargo, nginx responde con un error 404 para esta configuración. Sé que nginx y PHP están funcionando y tienen permiso porque la localhostconfiguración que estoy usando funciona bien.

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

        include /etc/nginx/php.conf;
}

¿Qué debo verificar para encontrar el problema? Aquí hay una copia de ese php.conf que ambos están cargando.

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
fuente

Respuestas:

12

¿Por qué no solo usar:

server_name *.frameworks.loc;
root /var/www/frameworks/$http_host/public;
Michael Hampton
fuente
¡Esto es justo lo que estaba buscando!
Xeoncross
13

La configuración de Nginx no es un programa, es una declaración. Cuando está utilizando la configuración de esta manera:

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

No hay forma de garantizar que su setdirectiva se ejecute antes root.

Pero hay un truco con la mapdirectiva que me gusta usar. Se basa en un hecho que mapse evalúa anteslocation

http {
  map $http_host $rootpath {
    ~^(.?<mypath>+)\.frameworks\.loc$  $mypath;
    default                            /      ;
  }
  ....
  root /var/www/frameworks/$rootpath
}
DukeLion
fuente
Esto parece divertido, planeo jugar más con el mapa ahora. Tampoco sabía que los archivos de configuración no se procesaron de forma lineal.
Xeoncross
¿Qué sentido tiene $mypathaquí? No se usa en ningún lado.
kodeart
@kodeart $mypathes el grupo de resultados para regex ~^(.?<mypath>+)\.frameworks\.loc$y $rootpathes el resultado de todo el truco del mapa.
Fabio Montefuscolo
4

Además de la gran respuesta de DukeLion , necesitaba cambiar de línea

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

a

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

en mi /etc/nginx/nginx.confarchivo como se sugiere aquí .

Agregando

root /var/www/frameworks/$rootpath

en /etc/nginx/sites-available/defaultbien trabajado después de eso.

zub0r
fuente
0

Quizás también puedas mirar lighttpd. Tiene soporte para exactamente lo que está preguntando aquí. Se llama mod_evhost .

Habilitar evhost

Agregue las siguientes líneas en su lighttpd.conf. Si está utilizando la distribución base de Debian / Ubuntu, simplemente enlace suave o copie de /etc/lighttpd/conf-available/10-evhost.confa /etc/lighttpd/conf-enabled/.

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

El %_(comodín) en evhost.path-patten significa usar el nombre de dominio completo (por ejemplo, www.example.com). Una solicitud de www.example.com se dirigirá automáticamente a la raíz del documento /home/www/www.example.com/.

Agregar un sitio adicional es tan fácil como crear otro directorio /home/wwwcon un nombre de dominio completo. No hay cambios en el archivo de configuración Lighttpd.

Hay otros comodines y se pueden usar para construir la estructura de directorios. Son como sigue

    Signo %% =>%
    % 0 => nombre de dominio + tld
    % 1 => tld
    % 2 => nombre de dominio sin tld
    % 3 => nombre del subdominio 1
    % 4 => nombre del subdominio 2
    % _ => nombre de dominio completo

La información detallada está aquí .

PD: Habilitar PHP también es fácil si estás en la plataforma debian / ubuntu. Solo habilita 10-fastcgi.confy 15-fastcgi-php.conf.

John Siu
fuente
0

NGINX usa la biblioteca de expresiones regulares PCRE.
A partir de la server_namedirectiva NGINX v0.8.25 permite capturas con nombre .

Las capturas con nombre en expresiones regulares crean variables ( 0.8.25 ) que luego se pueden usar en otras directivas. Al usar paréntesis con nombre, NGINX establece automáticamente una variable para cada paréntesis con nombre, durante la evaluación de nombres de servidor (supongo).

Utilizo el siguiente fragmento para "cercar" los entornos de desarrolladores. «Usuario» se refiere a su nombre de usuario y «proyecto» al proyecto en el que trabajan:

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

Tenga en cuenta que la configuración de nginx es declarativa y, como tal, las declaraciones estáticas siempre pueden ser más rápidas en comparación con los valores y variables calculados en tiempo de ejecución. La evaluación de expresiones regulares es relativamente costosa, supongo que debe usarse con parsimonia en entornos de carga pesada (producción).

Stphane
fuente