If you have an existing site — for example a shop, or a static site hosted elsewhere — Ghost can be run from a separate location e.g. yourdomain.com/blog otherwise known as a subdirectory.

Subdirectory and proxy setups are a paid add-on for our Business plan and require a specific custom Nginx or Apache configuration. In addition to a proxy, you must also contact us to indicate the path to be used with your publication.

Example configurations

The following configurations show how to setup a reverse proxy for a subdirectory.

Reverse proxy rules

Follow these rules to create a valid reverse proxy to Ghost(Pro). You can use the same setup to proxy if you don't need a subdirectory as well.

1. Provide a certificate & serve HTTPS traffic.
Only HTTPS traffic is supported.

2. Redirect non-HTTPS traffic to HTTPS.
It's more performant for this to be configured at the proxy level.

3. Proxy to your ghost.io subdomain, leaving it set as the HOST header.
Required to get through our security layer.

4. Have an X-Forwarded-Host header that matches the custom domain in my.ghost.org.
Without this, your blog will redirect to your ghost.io subdomain, causing a loop.

5. Include the X-Forwarded-Proto header set to https not http.
Without this your blog will redirect to https, causing a loop.

6. Include the X-Forwarded-For header, populated with the remote IP of the original request.
Without this, we aren't able to detect spam traffic patterns and your site risks being rate limited or incorrectly restricted.

7. Pass through all requests with the correct methods and headers
Your proxy must forward all HEAD, GET, POST, PUT and DELETE requests to your host with the request method, headers, and response intact, and must also pass through all standard HTTP headers and any x-ghost headers, including Authorization and set-cookie.

8. Ensure your DNS is dynamic
The underlying IPs of our infrastructure change regularly. If your proxy caches these values and is not able to refresh this dynamically your proxy will go offline without warning. Your proxy should therefore be configured with dynamic DNS resolution.

Troubleshooting

These configurations are only guaranteed to work in isolation. If you have any pre-existing top-level domain config, this could override the subdirectory. To troubleshoot any issues, review your top-level domain config for conflicts.

Validating your configuration

To verify your proxy is correctly configured, run this command to validate the correct headers are being sent:

curl -IL -H 'x-ghost-proxy:true' https://<your domain here>/<subdirectory>

If correct you’ll see a response header of x-ghost-proxy set to VALID. Otherwise you'll see INVALID next to it, and you should start by checking:

  1. x-forwarded-host must match your base custom domain set on my.ghost.org - if you're configuring example.com/blog/ then this would be example.com
  2. x-ghost-forwarded-proto must always be https
  3. x-ghost-host must always be their publication’s ghost.io URL - eg. yoursite.ghost.io

Once headers have been validated, you should complete the following actions to verify that traffic is being correctly routed and the site is behaving as expected:

  • Login to https://<your domain here>/<subdirectory>/ghost/
  • Upload an image
  • Create and schedule a post
  • Delete a post
  • Verify changes reflected in the sitemap at https://<your domain here>/<subdirectory>/sitemap.xml

If everything looks good, you're all set!