Dynamic root with subdomain not working with Nginx
nginx
Solution
I finally found the solution, and it's not so pretty.
In fact it was a mix of an old NGinx version (0.7.67, in Debian Squeeze) and some odd reaction (maybe from this version) of the NGinx configuration.
The following code works fine, but successful only in a NGinx version of 1.2.1 (it fails in 0.7.67, and not tested in other versions) :
map $host $username {
~^(?P<user>.+)\.example\.com$ $user;
}
server {
listen 80;
server_name *.example.com;
root /var/www/example.com/$username;
index index.php index.html;
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Make sure files with the following extensions do not get loaded by nginx because nginx would display the source code, and these files can contain PASSWORDS!
location ~* \.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)$|^(\..*|Entries.*|Repository|Root|Tag|Template)$|\.php_ {
deny all;
}
# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
location ~* \.(jpg|jpeg|png|gif|css|js|ico)$ {
expires max;
log_not_found off;
}
location ~ \.php$ {
server_tokens off;
try_files $uri $uri/ /index.php?$args;
fastcgi_pass unix:/tmp/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param GEOIP_COUNTRY_CODE $geoip_country_code;
fastcgi_intercept_errors off;
fastcgi_send_timeout 30s;
fastcgi_read_timeout 30s;
}
}
This alternative also works (for newer PCRE versions) :
map $host $username {
~^(?<user>.+)\.example\.com$ $user;
}
Problem
I tried everything I could, I can not make it work. I'd like to redirect my subdomains to a specific folder in my Debian server using NGinx, here's the configurations I tried : ``` server { listen 8080; server_name ~^(?<user>.+)\.example\.net$; root /srv/www/example.net/$user; } ``` => error is : Starting nginx: [emerg]: unknown "user" variable configuration file /etc/nginx/nginx.conf test failed (note: I also tried without the ^ as indicated here : Nginx server_name regexp not working as variable) If I try this instead : ``` server { listen 8080; server_name *.example.net$; root /srv/www/example.net/$1; } ``` Error is on the request : 2013/08/20 15:38:42 [error] 5456#0: *6 directory index of "/srv/www/example.net//" is forbidden, client: xxx.xxx.xxx.xxx, server: *.example.net, request: "GET / HTTP/1.1", host: "test.example.net:8080" Aka, $1 is empty ! The documentation is wrong then : http://nginx.org/en/docs/http/server_names.html Update: This is working (taken from https://serverfault.com/questions/457196/dynamic-nginx-domain-root-path-based-on-hostname): ``` server { server_name ~^(.+)\.example\.com$; root /var/www/example.com/$1/; } ``` BUT I'd like to display PHP Pages, and if I add the following in my server {}, the $1 is then empty (wtf?) : ``` index index.php index.html; location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { allow all; log_not_found off; access_log off; } # Make sure files with the following extensions do not get loaded by nginx because nginx would display the source code, and these files can contain PASSWORDS! location ~* \.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)$|^(\..*|Entries.*|Repository|Root|Tag|Template)$|\.php_ { deny all; } # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac). location ~ /\. { deny all; access_log off; log_not_found off; } location ~* \.(jpg|jpeg|png|gif|css|js|ico)$ { expires max; log_not_found off; } location ~ \.php$ { server_tokens off; try_files $uri $uri/ /index.php?$args; fastcgi_pass unix:/tmp/php5-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_script_name; fastcgi_param GEOIP_COUNTRY_CODE $geoip_country_code; fastcgi_intercept_errors off; fastcgi_send_timeout 30s; fastcgi_read_timeout 30s; } ```