Home • Blog • Article

How to Migrate from Ghost to WordPress in 2025?

By Fathima Nourin TM • •

Seamlessly Migrate from Ghost to WordPress: A Technical Engineering Guide

Migrating a content infrastructure from a Node.js-based application like Ghost to a PHP-driven content management system like WordPress requires a rigorous, programmatic approach. While Ghost utilizes a streamlined SQLite or MySQL schema structured around JSON exports, WordPress relies on a relational schema distributed across multiple core tables (wp_posts, wp_postmeta, wp_terms, wp_term_taxonomy, and wp_term_relationships). Executing this transition without data loss, broken media assets, or shattered search engine optimization (SEO) ranking equities demands a carefully engineered sequence of data extraction, transformation, loading (ETL), and server-side hardening.

1. Problem Statement and Architectural Impact

The core challenge in migrating from Ghost to WordPress lies in structural impedance mismatch. Ghost stores all content—posts, pages, tags, authors, and settings—within a single, nested JavaScript Object Notation (JSON) export file. In contrast, WordPress decomposes this information into a normalized relational database. Post content is stored in HTML or Gutenberg block format (JSON serialized inside database rows), while taxonomies, metadata, and user relationships are decoupled across specialized tables.

Affected Environments: This migration path impacts enterprise hosting infrastructures running LEMP (Linux, Nginx, MySQL/MariaDB, PHP-FPM) or LAMP stacks. During the ETL phase, database transaction locks, PHP memory exhaustion, and script execution timeouts are common failure vectors, particularly when dealing with extensive media libraries and thousands of historical posts.

🚨 Facing an active site error or malware warning?

Chat with an engineer on WhatsApp within 15 minutes.

💬 Chat on WhatsApp

Security and Business Consequences of Inadequacy: Incomplete migrations introduce severe security and operational risks. Broken internal redirects create sprawling chains of 404 errors that degrade domain authority. Furthermore, misconfigured file permissions or exposed temporary import directories during the migration window can allow unauthorized script execution, leading to arbitrary code execution (ACE) vulnerabilities via uploaded payload vectors.

2. Root Cause Analysis and Data Structures

Understanding the underlying schemas of both platforms is essential before executing any data transformation script. Ghost exports data wrapped in a db array, typically structured under a versioned schema (e.g., "version": "5.x.x"). Within this structure, the critical entities are:

  • Posts: Contained in the posts table array, encapsulating title, slug, HTML/Markdown content, publication status, and timestamps.
  • Tags: Contained in the tags array, mapping to WordPress categories and tags.
  • Posts_Tags: A junction table array mapping post IDs to tag IDs.
  • Users: Contained in the users array, mapping authors to their respective credentials and roles.

When migrating these entities to WordPress, the primary technical hurdle is converting Ghost’s Markdown or internal Lexical editor JSON format into valid WordPress HTML or Gutenberg block markup. If posts are rendered natively as HTML in Ghost, they must be safely ingested into the post_content column of the wp_posts table. Any failure to sanitize these inputs can introduce Cross-Site Scripting (XSS) vulnerabilities if malicious scripts were previously stored in Ghost metadata fields.

Additionally, permalink structures often differ. Ghost defaults to a clean /slug/ structure, whereas WordPress can be configured similarly. However, discrepancies in date prefixes or custom taxonomies can break inbound links unless precise rewrite rules are enforced at the web server level.

3. Step-by-Step Implementation and Migration Execution

Executing a reliable migration requires a multi-phase technical workflow utilizing WP-CLI, custom PHP transformation scripts, and database operations.

Phase 1: Ghost Data Export and Asset Harvesting

Navigate to your Ghost admin panel, access the Labs section, and export your content as a JSON file. Simultaneously, you must mirror all media assets located in your Ghost installation’s content/images/ directory. Use rsync to securely copy these assets to your local or staging server:

rsync -avz -e "ssh -p 22" user@ghost-server:/var/www/ghost/content/images/ ./local-ghost-media/

This command securely transfers all historical image uploads, preserving directory structures and file modification timestamps.

Phase 2: WordPress Staging Environment Provisioning

Deploy a clean WordPress instance on your target LEMP stack. Ensure your PHP configuration (php.ini) is tuned to handle large data payloads and extended execution times during the import phase:

memory_limit = 512M
max_execution_time = 300
upload_max_filesize = 64M
post_max_size = 64M

Restart your PHP-FPM service to apply these changes:

sudo systemctl restart php8.2-fpm

Phase 3: Data Transformation and Import via Custom Script

Because standard automated plugins often fail on complex Ghost schemas, building or utilizing a robust PHP migration script executed via WP-CLI is recommended. Below is a foundational PHP script snippet designed to parse the Ghost JSON export and insert posts into the WordPress database while maintaining meta integrity:

<?php
/**
 * Ghost to WordPress Core Migration Script Snippet
 */
if ( ! defined( 'WP_CLI' ) || ! WP_CLI ) {
    return;
}

$json_file = '/path/to/ghost-export.json';
if ( ! file_exists( $json_file ) ) {
    WP_CLI::error( "Ghost export file not found." );
}

$data = json_decode( file_get_contents( $json_file ), true );
$posts = $data['db'][0]['data']['posts'] ?? [];

