🚀 Executive Summary

TL;DR: Ghost sites often fail to index on Google due to incorrect canonical URLs (HTTP instead of HTTPS) caused by misconfigured reverse proxies. This issue is resolved by correctly configuring the reverse proxy (like Nginx) to pass `X-Forwarded-Proto` and `Host` headers, or by directly setting the `url` in Ghost’s `config.production.json`, or via CDN rules.

🎯 Key Takeaways

  • Ghost generates canonical URLs and sitemaps based on information from its reverse proxy; if the proxy communicates internally via HTTP but serves externally via HTTPS, Ghost will incorrectly generate `http://` URLs.
  • The most robust solution involves configuring the reverse proxy (e.g., Nginx) to explicitly pass `X-Forwarded-Proto $scheme;` and `proxy_set_header Host $host;` to Ghost, ensuring it dynamically builds correct HTTPS URLs.
  • Temporary or emergency fixes include hardcoding the `https://` URL in Ghost’s `config.production.json` or using CDN-level rules (like Cloudflare Transform Rules) to inject the correct `X-Forwarded-Proto` header before the request reaches the origin server.

A Problem with Indexing for Ghost Site?

Struggling with Google indexing your Ghost blog? The problem is likely your reverse proxy configuration. Here’s how to fix the underlying header and URL issues that are stopping search engines cold.

From the Trenches: Why Google Hates Your Ghost Blog’s URL (And How to Fix It)

It was 4:45 PM on a Friday. A frantic Slack DM from our Head of Marketing pops up: “Darian, NONE of the new campaign posts are on Google!” My heart sank. We’d just migrated our blog to a new containerized Ghost setup behind our standard Nginx ingress. A quick “view source” on the live site revealed the ugly truth: the canonical URL was pointing to http:// instead of https://. Google saw this mixed-content signal and, quite rightly, refused to index the page. It’s a classic, infuriatingly simple problem that almost always points to one culprit: a misconfigured reverse proxy.

So, What’s Actually Happening?

Here’s the deal: Ghost isn’t psychic. It builds its internal links, sitemap, and canonical URLs based on the information it receives from the server sitting in front of it—your reverse proxy. Your proxy (like Nginx, Caddy, or Traefik) is handling the public-facing HTTPS traffic, but it might be talking to the Ghost instance itself over plain old HTTP internally. If you don’t explicitly configure the proxy to pass the correct headers along, Ghost has no idea the original request was secure.

It receives a request and thinks, “Okay, this came to me over HTTP on my internal Docker network, so I’ll generate all my URLs with http://.” The result is a site that works fine in the browser but tells search engines a completely different, insecure story. Google sees this conflict and backs away slowly.

The Three Battle-Tested Fixes

I’ve fought this battle more times than I can count. Here are the three ways we solve it, from the quick band-aid to the permanent architectural fix.

Solution 1: The Brute-Force Config Fix

This is the fastest way to get your site working, especially if you’re in a hurry or have a simple single-server setup. You’re basically overriding whatever the proxy is telling Ghost and hardcoding the correct public URL directly into Ghost’s configuration.

SSH into your server and edit your config.production.json file:


{
  "url": "https://www.your-correct-domain.com",
  "server": {
    "port": 2368,
    "host": "127.0.0.1"
  },
  "database": {
    ...
  },
  ...
}

Find the "url" key and make sure it has the full, correct https:// address. After saving the file, restart Ghost with ghost restart. Your canonical URLs and sitemap should be fixed immediately.

Warning: While this works, it’s a bit of a “hack.” It forces the right URL but doesn’t fix the underlying problem that your proxy isn’t communicating correctly. If your environment changes, this hardcoded value could cause issues later.

Solution 2: The Professional Fix (Correcting Your Nginx Proxy)

This is the “right” way to do it. You configure your Nginx proxy to pass the necessary headers so Ghost can dynamically build the correct URL on its own. This is more robust and the standard for any production environment.

