<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>wordpress automation project Archives - WP-CLI Mastery</title>
	<atom:link href="https://wpclimastery.com/blog/tag/wordpress-automation-project/feed/" rel="self" type="application/rss+xml" />
	<link>https://wpclimastery.com/blog/tag/wordpress-automation-project/</link>
	<description>Automate WordPress Like a DevOps Pro.</description>
	<lastBuildDate>Mon, 24 Nov 2025 11:16:47 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://wpclimastery.com/wp-content/uploads/2025/11/cropped-favicon-32x32.webp</url>
	<title>wordpress automation project Archives - WP-CLI Mastery</title>
	<link>https://wpclimastery.com/blog/tag/wordpress-automation-project/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Building a Complete WordPress Deployment System with WP-CLI (Real Project)</title>
		<link>https://wpclimastery.com/blog/building-a-complete-wordpress-deployment-system-with-wp-cli-real-project/</link>
		
		<dc:creator><![CDATA[Krasen]]></dc:creator>
		<pubDate>Fri, 30 Jan 2026 09:00:00 +0000</pubDate>
				<category><![CDATA[Real-World WP-CLI Projects]]></category>
		<category><![CDATA[complete deployment automation]]></category>
		<category><![CDATA[devops wordpress]]></category>
		<category><![CDATA[wordpress automation project]]></category>
		<category><![CDATA[wordpress deployment system]]></category>
		<category><![CDATA[wp-cli project]]></category>
		<guid isPermaLink="false">https://wpclimastery.com/?p=160</guid>

					<description><![CDATA[<p>Professional WordPress deployments require coordinating server provisioning, WordPress installation, plugin configuration, database migrations, zero-downtime releases, automated backups, health monitoring, and rollback capabilities. Managing these manually across development, staging, and production...</p>
<p>The post <a href="https://wpclimastery.com/blog/building-a-complete-wordpress-deployment-system-with-wp-cli-real-project/">Building a Complete WordPress Deployment System with WP-CLI (Real Project)</a> appeared first on <a href="https://wpclimastery.com">WP-CLI Mastery</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Professional WordPress deployments require coordinating server provisioning, WordPress installation, plugin configuration, database migrations, zero-downtime releases, automated backups, health monitoring, and rollback capabilities. Managing these manually across development, staging, and production environments is error-prone and time-consuming.</p>



<p>A complete WordPress deployment system automates the entire lifecycle—provision servers, install WordPress, deploy code changes, run migrations, monitor health, and rollback failures—all with single commands executed by WP-CLI and Bash scripts.</p>



<p>In this guide, you’ll build a production-ready WordPress deployment system used by professional development teams, integrating server provisioning, automated deployments, monitoring, and disaster recovery into one cohesive system.</p>



<h3 class="wp-block-heading" id="architecture">System Architecture Overview</h3>



<p>Understand the complete deployment system components and workflow.</p>



<h4 class="wp-block-heading" id="deployment-system-components">Deployment System Components</h4>



<div class="sourceCode" id="cb1">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true"></a>┌─────────────────────┐</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true"></a>│  <span class="ex">Version</span> Control    │  ← Git repository (source of truth)</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true"></a>│      <span class="kw">(</span><span class="ex">Git</span><span class="kw">)</span>          │</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true"></a>└──────────┬──────────┘</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true"></a>           │</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true"></a>           ▼</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true"></a>┌─────────────────────┐</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true"></a>│  <span class="ex">CI/CD</span> Pipeline     │  ← GitHub Actions/GitLab CI</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true"></a>│   <span class="kw">(</span><span class="ex">Automated</span><span class="kw">)</span>       │</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true"></a>└──────────┬──────────┘</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true"></a>           │</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true"></a>           ▼</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true"></a>┌─────────────────────┐</span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true"></a>│ <span class="ex">Deployment</span> Scripts  │  ← WP-CLI + Bash automation</span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true"></a>│    <span class="kw">(</span><span class="ex">This</span> System<span class="kw">)</span>    │</span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true"></a>└──────────┬──────────┘</span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true"></a>           │</span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true"></a>    ┌──────┴──────┐</span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true"></a>    │             │</span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true"></a>    ▼             ▼</span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true"></a>┌────────┐   ┌────────┐</span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true"></a>│<span class="ex">Staging</span> │   │  Prod  │  ← WordPress environments</span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true"></a>└────────┘   └────────┘</span></code></pre>
</div>



<h4 class="wp-block-heading" id="system-features">System Features</h4>



<p><strong>Server provisioning</strong>: Automated WordPress server setup from scratch.</p>



<p><strong>Zero-downtime deploys</strong>: Release code without taking site offline.</p>



<p><strong>Database migrations</strong>: Automatic schema changes with rollback.</p>



<p><strong>Health monitoring</strong>: Continuous uptime and performance checks.</p>



<p><strong>Automatic backups</strong>: Pre-deployment snapshots with retention policies.</p>



<p><strong>One-command rollback</strong>: Instantly revert failed deployments.</p>



<p>Learn about <a href="https://aws.amazon.com/devops/what-is-devops/">DevOps deployment patterns</a>.</p>



<h3 class="wp-block-heading" id="project-structure">Project Structure and Setup</h3>



<p>Organize the deployment system codebase.</p>



<h4 class="wp-block-heading" id="directory-structure">Directory Structure</h4>



<div class="sourceCode" id="cb2">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true"></a><span class="ex">wordpress-deploy-system/</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true"></a>├── <span class="ex">bin/</span>                      # Executable scripts</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true"></a>│   ├── <span class="ex">deploy</span>                # Main deployment command</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true"></a>│   ├── <span class="ex">provision</span>             # Server provisioning</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true"></a>│   ├── <span class="ex">backup</span>                # Backup management</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true"></a>│   ├── <span class="ex">rollback</span>              # Rollback deployments</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true"></a>│   └── <span class="ex">monitor</span>               # Health monitoring</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true"></a>├── <span class="ex">lib/</span>                      # Reusable functions</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true"></a>│   ├── <span class="ex">common.sh</span>             # Shared utilities</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true"></a>│   ├── <span class="ex">deploy.sh</span>             # Deployment logic</span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true"></a>│   ├── <span class="ex">database.sh</span>           # DB operations</span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true"></a>│   └── <span class="ex">wordpress.sh</span>          # WordPress operations</span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true"></a>├── <span class="ex">config/</span>                   # Configuration files</span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true"></a>│   ├── <span class="ex">environments/</span>         # Environment-specific configs</span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true"></a>│   │   ├── <span class="ex">development.conf</span></span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true"></a>│   │   ├── <span class="ex">staging.conf</span></span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true"></a>│   │   └── <span class="ex">production.conf</span></span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true"></a>│   └── <span class="ex">deploy.conf</span>           # Global deployment config</span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true"></a>├── <span class="ex">migrations/</span>               # Database migrations</span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true"></a>│   ├── <span class="ex">001-initial-schema.sql</span></span>
<span id="cb2-21"><a href="#cb2-21" aria-hidden="true"></a>│   └── <span class="ex">002-add-custom-tables.sql</span></span>
<span id="cb2-22"><a href="#cb2-22" aria-hidden="true"></a>├── <span class="ex">hooks/</span>                    # Deployment hooks</span>
<span id="cb2-23"><a href="#cb2-23" aria-hidden="true"></a>│   ├── <span class="ex">pre-deploy.sh</span></span>
<span id="cb2-24"><a href="#cb2-24" aria-hidden="true"></a>│   ├── <span class="ex">post-deploy.sh</span></span>
<span id="cb2-25"><a href="#cb2-25" aria-hidden="true"></a>│   └── <span class="ex">health-check.sh</span></span>
<span id="cb2-26"><a href="#cb2-26" aria-hidden="true"></a>├── <span class="ex">logs/</span>                     # Deployment logs</span>
<span id="cb2-27"><a href="#cb2-27" aria-hidden="true"></a>└── <span class="ex">backups/</span>                  # Backup storage</span></code></pre>
</div>



<h4 class="wp-block-heading" id="installation-script">Installation Script</h4>



<div class="sourceCode" id="cb3">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true"></a><span class="co"># install.sh - Set up deployment system</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true"></a><span class="va">INSTALL_DIR=</span><span class="st">"/opt/wordpress-deploy"</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true"></a></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Installing WordPress Deployment System"</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"======================================="</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true"></a></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true"></a><span class="co"># Create directory structure</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true"></a><span class="fu">sudo</span> mkdir -p <span class="st">"</span><span class="va">$INSTALL_DIR</span><span class="st">"</span>/<span class="dt">{bin,lib,config/environments,migrations,hooks,logs,backups}</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true"></a></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true"></a><span class="co"># Copy files</span></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true"></a><span class="fu">sudo</span> cp -r bin/* <span class="st">"</span><span class="va">$INSTALL_DIR</span><span class="st">/bin/"</span></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true"></a><span class="fu">sudo</span> cp -r lib/* <span class="st">"</span><span class="va">$INSTALL_DIR</span><span class="st">/lib/"</span></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true"></a><span class="fu">sudo</span> cp -r config/* <span class="st">"</span><span class="va">$INSTALL_DIR</span><span class="st">/config/"</span></span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true"></a></span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true"></a><span class="co"># Make scripts executable</span></span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true"></a><span class="fu">sudo</span> chmod +x <span class="st">"</span><span class="va">$INSTALL_DIR</span><span class="st">"</span>/bin/*</span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true"></a><span class="fu">sudo</span> chmod +x <span class="st">"</span><span class="va">$INSTALL_DIR</span><span class="st">"</span>/hooks/*</span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true"></a></span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true"></a><span class="co"># Add to PATH</span></span>
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"export PATH=</span><span class="dt">\$</span><span class="st">PATH:</span><span class="va">$INSTALL_DIR</span><span class="st">/bin"</span> <span class="kw">|</span> <span class="fu">sudo</span> tee -a /etc/profile.d/wordpress-deploy.sh</span>
<span id="cb3-23"><a href="#cb3-23" aria-hidden="true"></a></span>
<span id="cb3-24"><a href="#cb3-24" aria-hidden="true"></a><span class="co"># Install WP-CLI if not present</span></span>
<span id="cb3-25"><a href="#cb3-25" aria-hidden="true"></a><span class="kw">if</span> ! <span class="bu">command</span> -v wp <span class="op">&amp;&gt;</span> /dev/null<span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb3-26"><a href="#cb3-26" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"Installing WP-CLI..."</span></span>
<span id="cb3-27"><a href="#cb3-27" aria-hidden="true"></a>    <span class="ex">curl</span> -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar</span>
<span id="cb3-28"><a href="#cb3-28" aria-hidden="true"></a>    <span class="fu">sudo</span> mv wp-cli.phar /usr/local/bin/wp</span>
<span id="cb3-29"><a href="#cb3-29" aria-hidden="true"></a>    <span class="fu">sudo</span> chmod +x /usr/local/bin/wp</span>
<span id="cb3-30"><a href="#cb3-30" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb3-31"><a href="#cb3-31" aria-hidden="true"></a></span>
<span id="cb3-32"><a href="#cb3-32" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"✓ Installation complete"</span></span>
<span id="cb3-33"><a href="#cb3-33" aria-hidden="true"></a><span class="bu">echo</span> <span class="st">"Usage: deploy &lt;environment&gt; &lt;release&gt;"</span></span></code></pre>
</div>



<h3 class="wp-block-heading" id="provisioning">Server Provisioning Automation</h3>



<p>Automate complete WordPress server setup.</p>



<h4 class="wp-block-heading" id="provisioning-script">Provisioning Script</h4>



<div class="sourceCode" id="cb4">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true"></a><span class="co"># bin/provision - Provision WordPress server</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true"></a></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true"></a><span class="kw">set</span> <span class="ex">-euo</span> pipefail</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true"></a></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true"></a><span class="bu">source</span> <span class="st">"</span><span class="va">$(</span><span class="fu">dirname</span> <span class="st">"</span><span class="va">$0</span><span class="st">"</span><span class="va">)</span><span class="st">/../lib/common.sh"</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true"></a></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true"></a><span class="va">ENVIRONMENT=</span><span class="st">"</span><span class="va">${1:-</span>staging<span class="va">}</span><span class="st">"</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true"></a><span class="va">CONFIG_FILE=</span><span class="st">"</span><span class="va">$CONFIG_DIR</span><span class="st">/environments/</span><span class="va">$ENVIRONMENT</span><span class="st">.conf"</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true"></a></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true"></a><span class="kw">if</span><span class="bu"> [</span> <span class="ot">!</span> <span class="ot">-f</span> <span class="st">"</span><span class="va">$CONFIG_FILE</span><span class="st">"</span><span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true"></a>    <span class="ex">error</span> <span class="st">"Configuration not found: </span><span class="va">$CONFIG_FILE</span><span class="st">"</span></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true"></a></span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true"></a><span class="bu">source</span> <span class="st">"</span><span class="va">$CONFIG_FILE</span><span class="st">"</span></span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true"></a></span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Provisioning WordPress server for: </span><span class="va">$ENVIRONMENT</span><span class="st">"</span></span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true"></a></span>
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true"></a><span class="co"># Update system packages</span></span>
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Updating system packages..."</span></span>
<span id="cb4-21"><a href="#cb4-21" aria-hidden="true"></a><span class="fu">sudo</span> apt-get update</span>
<span id="cb4-22"><a href="#cb4-22" aria-hidden="true"></a><span class="fu">sudo</span> apt-get upgrade -y</span>
<span id="cb4-23"><a href="#cb4-23" aria-hidden="true"></a></span>
<span id="cb4-24"><a href="#cb4-24" aria-hidden="true"></a><span class="co"># Install LAMP stack</span></span>
<span id="cb4-25"><a href="#cb4-25" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Installing LAMP stack..."</span></span>
<span id="cb4-26"><a href="#cb4-26" aria-hidden="true"></a><span class="fu">sudo</span> apt-get install -y <span class="kw">\</span></span>
<span id="cb4-27"><a href="#cb4-27" aria-hidden="true"></a>    <span class="ex">nginx</span> <span class="kw">\</span></span>
<span id="cb4-28"><a href="#cb4-28" aria-hidden="true"></a>    <span class="ex">mysql-server</span> <span class="kw">\</span></span>
<span id="cb4-29"><a href="#cb4-29" aria-hidden="true"></a>    <span class="ex">php8.1-fpm</span> <span class="kw">\</span></span>
<span id="cb4-30"><a href="#cb4-30" aria-hidden="true"></a>    <span class="ex">php8.1-mysql</span> <span class="kw">\</span></span>
<span id="cb4-31"><a href="#cb4-31" aria-hidden="true"></a>    <span class="ex">php8.1-xml</span> <span class="kw">\</span></span>
<span id="cb4-32"><a href="#cb4-32" aria-hidden="true"></a>    <span class="ex">php8.1-mbstring</span> <span class="kw">\</span></span>
<span id="cb4-33"><a href="#cb4-33" aria-hidden="true"></a>    <span class="ex">php8.1-curl</span> <span class="kw">\</span></span>
<span id="cb4-34"><a href="#cb4-34" aria-hidden="true"></a>    <span class="ex">php8.1-zip</span> <span class="kw">\</span></span>
<span id="cb4-35"><a href="#cb4-35" aria-hidden="true"></a>    <span class="ex">php8.1-gd</span> <span class="kw">\</span></span>
<span id="cb4-36"><a href="#cb4-36" aria-hidden="true"></a>    <span class="ex">php8.1-intl</span></span>
<span id="cb4-37"><a href="#cb4-37" aria-hidden="true"></a></span>
<span id="cb4-38"><a href="#cb4-38" aria-hidden="true"></a><span class="co"># Configure Nginx</span></span>
<span id="cb4-39"><a href="#cb4-39" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Configuring Nginx..."</span></span>
<span id="cb4-40"><a href="#cb4-40" aria-hidden="true"></a><span class="fu">sudo</span> tee /etc/nginx/sites-available/wordpress <span class="op">&lt;&lt;EOF</span></span>
<span id="cb4-41"><a href="#cb4-41" aria-hidden="true"></a>server {</span>
<span id="cb4-42"><a href="#cb4-42" aria-hidden="true"></a>    listen 80;</span>
<span id="cb4-43"><a href="#cb4-43" aria-hidden="true"></a>    server_name <span class="va">$SERVER_NAME</span>;</span>
<span id="cb4-44"><a href="#cb4-44" aria-hidden="true"></a>    root <span class="va">$DEPLOY_PATH</span>/current;</span>
<span id="cb4-45"><a href="#cb4-45" aria-hidden="true"></a>    index index.php;</span>
<span id="cb4-46"><a href="#cb4-46" aria-hidden="true"></a></span>
<span id="cb4-47"><a href="#cb4-47" aria-hidden="true"></a>    location / {</span>
<span id="cb4-48"><a href="#cb4-48" aria-hidden="true"></a>        try_files <span class="dt">\$</span>uri <span class="dt">\$</span>uri/ /index.php?<span class="dt">\$</span>args;</span>
<span id="cb4-49"><a href="#cb4-49" aria-hidden="true"></a>    }</span>
<span id="cb4-50"><a href="#cb4-50" aria-hidden="true"></a></span>
<span id="cb4-51"><a href="#cb4-51" aria-hidden="true"></a>    location ~ \.php$ {</span>
<span id="cb4-52"><a href="#cb4-52" aria-hidden="true"></a>        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;</span>
<span id="cb4-53"><a href="#cb4-53" aria-hidden="true"></a>        fastcgi_index index.php;</span>
<span id="cb4-54"><a href="#cb4-54" aria-hidden="true"></a>        include fastcgi_params;</span>
<span id="cb4-55"><a href="#cb4-55" aria-hidden="true"></a>        fastcgi_param SCRIPT_FILENAME <span class="dt">\$</span>document_root<span class="dt">\$</span>fastcgi_script_name;</span>
<span id="cb4-56"><a href="#cb4-56" aria-hidden="true"></a>    }</span>
<span id="cb4-57"><a href="#cb4-57" aria-hidden="true"></a>}</span>
<span id="cb4-58"><a href="#cb4-58" aria-hidden="true"></a><span class="op">EOF</span></span>
<span id="cb4-59"><a href="#cb4-59" aria-hidden="true"></a></span>
<span id="cb4-60"><a href="#cb4-60" aria-hidden="true"></a><span class="fu">sudo</span> ln -sf /etc/nginx/sites-available/wordpress /etc/nginx/sites-enabled/</span>
<span id="cb4-61"><a href="#cb4-61" aria-hidden="true"></a><span class="fu">sudo</span> nginx -t <span class="kw">&amp;&amp;</span> <span class="fu">sudo</span> systemctl reload nginx</span>
<span id="cb4-62"><a href="#cb4-62" aria-hidden="true"></a></span>
<span id="cb4-63"><a href="#cb4-63" aria-hidden="true"></a><span class="co"># Create deployment directories</span></span>
<span id="cb4-64"><a href="#cb4-64" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Creating deployment directories..."</span></span>
<span id="cb4-65"><a href="#cb4-65" aria-hidden="true"></a><span class="fu">sudo</span> mkdir -p <span class="st">"</span><span class="va">$DEPLOY_PATH</span><span class="st">"</span>/<span class="dt">{releases,shared}</span></span>
<span id="cb4-66"><a href="#cb4-66" aria-hidden="true"></a><span class="fu">sudo</span> mkdir -p <span class="st">"</span><span class="va">$DEPLOY_PATH</span><span class="st">/shared"</span>/<span class="dt">{wp-content/uploads,logs}</span></span>
<span id="cb4-67"><a href="#cb4-67" aria-hidden="true"></a></span>
<span id="cb4-68"><a href="#cb4-68" aria-hidden="true"></a><span class="co"># Set permissions</span></span>
<span id="cb4-69"><a href="#cb4-69" aria-hidden="true"></a><span class="fu">sudo</span> chown -R www-data:www-data <span class="st">"</span><span class="va">$DEPLOY_PATH</span><span class="st">"</span></span>
<span id="cb4-70"><a href="#cb4-70" aria-hidden="true"></a><span class="fu">sudo</span> chmod -R 755 <span class="st">"</span><span class="va">$DEPLOY_PATH</span><span class="st">"</span></span>
<span id="cb4-71"><a href="#cb4-71" aria-hidden="true"></a></span>
<span id="cb4-72"><a href="#cb4-72" aria-hidden="true"></a><span class="co"># Create MySQL database</span></span>
<span id="cb4-73"><a href="#cb4-73" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Creating WordPress database..."</span></span>
<span id="cb4-74"><a href="#cb4-74" aria-hidden="true"></a><span class="fu">sudo</span> mysql <span class="op">&lt;&lt;EOF</span></span>
<span id="cb4-75"><a href="#cb4-75" aria-hidden="true"></a>CREATE DATABASE IF NOT EXISTS <span class="va">$DB_NAME</span>;</span>
<span id="cb4-76"><a href="#cb4-76" aria-hidden="true"></a>CREATE USER IF NOT EXISTS '<span class="va">$DB_USER</span>'@'localhost' IDENTIFIED BY '<span class="va">$DB_PASS</span>';</span>
<span id="cb4-77"><a href="#cb4-77" aria-hidden="true"></a>GRANT ALL PRIVILEGES ON <span class="va">$DB_NAME</span>.* TO '<span class="va">$DB_USER</span>'@'localhost';</span>
<span id="cb4-78"><a href="#cb4-78" aria-hidden="true"></a>FLUSH PRIVILEGES;</span>
<span id="cb4-79"><a href="#cb4-79" aria-hidden="true"></a><span class="op">EOF</span></span>
<span id="cb4-80"><a href="#cb4-80" aria-hidden="true"></a></span>
<span id="cb4-81"><a href="#cb4-81" aria-hidden="true"></a><span class="co"># Install WordPress</span></span>
<span id="cb4-82"><a href="#cb4-82" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Installing WordPress..."</span></span>
<span id="cb4-83"><a href="#cb4-83" aria-hidden="true"></a><span class="bu">cd</span> <span class="st">"</span><span class="va">$DEPLOY_PATH</span><span class="st">"</span></span>
<span id="cb4-84"><a href="#cb4-84" aria-hidden="true"></a></span>
<span id="cb4-85"><a href="#cb4-85" aria-hidden="true"></a><span class="ex">wp</span> core download --path=initial-install</span>
<span id="cb4-86"><a href="#cb4-86" aria-hidden="true"></a><span class="bu">cd</span> initial-install</span>
<span id="cb4-87"><a href="#cb4-87" aria-hidden="true"></a></span>
<span id="cb4-88"><a href="#cb4-88" aria-hidden="true"></a><span class="ex">wp</span> config create <span class="kw">\</span></span>
<span id="cb4-89"><a href="#cb4-89" aria-hidden="true"></a>    <span class="ex">--dbname</span>=<span class="st">"</span><span class="va">$DB_NAME</span><span class="st">"</span> <span class="kw">\</span></span>
<span id="cb4-90"><a href="#cb4-90" aria-hidden="true"></a>    <span class="ex">--dbuser</span>=<span class="st">"</span><span class="va">$DB_USER</span><span class="st">"</span> <span class="kw">\</span></span>
<span id="cb4-91"><a href="#cb4-91" aria-hidden="true"></a>    <span class="ex">--dbpass</span>=<span class="st">"</span><span class="va">$DB_PASS</span><span class="st">"</span> <span class="kw">\</span></span>
<span id="cb4-92"><a href="#cb4-92" aria-hidden="true"></a>    <span class="ex">--dbhost</span>=localhost</span>
<span id="cb4-93"><a href="#cb4-93" aria-hidden="true"></a></span>
<span id="cb4-94"><a href="#cb4-94" aria-hidden="true"></a><span class="ex">wp</span> core install <span class="kw">\</span></span>
<span id="cb4-95"><a href="#cb4-95" aria-hidden="true"></a>    <span class="ex">--url</span>=<span class="st">"</span><span class="va">$SITE_URL</span><span class="st">"</span> <span class="kw">\</span></span>
<span id="cb4-96"><a href="#cb4-96" aria-hidden="true"></a>    <span class="ex">--title</span>=<span class="st">"</span><span class="va">$SITE_TITLE</span><span class="st">"</span> <span class="kw">\</span></span>
<span id="cb4-97"><a href="#cb4-97" aria-hidden="true"></a>    <span class="ex">--admin_user</span>=<span class="st">"</span><span class="va">$ADMIN_USER</span><span class="st">"</span> <span class="kw">\</span></span>
<span id="cb4-98"><a href="#cb4-98" aria-hidden="true"></a>    <span class="ex">--admin_password</span>=<span class="st">"</span><span class="va">$ADMIN_PASS</span><span class="st">"</span> <span class="kw">\</span></span>
<span id="cb4-99"><a href="#cb4-99" aria-hidden="true"></a>    <span class="ex">--admin_email</span>=<span class="st">"</span><span class="va">$ADMIN_EMAIL</span><span class="st">"</span></span>
<span id="cb4-100"><a href="#cb4-100" aria-hidden="true"></a></span>
<span id="cb4-101"><a href="#cb4-101" aria-hidden="true"></a><span class="co"># Move to shared directory</span></span>
<span id="cb4-102"><a href="#cb4-102" aria-hidden="true"></a><span class="fu">mv</span> wp-content/uploads/* <span class="st">"</span><span class="va">$DEPLOY_PATH</span><span class="st">/shared/wp-content/uploads/"</span></span>
<span id="cb4-103"><a href="#cb4-103" aria-hidden="true"></a><span class="fu">mv</span> wp-config.php <span class="st">"</span><span class="va">$DEPLOY_PATH</span><span class="st">/shared/"</span></span>
<span id="cb4-104"><a href="#cb4-104" aria-hidden="true"></a></span>
<span id="cb4-105"><a href="#cb4-105" aria-hidden="true"></a><span class="co"># Install SSL certificate (Let's Encrypt)</span></span>
<span id="cb4-106"><a href="#cb4-106" aria-hidden="true"></a><span class="kw">if</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$SSL_ENABLED</span><span class="st">"</span> <span class="ot">=</span> <span class="st">"true"</span><span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb4-107"><a href="#cb4-107" aria-hidden="true"></a>    <span class="ex">log</span> <span class="st">"Installing SSL certificate..."</span></span>
<span id="cb4-108"><a href="#cb4-108" aria-hidden="true"></a>    <span class="fu">sudo</span> apt-get install -y certbot python3-certbot-nginx</span>
<span id="cb4-109"><a href="#cb4-109" aria-hidden="true"></a>    <span class="fu">sudo</span> certbot --nginx -d <span class="st">"</span><span class="va">$SERVER_NAME</span><span class="st">"</span> --non-interactive --agree-tos -m <span class="st">"</span><span class="va">$ADMIN_EMAIL</span><span class="st">"</span></span>
<span id="cb4-110"><a href="#cb4-110" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb4-111"><a href="#cb4-111" aria-hidden="true"></a></span>
<span id="cb4-112"><a href="#cb4-112" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"✓ Server provisioning complete"</span></span>
<span id="cb4-113"><a href="#cb4-113" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"WordPress URL: </span><span class="va">$SITE_URL</span><span class="st">"</span></span>
<span id="cb4-114"><a href="#cb4-114" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Admin user: </span><span class="va">$ADMIN_USER</span><span class="st">"</span></span></code></pre>
</div>



<h4 class="wp-block-heading" id="environment-configuration-template">Environment Configuration Template</h4>



<div class="sourceCode" id="cb5">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true"></a><span class="co"># config/environments/production.conf</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true"></a></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true"></a><span class="co"># Server settings</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true"></a><span class="va">SERVER_NAME=</span><span class="st">"example.com"</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true"></a><span class="va">SITE_URL=</span><span class="st">"https://example.com"</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true"></a><span class="va">SITE_TITLE=</span><span class="st">"Production Site"</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true"></a></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true"></a><span class="co"># Deployment paths</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true"></a><span class="va">DEPLOY_PATH=</span><span class="st">"/var/www/production"</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true"></a><span class="va">RELEASE_DIR=</span><span class="st">"</span><span class="va">$DEPLOY_PATH</span><span class="st">/releases"</span></span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true"></a><span class="va">SHARED_DIR=</span><span class="st">"</span><span class="va">$DEPLOY_PATH</span><span class="st">/shared"</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true"></a><span class="va">CURRENT_LINK=</span><span class="st">"</span><span class="va">$DEPLOY_PATH</span><span class="st">/current"</span></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true"></a></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true"></a><span class="co"># Database credentials</span></span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true"></a><span class="va">DB_NAME=</span><span class="st">"wp_production"</span></span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true"></a><span class="va">DB_USER=</span><span class="st">"wp_user"</span></span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true"></a><span class="va">DB_PASS=</span><span class="st">"strong-password-here"</span></span>
<span id="cb5-18"><a href="#cb5-18" aria-hidden="true"></a><span class="va">DB_HOST=</span><span class="st">"localhost"</span></span>
<span id="cb5-19"><a href="#cb5-19" aria-hidden="true"></a></span>
<span id="cb5-20"><a href="#cb5-20" aria-hidden="true"></a><span class="co"># WordPress admin</span></span>
<span id="cb5-21"><a href="#cb5-21" aria-hidden="true"></a><span class="va">ADMIN_USER=</span><span class="st">"admin"</span></span>
<span id="cb5-22"><a href="#cb5-22" aria-hidden="true"></a><span class="va">ADMIN_PASS=</span><span class="st">"admin-password-here"</span></span>
<span id="cb5-23"><a href="#cb5-23" aria-hidden="true"></a><span class="va">ADMIN_EMAIL=</span><span class="st">"admin@example.com"</span></span>
<span id="cb5-24"><a href="#cb5-24" aria-hidden="true"></a></span>
<span id="cb5-25"><a href="#cb5-25" aria-hidden="true"></a><span class="co"># Git repository</span></span>
<span id="cb5-26"><a href="#cb5-26" aria-hidden="true"></a><span class="va">GIT_REPO=</span><span class="st">"git@github.com:yourcompany/wordpress-site.git"</span></span>
<span id="cb5-27"><a href="#cb5-27" aria-hidden="true"></a><span class="va">GIT_BRANCH=</span><span class="st">"main"</span></span>
<span id="cb5-28"><a href="#cb5-28" aria-hidden="true"></a></span>
<span id="cb5-29"><a href="#cb5-29" aria-hidden="true"></a><span class="co"># Deployment settings</span></span>
<span id="cb5-30"><a href="#cb5-30" aria-hidden="true"></a><span class="va">KEEP_RELEASES=</span>5</span>
<span id="cb5-31"><a href="#cb5-31" aria-hidden="true"></a><span class="va">BACKUP_RETENTION_DAYS=</span>30</span>
<span id="cb5-32"><a href="#cb5-32" aria-hidden="true"></a><span class="va">SSL_ENABLED=</span>true</span>
<span id="cb5-33"><a href="#cb5-33" aria-hidden="true"></a></span>
<span id="cb5-34"><a href="#cb5-34" aria-hidden="true"></a><span class="co"># Notifications</span></span>
<span id="cb5-35"><a href="#cb5-35" aria-hidden="true"></a><span class="va">SLACK_WEBHOOK=</span><span class="st">"https://hooks.slack.com/services/YOUR/WEBHOOK/URL"</span></span>
<span id="cb5-36"><a href="#cb5-36" aria-hidden="true"></a><span class="va">EMAIL_NOTIFICATIONS=</span><span class="st">"team@example.com"</span></span></code></pre>
</div>



<p>Learn about <a href="https://wordpress.org/about/requirements/">WordPress server requirements</a>.</p>



<h3 class="wp-block-heading" id="zero-downtime">Zero-Downtime Deployment Implementation</h3>



<p>Deploy code changes without taking site offline.</p>



<h4 class="wp-block-heading" id="main-deployment-script">Main Deployment Script</h4>



<div class="sourceCode" id="cb6">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true"></a><span class="co"># bin/deploy - Main deployment command</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true"></a></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true"></a><span class="kw">set</span> <span class="ex">-euo</span> pipefail</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true"></a></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true"></a><span class="bu">source</span> <span class="st">"</span><span class="va">$(</span><span class="fu">dirname</span> <span class="st">"</span><span class="va">$0</span><span class="st">"</span><span class="va">)</span><span class="st">/../lib/common.sh"</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true"></a><span class="bu">source</span> <span class="st">"</span><span class="va">$(</span><span class="fu">dirname</span> <span class="st">"</span><span class="va">$0</span><span class="st">"</span><span class="va">)</span><span class="st">/../lib/deploy.sh"</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true"></a></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true"></a><span class="va">ENVIRONMENT=</span><span class="st">"</span><span class="va">${1:-</span>staging<span class="va">}</span><span class="st">"</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true"></a><span class="va">RELEASE_TAG=</span><span class="st">"</span><span class="va">${2:-</span>HEAD<span class="va">}</span><span class="st">"</span></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true"></a><span class="va">CONFIG_FILE=</span><span class="st">"</span><span class="va">$CONFIG_DIR</span><span class="st">/environments/</span><span class="va">$ENVIRONMENT</span><span class="st">.conf"</span></span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true"></a></span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true"></a><span class="kw">if</span><span class="bu"> [</span> <span class="ot">!</span> <span class="ot">-f</span> <span class="st">"</span><span class="va">$CONFIG_FILE</span><span class="st">"</span><span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true"></a>    <span class="ex">error</span> <span class="st">"Configuration not found: </span><span class="va">$CONFIG_FILE</span><span class="st">"</span></span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true"></a></span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true"></a><span class="bu">source</span> <span class="st">"</span><span class="va">$CONFIG_FILE</span><span class="st">"</span></span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true"></a></span>
<span id="cb6-19"><a href="#cb6-19" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"=== WordPress Deployment Started ==="</span></span>
<span id="cb6-20"><a href="#cb6-20" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Environment: </span><span class="va">$ENVIRONMENT</span><span class="st">"</span></span>
<span id="cb6-21"><a href="#cb6-21" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Release: </span><span class="va">$RELEASE_TAG</span><span class="st">"</span></span>
<span id="cb6-22"><a href="#cb6-22" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Time: </span><span class="va">$(</span><span class="fu">date</span><span class="va">)</span><span class="st">"</span></span>
<span id="cb6-23"><a href="#cb6-23" aria-hidden="true"></a></span>
<span id="cb6-24"><a href="#cb6-24" aria-hidden="true"></a><span class="co"># Pre-deployment checks</span></span>
<span id="cb6-25"><a href="#cb6-25" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Running pre-deployment checks..."</span></span>
<span id="cb6-26"><a href="#cb6-26" aria-hidden="true"></a><span class="ex">run_hook</span> <span class="st">"pre-deploy"</span> <span class="kw">||</span> <span class="ex">error</span> <span class="st">"Pre-deployment checks failed"</span></span>
<span id="cb6-27"><a href="#cb6-27" aria-hidden="true"></a></span>
<span id="cb6-28"><a href="#cb6-28" aria-hidden="true"></a><span class="co"># Create backup</span></span>
<span id="cb6-29"><a href="#cb6-29" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Creating pre-deployment backup..."</span></span>
<span id="cb6-30"><a href="#cb6-30" aria-hidden="true"></a><span class="st">"</span><span class="va">$BIN_DIR</span><span class="st">/backup"</span> <span class="st">"</span><span class="va">$ENVIRONMENT</span><span class="st">"</span> <span class="kw">||</span> <span class="ex">error</span> <span class="st">"Backup failed"</span></span>
<span id="cb6-31"><a href="#cb6-31" aria-hidden="true"></a></span>
<span id="cb6-32"><a href="#cb6-32" aria-hidden="true"></a><span class="co"># Prepare new release</span></span>
<span id="cb6-33"><a href="#cb6-33" aria-hidden="true"></a><span class="va">RELEASE_ID=$(</span><span class="fu">date</span> +%Y%m%d_%H%M%S<span class="va">)</span></span>
<span id="cb6-34"><a href="#cb6-34" aria-hidden="true"></a><span class="va">RELEASE_PATH=</span><span class="st">"</span><span class="va">$RELEASE_DIR</span><span class="st">/</span><span class="va">$RELEASE_ID</span><span class="st">"</span></span>
<span id="cb6-35"><a href="#cb6-35" aria-hidden="true"></a></span>
<span id="cb6-36"><a href="#cb6-36" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Creating release: </span><span class="va">$RELEASE_ID</span><span class="st">"</span></span>
<span id="cb6-37"><a href="#cb6-37" aria-hidden="true"></a><span class="fu">mkdir</span> -p <span class="st">"</span><span class="va">$RELEASE_PATH</span><span class="st">"</span></span>
<span id="cb6-38"><a href="#cb6-38" aria-hidden="true"></a></span>
<span id="cb6-39"><a href="#cb6-39" aria-hidden="true"></a><span class="co"># Clone code from Git</span></span>
<span id="cb6-40"><a href="#cb6-40" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Cloning repository..."</span></span>
<span id="cb6-41"><a href="#cb6-41" aria-hidden="true"></a><span class="fu">git</span> clone --depth 1 --branch <span class="st">"</span><span class="va">$GIT_BRANCH</span><span class="st">"</span> <span class="st">"</span><span class="va">$GIT_REPO</span><span class="st">"</span> <span class="st">"</span><span class="va">$RELEASE_PATH</span><span class="st">"</span></span>
<span id="cb6-42"><a href="#cb6-42" aria-hidden="true"></a><span class="bu">cd</span> <span class="st">"</span><span class="va">$RELEASE_PATH</span><span class="st">"</span></span>
<span id="cb6-43"><a href="#cb6-43" aria-hidden="true"></a></span>
<span id="cb6-44"><a href="#cb6-44" aria-hidden="true"></a><span class="co"># Install dependencies</span></span>
<span id="cb6-45"><a href="#cb6-45" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Installing dependencies..."</span></span>
<span id="cb6-46"><a href="#cb6-46" aria-hidden="true"></a><span class="kw">if</span><span class="bu"> [</span> <span class="ot">-f</span> composer.json<span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb6-47"><a href="#cb6-47" aria-hidden="true"></a>    <span class="ex">composer</span> install --no-dev --optimize-autoloader</span>
<span id="cb6-48"><a href="#cb6-48" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb6-49"><a href="#cb6-49" aria-hidden="true"></a></span>
<span id="cb6-50"><a href="#cb6-50" aria-hidden="true"></a><span class="kw">if</span><span class="bu"> [</span> <span class="ot">-f</span> package.json<span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb6-51"><a href="#cb6-51" aria-hidden="true"></a>    <span class="ex">npm</span> ci --production</span>
<span id="cb6-52"><a href="#cb6-52" aria-hidden="true"></a>    <span class="ex">npm</span> run build</span>
<span id="cb6-53"><a href="#cb6-53" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb6-54"><a href="#cb6-54" aria-hidden="true"></a></span>
<span id="cb6-55"><a href="#cb6-55" aria-hidden="true"></a><span class="co"># Link shared directories</span></span>
<span id="cb6-56"><a href="#cb6-56" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Linking shared resources..."</span></span>
<span id="cb6-57"><a href="#cb6-57" aria-hidden="true"></a><span class="fu">ln</span> -nfs <span class="st">"</span><span class="va">$SHARED_DIR</span><span class="st">/wp-content/uploads"</span> <span class="st">"</span><span class="va">$RELEASE_PATH</span><span class="st">/wp-content/uploads"</span></span>
<span id="cb6-58"><a href="#cb6-58" aria-hidden="true"></a><span class="fu">ln</span> -nfs <span class="st">"</span><span class="va">$SHARED_DIR</span><span class="st">/wp-config.php"</span> <span class="st">"</span><span class="va">$RELEASE_PATH</span><span class="st">/wp-config.php"</span></span>
<span id="cb6-59"><a href="#cb6-59" aria-hidden="true"></a></span>
<span id="cb6-60"><a href="#cb6-60" aria-hidden="true"></a><span class="co"># Run database migrations</span></span>
<span id="cb6-61"><a href="#cb6-61" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Running database migrations..."</span></span>
<span id="cb6-62"><a href="#cb6-62" aria-hidden="true"></a><span class="ex">run_migrations</span> <span class="st">"</span><span class="va">$RELEASE_PATH</span><span class="st">"</span> <span class="kw">||</span> <span class="kw">{</span></span>
<span id="cb6-63"><a href="#cb6-63" aria-hidden="true"></a>    <span class="ex">error</span> <span class="st">"Database migration failed"</span></span>
<span id="cb6-64"><a href="#cb6-64" aria-hidden="true"></a>    <span class="ex">rollback_deployment</span> <span class="st">"</span><span class="va">$ENVIRONMENT</span><span class="st">"</span> <span class="st">"</span><span class="va">$RELEASE_ID</span><span class="st">"</span></span>
<span id="cb6-65"><a href="#cb6-65" aria-hidden="true"></a>    <span class="bu">exit</span> 1</span>
<span id="cb6-66"><a href="#cb6-66" aria-hidden="true"></a><span class="kw">}</span></span>
<span id="cb6-67"><a href="#cb6-67" aria-hidden="true"></a></span>
<span id="cb6-68"><a href="#cb6-68" aria-hidden="true"></a><span class="co"># Health check on new release</span></span>
<span id="cb6-69"><a href="#cb6-69" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Running health checks..."</span></span>
<span id="cb6-70"><a href="#cb6-70" aria-hidden="true"></a><span class="ex">test_release</span> <span class="st">"</span><span class="va">$RELEASE_PATH</span><span class="st">"</span> <span class="kw">||</span> <span class="kw">{</span></span>
<span id="cb6-71"><a href="#cb6-71" aria-hidden="true"></a>    <span class="ex">error</span> <span class="st">"Health checks failed"</span></span>
<span id="cb6-72"><a href="#cb6-72" aria-hidden="true"></a>    <span class="ex">rollback_deployment</span> <span class="st">"</span><span class="va">$ENVIRONMENT</span><span class="st">"</span> <span class="st">"</span><span class="va">$RELEASE_ID</span><span class="st">"</span></span>
<span id="cb6-73"><a href="#cb6-73" aria-hidden="true"></a>    <span class="bu">exit</span> 1</span>
<span id="cb6-74"><a href="#cb6-74" aria-hidden="true"></a><span class="kw">}</span></span>
<span id="cb6-75"><a href="#cb6-75" aria-hidden="true"></a></span>
<span id="cb6-76"><a href="#cb6-76" aria-hidden="true"></a><span class="co"># Atomic switch to new release</span></span>
<span id="cb6-77"><a href="#cb6-77" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Switching to new release..."</span></span>
<span id="cb6-78"><a href="#cb6-78" aria-hidden="true"></a><span class="fu">ln</span> -nfs <span class="st">"</span><span class="va">$RELEASE_PATH</span><span class="st">"</span> <span class="st">"</span><span class="va">$CURRENT_LINK</span><span class="st">"</span></span>
<span id="cb6-79"><a href="#cb6-79" aria-hidden="true"></a></span>
<span id="cb6-80"><a href="#cb6-80" aria-hidden="true"></a><span class="co"># Post-deployment tasks</span></span>
<span id="cb6-81"><a href="#cb6-81" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Running post-deployment tasks..."</span></span>
<span id="cb6-82"><a href="#cb6-82" aria-hidden="true"></a><span class="bu">cd</span> <span class="st">"</span><span class="va">$CURRENT_LINK</span><span class="st">"</span></span>
<span id="cb6-83"><a href="#cb6-83" aria-hidden="true"></a><span class="ex">wp</span> cache flush</span>
<span id="cb6-84"><a href="#cb6-84" aria-hidden="true"></a><span class="ex">wp</span> rewrite flush</span>
<span id="cb6-85"><a href="#cb6-85" aria-hidden="true"></a></span>
<span id="cb6-86"><a href="#cb6-86" aria-hidden="true"></a><span class="ex">run_hook</span> <span class="st">"post-deploy"</span></span>
<span id="cb6-87"><a href="#cb6-87" aria-hidden="true"></a></span>
<span id="cb6-88"><a href="#cb6-88" aria-hidden="true"></a><span class="co"># Cleanup old releases</span></span>
<span id="cb6-89"><a href="#cb6-89" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Cleaning up old releases..."</span></span>
<span id="cb6-90"><a href="#cb6-90" aria-hidden="true"></a><span class="ex">cleanup_releases</span> <span class="st">"</span><span class="va">$RELEASE_DIR</span><span class="st">"</span> <span class="st">"</span><span class="va">$KEEP_RELEASES</span><span class="st">"</span></span>
<span id="cb6-91"><a href="#cb6-91" aria-hidden="true"></a></span>
<span id="cb6-92"><a href="#cb6-92" aria-hidden="true"></a><span class="co"># Send notifications</span></span>
<span id="cb6-93"><a href="#cb6-93" aria-hidden="true"></a><span class="ex">notify_deployment</span> <span class="st">"success"</span> <span class="st">"</span><span class="va">$ENVIRONMENT</span><span class="st">"</span> <span class="st">"</span><span class="va">$RELEASE_ID</span><span class="st">"</span></span>
<span id="cb6-94"><a href="#cb6-94" aria-hidden="true"></a></span>
<span id="cb6-95"><a href="#cb6-95" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"=== Deployment Complete ==="</span></span>
<span id="cb6-96"><a href="#cb6-96" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Active release: </span><span class="va">$RELEASE_ID</span><span class="st">"</span></span>
<span id="cb6-97"><a href="#cb6-97" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Site URL: </span><span class="va">$SITE_URL</span><span class="st">"</span></span></code></pre>
</div>



<h4 class="wp-block-heading" id="shared-functions-library">Shared Functions Library</h4>



<div class="sourceCode" id="cb7">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true"></a><span class="co"># lib/common.sh - Common utilities</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true"></a></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true"></a><span class="va">LOG_FILE=</span><span class="st">"</span><span class="va">$LOG_DIR</span><span class="st">/deploy-</span><span class="va">$(</span><span class="fu">date</span> +%Y%m%d<span class="va">)</span><span class="st">.log"</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true"></a></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true"></a><span class="fu">log()</span> <span class="kw">{</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"[</span><span class="va">$(</span><span class="fu">date</span> <span class="st">'+%Y-%m-%d %H:%M:%S'</span><span class="va">)</span><span class="st">] </span><span class="va">$@</span><span class="st">"</span> <span class="kw">|</span> <span class="fu">tee</span> -a <span class="st">"</span><span class="va">$LOG_FILE</span><span class="st">"</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true"></a><span class="kw">}</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true"></a></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true"></a><span class="fu">error()</span> <span class="kw">{</span></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true"></a>    <span class="bu">echo</span> <span class="st">"[ERROR] </span><span class="va">$@</span><span class="st">"</span> <span class="kw">|</span> <span class="fu">tee</span> -a <span class="st">"</span><span class="va">$LOG_FILE</span><span class="st">"</span> <span class="op">&gt;&amp;2</span></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true"></a>    <span class="ex">notify_deployment</span> <span class="st">"failure"</span> <span class="st">"</span><span class="va">$ENVIRONMENT</span><span class="st">"</span> <span class="st">"</span><span class="va">$RELEASE_ID</span><span class="st">"</span></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true"></a>    <span class="bu">exit</span> 1</span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true"></a><span class="kw">}</span></span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true"></a></span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true"></a><span class="fu">run_hook()</span> <span class="kw">{</span></span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true"></a>    <span class="bu">local</span> <span class="va">hook_name=</span><span class="st">"</span><span class="va">$1</span><span class="st">"</span></span>
<span id="cb7-17"><a href="#cb7-17" aria-hidden="true"></a>    <span class="bu">local</span> <span class="va">hook_script=</span><span class="st">"</span><span class="va">$HOOKS_DIR</span><span class="st">/</span><span class="va">${hook_name}</span><span class="st">.sh"</span></span>
<span id="cb7-18"><a href="#cb7-18" aria-hidden="true"></a></span>
<span id="cb7-19"><a href="#cb7-19" aria-hidden="true"></a>    <span class="kw">if</span><span class="bu"> [</span> <span class="ot">-f</span> <span class="st">"</span><span class="va">$hook_script</span><span class="st">"</span><span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb7-20"><a href="#cb7-20" aria-hidden="true"></a>        <span class="ex">log</span> <span class="st">"Running hook: </span><span class="va">$hook_name</span><span class="st">"</span></span>
<span id="cb7-21"><a href="#cb7-21" aria-hidden="true"></a>        <span class="fu">bash</span> <span class="st">"</span><span class="va">$hook_script</span><span class="st">"</span> <span class="st">"</span><span class="va">$ENVIRONMENT</span><span class="st">"</span></span>
<span id="cb7-22"><a href="#cb7-22" aria-hidden="true"></a>    <span class="kw">fi</span></span>
<span id="cb7-23"><a href="#cb7-23" aria-hidden="true"></a><span class="kw">}</span></span>
<span id="cb7-24"><a href="#cb7-24" aria-hidden="true"></a></span>
<span id="cb7-25"><a href="#cb7-25" aria-hidden="true"></a><span class="fu">notify_deployment()</span> <span class="kw">{</span></span>
<span id="cb7-26"><a href="#cb7-26" aria-hidden="true"></a>    <span class="bu">local</span> <span class="va">status=</span><span class="st">"</span><span class="va">$1</span><span class="st">"</span></span>
<span id="cb7-27"><a href="#cb7-27" aria-hidden="true"></a>    <span class="bu">local</span> <span class="va">environment=</span><span class="st">"</span><span class="va">$2</span><span class="st">"</span></span>
<span id="cb7-28"><a href="#cb7-28" aria-hidden="true"></a>    <span class="bu">local</span> <span class="va">release=</span><span class="st">"</span><span class="va">$3</span><span class="st">"</span></span>
<span id="cb7-29"><a href="#cb7-29" aria-hidden="true"></a></span>
<span id="cb7-30"><a href="#cb7-30" aria-hidden="true"></a>    <span class="co"># Slack notification</span></span>
<span id="cb7-31"><a href="#cb7-31" aria-hidden="true"></a>    <span class="kw">if</span><span class="bu"> [</span> <span class="ot">-n</span> <span class="st">"</span><span class="va">$SLACK_WEBHOOK</span><span class="st">"</span><span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb7-32"><a href="#cb7-32" aria-hidden="true"></a>        <span class="ex">curl</span> -X POST <span class="st">"</span><span class="va">$SLACK_WEBHOOK</span><span class="st">"</span> <span class="kw">\</span></span>
<span id="cb7-33"><a href="#cb7-33" aria-hidden="true"></a>            <span class="ex">-H</span> <span class="st">'Content-Type: application/json'</span> <span class="kw">\</span></span>
<span id="cb7-34"><a href="#cb7-34" aria-hidden="true"></a>            <span class="ex">-d</span> <span class="st">"{</span><span class="dt">\"</span><span class="st">text</span><span class="dt">\"</span><span class="st">:</span><span class="dt">\"</span><span class="st">Deployment </span><span class="va">$status</span><span class="st">: </span><span class="va">$environment</span><span class="st"> (</span><span class="va">$release</span><span class="st">)</span><span class="dt">\"</span><span class="st">}"</span></span>
<span id="cb7-35"><a href="#cb7-35" aria-hidden="true"></a>    <span class="kw">fi</span></span>
<span id="cb7-36"><a href="#cb7-36" aria-hidden="true"></a></span>
<span id="cb7-37"><a href="#cb7-37" aria-hidden="true"></a>    <span class="co"># Email notification</span></span>
<span id="cb7-38"><a href="#cb7-38" aria-hidden="true"></a>    <span class="kw">if</span><span class="bu"> [</span> <span class="ot">-n</span> <span class="st">"</span><span class="va">$EMAIL_NOTIFICATIONS</span><span class="st">"</span><span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb7-39"><a href="#cb7-39" aria-hidden="true"></a>        <span class="bu">echo</span> <span class="st">"Deployment </span><span class="va">$status</span><span class="st"> on </span><span class="va">$environment</span><span class="st"> (Release: </span><span class="va">$release</span><span class="st">)"</span> <span class="kw">|</span> <span class="kw">\</span></span>
<span id="cb7-40"><a href="#cb7-40" aria-hidden="true"></a>            <span class="ex">mail</span> -s <span class="st">"WordPress Deployment </span><span class="va">$status</span><span class="st">"</span> <span class="st">"</span><span class="va">$EMAIL_NOTIFICATIONS</span><span class="st">"</span></span>
<span id="cb7-41"><a href="#cb7-41" aria-hidden="true"></a>    <span class="kw">fi</span></span>
<span id="cb7-42"><a href="#cb7-42" aria-hidden="true"></a><span class="kw">}</span></span>
<span id="cb7-43"><a href="#cb7-43" aria-hidden="true"></a></span>
<span id="cb7-44"><a href="#cb7-44" aria-hidden="true"></a><span class="fu">cleanup_releases()</span> <span class="kw">{</span></span>
<span id="cb7-45"><a href="#cb7-45" aria-hidden="true"></a>    <span class="bu">local</span> <span class="va">release_dir=</span><span class="st">"</span><span class="va">$1</span><span class="st">"</span></span>
<span id="cb7-46"><a href="#cb7-46" aria-hidden="true"></a>    <span class="bu">local</span> <span class="va">keep_count=</span><span class="st">"</span><span class="va">$2</span><span class="st">"</span></span>
<span id="cb7-47"><a href="#cb7-47" aria-hidden="true"></a></span>
<span id="cb7-48"><a href="#cb7-48" aria-hidden="true"></a>    <span class="bu">cd</span> <span class="st">"</span><span class="va">$release_dir</span><span class="st">"</span></span>
<span id="cb7-49"><a href="#cb7-49" aria-hidden="true"></a>    <span class="fu">ls</span> -t <span class="kw">|</span> <span class="fu">tail</span> -n +<span class="va">$((</span>keep_count + 1<span class="va">))</span> <span class="kw">|</span> <span class="fu">xargs</span> rm -rf</span>
<span id="cb7-50"><a href="#cb7-50" aria-hidden="true"></a><span class="kw">}</span></span></code></pre>
</div>



<h3 class="wp-block-heading" id="migrations">Database Migration System</h3>



<p>Manage database schema changes safely.</p>



<h4 class="wp-block-heading" id="migration-runner">Migration Runner</h4>



<div class="sourceCode" id="cb8">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true"></a><span class="co"># lib/database.sh - Database migration functions</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true"></a></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true"></a><span class="fu">run_migrations()</span> <span class="kw">{</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true"></a>    <span class="bu">local</span> <span class="va">release_path=</span><span class="st">"</span><span class="va">$1</span><span class="st">"</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true"></a>    <span class="bu">local</span> <span class="va">migration_dir=</span><span class="st">"</span><span class="va">$MIGRATIONS_DIR</span><span class="st">"</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true"></a>    <span class="bu">local</span> <span class="va">applied_file=</span><span class="st">"</span><span class="va">$SHARED_DIR</span><span class="st">/.applied-migrations"</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true"></a></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true"></a>    <span class="fu">touch</span> <span class="st">"</span><span class="va">$applied_file</span><span class="st">"</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true"></a></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true"></a>    <span class="ex">log</span> <span class="st">"Checking for pending migrations..."</span></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true"></a></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true"></a>    <span class="kw">for</span> <span class="ex">migration</span> in <span class="va">$(</span><span class="fu">ls</span> <span class="st">"</span><span class="va">$migration_dir</span><span class="st">"</span>/*.sql <span class="kw">|</span> <span class="fu">sort</span><span class="va">)</span><span class="kw">;</span> <span class="kw">do</span></span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true"></a>        <span class="bu">local</span> <span class="va">migration_name=$(</span><span class="fu">basename</span> <span class="st">"</span><span class="va">$migration</span><span class="st">"</span><span class="va">)</span></span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true"></a></span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true"></a>        <span class="co"># Check if already applied</span></span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true"></a>        <span class="kw">if</span> <span class="fu">grep</span> -q <span class="st">"</span><span class="va">$migration_name</span><span class="st">"</span> <span class="st">"</span><span class="va">$applied_file</span><span class="st">"</span><span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true"></a>            <span class="ex">log</span> <span class="st">"  ⊘ Skipping: </span><span class="va">$migration_name</span><span class="st"> (already applied)"</span></span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true"></a>            <span class="bu">continue</span></span>
<span id="cb8-19"><a href="#cb8-19" aria-hidden="true"></a>        <span class="kw">fi</span></span>
<span id="cb8-20"><a href="#cb8-20" aria-hidden="true"></a></span>
<span id="cb8-21"><a href="#cb8-21" aria-hidden="true"></a>        <span class="ex">log</span> <span class="st">"  → Applying: </span><span class="va">$migration_name</span><span class="st">"</span></span>
<span id="cb8-22"><a href="#cb8-22" aria-hidden="true"></a></span>
<span id="cb8-23"><a href="#cb8-23" aria-hidden="true"></a>        <span class="co"># Run migration</span></span>
<span id="cb8-24"><a href="#cb8-24" aria-hidden="true"></a>        <span class="kw">if</span> <span class="ex">wp</span> db query <span class="op">&lt;</span> <span class="st">"</span><span class="va">$migration</span><span class="st">"</span> --path=<span class="st">"</span><span class="va">$release_path</span><span class="st">"</span><span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb8-25"><a href="#cb8-25" aria-hidden="true"></a>            <span class="bu">echo</span> <span class="st">"</span><span class="va">$migration_name</span><span class="st">"</span> <span class="op">&gt;&gt;</span> <span class="st">"</span><span class="va">$applied_file</span><span class="st">"</span></span>
<span id="cb8-26"><a href="#cb8-26" aria-hidden="true"></a>            <span class="ex">log</span> <span class="st">"  ✓ Applied: </span><span class="va">$migration_name</span><span class="st">"</span></span>
<span id="cb8-27"><a href="#cb8-27" aria-hidden="true"></a>        <span class="kw">else</span></span>
<span id="cb8-28"><a href="#cb8-28" aria-hidden="true"></a>            <span class="ex">error</span> <span class="st">"Migration failed: </span><span class="va">$migration_name</span><span class="st">"</span></span>
<span id="cb8-29"><a href="#cb8-29" aria-hidden="true"></a>        <span class="kw">fi</span></span>
<span id="cb8-30"><a href="#cb8-30" aria-hidden="true"></a>    <span class="kw">done</span></span>
<span id="cb8-31"><a href="#cb8-31" aria-hidden="true"></a></span>
<span id="cb8-32"><a href="#cb8-32" aria-hidden="true"></a>    <span class="ex">log</span> <span class="st">"✓ All migrations applied"</span></span>
<span id="cb8-33"><a href="#cb8-33" aria-hidden="true"></a><span class="kw">}</span></span>
<span id="cb8-34"><a href="#cb8-34" aria-hidden="true"></a></span>
<span id="cb8-35"><a href="#cb8-35" aria-hidden="true"></a><span class="fu">rollback_migration()</span> <span class="kw">{</span></span>
<span id="cb8-36"><a href="#cb8-36" aria-hidden="true"></a>    <span class="bu">local</span> <span class="va">migration_name=</span><span class="st">"</span><span class="va">$1</span><span class="st">"</span></span>
<span id="cb8-37"><a href="#cb8-37" aria-hidden="true"></a>    <span class="bu">local</span> <span class="va">rollback_file=</span><span class="st">"</span><span class="va">$MIGRATIONS_DIR</span><span class="st">/</span><span class="va">${migration_name%</span>.sql<span class="va">}</span><span class="st">-rollback.sql"</span></span>
<span id="cb8-38"><a href="#cb8-38" aria-hidden="true"></a></span>
<span id="cb8-39"><a href="#cb8-39" aria-hidden="true"></a>    <span class="kw">if</span><span class="bu"> [</span> <span class="ot">-f</span> <span class="st">"</span><span class="va">$rollback_file</span><span class="st">"</span><span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb8-40"><a href="#cb8-40" aria-hidden="true"></a>        <span class="ex">log</span> <span class="st">"Rolling back migration: </span><span class="va">$migration_name</span><span class="st">"</span></span>
<span id="cb8-41"><a href="#cb8-41" aria-hidden="true"></a>        <span class="ex">wp</span> db query <span class="op">&lt;</span> <span class="st">"</span><span class="va">$rollback_file</span><span class="st">"</span></span>
<span id="cb8-42"><a href="#cb8-42" aria-hidden="true"></a>    <span class="kw">else</span></span>
<span id="cb8-43"><a href="#cb8-43" aria-hidden="true"></a>        <span class="ex">error</span> <span class="st">"Rollback file not found: </span><span class="va">$rollback_file</span><span class="st">"</span></span>
<span id="cb8-44"><a href="#cb8-44" aria-hidden="true"></a>    <span class="kw">fi</span></span>
<span id="cb8-45"><a href="#cb8-45" aria-hidden="true"></a><span class="kw">}</span></span></code></pre>
</div>



<h4 class="wp-block-heading" id="example-migration-files">Example Migration Files</h4>



<div class="sourceCode" id="cb9">
<pre class="sourceCode sql"><code class="sourceCode sql"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true"></a><span class="co">-- migrations/001-add-custom-tables.sql</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true"></a></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true"></a><span class="kw">CREATE</span> <span class="kw">TABLE</span> <span class="cf">IF</span> <span class="kw">NOT</span> <span class="kw">EXISTS</span> wp_custom_data (</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true"></a>    <span class="kw">id</span> BIGINT(<span class="dv">20</span>) UNSIGNED <span class="kw">NOT</span> <span class="kw">NULL</span> AUTO_INCREMENT,</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true"></a>    user_id BIGINT(<span class="dv">20</span>) UNSIGNED <span class="kw">NOT</span> <span class="kw">NULL</span>,</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true"></a>    data_key <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">NOT</span> <span class="kw">NULL</span>,</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true"></a>    data_value LONGTEXT,</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true"></a>    created_at DATETIME <span class="kw">DEFAULT</span> <span class="fu">CURRENT_TIMESTAMP</span>,</span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true"></a>    <span class="kw">PRIMARY</span> <span class="kw">KEY</span> (<span class="kw">id</span>),</span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true"></a>    <span class="kw">KEY</span> user_id (user_id)</span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true"></a>) ENGINE<span class="op">=</span>InnoDB <span class="kw">DEFAULT</span> CHARSET<span class="op">=</span>utf8mb4;</span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true"></a></span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true"></a><span class="co">-- migrations/001-add-custom-tables-rollback.sql</span></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true"></a></span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true"></a><span class="kw">DROP</span> <span class="kw">TABLE</span> <span class="cf">IF</span> <span class="kw">EXISTS</span> wp_custom_data;</span></code></pre>
</div>



<h3 class="wp-block-heading" id="rollback">Rollback System</h3>



<p>Instantly revert failed deployments.</p>



<h4 class="wp-block-heading" id="rollback-script">Rollback Script</h4>



<div class="sourceCode" id="cb10">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true"></a><span class="co"># bin/rollback - Rollback to previous release</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true"></a></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true"></a><span class="kw">set</span> <span class="ex">-euo</span> pipefail</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true"></a></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true"></a><span class="bu">source</span> <span class="st">"</span><span class="va">$(</span><span class="fu">dirname</span> <span class="st">"</span><span class="va">$0</span><span class="st">"</span><span class="va">)</span><span class="st">/../lib/common.sh"</span></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true"></a></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true"></a><span class="va">ENVIRONMENT=</span><span class="st">"</span><span class="va">${1:-</span>staging<span class="va">}</span><span class="st">"</span></span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true"></a><span class="va">CONFIG_FILE=</span><span class="st">"</span><span class="va">$CONFIG_DIR</span><span class="st">/environments/</span><span class="va">$ENVIRONMENT</span><span class="st">.conf"</span></span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true"></a></span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true"></a><span class="bu">source</span> <span class="st">"</span><span class="va">$CONFIG_FILE</span><span class="st">"</span></span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true"></a></span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"=== Starting Rollback ==="</span></span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true"></a></span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true"></a><span class="co"># Get current release</span></span>
<span id="cb10-16"><a href="#cb10-16" aria-hidden="true"></a><span class="va">CURRENT=$(</span><span class="fu">readlink</span> <span class="st">"</span><span class="va">$CURRENT_LINK</span><span class="st">"</span><span class="va">)</span></span>
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true"></a><span class="va">CURRENT_NAME=$(</span><span class="fu">basename</span> <span class="st">"</span><span class="va">$CURRENT</span><span class="st">"</span><span class="va">)</span></span>
<span id="cb10-18"><a href="#cb10-18" aria-hidden="true"></a></span>
<span id="cb10-19"><a href="#cb10-19" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Current release: </span><span class="va">$CURRENT_NAME</span><span class="st">"</span></span>
<span id="cb10-20"><a href="#cb10-20" aria-hidden="true"></a></span>
<span id="cb10-21"><a href="#cb10-21" aria-hidden="true"></a><span class="co"># Get previous release</span></span>
<span id="cb10-22"><a href="#cb10-22" aria-hidden="true"></a><span class="va">PREVIOUS=$(</span><span class="fu">ls</span> -t <span class="st">"</span><span class="va">$RELEASE_DIR</span><span class="st">"</span> <span class="kw">|</span> <span class="fu">grep</span> -v <span class="st">"^</span><span class="va">$CURRENT_NAME</span><span class="st"><pre wp-pre-tag-9=""></pre>quot;</span> <span class="kw">|</span> <span class="fu">head</span> -n 1<span class="va">)</span></span>
<span id="cb10-23"><a href="#cb10-23" aria-hidden="true"></a></span>
<span id="cb10-24"><a href="#cb10-24" aria-hidden="true"></a><span class="kw">if</span><span class="bu"> [</span> <span class="ot">-z</span> <span class="st">"</span><span class="va">$PREVIOUS</span><span class="st">"</span><span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb10-25"><a href="#cb10-25" aria-hidden="true"></a>    <span class="ex">error</span> <span class="st">"No previous release found for rollback"</span></span>
<span id="cb10-26"><a href="#cb10-26" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb10-27"><a href="#cb10-27" aria-hidden="true"></a></span>
<span id="cb10-28"><a href="#cb10-28" aria-hidden="true"></a><span class="va">PREVIOUS_PATH=</span><span class="st">"</span><span class="va">$RELEASE_DIR</span><span class="st">/</span><span class="va">$PREVIOUS</span><span class="st">"</span></span>
<span id="cb10-29"><a href="#cb10-29" aria-hidden="true"></a></span>
<span id="cb10-30"><a href="#cb10-30" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Rolling back to: </span><span class="va">$PREVIOUS</span><span class="st">"</span></span>
<span id="cb10-31"><a href="#cb10-31" aria-hidden="true"></a></span>
<span id="cb10-32"><a href="#cb10-32" aria-hidden="true"></a><span class="co"># Backup current state (in case rollback fails)</span></span>
<span id="cb10-33"><a href="#cb10-33" aria-hidden="true"></a><span class="va">ROLLBACK_BACKUP=</span><span class="st">"</span><span class="va">$BACKUP_DIR</span><span class="st">/pre-rollback-</span><span class="va">$(</span><span class="fu">date</span> +%Y%m%d_%H%M%S<span class="va">)</span><span class="st">"</span></span>
<span id="cb10-34"><a href="#cb10-34" aria-hidden="true"></a><span class="fu">mkdir</span> -p <span class="st">"</span><span class="va">$ROLLBACK_BACKUP</span><span class="st">"</span></span>
<span id="cb10-35"><a href="#cb10-35" aria-hidden="true"></a><span class="ex">wp</span> db export <span class="st">"</span><span class="va">$ROLLBACK_BACKUP</span><span class="st">/database.sql.gz"</span> --path=<span class="st">"</span><span class="va">$CURRENT</span><span class="st">"</span></span>
<span id="cb10-36"><a href="#cb10-36" aria-hidden="true"></a></span>
<span id="cb10-37"><a href="#cb10-37" aria-hidden="true"></a><span class="co"># Switch to previous release</span></span>
<span id="cb10-38"><a href="#cb10-38" aria-hidden="true"></a><span class="fu">ln</span> -nfs <span class="st">"</span><span class="va">$PREVIOUS_PATH</span><span class="st">"</span> <span class="st">"</span><span class="va">$CURRENT_LINK</span><span class="st">"</span></span>
<span id="cb10-39"><a href="#cb10-39" aria-hidden="true"></a></span>
<span id="cb10-40"><a href="#cb10-40" aria-hidden="true"></a><span class="co"># Clear caches</span></span>
<span id="cb10-41"><a href="#cb10-41" aria-hidden="true"></a><span class="bu">cd</span> <span class="st">"</span><span class="va">$CURRENT_LINK</span><span class="st">"</span></span>
<span id="cb10-42"><a href="#cb10-42" aria-hidden="true"></a><span class="ex">wp</span> cache flush</span>
<span id="cb10-43"><a href="#cb10-43" aria-hidden="true"></a><span class="ex">wp</span> rewrite flush</span>
<span id="cb10-44"><a href="#cb10-44" aria-hidden="true"></a></span>
<span id="cb10-45"><a href="#cb10-45" aria-hidden="true"></a><span class="co"># Verify rollback</span></span>
<span id="cb10-46"><a href="#cb10-46" aria-hidden="true"></a><span class="kw">if</span> <span class="ex">wp</span> core is-installed --path=<span class="st">"</span><span class="va">$CURRENT_LINK</span><span class="st">"</span><span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb10-47"><a href="#cb10-47" aria-hidden="true"></a>    <span class="ex">log</span> <span class="st">"✓ Rollback successful"</span></span>
<span id="cb10-48"><a href="#cb10-48" aria-hidden="true"></a>    <span class="ex">notify_deployment</span> <span class="st">"rollback-success"</span> <span class="st">"</span><span class="va">$ENVIRONMENT</span><span class="st">"</span> <span class="st">"</span><span class="va">$PREVIOUS</span><span class="st">"</span></span>
<span id="cb10-49"><a href="#cb10-49" aria-hidden="true"></a><span class="kw">else</span></span>
<span id="cb10-50"><a href="#cb10-50" aria-hidden="true"></a>    <span class="ex">error</span> <span class="st">"Rollback verification failed"</span></span>
<span id="cb10-51"><a href="#cb10-51" aria-hidden="true"></a><span class="kw">fi</span></span>
<span id="cb10-52"><a href="#cb10-52" aria-hidden="true"></a></span>
<span id="cb10-53"><a href="#cb10-53" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"=== Rollback Complete ==="</span></span>
<span id="cb10-54"><a href="#cb10-54" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"Active release: </span><span class="va">$PREVIOUS</span><span class="st">"</span></span></code></pre>
</div>



<h3 class="wp-block-heading" id="monitoring">Health Monitoring System</h3>



<p>Continuous uptime and performance monitoring.</p>



<h4 class="wp-block-heading" id="monitoring-script">Monitoring Script</h4>



<div class="sourceCode" id="cb11">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true"></a><span class="co">#!/bin/bash</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true"></a><span class="co"># bin/monitor - WordPress health monitoring</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true"></a></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true"></a><span class="kw">set</span> <span class="ex">-euo</span> pipefail</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true"></a></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true"></a><span class="bu">source</span> <span class="st">"</span><span class="va">$(</span><span class="fu">dirname</span> <span class="st">"</span><span class="va">$0</span><span class="st">"</span><span class="va">)</span><span class="st">/../lib/common.sh"</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true"></a></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true"></a><span class="va">ENVIRONMENT=</span><span class="st">"</span><span class="va">${1:-</span>production<span class="va">}</span><span class="st">"</span></span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true"></a><span class="va">CONFIG_FILE=</span><span class="st">"</span><span class="va">$CONFIG_DIR</span><span class="st">/environments/</span><span class="va">$ENVIRONMENT</span><span class="st">.conf"</span></span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true"></a></span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true"></a><span class="bu">source</span> <span class="st">"</span><span class="va">$CONFIG_FILE</span><span class="st">"</span></span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true"></a></span>
<span id="cb11-13"><a href="#cb11-13" aria-hidden="true"></a><span class="fu">check_site_health()</span> <span class="kw">{</span></span>
<span id="cb11-14"><a href="#cb11-14" aria-hidden="true"></a>    <span class="bu">local</span> <span class="va">url=</span><span class="st">"</span><span class="va">$1</span><span class="st">"</span></span>
<span id="cb11-15"><a href="#cb11-15" aria-hidden="true"></a>    <span class="bu">local</span> <span class="va">response=$(</span><span class="ex">curl</span> -s -o /dev/null -w <span class="st">"%{http_code}"</span> <span class="st">"</span><span class="va">$url</span><span class="st">"</span><span class="va">)</span></span>
<span id="cb11-16"><a href="#cb11-16" aria-hidden="true"></a></span>
<span id="cb11-17"><a href="#cb11-17" aria-hidden="true"></a>    <span class="kw">if</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$response</span><span class="st">"</span> <span class="ot">=</span> <span class="st">"200"</span><span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb11-18"><a href="#cb11-18" aria-hidden="true"></a>        <span class="ex">log</span> <span class="st">"✓ Site accessible: </span><span class="va">$url</span><span class="st">"</span></span>
<span id="cb11-19"><a href="#cb11-19" aria-hidden="true"></a>        <span class="bu">return</span> 0</span>
<span id="cb11-20"><a href="#cb11-20" aria-hidden="true"></a>    <span class="kw">else</span></span>
<span id="cb11-21"><a href="#cb11-21" aria-hidden="true"></a>        <span class="ex">error</span> <span class="st">"✗ Site down: </span><span class="va">$url</span><span class="st"> (HTTP </span><span class="va">$response</span><span class="st">)"</span></span>
<span id="cb11-22"><a href="#cb11-22" aria-hidden="true"></a>        <span class="bu">return</span> 1</span>
<span id="cb11-23"><a href="#cb11-23" aria-hidden="true"></a>    <span class="kw">fi</span></span>
<span id="cb11-24"><a href="#cb11-24" aria-hidden="true"></a><span class="kw">}</span></span>
<span id="cb11-25"><a href="#cb11-25" aria-hidden="true"></a></span>
<span id="cb11-26"><a href="#cb11-26" aria-hidden="true"></a><span class="fu">check_database_connection()</span> <span class="kw">{</span></span>
<span id="cb11-27"><a href="#cb11-27" aria-hidden="true"></a>    <span class="kw">if</span> <span class="ex">wp</span> db check --path=<span class="st">"</span><span class="va">$CURRENT_LINK</span><span class="st">"</span><span class="kw">;</span> <span class="kw">then</span></span>
<span id="cb11-28"><a href="#cb11-28" aria-hidden="true"></a>        <span class="ex">log</span> <span class="st">"✓ Database connection OK"</span></span>
<span id="cb11-29"><a href="#cb11-29" aria-hidden="true"></a>        <span class="bu">return</span> 0</span>
<span id="cb11-30"><a href="#cb11-30" aria-hidden="true"></a>    <span class="kw">else</span></span>
<span id="cb11-31"><a href="#cb11-31" aria-hidden="true"></a>        <span class="ex">error</span> <span class="st">"✗ Database connection failed"</span></span>
<span id="cb11-32"><a href="#cb11-32" aria-hidden="true"></a>        <span class="bu">return</span> 1</span>
<span id="cb11-33"><a href="#cb11-33" aria-hidden="true"></a>    <span class="kw">fi</span></span>
<span id="cb11-34"><a href="#cb11-34" aria-hidden="true"></a><span class="kw">}</span></span>
<span id="cb11-35"><a href="#cb11-35" aria-hidden="true"></a></span>
<span id="cb11-36"><a href="#cb11-36" aria-hidden="true"></a><span class="fu">check_disk_space()</span> <span class="kw">{</span></span>
<span id="cb11-37"><a href="#cb11-37" aria-hidden="true"></a>    <span class="bu">local</span> <span class="va">usage=$(</span><span class="fu">df</span> -h <span class="st">"</span><span class="va">$DEPLOY_PATH</span><span class="st">"</span> <span class="kw">|</span> <span class="fu">awk</span> <span class="st">'NR==2 {print $5}'</span> <span class="kw">|</span> <span class="fu">sed</span> <span class="st">'s/%//'</span><span class="va">)</span></span>
<span id="cb11-38"><a href="#cb11-38" aria-hidden="true"></a></span>
<span id="cb11-39"><a href="#cb11-39" aria-hidden="true"></a>    <span class="kw">if</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$usage</span><span class="st">"</span> <span class="ot">-lt</span> 80<span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb11-40"><a href="#cb11-40" aria-hidden="true"></a>        <span class="ex">log</span> <span class="st">"✓ Disk space OK (</span><span class="va">$usage</span><span class="st">%)"</span></span>
<span id="cb11-41"><a href="#cb11-41" aria-hidden="true"></a>        <span class="bu">return</span> 0</span>
<span id="cb11-42"><a href="#cb11-42" aria-hidden="true"></a>    <span class="kw">else</span></span>
<span id="cb11-43"><a href="#cb11-43" aria-hidden="true"></a>        <span class="ex">log</span> <span class="st">"⚠ Disk space warning: </span><span class="va">$usage</span><span class="st">%"</span></span>
<span id="cb11-44"><a href="#cb11-44" aria-hidden="true"></a>        <span class="bu">return</span> 1</span>
<span id="cb11-45"><a href="#cb11-45" aria-hidden="true"></a>    <span class="kw">fi</span></span>
<span id="cb11-46"><a href="#cb11-46" aria-hidden="true"></a><span class="kw">}</span></span>
<span id="cb11-47"><a href="#cb11-47" aria-hidden="true"></a></span>
<span id="cb11-48"><a href="#cb11-48" aria-hidden="true"></a><span class="fu">check_plugin_updates()</span> <span class="kw">{</span></span>
<span id="cb11-49"><a href="#cb11-49" aria-hidden="true"></a>    <span class="bu">local</span> <span class="va">updates=$(</span><span class="ex">wp</span> plugin list --update=available --format=count --path=<span class="st">"</span><span class="va">$CURRENT_LINK</span><span class="st">"</span><span class="va">)</span></span>
<span id="cb11-50"><a href="#cb11-50" aria-hidden="true"></a></span>
<span id="cb11-51"><a href="#cb11-51" aria-hidden="true"></a>    <span class="kw">if</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$updates</span><span class="st">"</span> <span class="ot">-eq</span> 0<span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb11-52"><a href="#cb11-52" aria-hidden="true"></a>        <span class="ex">log</span> <span class="st">"✓ All plugins up to date"</span></span>
<span id="cb11-53"><a href="#cb11-53" aria-hidden="true"></a>    <span class="kw">else</span></span>
<span id="cb11-54"><a href="#cb11-54" aria-hidden="true"></a>        <span class="ex">log</span> <span class="st">"⚠ </span><span class="va">$updates</span><span class="st"> plugin updates available"</span></span>
<span id="cb11-55"><a href="#cb11-55" aria-hidden="true"></a>    <span class="kw">fi</span></span>
<span id="cb11-56"><a href="#cb11-56" aria-hidden="true"></a><span class="kw">}</span></span>
<span id="cb11-57"><a href="#cb11-57" aria-hidden="true"></a></span>
<span id="cb11-58"><a href="#cb11-58" aria-hidden="true"></a><span class="co"># Run all checks</span></span>
<span id="cb11-59"><a href="#cb11-59" aria-hidden="true"></a><span class="ex">log</span> <span class="st">"=== Health Check: </span><span class="va">$ENVIRONMENT</span><span class="st"> ==="</span></span>
<span id="cb11-60"><a href="#cb11-60" aria-hidden="true"></a></span>
<span id="cb11-61"><a href="#cb11-61" aria-hidden="true"></a><span class="va">FAILED=</span>0</span>
<span id="cb11-62"><a href="#cb11-62" aria-hidden="true"></a></span>
<span id="cb11-63"><a href="#cb11-63" aria-hidden="true"></a><span class="ex">check_site_health</span> <span class="st">"</span><span class="va">$SITE_URL</span><span class="st">"</span> <span class="kw">||</span> <span class="va">FAILED=$((</span>FAILED + 1<span class="va">))</span></span>
<span id="cb11-64"><a href="#cb11-64" aria-hidden="true"></a><span class="ex">check_database_connection</span> <span class="kw">||</span> <span class="va">FAILED=$((</span>FAILED + 1<span class="va">))</span></span>
<span id="cb11-65"><a href="#cb11-65" aria-hidden="true"></a><span class="ex">check_disk_space</span> <span class="kw">||</span> <span class="va">FAILED=$((</span>FAILED + 1<span class="va">))</span></span>
<span id="cb11-66"><a href="#cb11-66" aria-hidden="true"></a><span class="ex">check_plugin_updates</span></span>
<span id="cb11-67"><a href="#cb11-67" aria-hidden="true"></a></span>
<span id="cb11-68"><a href="#cb11-68" aria-hidden="true"></a><span class="kw">if</span><span class="bu"> [</span> <span class="st">"</span><span class="va">$FAILED</span><span class="st">"</span> <span class="ot">-gt</span> 0<span class="bu"> ]</span>; <span class="kw">then</span></span>
<span id="cb11-69"><a href="#cb11-69" aria-hidden="true"></a>    <span class="ex">error</span> <span class="st">"</span><span class="va">$FAILED</span><span class="st"> health checks failed"</span></span>
<span id="cb11-70"><a href="#cb11-70" aria-hidden="true"></a><span class="kw">else</span></span>
<span id="cb11-71"><a href="#cb11-71" aria-hidden="true"></a>    <span class="ex">log</span> <span class="st">"✓ All health checks passed"</span></span>
<span id="cb11-72"><a href="#cb11-72" aria-hidden="true"></a><span class="kw">fi</span></span></code></pre>
</div>



<h4 class="wp-block-heading" id="scheduled-monitoring">Scheduled Monitoring</h4>



<div class="sourceCode" id="cb12">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true"></a><span class="co"># Add to crontab: crontab -e</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true"></a></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true"></a><span class="co"># Health check every 5 minutes</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true"></a><span class="ex">*/5</span> * * * * /opt/wordpress-deploy/bin/monitor production <span class="op">&gt;&gt;</span> /var/log/wp-monitor.log <span class="op">2&gt;&amp;1</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true"></a></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true"></a><span class="co"># Daily deployment report</span></span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true"></a><span class="ex">0</span> 9 * * * /opt/wordpress-deploy/bin/report production <span class="kw">|</span> <span class="ex">mail</span> -s <span class="st">"Daily WordPress Report"</span> team@example.com</span></code></pre>
</div>



<h3 class="wp-block-heading" id="next-steps">Next Steps</h3>



<p>You now have a complete production-ready WordPress deployment system.</p>



<h4 class="wp-block-heading" id="recommended-learning-path">Recommended Learning Path</h4>



<p><strong>Week 1</strong>: System setup</p>



<ul class="wp-block-list">
<li>Install deployment system</li>



<li>Configure environments</li>



<li>Test provisioning</li>
</ul>



<p><strong>Week 2</strong>: Deployment workflow</p>



<ul class="wp-block-list">
<li>Practice deployments</li>



<li>Test rollback procedures</li>



<li>Configure notifications</li>
</ul>



<p><strong>Week 3</strong>: CI/CD integration</p>



<ul class="wp-block-list">
<li>Connect to GitHub Actions</li>



<li>Automate testing</li>



<li>Deploy on merge</li>
</ul>



<p><strong>Week 4</strong>: Production hardening</p>



<ul class="wp-block-list">
<li>Implement monitoring</li>



<li>Optimize performance</li>



<li>Document procedures</li>
</ul>



<h4 class="wp-block-heading" id="advanced-topics">Advanced Topics</h4>



<ol class="wp-block-list">
<li><strong><a href="#">Multi-Server Deployments</a></strong> &#8211; Load-balanced WordPress</li>



<li><strong><a href="#">Container-Based Deployments</a></strong> &#8211; Docker/Kubernetes</li>



<li><strong><a href="#">GitOps Workflows</a></strong> &#8211; Infrastructure as code</li>
</ol>



<h4 class="wp-block-heading" id="get-more-resources">Get More Resources</h4>



<p><strong><a href="#">Download complete system</a></strong> including:</p>



<ul class="wp-block-list">
<li>Full deployment scripts</li>



<li>Configuration templates</li>



<li>Documentation</li>
</ul>



<p><strong><a href="/#get-started">Join our email course</a></strong> for:</p>



<ul class="wp-block-list">
<li>Weekly WP-CLI tutorials</li>



<li>DevOps best practices</li>



<li>Production war stories</li>
</ul>



<h3 class="wp-block-heading" id="conclusion">Conclusion</h3>



<p>A complete WordPress deployment system automates the entire lifecycle from server provisioning to zero-downtime deployments, monitoring, and rollback—enabling professional DevOps workflows for WordPress sites.</p>



<p>What we covered:</p>



<p>✅ Complete system architecture and project structure <br>✅ Automated server provisioning from scratch <br>✅ Zero-downtime deployment implementation <br>✅ Database migration system with rollback <br>✅ Instant rollback for failed deployments <br>✅ Continuous health monitoring and alerting</p>



<p>Build this system, and you’ll deploy WordPress professionally—automated provisioning, zero-downtime releases, instant rollbacks, and comprehensive monitoring for production-grade WordPress operations.</p>



<p><strong>Ready for more?</strong> Learn <a href="#">high-availability WordPress</a> or <a href="#">enterprise DevOps</a>.</p>



<p><strong>Questions about WordPress deployment systems?</strong> Drop a comment below!</p>



<p><strong>Found this helpful?</strong> Share with other DevOps engineers.</p>
<p>The post <a href="https://wpclimastery.com/blog/building-a-complete-wordpress-deployment-system-with-wp-cli-real-project/">Building a Complete WordPress Deployment System with WP-CLI (Real Project)</a> appeared first on <a href="https://wpclimastery.com">WP-CLI Mastery</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