foreach ( $posts as $post ) {
    $post_data = array(
        'post_title'    => sanitize_text_field( $post['title'] ),
        'post_name'     => sanitize_title( $post['slug'] ),
        'post_content'  => wp_unslash( $post['html'] ),
        'post_status'   => ( $post['status'] === 'published' ) ? 'publish' : 'draft',
        'post_date'     => date( 'Y-m-d H:i:s', strtotime( $post['created_at'] ) ),
        'post_type'     => 'post',
    );

    $post_id = wp_insert_post( $post_data, true );

    if ( is_wp_error( $post_id ) ) {
        WP_CLI::warning( "Failed to import post: " . $post['title'] );
    } else {
        // Store original Ghost ID for reference and redirect mapping
        update_post_meta( $post_id, '_ghost_id', $post['id'] );
        WP_CLI::success( "Successfully imported: " . $post['title'] );
    }
}

Execute this script using WP-CLI from your WordPress root directory:

wp eval-file migrate-ghost.php

Phase 4: Media Re-indexing and URL Rewriting

Once posts are imported, all image URLs pointing to the old Ghost domain must be updated to point to the new WordPress /wp-content/uploads/ directory. Run the following SQL queries via your database management interface or CLI to perform safe string replacements across the database:

UPDATE wp_posts SET post_content = REPLACE(post_content, 'https://old-ghost-domain.com/content/images/', 'https://new-wordpress-domain.com/wp-content/uploads/');
UPDATE wp_postmeta SET meta_value = REPLACE(meta_value, 'https://old-ghost-domain.com/content/images/', 'https://new-wordpress-domain.com/wp-content/uploads/');

4. Production Hardening and Edge Cases

Migrating content is only half the battle; securing and stabilizing the production environment is critical for enterprise deployment.

Permalink and SEO Redirection: If your Ghost URL structure included specific date parameters (e.g., /YYYY/MM/DD/slug/) and your WordPress structure is purely /slug/, you must configure explicit 301 redirects at the Nginx server level to prevent link equity decay. Add the following block to your Nginx virtual host configuration:

server {
    listen 443 ssl;
    server_name example.com;

    # Catch legacy Ghost date-based permalinks and redirect to WordPress structure
    location ~* ^/\d{4}/\d{2}/\d{2}/([^/]+)/?$ {
        return 301 https://example.com/$1/;
    }
}

File Permissions and Security Hardening: During migration, developers often loosen file permissions to allow import tools to write files. Immediately after completing the import, lock down your WordPress directory permissions using these terminal commands:

find /var/www/html -type d -exec chmod 755 {} \;
find /var/www/html -type f -exec chmod 644 {} \;
sudo chmod 600 /var/www/html/wp-config.php

Caching and Performance Trade-offs: WordPress relies heavily on object caching (Redis or Memcached) and page caching (FastCGI or plugin-based) to match Ghost’s native high-performance delivery speed. Ensure your object cache drop-in (object-cache.php) is active and configured to handle session and database query caching efficiently.

5. Diagnostic Verification and Verification Checklist

Before switching your DNS pointers to the new WordPress production environment, execute the following verification protocol to ensure complete data integrity, security compliance, and performance readiness.

Verification Category Check Item Expected Result / Metric Diagnostic Command / Tool
Data Integrity Post Count Reconciliation Ghost total posts match WordPress published post count. wp post list --format=count
SEO & Routing HTTP Status Validation Legacy URLs return 301 Moved Permanently pointing to new slugs. curl -I https://example.com/old-slug/
Media Assets Broken Image Audit Zero 404 Not Found errors for image assets in page source. Screaming Frog SEO Spider / Browser DevTools Network Tab
Security File Permission Audit wp-config.php set to 600; uploads folder prohibits PHP execution. name wp-config.php -exec stat -c "%a" {} \;
Performance TTFB (Time to First Byte) Under 200ms globally utilizing edge caching and CDN layers. WebPageTest / GTmetrix

Monitor your web server error logs continuously during the initial cutover phase to capture and resolve any lingering database connection anomalies or missing asset dependencies:

tail -f /var/log/nginx/error.log
tail -f /var/log/php8.2-fpm.log

By executing this rigorous engineering framework, your migration from Ghost to WordPress will preserve your search visibility, secure your underlying infrastructure against modern exploit vectors, and deliver a high-performance content platform ready for enterprise scale.

Follow SiteSuraksha on Google
Add us to your preferred sources for verified WordPress & hosting guides.
FREE 30-SECOND DIAGNOSTIC

Is Your Website Fast & Secure?

Run an instant scan for security vulnerabilities, bloated plugins, and TTFB latency.

🔍 Test Your Site Now →
Map Your Issue to Guaranteed IT Care
Security & Malware
Hacks, 0-day exploits & backup failures
Pro Care (₹5,420/mo) →
Speed & Cloud Bills
Slow checkout, high TTFB & cloud waste
Pro Care (₹5,420/mo) →
ERP & Automation
GST pipelines, RPA & AI support agents
Enterprise (₹14,999/mo) →
EXPERT WORDPRESS CARE

Need Help Securing or Speeding Up Your Site?

Get 24/7 proactive security WAF, daily cloud backups, and sub-second speed optimization from ₹3,470/mo.

💬 Chat on WhatsApp Explore Plans
← Back to All Articles