{"slug":"wordpress-staging-environments","title":"WordPress Staging Environments","tags":["staging","development","local","wp-cli","deployment"],"agent_summary":"WordPress staging setup options (Local by Flywheel, MainWP Staging, manual VPS clone), WP-CLI staging commands, staging wp-config settings to block indexing and trap emails.","trigger_phrases":["wordpress staging","staging environment wordpress","local by flywheel","wordpress test site","clone wordpress to staging","staging wp-config","prevent staging indexing"],"runnable":true,"markdown":"\nAlways test on staging before pushing to production. Never develop on a live site.\n\n## Staging Options\n\n| Method | Best For | Cost |\n|--------|----------|------|\n| Local by Flywheel | Local dev, no server needed | Free |\n| WP Engine staging | Managed hosting clients | Included |\n| MainWP Staging extension | Fleet management via MainWP | MainWP plan |\n| WPvivid staging | Any shared/VPS hosting | Free/paid |\n| Manual clone (WP-CLI + rsync) | VPS clients, full control | $0 |\n| Hostinger staging | hPanel one-click | Included |\n| WPX staging | WPX control panel one-click | Included |\n\n## Manual Staging Setup (VPS)\n\n```bash\n# 1. Create staging database\nmysql -u root -p -e \"CREATE DATABASE staging_mysite CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\"\nmysql -u root -p -e \"CREATE USER 'staging_user'@'localhost' IDENTIFIED BY 'password';\"\nmysql -u root -p -e \"GRANT ALL PRIVILEGES ON staging_mysite.* TO 'staging_user'@'localhost';\"\n\n# 2. Copy files (excluding wp-config.php)\nrsync -av /var/www/production/ /var/www/staging/ --exclude=wp-config.php\n\n# 3. Export production DB and import to staging\nwp db export /tmp/prod-db.sql --path=/var/www/production\nwp db import /tmp/prod-db.sql --path=/var/www/staging\n\n# 4. Update staging wp-config.php with staging DB credentials\n# 5. Search-replace URLs\nwp search-replace 'https://production.com' 'https://staging.production.com' \\\n  --all-tables --path=/var/www/staging\n```\n\n## Staging wp-config.php Settings\n\n```php\n// Identify environment\ndefine('WP_ENVIRONMENT_TYPE', 'staging');\n\n// Prevent search engine indexing\ndefine('DISALLOW_INDEXING', true);\n\n// Block outgoing emails (trap locally)\nadd_filter('wp_mail', function($args) {\n    $args['to'] = 'dev@agency.com'; // redirect all email to dev\n    return $args;\n});\n```\n\n## Block Indexing Programmatically\n\n```php\n// In staging wp-config.php or functions.php\nif (strpos($_SERVER['HTTP_HOST'] ?? '', 'staging') !== false) {\n    add_action('pre_option_blog_public', '__return_zero');\n}\n```\n\n## Push Staging to Production\n\n1. Run full test on staging — forms, checkout, layout, performance\n2. Export staging DB changes\n3. Import to production (or use WPvivid push feature)\n4. Sync `uploads/` if new media was added: `rsync -av staging/wp-content/uploads/ production/wp-content/uploads/`\n5. Never push staging wp-config.php to production\n","html":"<p>Always test on staging before pushing to production. Never develop on a live site.</p>\n<h2>Staging Options</h2>\n<p>| Method | Best For | Cost |\n|--------|----------|------|\n| Local by Flywheel | Local dev, no server needed | Free |\n| WP Engine staging | Managed hosting clients | Included |\n| MainWP Staging extension | Fleet management via MainWP | MainWP plan |\n| WPvivid staging | Any shared/VPS hosting | Free/paid |\n| Manual clone (WP-CLI + rsync) | VPS clients, full control | $0 |\n| Hostinger staging | hPanel one-click | Included |\n| WPX staging | WPX control panel one-click | Included |</p>\n<h2>Manual Staging Setup (VPS)</h2>\n<pre><code class=\"language-bash\"># 1. Create staging database\nmysql -u root -p -e \"CREATE DATABASE staging_mysite CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\"\nmysql -u root -p -e \"CREATE USER 'staging_user'@'localhost' IDENTIFIED BY 'password';\"\nmysql -u root -p -e \"GRANT ALL PRIVILEGES ON staging_mysite.* TO 'staging_user'@'localhost';\"\n\n# 2. Copy files (excluding wp-config.php)\nrsync -av /var/www/production/ /var/www/staging/ --exclude=wp-config.php\n\n# 3. Export production DB and import to staging\nwp db export /tmp/prod-db.sql --path=/var/www/production\nwp db import /tmp/prod-db.sql --path=/var/www/staging\n\n# 4. Update staging wp-config.php with staging DB credentials\n# 5. Search-replace URLs\nwp search-replace 'https://production.com' 'https://staging.production.com' \\\n  --all-tables --path=/var/www/staging\n</code></pre>\n<h2>Staging wp-config.php Settings</h2>\n<pre><code class=\"language-php\">// Identify environment\ndefine('WP_ENVIRONMENT_TYPE', 'staging');\n\n// Prevent search engine indexing\ndefine('DISALLOW_INDEXING', true);\n\n// Block outgoing emails (trap locally)\nadd_filter('wp_mail', function($args) {\n    $args['to'] = 'dev@agency.com'; // redirect all email to dev\n    return $args;\n});\n</code></pre>\n<h2>Block Indexing Programmatically</h2>\n<pre><code class=\"language-php\">// In staging wp-config.php or functions.php\nif (strpos($_SERVER['HTTP_HOST'] ?? '', 'staging') !== false) {\n    add_action('pre_option_blog_public', '__return_zero');\n}\n</code></pre>\n<h2>Push Staging to Production</h2>\n<ol>\n<li>Run full test on staging — forms, checkout, layout, performance</li>\n<li>Export staging DB changes</li>\n<li>Import to production (or use WPvivid push feature)</li>\n<li>Sync <code>uploads/</code> if new media was added: <code>rsync -av staging/wp-content/uploads/ production/wp-content/uploads/</code></li>\n<li>Never push staging wp-config.php to production</li>\n</ol>\n"}