WordPress Development Workflow: From Local to Production

·9 min read·
workflowdevopswordpress

A robust WordPress development workflow is the backbone of any successful project. Whether you're a solo developer or part of a larger team, having a well-defined process for moving code from local development to production can save you countless hours and prevent costly mistakes.

In this comprehensive guide, we'll walk through setting up an efficient WordPress development workflow that scales with your projects and keeps your sanity intact. We'll cover everything from local development environments to automated deployment strategies, with practical examples you can implement today.

Setting Up Your Local Development Environment

Your local development environment is where the magic happens. It needs to be reliable, fast, and as close to your production environment as possible to avoid the dreaded "it works on my machine" syndrome.

Choosing the Right Local Environment

There are several excellent options for local WordPress development:

  • Local by Flywheel: User-friendly with one-click SSL and easy site sharing
  • XAMPP/MAMP: Traditional Apache/MySQL/PHP stacks
  • Docker: Containerized environments for ultimate flexibility
  • Valet/Herd: Lightweight solutions for macOS developers

For most developers, I recommend starting with Local by Flywheel for its simplicity, then graduating to Docker as your needs become more complex.

Here's a basic Docker Compose setup for WordPress development:

version: '3.8'
services:
  wordpress:
    image: wordpress:latest
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: password
    volumes:
      - ./wp-content:/var/www/html/wp-content
  
  db:
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: password
      MYSQL_ROOT_PASSWORD: rootpassword
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:

Version Control Best Practices

Your WordPress project should live in Git from day one. Here's a .gitignore file that covers the essentials:

# WordPress core
/wp-admin/
/wp-includes/
/wp-content/index.php
/wp-content/languages
/wp-content/plugins/index.php
/wp-content/themes/index.php

# WordPress config
wp-config.php
wp-config-local.php

# Uploads
/wp-content/uploads/

# Plugins (unless custom)
/wp-content/plugins/

# Cache and logs
/wp-content/cache/
*.log

# Environment files
.env
.env.local

The key principle here is to only version control what you've built. WordPress core, third-party plugins, and uploads shouldn't be in your repository. Instead, use dependency management tools like Composer to manage these components.

Development Workflow Strategies

Feature Branch Workflow

The feature branch workflow is perfect for WordPress development. Here's how it works:

  1. Main branch contains production-ready code
  2. Develop branch contains the latest development changes
  3. Feature branches are created for each new feature or bug fix
# Create a new feature branch
git checkout -b feature/new-homepage-design

# Work on your feature
git add .
git commit -m "Add hero section to homepage template"

# Push and create pull request
git push origin feature/new-homepage-design

This approach works particularly well when combined with WapuuLink's WordPress Developer API for automated testing and deployment workflows.

Database Management

One of the biggest challenges in WordPress development is managing database changes across environments. Here are several strategies:

1. Migration Scripts Create custom WP-CLI commands for database changes:

<?php
class Update_User_Meta_Command extends WP_CLI_Command {
    /**
     * Updates user meta structure for v2.0
     */
    public function update_user_meta() {
        $users = get_users();
        foreach ($users as $user) {
            // Migrate old meta structure
            $old_preference = get_user_meta($user->ID, 'old_pref', true);
            if ($old_preference) {
                update_user_meta($user->ID, 'new_preference_structure', $old_preference);
                delete_user_meta($user->ID, 'old_pref');
            }
        }
        WP_CLI::success('User meta migration completed.');
    }
}

WP_CLI::add_command('migrate user-meta', 'Update_User_Meta_Command');

2. Configuration Management Use tools like WordPress CLI to export and import configuration:

# Export current site options
wp option list --format=json > site-config.json

# Import on another environment
wp option import site-config.json

Staging Environment Setup

Your staging environment should mirror production as closely as possible. This is where you test everything before it goes live.

Automated Staging Deployments

Set up automated deployments to staging whenever you push to your develop branch. Here's a GitHub Actions workflow example:

