{"id":4569,"date":"2026-02-05T20:56:01","date_gmt":"2026-02-05T17:56:01","guid":{"rendered":"https:\/\/www.dchost.com\/blog\/hosting-ghost-blog-and-headless-blogging-with-node-js-reverse-proxy-and-ssl\/"},"modified":"2026-02-05T20:56:01","modified_gmt":"2026-02-05T17:56:01","slug":"hosting-ghost-blog-and-headless-blogging-with-node-js-reverse-proxy-and-ssl","status":"publish","type":"post","link":"https:\/\/www.dchost.com\/blog\/en\/hosting-ghost-blog-and-headless-blogging-with-node-js-reverse-proxy-and-ssl\/","title":{"rendered":"Hosting Ghost Blog and Headless Blogging with Node.js, Reverse Proxy and SSL"},"content":{"rendered":"<div class=\"dchost-blog-content-wrapper\"><p>If you are planning to host a Ghost blog or use Ghost as a headless blogging platform, you quickly notice it behaves differently from classic PHP-based systems like WordPress. Ghost runs on Node.js, listens on its own port, and expects you to put a reverse proxy and SSL in front of it. When this setup is done properly, you get a very fast, modern publishing stack that can serve a traditional blog, a headless content API, or both at the same time. In this article, we will walk through how we at dchost.com typically design and deploy Ghost: choosing the right server, installing Node.js and Ghost, putting Nginx in front as a reverse proxy, enabling HTTPS with SSL, and integrating Ghost into headless architectures where a separate frontend (for example Next.js or Nuxt) consumes its content API. The goal is to give you a practical, copy\u2011paste\u2011friendly blueprint you can reuse on your own <a href=\"https:\/\/www.dchost.com\/vps\">VPS<\/a> or <a href=\"https:\/\/www.dchost.com\/dedicated-server\">dedicated server<\/a>.<\/p>\n<div id=\"toc_container\" class=\"toc_transparent no_bullets\"><p class=\"toc_title\">\u0130&ccedil;indekiler<\/p><ul class=\"toc_list\"><li><a href=\"#Why_Ghost_and_Headless_Blogging_Need_a_Different_Hosting_Approach\"><span class=\"toc_number toc_depth_1\">1<\/span> Why Ghost and Headless Blogging Need a Different Hosting Approach<\/a><\/li><li><a href=\"#Planning_the_Server_Resources_OS_and_Network_Layout\"><span class=\"toc_number toc_depth_1\">2<\/span> Planning the Server: Resources, OS and Network Layout<\/a><ul><li><a href=\"#Choosing_VPS_vs_dedicated_vs_colocation\"><span class=\"toc_number toc_depth_2\">2.1<\/span> Choosing VPS vs dedicated vs colocation<\/a><\/li><li><a href=\"#Operating_system_and_base_hardening\"><span class=\"toc_number toc_depth_2\">2.2<\/span> Operating system and base hardening<\/a><\/li><li><a href=\"#Network_and_DNS_layout\"><span class=\"toc_number toc_depth_2\">2.3<\/span> Network and DNS layout<\/a><\/li><\/ul><\/li><li><a href=\"#Installing_Nodejs_Ghost-CLI_and_Running_Ghost_as_a_Service\"><span class=\"toc_number toc_depth_1\">3<\/span> Installing Node.js, Ghost-CLI and Running Ghost as a Service<\/a><ul><li><a href=\"#Preparing_the_system_for_Ghost\"><span class=\"toc_number toc_depth_2\">3.1<\/span> Preparing the system for Ghost<\/a><\/li><li><a href=\"#Creating_a_directory_and_system_user_for_Ghost\"><span class=\"toc_number toc_depth_2\">3.2<\/span> Creating a directory and system user for Ghost<\/a><\/li><li><a href=\"#Installing_Ghost-CLI_and_Ghost_itself\"><span class=\"toc_number toc_depth_2\">3.3<\/span> Installing Ghost-CLI and Ghost itself<\/a><\/li><\/ul><\/li><li><a href=\"#Putting_Nginx_In_Front_as_a_Reverse_Proxy\"><span class=\"toc_number toc_depth_1\">4<\/span> Putting Nginx In Front as a Reverse Proxy<\/a><ul><li><a href=\"#What_a_reverse_proxy_does_in_a_Ghost_setup\"><span class=\"toc_number toc_depth_2\">4.1<\/span> What a reverse proxy does in a Ghost setup<\/a><\/li><li><a href=\"#Basic_Nginx_server_block_for_Ghost_HTTP_only_first_step\"><span class=\"toc_number toc_depth_2\">4.2<\/span> Basic Nginx server block for Ghost (HTTP only, first step)<\/a><\/li><\/ul><\/li><li><a href=\"#Enabling_HTTPS_and_HTTP2_with_SSL\"><span class=\"toc_number toc_depth_1\">5<\/span> Enabling HTTPS and HTTP\/2 with SSL<\/a><ul><li><a href=\"#Why_SSL_matters_even_for_a_simple_blog\"><span class=\"toc_number toc_depth_2\">5.1<\/span> Why SSL matters even for a simple blog<\/a><\/li><li><a href=\"#Obtaining_a_Lets_Encrypt_certificate_with_Certbot\"><span class=\"toc_number toc_depth_2\">5.2<\/span> Obtaining a Let\u2019s Encrypt certificate with Certbot<\/a><\/li><li><a href=\"#Modern_TLS_and_performance_tuning\"><span class=\"toc_number toc_depth_2\">5.3<\/span> Modern TLS and performance tuning<\/a><\/li><\/ul><\/li><li><a href=\"#Using_Ghost_as_a_Headless_Blogging_Platform\"><span class=\"toc_number toc_depth_1\">6<\/span> Using Ghost as a Headless Blogging Platform<\/a><ul><li><a href=\"#Ghosts_Content_API_in_practice\"><span class=\"toc_number toc_depth_2\">6.1<\/span> Ghost\u2019s Content API in practice<\/a><\/li><li><a href=\"#Routing_patterns_for_headless_Ghost\"><span class=\"toc_number toc_depth_2\">6.2<\/span> Routing patterns for headless Ghost<\/a><\/li><li><a href=\"#Where_to_run_the_frontend\"><span class=\"toc_number toc_depth_2\">6.3<\/span> Where to run the frontend<\/a><\/li><\/ul><\/li><li><a href=\"#Production_Hardening_Process_Management_Logs_Backups_and_Monitoring\"><span class=\"toc_number toc_depth_1\">7<\/span> Production Hardening: Process Management, Logs, Backups and Monitoring<\/a><ul><li><a href=\"#Process_management_and_zerodowntime_deploys\"><span class=\"toc_number toc_depth_2\">7.1<\/span> Process management and zero\u2011downtime deploys<\/a><\/li><li><a href=\"#Logging_and_diagnostics\"><span class=\"toc_number toc_depth_2\">7.2<\/span> Logging and diagnostics<\/a><\/li><li><a href=\"#Backups_and_disaster_recovery\"><span class=\"toc_number toc_depth_2\">7.3<\/span> Backups and disaster recovery<\/a><\/li><li><a href=\"#Security_basics\"><span class=\"toc_number toc_depth_2\">7.4<\/span> Security basics<\/a><\/li><\/ul><\/li><li><a href=\"#Putting_It_All_Together_and_Next_Steps\"><span class=\"toc_number toc_depth_1\">8<\/span> Putting It All Together and Next Steps<\/a><\/li><\/ul><\/div>\n<h2><span id=\"Why_Ghost_and_Headless_Blogging_Need_a_Different_Hosting_Approach\">Why Ghost and Headless Blogging Need a Different Hosting Approach<\/span><\/h2>\n<p>Ghost is designed as a modern publishing platform with performance and clean content APIs in mind. That comes with a few implications for hosting:<\/p>\n<ul>\n<li><strong>It runs on Node.js<\/strong>, not PHP. So traditional shared hosting optimized for PHP\/MySQL is usually not a good fit.<\/li>\n<li><strong>It listens on an internal port<\/strong> (by default 2368) and expects you to put a web server like Nginx in front as a reverse proxy.<\/li>\n<li><strong>It has a built\u2011in JSON Content API<\/strong>, which makes Ghost perfect as a headless CMS feeding one or more frontends.<\/li>\n<li><strong>It benefits a lot from proper SSL and HTTP\/2<\/strong>, especially when you start serving images, scripts and multiple frontends.<\/li>\n<\/ul>\n<p>In our daily work at dchost.com, we see two main Ghost scenarios:<\/p>\n<ol>\n<li><strong>Classic Ghost blog<\/strong> on its own domain like blog.example.com (or as the main site), served directly by Ghost, with Nginx + SSL in front.<\/li>\n<li><strong>Headless Ghost<\/strong> where Ghost only provides the content API and admin panel, while a separate frontend (Next.js, Nuxt, a mobile app, etc.) renders pages, often deployed on the same VPS or on another server.<\/li>\n<\/ol>\n<p>Both scenarios share the same foundation: a clean Node.js runtime, a process manager or systemd service, Nginx as reverse proxy, and an HTTPS setup that is easy to maintain. If you are new to Node.js hosting, our article <a href='https:\/\/www.dchost.com\/blog\/en\/node-js-ve-express-icin-dogru-hosting-paylasimli-vps-ve-serverless-karsilastirmasi\/'>hosting Node.js and Express applications on shared hosting vs VPS vs serverless<\/a> gives useful background on when a VPS or dedicated server is the right choice.<\/p>\n<h2><span id=\"Planning_the_Server_Resources_OS_and_Network_Layout\">Planning the Server: Resources, OS and Network Layout<\/span><\/h2>\n<h3><span id=\"Choosing_VPS_vs_dedicated_vs_colocation\">Choosing VPS vs dedicated vs colocation<\/span><\/h3>\n<p>For most Ghost blogs and headless setups, a <strong>Linux VPS<\/strong> is the sweet spot: enough control to run Node.js and Nginx, but still easy to manage. At dchost.com we typically recommend:<\/p>\n<ul>\n<li><strong>Small personal or company blog<\/strong>: 1 vCPU, 1\u20132 GB RAM, fast SSD\/NVMe storage.<\/li>\n<li><strong>Medium\u2011size publication or agency blog<\/strong> with thousands of visitors per day: 2\u20134 vCPU, 4\u20138 GB RAM.<\/li>\n<li><strong>Multi\u2011language headless setup<\/strong> with multiple frontends and heavy API traffic: 4+ vCPU, 8+ GB RAM, often on a larger VPS or a dedicated server.<\/li>\n<\/ul>\n<p>If you expect very large traffic peaks, a <strong>dedicated server<\/strong> or <strong>colocation<\/strong> at our data centers lets you scale CPU and storage further, and combine Ghost with additional services (CDN origin, search, analytics) on the same physical machine.<\/p>\n<h3><span id=\"Operating_system_and_base_hardening\">Operating system and base hardening<\/span><\/h3>\n<p>We usually start with a fresh <strong>Ubuntu LTS<\/strong> or <strong>Debian<\/strong> image on the VPS or dedicated server. The general first\u2011day setup is similar to what we describe in our guide on <a href='https:\/\/www.dchost.com\/blog\/en\/yeni-vpste-ilk-24-saat-guncelleme-guvenlik-duvari-ve-kullanici-hesaplari\/'>what to do in the first 24 hours on a new VPS<\/a>:<\/p>\n<ul>\n<li>Update system packages and security patches.<\/li>\n<li>Create a non\u2011root user with sudo access.<\/li>\n<li>Harden SSH access (key\u2011based login, non\u2011standard port if you prefer, disable root login).<\/li>\n<li>Enable a simple firewall (ufw or firewalld) with only SSH and HTTP\/HTTPS open.<\/li>\n<\/ul>\n<h3><span id=\"Network_and_DNS_layout\">Network and DNS layout<\/span><\/h3>\n<p>Before installing Ghost, decide how you want your domains and subdomains to look. Common patterns include:<\/p>\n<ul>\n<li><strong>Main site on Ghost<\/strong>: example.com points to Ghost (via Nginx reverse proxy).<\/li>\n<li><strong>Blog as a subdomain<\/strong>: blog.example.com for Ghost, www.example.com for your main site or app.<\/li>\n<li><strong>Headless API subdomain<\/strong>: content.example.com or ghost.example.com serving only the admin panel and JSON API; frontend lives elsewhere.<\/li>\n<\/ul>\n<p>On your domain registrar, set A (and optionally AAAA) records to the VPS IP. If you are unsure how DNS pieces fit together, our article on <a href='https:\/\/www.dchost.com\/blog\/en\/web-hosting-nedir-domain-dns-sunucu-ve-ssl-nasil-birlikte-calisir\/'>how domain, DNS, server and SSL work together<\/a> gives a practical overview.<\/p>\n<h2><span id=\"Installing_Nodejs_Ghost-CLI_and_Running_Ghost_as_a_Service\">Installing Node.js, Ghost-CLI and Running Ghost as a Service<\/span><\/h2>\n<h3><span id=\"Preparing_the_system_for_Ghost\">Preparing the system for Ghost<\/span><\/h3>\n<p>Ghost runs on Node.js and is easiest to manage via the official Ghost\u2011CLI tool. A typical base setup on Ubuntu\/Debian looks like this:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo apt update &amp;&amp; sudo apt upgrade -y\nsudo apt install -y nginx mysql-server\n\n# Optional: secure MySQL quickly\nsudo mysql_secure_installation\n<\/code><\/pre>\n<p>Ghost officially supports specific Node.js LTS versions. We usually install Node.js from the NodeSource repository or nvm. For a system\u2011wide installation using NodeSource:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">curl -fsSL https:\/\/deb.nodesource.com\/setup_lts.x | sudo -E bash -\nsudo apt install -y nodejs\n\nnode -v\nnpm -v\n<\/code><\/pre>\n<h3><span id=\"Creating_a_directory_and_system_user_for_Ghost\">Creating a directory and system user for Ghost<\/span><\/h3>\n<p>We like to keep Ghost isolated under <code>\/var\/www<\/code> and run it as a dedicated user:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo mkdir -p \/var\/www\/ghost\nsudo useradd -r -U -d \/var\/www\/ghost ghost\nsudo chown ghost:ghost \/var\/www\/ghost\n<\/code><\/pre>\n<h3><span id=\"Installing_Ghost-CLI_and_Ghost_itself\">Installing Ghost-CLI and Ghost itself<\/span><\/h3>\n<p>Ghost\u2011CLI simplifies installation, upgrades and systemd service management. Install it globally:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo npm install -g ghost-cli@latest\n<\/code><\/pre>\n<p>Then switch to the Ghost directory as the ghost user and run the installer:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo -u ghost -H bash\ncd \/var\/www\/ghost\n\nghost install\n<\/code><\/pre>\n<p>Ghost\u2011CLI will ask a series of questions:<\/p>\n<ul>\n<li><strong>Blog URL<\/strong> (e.g. https:\/\/blog.example.com)<\/li>\n<li><strong>MySQL connection details<\/strong><\/li>\n<li>Whether to <strong>set up systemd<\/strong> to manage the service<\/li>\n<li>Whether to <strong>configure Nginx<\/strong> automatically<\/li>\n<li>Whether to <strong>set up SSL<\/strong> using Let&rsquo;s Encrypt<\/li>\n<\/ul>\n<p>You can let Ghost\u2011CLI handle Nginx and SSL automatically, or you can choose to skip those parts and configure them manually. In this article we will walk through a manual Nginx and SSL setup so you fully understand what is going on behind the scenes.<\/p>\n<p>After the installer runs, Ghost will typically be running on an internal port (for example 2368) and managed by systemd as a service named something like <code>ghost_blog-example-com<\/code>. You can check its status with:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo systemctl status ghost_blog-example-com\n<\/code><\/pre>\n<p>Ghost is now reachable on <code>http:\/\/127.0.0.1:2368<\/code>. The next step is to expose it to the outside world safely via Nginx.<\/p>\n<h2><span id=\"Putting_Nginx_In_Front_as_a_Reverse_Proxy\">Putting Nginx In Front as a Reverse Proxy<\/span><\/h2>\n<h3><span id=\"What_a_reverse_proxy_does_in_a_Ghost_setup\">What a reverse proxy does in a Ghost setup<\/span><\/h3>\n<p>A <strong>reverse proxy<\/strong> sits in front of your application server and forwards incoming HTTP\/HTTPS requests to it. With Ghost, the typical pattern is:<\/p>\n<ul>\n<li>Clients connect to <strong>port 80\/443 on Nginx<\/strong>.<\/li>\n<li>Nginx terminates SSL (for HTTPS), handles HTTP\/2, compression, caching headers, and routing.<\/li>\n<li>Nginx forwards requests to <strong>Ghost on 127.0.0.1:2368<\/strong>.<\/li>\n<\/ul>\n<p>This design has several benefits:<\/p>\n<ul>\n<li>You can <strong>host multiple sites<\/strong> (Ghost, API, other apps) on the same server, each on different domains or paths.<\/li>\n<li>Nginx can handle <strong>static assets, gzip\/Brotli<\/strong>, and <strong>HTTP\/2\/3<\/strong> more efficiently than a raw Node.js process.<\/li>\n<li>You get a clean place to manage <strong>redirects, HSTS, security headers<\/strong>, and other HTTP niceties.<\/li>\n<\/ul>\n<p>If you want a broader overview of reverse proxy concepts and examples, our guide on <a href='https:\/\/www.dchost.com\/blog\/en\/nginx-reverse-proxy-ve-basit-load-balancer-kurulumu-kucuk-projeler-icin-uygulamali-rehber\/'>Nginx reverse proxy and simple load balancer setup for small projects<\/a> walks through several scenarios very similar to Ghost.<\/p>\n<h3><span id=\"Basic_Nginx_server_block_for_Ghost_HTTP_only_first_step\">Basic Nginx server block for Ghost (HTTP only, first step)<\/span><\/h3>\n<p>Let us start with a simple HTTP server block (we will add SSL in the next section). Create a new file like <code>\/etc\/nginx\/sites-available\/blog.example.com.conf<\/code>:<\/p>\n<pre class=\"language-nginx line-numbers\"><code class=\"language-nginx\">server {\n    listen 80;\n    listen [::]:80;\n    server_name blog.example.com;\n\n    # Optional: redirect www blog to non-www\n    # if ($host = 'www.blog.example.com') {\n    #     return 301 $scheme:\/\/blog.example.com$request_uri;\n    # }\n\n    # Proxy all requests to Ghost\n    location \/ {\n        proxy_pass http:\/\/127.0.0.1:2368;\n\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n\n        proxy_http_version 1.1;\n        proxy_set_header X-Forwarded-Host $host;\n\n        # Increase timeouts slightly for admin operations\n        proxy_read_timeout 90;\n        proxy_connect_timeout 90;\n        proxy_send_timeout 90;\n    }\n}\n<\/code><\/pre>\n<p>Enable the site and test the Nginx configuration:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo ln -s \/etc\/nginx\/sites-available\/blog.example.com.conf \n  \/etc\/nginx\/sites-enabled\/\n\nsudo nginx -t\nsudo systemctl reload nginx\n<\/code><\/pre>\n<p>At this point, <code>http:\/\/blog.example.com<\/code> should show your Ghost blog, but without HTTPS yet. Leave it this way for a few minutes; we will layer SSL on top in the next step.<\/p>\n<h2><span id=\"Enabling_HTTPS_and_HTTP2_with_SSL\">Enabling HTTPS and HTTP\/2 with SSL<\/span><\/h2>\n<h3><span id=\"Why_SSL_matters_even_for_a_simple_blog\">Why SSL matters even for a simple blog<\/span><\/h3>\n<p>Even if you are just running a personal blog, HTTPS is no longer optional. Browsers warn users on insecure login forms, search engines prefer HTTPS, and features like HTTP\/2\/3 require TLS. When we design hosting for clients, we default everything to HTTPS, including staging sites.<\/p>\n<p>You can use a free Let&rsquo;s Encrypt certificate or a commercial certificate, depending on your needs. If you want a deeper comparison, we explain the trade\u2011offs in our article about <a href='https:\/\/www.dchost.com\/blog\/en\/ucretsiz-lets-encrypt-mi-kurumsal-ssl-sertifikasi-mi-e%e2%80%91ticaret-ve-kurumsal-siteler-icin-yol-haritasi\/'>Let&rsquo;s Encrypt vs commercial SSL certificates<\/a>. For most Ghost blogs, Let&rsquo;s Encrypt is more than sufficient.<\/p>\n<h3><span id=\"Obtaining_a_Lets_Encrypt_certificate_with_Certbot\">Obtaining a Let\u2019s Encrypt certificate with Certbot<\/span><\/h3>\n<p>The easiest way on Ubuntu\/Debian with Nginx is to use Certbot. Install it from the OS repository or the official snap:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo apt install -y certbot python3-certbot-nginx\n<\/code><\/pre>\n<p>Then run:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo certbot --nginx -d blog.example.com\n<\/code><\/pre>\n<p>Certbot will:<\/p>\n<ul>\n<li>Verify that <code>blog.example.com<\/code> points to this server.<\/li>\n<li>Request a certificate from Let&rsquo;s Encrypt.<\/li>\n<li>Update your Nginx configuration with SSL directives.<\/li>\n<li>Optionally set up an automatic HTTP to HTTPS redirect.<\/li>\n<\/ul>\n<p>After this step, your Nginx server block will have additional lines like:<\/p>\n<pre class=\"language-nginx line-numbers\"><code class=\"language-nginx\">server {\n    listen 443 ssl http2;\n    listen [::]:443 ssl http2;\n    server_name blog.example.com;\n\n    ssl_certificate \/etc\/letsencrypt\/live\/blog.example.com\/fullchain.pem;\n    ssl_certificate_key \/etc\/letsencrypt\/live\/blog.example.com\/privkey.pem;\n\n    include \/etc\/letsencrypt\/options-ssl-nginx.conf;\n    ssl_dhparam \/etc\/letsencrypt\/ssl-dhparams.pem;\n\n    # ... your proxy_pass config ...\n}\n\nserver {\n    listen 80;\n    listen [::]:80;\n    server_name blog.example.com;\n    return 301 https:\/\/$host$request_uri;\n}\n<\/code><\/pre>\n<p>Certbot also installs a cron job or systemd timer for automatic renewal. You can test it with:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo certbot renew --dry-run\n<\/code><\/pre>\n<p>If you want to go deeper into HTTPS best practices (HSTS, redirect strategies, mixed content), our guide on <a href='https:\/\/www.dchost.com\/blog\/en\/httpden-httpse-gecis-rehberi-301-yonlendirme-hsts-ve-seoyu-korumak\/'>full HTTPS migration with 301 redirects, HSTS and SEO\u2011safe setup<\/a> walks through a full migration story that applies equally well to Ghost.<\/p>\n<h3><span id=\"Modern_TLS_and_performance_tuning\">Modern TLS and performance tuning<\/span><\/h3>\n<p>Once HTTPS is in place, we usually add a few extra touches:<\/p>\n<ul>\n<li><strong>Enable HTTP\/2<\/strong> (already done by <code>http2<\/code> in the Nginx listen directive).<\/li>\n<li><strong>Turn on gzip or Brotli compression<\/strong> for HTML, CSS, JS and JSON API responses.<\/li>\n<li>Optionally <strong>add HSTS<\/strong> once you are confident everything works over HTTPS only.<\/li>\n<\/ul>\n<p>Most of these can be handled in a small Nginx include file shared by your sites. For an even more performance\u2011focused setup, especially when combining TLS 1.3, OCSP stapling and Brotli, see our practical guide on <a href='https:\/\/www.dchost.com\/blog\/en\/nginxte-tls-1-3-ocsp-stapling-ve-brotli-nasil-kurulur-hizli-ve-guvenli-httpsnin-sicacik-rehberi\/'>configuring TLS 1.3, OCSP stapling and Brotli on Nginx<\/a>.<\/p>\n<h2><span id=\"Using_Ghost_as_a_Headless_Blogging_Platform\">Using Ghost as a Headless Blogging Platform<\/span><\/h2>\n<h3><span id=\"Ghosts_Content_API_in_practice\">Ghost\u2019s Content API in practice<\/span><\/h3>\n<p>Ghost exposes a <strong>Content API<\/strong> and an <strong>Admin API<\/strong> over HTTP. This makes it a very capable headless CMS for blogs, magazines and documentation sites. Typical headless use cases include:<\/p>\n<ul>\n<li>Serving a blog frontend built with <strong>Next.js, Nuxt, Gatsby, Astro<\/strong> or another static\/SSR framework.<\/li>\n<li>Sharing content between a website and a <strong>mobile app<\/strong>.<\/li>\n<li>Publishing posts to <strong>multiple brands or domains<\/strong> from a single Ghost instance.<\/li>\n<\/ul>\n<p>From a hosting perspective, nothing changes on the Ghost side: it still runs as a Node.js service on an internal port and is proxied by Nginx. The difference is how your frontend connects to it and how you structure routing on the reverse proxy.<\/p>\n<h3><span id=\"Routing_patterns_for_headless_Ghost\">Routing patterns for headless Ghost<\/span><\/h3>\n<p>There are two common patterns we implement for clients.<\/p>\n<p><strong>1. Separate subdomains for frontend and Ghost<\/strong><\/p>\n<ul>\n<li>Ghost admin and API at <code>ghost.example.com<\/code>.<\/li>\n<li>Public frontend at <code>blog.example.com<\/code> or <code>www.example.com<\/code>.<\/li>\n<\/ul>\n<p>In this model, Ghost is never directly visible to visitors. Only your editors log in to <code>ghost.example.com<\/code>, and your frontend consumes the Content API with an API key. Each subdomain has its own Nginx server block, <a href=\"https:\/\/www.dchost.com\/ssl\">SSL certificate<\/a> and caching rules.<\/p>\n<p><strong>2. Single domain, path\u2011based routing<\/strong><\/p>\n<ul>\n<li>Public frontend handles everything under <code>\/<\/code>.<\/li>\n<li>Ghost admin and API live under <code>\/ghost\/<\/code> or <code>\/content\/<\/code>.<\/li>\n<\/ul>\n<p>Here, Nginx decides by path which upstream to send traffic to: your frontend (for example a Node.js SSR app) or the Ghost service. A simplified example:<\/p>\n<pre class=\"language-nginx line-numbers\"><code class=\"language-nginx\">server {\n    listen 443 ssl http2;\n    server_name example.com;\n\n    # SSL directives omitted for brevity\n\n    # Frontend (Next.js) upstream\n    location \/ {\n        proxy_pass http:\/\/127.0.0.1:3000;\n        # ... proxy headers ...\n    }\n\n    # Ghost admin + API\n    location \/ghost\/ {\n        proxy_pass http:\/\/127.0.0.1:2368;\n        # ... proxy headers ...\n    }\n}\n<\/code><\/pre>\n<p>This lets your editors access Ghost at <code>https:\/\/example.com\/ghost\/<\/code> while visitors see only the frontend. If you want a broader overview of headless and Jamstack patterns (including static builds and object storage origins), our guide on <a href='https:\/\/www.dchost.com\/blog\/en\/headless-cms-ve-jamstack-siteler-icin-hosting-rehberi-statik-build-object-storage-ve-serverless-fonksiyonlar\/'>hosting headless CMS and Jamstack sites<\/a> is a good companion read.<\/p>\n<h3><span id=\"Where_to_run_the_frontend\">Where to run the frontend<\/span><\/h3>\n<p>Depending on your scale and team preferences, you can:<\/p>\n<ul>\n<li>Run the frontend on the <strong>same VPS or dedicated server<\/strong> as Ghost (simple, cost\u2011effective for small to medium projects).<\/li>\n<li>Use a <strong>separate VPS<\/strong> for the frontend if it needs more CPU or has different scaling requirements.<\/li>\n<li>Build a fully static frontend and serve it from <strong>object storage + CDN<\/strong>, using Ghost only as a content source for builds.<\/li>\n<\/ul>\n<p>Whatever you choose, the key is to keep your architecture simple at first and only split components when you truly need extra isolation or scaling headroom.<\/p>\n<h2><span id=\"Production_Hardening_Process_Management_Logs_Backups_and_Monitoring\">Production Hardening: Process Management, Logs, Backups and Monitoring<\/span><\/h2>\n<h3><span id=\"Process_management_and_zerodowntime_deploys\">Process management and zero\u2011downtime deploys<\/span><\/h3>\n<p>If you used Ghost\u2011CLI, it already set up a systemd service. For custom Node.js headless frontends that live next to Ghost, we recommend using <strong>systemd units or a process manager like PM2<\/strong> and an Nginx reverse proxy in front. We describe a practical, no\u2011drama pattern in our article on <a href='https:\/\/www.dchost.com\/blog\/en\/node-jsi-canliya-alirken-panik-yapma-pm2-systemd-nginx-ssl-ve-sifir-kesinti-deploy-nasil-kurulur\/'>hosting Node.js in production with PM2\/systemd, Nginx, SSL and zero\u2011downtime deploys<\/a>.<\/p>\n<p>For Ghost itself, upgrades are usually handled by Ghost\u2011CLI with commands like <code>ghost update<\/code>, which gracefully restarts the process via systemd.<\/p>\n<h3><span id=\"Logging_and_diagnostics\">Logging and diagnostics<\/span><\/h3>\n<p>When running Ghost and potentially a separate frontend, keep an eye on three log sources:<\/p>\n<ul>\n<li><strong>Ghost logs<\/strong> (under <code>\/var\/www\/ghost\/content\/logs\/<\/code> by default).<\/li>\n<li><strong>Nginx access and error logs<\/strong> under <code>\/var\/log\/nginx\/<\/code>.<\/li>\n<li><strong>Systemd journal<\/strong> for Ghost services (<code>journalctl -u ghost_...<\/code>).<\/li>\n<\/ul>\n<p>For growing projects, centralised log aggregation (for example with Loki + Promtail or ELK) helps a lot, especially when you add more servers later.<\/p>\n<h3><span id=\"Backups_and_disaster_recovery\">Backups and disaster recovery<\/span><\/h3>\n<p>Ghost stores content primarily in a <strong>MySQL\/MariaDB database<\/strong> and in its <code>content\/<\/code> directory (images, themes, configuration). A minimal backup plan should include:<\/p>\n<ul>\n<li>Regular <strong>database dumps<\/strong> (mysqldump or XtraBackup) to off\u2011site storage.<\/li>\n<li>File backups of the <code>\/var\/www\/ghost\/content\/<\/code> directory.<\/li>\n<li>Configuration backups for Nginx and systemd units.<\/li>\n<\/ul>\n<p>If you are designing a broader backup policy for multiple sites and apps, our 3\u20112\u20111 backup article on <a href='https:\/\/www.dchost.com\/blog\/en\/3-2-1-yedekleme-stratejisi-neden-ise-yariyor-cpanel-plesk-ve-vpste-otomatik-yedekleri-nasil-kurarsin\/'>why the 3\u20112\u20111 backup strategy works and how to automate backups on cPanel, Plesk and VPS<\/a> is a good framework to start with.<\/p>\n<h3><span id=\"Security_basics\">Security basics<\/span><\/h3>\n<p>Beyond SSL and updated software, a secure Ghost and headless setup should include:<\/p>\n<ul>\n<li><strong>Firewall rules<\/strong> that only allow ports 22, 80 and 443 from the internet. Ghost should only listen on 127.0.0.1.<\/li>\n<li><strong>Regular OS and package updates<\/strong>, including Node.js security patches.<\/li>\n<li><strong>Strong passwords and 2FA<\/strong> for Ghost admin users where possible.<\/li>\n<li>Optionally a <strong>Web Application Firewall (WAF)<\/strong>, either at the CDN level or on the server (for example ModSecurity in front of Nginx).<\/li>\n<\/ul>\n<p>For a deeper security checklist around VPS hardening (SSH, firewalls, Fail2ban and more), our guide on <a href='https:\/\/www.dchost.com\/blog\/en\/vps-sunucu-guvenligi-nasil-saglanir-kapiyi-acik-birakmadan-yasamanin-sirri\/'>how to secure a VPS server without drama<\/a> provides a step\u2011by\u2011step path you can follow for the same server that hosts Ghost.<\/p>\n<h2><span id=\"Putting_It_All_Together_and_Next_Steps\">Putting It All Together and Next Steps<\/span><\/h2>\n<p>Hosting a Ghost blog or a headless Ghost\u2011powered publishing stack is not complicated once you see the full picture. You need a clean Node.js runtime, a service manager (systemd or PM2), Nginx as a reverse proxy, and an SSL setup that is automated and well\u2011understood. On top of this foundation, you can decide whether Ghost will render the blog itself, or whether it will only provide content via its APIs to a separate frontend built with modern frameworks.<\/p>\n<p>At dchost.com we typically start clients on a VPS with enough CPU, RAM and NVMe storage to handle both Ghost and, if needed, a Node.js frontend on the same machine. When the project grows, it is easy to split roles: a dedicated Ghost instance as a pure headless CMS, multiple frontends on separate servers, object storage for media and a CDN in front of everything. The reverse proxy and SSL layer you built for the first small blog still scales nicely in those more advanced architectures.<\/p>\n<p>If you are planning your own Ghost deployment and want help sizing a VPS or dedicated server, or designing a headless architecture that fits your content and traffic patterns, our team at dchost.com can walk through your requirements and propose a concrete, no\u2011surprises plan. Whether you just need a fast, minimal Ghost blog or a multi\u2011frontend headless publishing platform, the steps in this guide will give you a solid, production\u2011ready foundation.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>If you are planning to host a Ghost blog or use Ghost as a headless blogging platform, you quickly notice it behaves differently from classic PHP-based systems like WordPress. Ghost runs on Node.js, listens on its own port, and expects you to put a reverse proxy and SSL in front of it. When this setup [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":4570,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-4569","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-teknoloji"],"_links":{"self":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts\/4569","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/comments?post=4569"}],"version-history":[{"count":0,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts\/4569\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/media\/4570"}],"wp:attachment":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/media?parent=4569"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/categories?post=4569"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/tags?post=4569"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}