Setting Up Ghost with Nginx as a Reverse Proxy and SSL
Learn how to set up Ghost with Nginx as a reverse proxy and configure SSL. I faced issues with SSL redirects and theme previews, but resolved them by modifying Ghost's source code. Discover the problem and solution in this detailed guide.
When I installed Ghost on my server and configured Nginx as the reverse proxy server, I also set up SSL in Nginx. Additionally, I updated the URL for the website in Ghost's configuration file to https://blog.y9i.cc
. However, I encountered an issue where I couldn't access the URL.
The Issue
When I tried to visit localhost:2368
on the server, it attempted to redirect to https://localhost:2368
. The output was as follows:
$ curl localhost:2368
Moved Permanently. Redirecting to https://localhost:2368/
Conversely, when I configured the URL as http://blog.y9i.cc
, I could access the website via https://blog.y9i.cc
. However, updating the theme in Ghost caused the preview page to fail to display. Inspecting the network tab in Chrome's developer tools revealed that the page was being loaded from http://blog.y9i.cc
.
Investigation
To solve this problem, I delved into Ghost's source code and discovered that it enforces a redirect to SSL when the website is configured to use an HTTPS link. The relevant code is located in the file /current/core/server/web/shared/middleware/url-redirects.js
:
/**
* Takes care of
*
* 1. required SSL redirects
*/
_private.getFrontendRedirectUrl = ({requestedHost, requestedUrl, queryParameters, secure}) => {
const siteUrl = urlUtils.urlFor('home', true);
debug('getFrontendRedirectUrl', requestedHost, requestedUrl, siteUrl);
// CASE: configured canonical url is HTTPS, but request is HTTP, redirect to requested host + SSL
if (urlUtils.isSSL(siteUrl) && !secure) {
debug('redirect because protocol does not match');
return _private.redirectUrl({
redirectTo: `https://${requestedHost}`,
pathname: requestedUrl,
query: queryParameters
});
}
};
Solution
The solution to the problem was to modify the function to return null
, bypassing the SSL redirect. The updated function is as follows:
_private.getFrontendRedirectUrl = ({requestedHost, requestedUrl, queryParameters, secure}) => {
return null;
};
After making this change, the admin page displayed correctly, and the theme preview issue was resolved.