In general, my journey to set up a Ghost instance on Digital Ocean wasn't too bad; however, I did end up with a few hiccups. For one, I'm still waiting on my Mailgun set-up to work. For another, I struggled to determine how to establish redirects from WWW to non-WWW and HTTP to HTTPS.

For the latter, I scoured the world wide web looking for some sort of tutorial or blog post that would help me out. I failed to find one but I did find a discussion on the Digital Ocean Discourse that I have since lost the link to.

The discussion outlined that if you already have set up SSL with your non-WWW domain, you can perform the following steps to implement the redirects correctly: run

ghost config url https://www.javednissar.ca
Replace javednissar.ca with your domain

Then, run

ghost setup nginx ssl
This will setup nginx and ssl with the www subdomain by getting a new ssl certificate for www.javednissar.ca

Afterwards, you'll need to go into the NGINX configuration files in /var/www/ghost/system/files. In my case, I had to modify javednissar.ca.conf (the configuration for http://javednissar.ca), www.javednissar.ca.conf (the configuration for http://www.javednissar.ca), and www.javednissar.ca-ssl.conf (the configuration for https://www.javednissar.ca). In these files you'll need to comment out the location block that is not for ~/.well-known (that's necessary for renewing the SSL certificate with Let's Encrypt) and then you need to add the following as the last line of the server block:

return 301 https://javednissar.ca$request_uri
Replace javednissar.ca with your non-WWW URL

The current contents of javednissar.ca.conf, www.javednissar.ca.conf, and www.javednissar.ca-ssl.conf are below.

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

    server_name javednissar.ca;
    root /var/www/ghost/system/nginx-root; # Used for acme.sh SSL verification (https://acme.sh)

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

    location ~ /.well-known {
        allow all;
    }

    client_max_body_size 50m;

    return 301 https://javednissar.ca$request_uri;
}
server {
    listen 80;
    listen [::]:80;

    server_name www.javednissar.ca;
    root /var/www/ghost/system/nginx-root; # Used for acme.sh SSL verification (https://acme.sh)

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

    location ~ /.well-known {
        allow all;
    }

    client_max_body_size 50m;

    return 301 https://javednissar.ca$request_uri;
}
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name www.javednissar.ca;
    root /var/www/ghost/system/nginx-root; # Used for acme.sh SSL verification (https://acme.sh)

    ssl_certificate /etc/letsencrypt/www.javednissar.ca/fullchain.cer;
    ssl_certificate_key /etc/letsencrypt/www.javednissar.ca/www.javednissar.ca.key;
    include /etc/nginx/snippets/ssl-params.conf;

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

    location ~ /.well-known {
        allow all;
    }

    client_max_body_size 50m;
    return 301 https://javednissar.ca$request_uri;
}

After, the modifications to the NGINX configuration files have been made, you'll need to run the following command to make the non-WWW domain the main domain of the site.

ghost config url https://javednissar.ca
Replace javednissar.ca with your non-WWW URL