Hosting Ghost blog with Nginx - config example with www redirect and SSL by LetsEncrypt

March 19, 2016 in #Server

Here's a sample Nginx configuration for Ghost blogging platform, that includes: 1) standard proxy configuration to successfuly host Ghost blog; 2) redirect "www" to "non-www" website; 3) use "https" over "http" website;

######################################################################
# Redirect http://www.your-site.com to https://your-site.com 
######################################################################
server {  
    listen          80;
    server_name     www.your-site.com;
    return          301 https://your-site.com$request_uri;
}

######################################################################
# Redirect https://www.your-site.com to https://your-site.com 
######################################################################
server {  
    listen          443;
    server_name     www.your-site.com;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/your-site.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-site.com/privkey.pem;

    ssl_session_timeout 180m;
    ssl_session_cache shared:SSL:20m;

    ssl_prefer_server_ciphers on;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

    return          301 https://your-site.com$request_uri;
}

######################################################################
# Redirect http://your-site.com to https://your-site.com 
######################################################################
server {  
    listen          80;
    server_name     your-site.com;
    return          301 https://$host$request_uri;
}

######################################################################
# Handling https://your-site.com - proxy, logs, ssl configuration 
######################################################################
server {  
    listen          443;
    server_name     your-site.com;

    access_log      /var/log/nginx/your-site.access.log;
    error_log       /var/log/nginx/your-site.error.log;

    location / {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header Host $http_host;
            proxy_pass http://127.0.0.1:2368;
    }

    ssl on;
    ssl_certificate /etc/letsencrypt/live/your-site.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-site.com/privkey.pem;

    ssl_session_timeout 180m;
    ssl_session_cache shared:SSL:20m;

    ssl_prefer_server_ciphers on;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
}

This example assumes that you have already set-up SSL by LetsEncrypt (if you have not, check this tutorial) and added "www" A record in your domain configuration - my DigitalOcean domain configuration looks like this:

A-Record

Note that you need to set correct production URL in your Ghost config.js file in order to use this nginx configuration:

config = {
    ...
    production: {            
        url: 'https://your-site.com',
        ...
    }
    ...
}

If you did it all correctly, you should now have your site running on https://your-site.com! If you try opening the "http" website or any website with "www", you'll be redirected to correct one - "non-www-https". Enjoy!