name: Deploy to Staging
on:
  push:
    branches: [ develop ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    
    - name: Setup PHP
      uses: shivammathur/setup-php@v2
      with:
        php-version: '8.1'
    
    - name: Install dependencies
      run: composer install --no-dev --optimize-autoloader
    
    - name: Deploy to staging
      uses: easingthemes/ssh-deploy@v2.1.5
      env:
        SSH_PRIVATE_KEY: ${{ secrets.STAGING_SSH_KEY }}
        REMOTE_HOST: ${{ secrets.STAGING_HOST }}
        REMOTE_USER: ${{ secrets.STAGING_USER }}
        SOURCE: "."
        TARGET: "/var/www/staging"

Testing on Staging

Your staging environment is perfect for automated testing. Consider implementing:

Production Deployment Strategies

When it comes to production deployments, reliability and speed are paramount. Here are the most effective strategies for WordPress sites.

Blue-Green Deployments

Blue-green deployments minimize downtime by maintaining two identical production environments. While one serves live traffic (blue), you deploy to the other (green), then switch traffic over.

#!/bin/bash
# Simple blue-green deployment script

CURRENT=$(readlink /var/www/current)
if [[ $CURRENT == *"blue"* ]]; then
    DEPLOY_TO="green"
    LIVE="blue"
else
    DEPLOY_TO="blue"
    LIVE="green"
fi

echo "Deploying to $DEPLOY_TO environment..."

# Deploy code to the inactive environment
rsync -av --delete /tmp/deploy/ /var/www/$DEPLOY_TO/

# Run any necessary updates
cd /var/www/$DEPLOY_TO
wp core update-db --allow-root

# Switch traffic
ln -sfn /var/www/$DEPLOY_TO /var/www/current

# Restart services
systemctl reload nginx
systemctl reload php8.1-fpm

echo "Deployment complete. Traffic switched to $DEPLOY_TO"

Zero-Downtime Deployments

For high-traffic sites, even a few seconds of downtime isn't acceptable. Here's a deployment strategy that achieves true zero-downtime:

  1. Deploy code to a new directory with a timestamp
  2. Run database migrations (design them to be backward-compatible)
  3. Update the symlink to point to the new directory
  4. Reload services (PHP-FPM, opcache, etc.)
  5. Clean up old deployments

This approach works exceptionally well when combined with API-driven workflows. You can use WapuuLink's API to trigger deployments, run health checks, and manage the entire process programmatically.

Automation and CI/CD

Automation is what transforms a good workflow into a great one. Let's explore how to automate the repetitive parts of your deployment process.

Continuous Integration Setup

A robust CI pipeline for WordPress should include:

  • Code quality checks (PHP_CodeSniffer, ESLint)
  • Security scanning (WPScan, composer audit)
  • Unit testing (PHPUnit)
  • Integration testing

Here's a comprehensive GitHub Actions workflow:

name: WordPress CI/CD Pipeline

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    
    services:
      mysql:
        image: mysql:5.7
        env:
          MYSQL_ROOT_PASSWORD: password
          MYSQL_DATABASE: wordpress_test
        options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3

    steps:
    - uses: actions/checkout@v2
    
    - name: Setup PHP
      uses: shivammathur/setup-php@v2
      with:
        php-version: '8.1'
        extensions: mysql
    
    - name: Install WordPress Test Suite
      run: |
        bash bin/install-wp-tests.sh wordpress_test root password 127.0.0.1 latest
    
    - name: Run PHPUnit tests
      run: vendor/bin/phpunit
    
    - name: Run PHP_CodeSniffer
      run: vendor/bin/phpcs --standard=WordPress .
    
    - name: Security scan
      run: composer audit

  deploy:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    
    steps:
    - name: Deploy to production
      run: |
        # Your deployment script here
        echo "Deploying to production..."

Database Synchronization

One of the trickiest aspects of WordPress workflows is keeping databases synchronized between environments. Here are some strategies that work well:

Content Staging: Use plugins like WP Staging or custom scripts to copy production data to staging periodically, while preserving development-specific settings.

Selective Sync: Create scripts that sync specific content types or date ranges:

<?php
// Sync recent posts for content testing
function sync_recent_content() {
    $recent_posts = get_posts([
        'numberposts' => 50,
        'post_status' => 'publish',
        'date_query' => [
            'after' => '30 days ago'
        ]
    ]);
    
    // Export and transfer logic here
    foreach ($recent_posts as $post) {
        // Process each post for staging environment
    }
}

For complex synchronization needs, consider using WapuuLink's API documentation to build custom sync workflows that maintain data integrity across environments.

Monitoring and Maintenance

Your workflow doesn't end at deployment. Ongoing monitoring and maintenance are crucial for long-term success.

Automated Monitoring

Set up monitoring for:

  • Site uptime and response times
  • Error rates in PHP and WordPress logs
  • Performance metrics like Time to First Byte (TTFB)
  • Security issues and plugin vulnerabilities

Tools like New Relic, Query Monitor, or custom solutions can provide the visibility you need.

Automated Updates

Create a strategy for handling WordPress core, plugin, and theme updates:

#!/bin/bash
# Automated update script with rollback capability

# Create backup
wp db export backup-$(date +%Y%m%d-%H%M%S).sql

# Update WordPress core
wp core update

# Update plugins (exclude problematic ones)
wp plugin update --all --exclude=problematic-plugin

# Run health check
HEALTH_CHECK=$(wp eval 'echo is_admin() ? "OK" : "FAIL";')

if [ "$HEALTH_CHECK" != "OK" ]; then
    echo "Health check failed, rolling back..."
    # Rollback logic here
    exit 1
fi

echo "Updates completed successfully"

The power of a well-designed workflow becomes even more apparent when you can integrate it with modern tools. For instance, our guide on how AI is changing WordPress agency workflows shows how artificial intelligence can automate many of the manual steps we've discussed.

Advanced Workflow Techniques

Environment Configuration Management

Use environment-specific configuration files to manage settings across different stages:

<?php
// wp-config.php
$environment = $_ENV['WP_ENVIRONMENT'] ?? 'production';

switch ($environment) {
    case 'local':
        define('WP_DEBUG', true);
        define('WP_DEBUG_LOG', true);
        define('SCRIPT_DEBUG', true);
        break;
    
    case 'staging':
        define('WP_DEBUG', false);
        define('WP_DEBUG_LOG', true);
        // Prevent search engines from indexing
        define('BLOG_PUBLIC', 0);
        break;
    
    case 'production':
        define('WP_DEBUG', false);
        define('WP_DEBUG_LOG', false);
        define('SCRIPT_DEBUG', false);
        break;
}

Automated Testing Integration

Integrate automated testing into your workflow using tools like Codeception or WordPress's own testing framework:

<?php
class HomepageCest
{
    public function _before(AcceptanceTester $I)
    {
        $I->amOnPage('/');
    }

    public function seeHomepageElements(AcceptanceTester $I)
    {
        $I->see('Welcome to Our Site', 'h1');
        $I->seeElement('.hero-section');
        $I->seeElement('.navigation-menu');
    }

    public function checkPageLoadTime(AcceptanceTester $I)
    {
        $start = microtime(true);
        $I->amOnPage('/');
        $loadTime = microtime(true) - $start;
        
        $I->assertLessThan(2.0, $loadTime, 'Page should load in under 2 seconds');
    }
}

API-Driven Workflows

Modern WordPress development increasingly relies on API-driven approaches. Whether you're using the WordPress REST API, WapuuLink API, or GraphQL, APIs can streamline your workflow significantly.

For example, you might use WP-CLI with API calls to automate complex deployment tasks:

#!/bin/bash
# API-driven deployment script

# Trigger pre-deployment checks via API
curl -X POST "https://api.yoursite.com/deploy/pre-check" \
     -H "Authorization: Bearer $API_TOKEN"

# Deploy code
git pull origin main
composer install --no-dev

# Notify completion via API
curl -X POST "https://api.yoursite.com/deploy/complete" \
     -H "Authorization: Bearer $API_TOKEN" \
     -d '{"version": "'$(git rev-parse HEAD)'", "environment": "production"}'

This API-first approach makes it easy to integrate with external tools and create custom dashboards for monitoring your deployments.

Troubleshooting Common Workflow Issues

Even with the best workflows, issues arise. Here are solutions to common problems:

Database Sync Conflicts

When database changes conflict between environments, use WordPress's built-in update system:

<?php
// In your plugin or theme's functions.php
function my_database_update_check() {
    $current_version = get_option('my_db_version', '0');
    
    if (version_compare($current_version, '1.2.0', '<')) {
        my_database_update_1_2_0();
        update_option('my_db_version', '1.2.0');
    }
}
add_action('init', 'my_database_update_check');

Plugin Conflicts in Production

Use a staged rollout approach:

# Enable new plugin for admin users only
wp plugin activate