Subdomains + (optional) Domain-Mapping

Update: This article is updated for WordPress 3.5 multisite’s file-handling.

easyengine (ee) note: If you are using easyengine, you can accomplish everything in this article using following command:

 

ee site create example.com --wpsubdom

In this article, we will setup WordPress Multisite using Subdomains. If you haven’t created a WordPress Multisite network, please check this guide first.

Nginx Config

Below is recommended Nginx configuration.

server {
        ##DM - uncomment following line for domain mapping	
        #listen 80 default_server;
	server_name example.com *.example.com ;
	##DM - uncomment following line for domain mapping
	#server_name_in_redirect off;

	access_log   /var/log/nginx/example.com.access.log;
	error_log    /var/log/nginx/example.com.error.log;

	root /var/www/example.com/htdocs;
	index index.php;

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

	location ~ \.php$ {
		try_files $uri =404;
		include fastcgi_params;
		fastcgi_pass 127.0.0.1:9000;
	}

	location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
		access_log off;	log_not_found off; expires max;
	}

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

Domain Mapping

You need to uncomment few lines in above nginx-config to get domain-mapping working. Apart from above config changes, you can read this guide to setup/configure domain-mapping.

Must Read:

29 responses to “Subdomains + (optional) Domain-Mapping”

  1. hi, in which cases is blogs.dir used? i’ve just configured a subdomains multisite with v3.5.1 and uploading an image on blogid=2 creates it under wp-content/uploads/sites/2/ so it’s served as a static file by nginx.

    • It looks like you have installed a fresh WordPress setup.

      From WordPress 3.5, blogs.dir folder is no longer created. You can ignore everything related to blogs.dir. Above config will work without any issues.

      As there are many tutorials related to WordPress Multisite, I will update them in one go soon.

      If you face any issue, please let me know.

  2. I tried using this config but I kept getting a 502 error. I’m on WordPress 3.5.1. Is there something specific I need to change?

  3. Pardon the English because I’m from Brazil.

    I have a WordPress with Nginx, put this configuration in nginx.conf, below the line that already existed. Nginx rebooted and still gives the error.
    http://blog.codehost.com.br/

    Remembering that this is a server with multiple domains.

    Use with Centos WHM

    
    user  nobody;
    
    #no need for more workers in the proxy mode
    
    worker_processes  2;
    error_log  /var/log/nginx/error.log info;
    worker_rlimit_nofile 20480;
    events {
     worker_connections 5120; # increase for busier servers
     use epoll; # you should use epoll here for Linux kernels 2.6.x
    }
    http {
     server_name_in_redirect off;
     server_names_hash_max_size 10240;
     server_names_hash_bucket_size 1024;
     include    mime.types;
     default_type  application/octet-stream;
     server_tokens off;
    
    #remove/commentout disable_symlinks if_not_owner;if you get Permission denied error
    
    disable_symlinks if_not_owner;
    
    sendfile on;
     tcp_nopush on;
     tcp_nodelay on;
     keepalive_timeout  5;
     gzip on;
     gzip_vary on;
     gzip_disable "MSIE [1-6].";
     gzip_proxied any;
     gzip_http_version 1.1;
     gzip_min_length  1000;
     gzip_comp_level  6;
     gzip_buffers  16 8k;
    
    #You can remove image/png image/x-icon image/gif image/jpeg if you have slow CPU
    
    gzip_types    text/plain text/xml text/css application/x-javascript application/xml image/png image/x-icon image/gif image/jpeg application/xml+rss text/javascript application/atom+xml;
     ignore_invalid_headers on;
     client_header_timeout  3m;
     client_body_timeout 3m;
     send_timeout     3m;
     reset_timedout_connection on;
     connection_pool_size  256;
     client_header_buffer_size 256k;
     large_client_header_buffers 4 256k;
     client_max_body_size 200M; 
     client_body_buffer_size 128k;
     request_pool_size  32k;
     output_buffers   4 32k;
     postpone_output  1460;
     proxy_temp_path  /tmp/nginx_proxy/;
     client_body_in_file_only on;
     log_format bytes_log "$msec $bytes_sent .";
     include "/etc/nginx/vhosts/*";
    }
    

    Teste Nginx WordPress

    
    server {
            ##DM - uncomment following line for domain mapping
            listen 80 default_server;
        server_name codehost.com.br *.codehost.com.br ;
        ##DM - uncomment following line for domain mapping
        server_name_in_redirect off;
    
    access_log   /var/log/nginx/codehost.com.br.access.log;
    error_log    /var/log/nginx/codehost.com.br.error.log;
    
    root /home/codehost/public_html;
    index index.php;
    
    location / {
        try_files $uri $uri/ /index.php?$args ;
    }
    
    location ~ \.php$ {
        try_files $uri /index.php;
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
    }
    
    location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
        access_log off; log_not_found off; expires max;
    }
    
    location = /robots.txt { access_log off; log_not_found off; }
    location ~ /\. { deny  all; access_log off; log_not_found off; }
    
    }
    
  4. First – I love your tutorials. They are the best at WordPress / Nginx and Multisite. I appreciate your logic and particularly liked your post showing us the best locations for certain files. I am moving from cpanel/whm to Nginx. The sites I have already moved are so much faster it is insane.

    My question:

    What is the best way to configure a second wordpress multisite on the same nginx configuration. I have configured exactly as you outlined for one – however – I know I run into issues whenever attempt to create another site-enabled config file… specifically in the lines here:

    ##DM - uncomment following line for domain mapping
            listen 80 default_server;
            server_name myfirstmultisitegroupdomain.com *.myfirstmultisitegroupdomain.com ;
            ##DM - uncomment following line for domain mapping
            server_name_in_redirect off;
    

    So when I go to create another multisite group, I do this again:

    ##DM - uncomment following line for domain mapping
            listen 80 default_server;
            server_name myothermultisitedomain.com *.myothermultisitedomain.com ;
            ##DM - uncomment following line for domain mapping
            server_name_in_redirect off;
    

    I have a great server I am using, and I have many small groups. I want to load multiple groups on once server. I have read a couple of places that you cannot put more than one multisite group on one nginx installation. I know that cannot be right.

    Any suggestions or guidance would be greatly appreciated.

    Thanks,

    John

    • You can not have listen 80 default_server; twice.

      If you are using multisite without domain mapping, then you can change listen 80 default_server; to simply listen 80; in one or both config.

      server_name field alone is sufficient to map all subdomains for a particular domain correctly.

      If you are using domain-mapping on both sites then easiest you can do is to have 2 dedicated-IP’s on your server. For example, you get IP’s 1.1.1.1 and 2.2.2.2, then you can change listen 80 default_server; to listen 1.1.1.1:80 default_server; and listen 2.2.2.2:80 default_server; in respective sites.

      If you do not have dedicated-IP’s then on smaller network, change listen 80 default_server; to simply listen 80; and then add all mapped-domains in server_name. This is tedious but will work as long as number of mapped-domains are limited.

  5. Hi,

    When I upload to my media and then go grab the url of the image , it looks like this

    domain.com/wp-content/uploads/sites/37/2013/06/image.png

    Is there some way for /sites/37/ to not show up in the url?

    Thank you so much,

    Nick

  6. I tried copying your config above, save for the few changes relevant to my installation of php-fpm, and some of it works. The wp-admin stuff will work, but going to domain.com downloads the php file as a file named “download”. That is the reason I came here, your config example didn’t fix it though, so there must be something else I am doing wrong?

    server {
    listen 192.168.1.250:80;
    server_name blog.com *.blog.com;
    root /usr/local/www/docs/blog.com/http;
    index index.php;

    #server_name_in_redirect off;

    access_log /usr/local/www/docs/blog.com/logs/access.log;
    error_log /usr/local/www/docs/blog.com/logs/error.log error;

    client_max_body_size 2M;

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

    location ~ \.php$ {
    try_files $uri /index.php;
    #root html;
    fastcgi_pass 127.0.0.1:9000;
    #fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /usr/local/www/docs/blog.com/http/$fastcgi_script_name;
    include fastcgi_params;
    }

    location ~ /\. { deny all; access_log off; log_not_found off; }

    }

    • Sorry about the code thing being messed up in the previous comment. A little more playing around with no progress. Viewing a site, or just the domain name, downloads the index.php file as “download”. I entered in the domain.com/wp-config.php and it seems to actually process that one, as the page returns blank, as expected. Browsing to an invalid filename returns the WordPress pretty file not found page. From the “This is embarassing…” 404 page clicking the default “sample page” (domain.com/sample-page/) works, it seems for whatever reason to not be willing to process the index.php file, everything else seems to be working.

      Thanks for the help.

      • One more comment, or you could delete the other two, if you prefer. I got the issue resolved. Not sure what was wrong in the configuration, but I think hours were wasted due to a problem existing between the keyboard and the chair. To anyone else who sees this, CLEAR THE CACHE ON YOUR BROWSER. It helps. 🙂

        • @Tom

          Glad to know your issue got fixed. 🙂

          In such cases, IMHO, rather than clearing browser cache, try incognito/private-browsing mode OR use CTRL+SHIFT+R (to refresh page without using cache).

  7. Follow the guide step by step for setting up the Ubuntu 12.04 server as well as wordpress. I am attempting to enable multisite with subdomains. Whenever I try to access the subdomain, it takes me to my internet providers page and says “Unable to find”. Any suggestions as to what I can try?

    Using WordPress 3.6.1

  8. Where should we put this config in now? I don’t have a etc\nginx folder as I used the easy install method on ubuntu?

    My problem is that if I point a A entry to my server ie. demo1.mydomain.com and I change the url of the site to that domain everything works.
    If I want to set a second dns demo2.mydomain.com to my server I get a 503 Error from nginx.

    Please help!

    • Hey Daniel, you can use nginx -t to get the path of your nginx configuration file. Then follow the article to add another domain name to nginx.