Current Situation:

I have succesfully managed to manualy set up an SSL certificate on my Serverpilot (nginx/apache) server. Because my website runs on a Serverpilot server, it is partly nginx, partly Apache. I could do all the redirects in Apache on my server but I prefer to do it the correct way in my nginx configuration file, since I have read that this is much more efficient way.

Since nginx is managed by serverpilot I had to do the changes in a seperate nginx configuration file which is located in this folder on my server: /etc/nginx-sp/vhosts.d. As you can see, Serverpilot does not use the standard nginx configuration, with the Serverpilot install comes the Serverpilot configuration files.

There are two files in this /etc/nginx-sp/vhosts.d folder:

  1. example.conf (this is the standard configuration file of Serverpilot. I didn't change it)
  2. example.ssl.conf (this is the file I have created with the ssl rules)

From what I understand, Nginx reads the first .conf first and will read the second .conf second. Is that correct? What

The example.conf (Serverpilot standard config file) contains the following:

server {
  listen       80;  
  listen       [::]:80;  

root   /srv/users/serverpilot/apps/example/public;

access_log  /srv/users/serverpilot/log/example/example_nginx.access.log main;
error_log  /srv/users/serverpilot/log/example/example_nginx.error.log;

proxy_set_header    Host              $host;
proxy_set_header    X-Real-IP         $remote_addr;
proxy_set_header    X-Forwarded-For   $proxy_add_x_forwarded_for;

include /etc/nginx-sp/vhosts.d/example.d/*.nonssl_conf;
include /etc/nginx-sp/vhosts.d/example.d/*.conf;

I have created an example.ssl.conf containing the following:

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name  example.net www.example.net;

ssl on;

# certificates
ssl_certificate         /etc/nginx-sp/certs/example.net/example.net.chained.crt;
ssl_certificate_key     /etc/nginx-sp/certs/example.net/example.net.key;

    #SSL Optimization
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:20m;
ssl_session_tickets off;

    # modern configuration
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;


    # OCSP stapling 
    ssl_stapling on; 
    ssl_stapling_verify on; 

    # verify chain of trust of OCSP response 
    ssl_trusted_certificate /etc/nginx-sp/certs/example.net/example.net.chained.crt;
    #root directory and logfiles 
    root /srv/users/serverpilot/apps/example/public; 

    access_log /srv/users/serverpilot/log/example/example_nginx.access.log main; 
    error_log /srv/users/serverpilot/log/example/example_nginx.error.log; 

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-SSL on; 
    proxy_set_header X-Forwarded-Proto $scheme; 

    include /etc/nginx-sp/vhosts.d/example.d/*.nonssl_conf; 
    include /etc/nginx-sp/vhosts.d/example.d/*.conf; 

I have tested Redirect chain with this configuration

I have tested the redirects by filling of all possible url's combinations in https://httpstatus.io/. This is the test result:

url                          statuscodes
url with http + www          301  → 200 (1 redirect)
url with http                301  → 200 (1 redirect)    
url with https + www         301  → 200 (1 redirect)
url with https               200        (0 redirect)

My question is: the redirect from http + www to https is performed in one step. Is this correct? If I test a few other websites, there is always one redirect conducted in two steps. So in my case a redirect from url with http + www should be: 301 → 301 → 200 (2 redirect)

Did I make a mistake somewhere? Or is this the optimum solution?

I hope you can help me out.

Kind regards, Jan


  1. Redirect should be limited to max. 1 step (301 -> 200)
  2. The redirect should be performed as fast as possible by the server
  3. The config files should be protected from serverpilot updates, so when serverpilot updates it's system, no files get overwritten, no errors will take place.
  4. Redirects should be accepted by the most common browsers (Chrome, Firefox, IE, Safari)

I have read in an article: https://serverfault.com/a/258424/377649 that 'the best way to accomplish this is using three server blocks: one to redirect http to https, one to redirect the https www-name to no-www, and one to actually handle requests.'


Why are you playing with .htaccess files? That's Apache, not Nginx.

Here's how you generally do a rewrite rule in Nginx. This goes into your site config file.

location /path/ {
  return 301 https://www.example.com/path/;

Here's how you do the redirect to the root domain, you use two location blocks

server {
  listen 443 ssl http2; # http2 only if you built that module in
  server_name www.example.com;

  ssl_certificate /path/to/file;
  ssl_certificate_key /path/to/file;

  # Insert other SSL configuration

  return 301 https://example.com$request_uri;

server {
  listen 80;
  server_name example.com www.example.com;
  return 301 https://example.com$request_uri;
| improve this answer | |
  • Hi Tim, thank you for answering, I had some progress last days and updated my question with extra info on my situation. I hope everything is clear and you can help me out answering my questions. – Jan Pieters Sep 28 '16 at 15:16
  • What happened when you tried my suggestion? You haven't described the relationship between Apache and Nginx, which makes it difficult to answer your question unless you're experienced with Serverpilot, which I've never even heard of. – Tim Sep 28 '16 at 18:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.