I have the following questions about my server block(s) for a WordPress site running solely on https, with nginx and W3TC browser caching.


Ubuntu - 14.04LTS

nginx - 1.4.6

PHP - 5.5.9

mysql - Ver 14.14 Distrib 5.5.41

My questions are as follows:

  1. Does the order of the "location" sections matter?
  2. Does the order of the W3TC block matter?
  3. I've seen some where "ssl" is put in the listen directive instead of using "ssl on;" later -- does it matter?
  4. I handle www => non-www in the top server block, but I'm not explicitly addressing http://domain.com => https://domain.com (forcing SSL) -- yet it somehow is doing that for me. Any ideas why that's working even though I haven't told it to? I'm glad it's working, I just want to understand why it's working.
  5. Any other general advice on the setup is appreciated as well. Thanks!

Virtual Host Config:

server {
  server_name www.domain.com;
  rewrite ^(.*) https://domain.com$1 permanent;

server {
  listen 443 default_server;
  server_name domain.com;

  root /usr/share/nginx/html/domain.com;
  index index.php index.html index.htm;

  # BEGIN W3TC Browser Cache
  gzip on;
  gzip_types text/css text/x-component application/x-javascript application/javascript text/javascript text/x-js text/richtext image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;
  # END W3TC Browser Cache

  ssl on;
  ssl_certificate /etc/ssl/certs/domain.com.rapidssl.crt;
  ssl_certificate_key /etc/ssl/private/domain.com.key;
  ssl_session_timeout 5m;
  ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
  ssl_prefer_server_ciphers on;

  location / {
    try_files $uri $uri/ /index.php?q=$uri&$args;

  error_page 404 /404.html;
  error_page 500 502 503 504 /50x.html;
  location = /50x.html {
    root /usr/share/nginx/html;

  location ~ \.php$ {
    try_files $uri =404;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;

1 Answer 1


Please don't post multiple questions in one.

The first step, when you don't know how something works, is to search for the documentation. In the case of nginx, directives are exhaustively explained through the official documentation directive index.

  1. It depends on the location block nature. Prefixed location blocks order is not important, but regex location blocks order is, since the first one matching the request URI will be picked.

  2. Configuration directives order does not matter except for few cases like if blocks. Gzip directives are not part of these.

  3. In fact ssl on is the old way to do it and the listen directive parameter ssl is the new one. The usage of ssl on forces the server block to accept HTTPS only while the usage of the listen directive parameter allows to handle both HTTP and HTTPs in the same server block.

  4. Actually you explicitely asked nginx to do this. Another way to have the same result is using return 301 https://domain.com$request_uri. The rewrite patten ^(.*) matches all URIs and capture them. Then it rewrites them permanently (301 redirect) to https://domain.com<uri>. Refer to the documentation to understand how the rewrite directive works if you are confused.

  5. Opinion-based questions do not fit SF standards.

  • Thanks a million for your quick reply Xavier, can you explain your answer to #4 a bit more though? I was under the impression that my first server block would redirect only when "www" existed -- but it would Not capture and redirect something like domain.com (non www) => domain.com.
    – Paul
    Jan 27, 2015 at 20:06
  • @Paul If you don't define explicitely a default server block for a given port (i.e. the server block that will handle all Host headers not matched by the server_name directives of other server blocks also listening on that port) then the first one in your configuration files reading order will be used. In your case you have only two server blocks, each listening on a different port so they are considered as default server blocks for each port, thus they will process all requests no matters the Host header value in the incoming request. Jan 27, 2015 at 20:12
  • 1
    Ah, that makes sense. So it is equivalent of server { listen 80 default_server; server_name domain.com www.domain.com; rewrite ^(.*) https://domain.com$1 permanent; }
    – Paul
    Jan 27, 2015 at 22:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .