Opened 11 years ago

Last modified 11 years ago

#314 new enhancement

Dynamic document roots, defaults and prescedence

Reported by: Renich Bon Ciric Owned by:
Priority: minor Milestone:
Component: nginx-core Version: 1.2.x
Keywords: dynamic document root, default Cc:
uname -a: Linux introdeskg02org 3.8.1-201.fc18.x86_64 #1 SMP Thu Feb 28 19:23:08 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.2.7
built by gcc 4.7.2 20121109 (Red Hat 4.7.2-8) (GCC)
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/ --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --with-http_perl_module --with-mail --with-mail_ssl_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic' --with-ld-opt='-Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E'


Hello guys,

Check the following example:

# This is a really cool example of how to have dynamic document roots
# based on the url.
# Nginx will find the document root based on the URL of the request.
# This, combined with a wildcard in your dns file, will let you create
# directories and make them inmmediatelly available for nginx to find.
# Very useful on dev environments or ISPs that have their stuff in order.

server {
    listen 80;
    server_name ~^(?<sub>.+?)\.(?<dom>.+)$;
    root /srv/www/html/$dom/$sub/public;
    index index.html index.htm;
    autoindex on;

    location / {
        try_files $uri $uri/ =404;

    location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
        # Some basic cache-control for static files to be sent to the browser
        expires max;
        add_header Pragma public;
        add_header Cache-Control "public, must-revalidate, proxy-revalidate";

    location = /robots.txt { access_log off; log_not_found off; }
    location = /favicon.ico { access_log off; log_not_found off; }
    location ~ /\. { access_log off; log_not_found off; allow all; }
    location ~ ~$ { access_log off; log_not_found off; deny all; }

That and wildcard domains (*.example.tld) will give you an awesome configuration for one type of website. For example, regular PHP sites, Wordpress, Zend Framework, etc. This is useful in so many ways:

  • Dev environments
    • You don't need to touch your dns nor nginx configuration. You just create the proper dir structure and that's it.
  • ISPs
    • There're a lot of people that develop websites and host them. These settings, as long as they keep the dir structure, work fine.
  • Owned servers
    • if you keep your own server for many sites, just configure once and just deploy with the proper dir structure. You will not have to restart your server (or reload it) or anything of the sorts. Just point the domain to it and upload the files.
  • WebAdmins
    • Web admins can benefit from implementing default configs for most common needs, frameworks and software they use. Besides, it is a lot easier to maintain a single file for all your drupal websites (... also, more dangerous, in case you mess up)

Some problems remain. For example:

# regular html sites

  • example.tld
  • example1.tld
  • phpexample.tld
  • wordpressexample.tld
  • wordpressexample1.tld
  • wordpressexample2.tld

Let's say I have three configurations. One for each website type: html, php, wordpress.

Now, my directory structure would look like this:


# Problems

  • How will nginx know where to look for the website?

There should be a filtering statement, defining which domains are available in that configuration maybe.

  • What about when it does find the domain but not the subdomain it's looking for?

There should be some kind of default configuration. It should default to some document root in case none matches but the domain does; per configuration. For example, if I look for something.example.tld, it should default to www or some other doc root I define.

In general, I think this would be very useful. Once configured, you don't have to touch your nginx configuration again. In case of optimization and tweaks, you just tweak once and all get the benefit of it.

Change History (0)

Note: See TracTickets for help on using tickets.