In your Nginx site configuration file (e.g., /etc/nginx/sites-available/your-domain.conf), your location block for Ghost should look like this:


location / {
    proxy_pass http://127.0.0.1:2368;
    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-Proto $scheme;
}

The magic bullets are:

  • proxy_set_header Host $host;: Tells Ghost the original domain the user requested.
  • proxy_set_header X-Forwarded-Proto $scheme;: This is the most critical one. It tells Ghost whether the original scheme was http or https.

After adding these lines, reload Nginx with sudo systemctl reload nginx. You may also need to restart Ghost for the changes to be fully picked up. Your site will now be aware of its public-facing context.

Solution 3: The ‘Get It Done Now’ Fix (Using a CDN Rule)

Sometimes you don’t have shell access, or the infrastructure is managed by another team that’s slow to respond. In this emergency scenario, you can often fix the problem at the edge with a CDN like Cloudflare.

You can use a feature like Cloudflare’s “Transform Rules” to modify the request headers before they even hit your server. You would create a rule that does the following:

  1. Matches: All incoming traffic to your-domain.com/*
  2. Action: Modify request header. Set the X-Forwarded-Proto header to have a static value of https.

This effectively injects the correct header at the CDN level, so even if your origin Nginx server is misconfigured, Ghost receives the right information. It’s a powerful way to fix things when you can’t touch the origin server.

Pro Tip: This is a lifesaver, but remember that it’s masking a misconfiguration on your server (we call this “technical debt”). The best long-term solution is to fix the origin (Solution 2), but in a pinch, fixing it at the edge is perfectly valid to get the site indexed.

Which Fix Should You Choose?

To make it simple, here’s my breakdown.

Solution Best For Pros Cons
1. Ghost Config Emergencies, single-server setups Very fast, no proxy knowledge needed Brittle, masks underlying issues
2. Nginx Proxy All standard production environments Correct, robust, scalable Requires server/proxy access & knowledge
3. CDN Rule No server access, complex infra Instant fix, no origin changes needed Can hide server problems, vendor lock-in

There’s nothing more frustrating than creating great content that no one can find. Nine times out of ten, these indexing issues with self-hosted Ghost come down to this simple communication breakdown. Pick the fix that matches your situation, get those headers straight, and tell Google Search Console to re-index your site. Now you can finally go enjoy your weekend.

Darian Vance - Lead Cloud Architect

Darian Vance

Lead Cloud Architect & DevOps Strategist

With over 12 years in system architecture and automation, Darian specializes in simplifying complex cloud infrastructures. An advocate for open-source solutions, he founded TechResolve to provide engineers with actionable, battle-tested troubleshooting guides and robust software alternatives.


🤖 Frequently Asked Questions

âť“ Why isn’t my Ghost site being indexed by Google?

Your Ghost site is likely not being indexed because its canonical URLs are incorrectly showing `http://` instead of `https://`, a common issue stemming from a misconfigured reverse proxy that doesn’t properly communicate the original request scheme to Ghost.

âť“ How do the Nginx proxy fix and the Ghost config fix compare for indexing issues?

The Nginx proxy fix is the robust, long-term solution as it correctly informs Ghost about the public-facing HTTPS scheme, allowing Ghost to dynamically generate correct URLs. The Ghost config fix is a quick, brute-force method that hardcodes the URL, which is faster but less flexible and masks the underlying proxy misconfiguration.

âť“ What is a common implementation pitfall when setting up Ghost behind a reverse proxy?

A common pitfall is failing to configure the reverse proxy (e.g., Nginx) to pass the `X-Forwarded-Proto` header. Without this, Ghost assumes internal HTTP communication and generates insecure `http://` canonical URLs, preventing proper search engine indexing. The solution is to add `proxy_set_header X-Forwarded-Proto $scheme;` to your proxy configuration.

Leave a Reply

Discover more from TechResolve - SaaS Troubleshooting & Software Alternatives

Subscribe now to keep reading and get access to the full archive.

Continue reading