Skip to content

samahjoob/WP-Mirror

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 

Repository files navigation

πŸš€ WordPress Local Mirror System

πŸ’‘ Overview

This project proposes and documents a comprehensive solution for creating and managing local mirrors of WordPress core, plugins, and themes. This is crucial for users in regions experiencing frequent internet disconnections, global routing limitations, or censorship, ensuring continuous operation and maintainability of WordPress websites.

While WordPress.org cannot host mirrors for every region, this project provides the blueprint, tooling, and documentation for communities and hosting providers to build and maintain their own reliable WordPress mirrors.

❓ The Problem

In many regions, particularly Iran, prolonged internet outages (lasting weeks or months) are common due to political or infrastructural reasons. This prevents users from accessing essential WordPress resources:

  • Core updates (wordpress.org/latest.zip)
  • Plugin and theme downloads (from wordpress.org/plugins/ and wordpress.org/themes/)
  • API metadata (api.wordpress.org) for checks and installations
  • Translation files

This renders WordPress websites unmanageable during these periods, impacting businesses, developers, and the entire digital ecosystem reliant on WordPress.

βœ… The Solution: A Self-Hosted Mirror System

This project outlines a replicable system that allows any entity to host a local mirror of WordPress resources. The core idea is to:

  1. Mirror WordPress.org: Periodically download and store WordPress core, plugins, themes, and related metadata.
  2. Provide Local Access: Serve these resources via a local HTTP server.
  3. Enable Fallback: Configure WordPress installations to use the local mirror automatically when official servers are unreachable.

βš™οΈ Technical Architecture

The proposed system consists of three main layers:

1. Mirror Repository Layer

This layer is responsible for storing the mirrored files. It should mimic the structure of WordPress.org as closely as possible for compatibility.

  • Storage: Local file system, object storage (e.g., S3-compatible), or any HTTP-accessible server.
  • Directory Structure Example:
    /var/www/wp-mirror/
    β”œβ”€β”€ core/
    β”‚   β”œβ”€β”€ latest.zip
    β”‚   └── versions/
    β”‚       β”œβ”€β”€ 6.5.2.zip
    β”‚       └── 6.5.3.zip
    β”œβ”€β”€ plugins/
    β”‚   β”œβ”€β”€ akismet/
    β”‚   β”‚   └── versions/
    β”‚   β”‚       └── 5.8.0.zip
    β”‚   β”œβ”€β”€ woocommerce/
    β”‚   β”‚   └── versions/
    β”‚   β”‚       └── 8.9.0.zip
    β”‚   └── ...
    β”œβ”€β”€ themes/
    β”‚   β”œβ”€β”€ twentytwentyfour/
    β”‚   β”‚   └── versions/
    β”‚   β”‚       └── 1.3.zip
    β”‚   └── ...
    β”œβ”€β”€ translations/
    β”‚   β”œβ”€β”€ en_US/
    β”‚   β”‚   └── core-2024-04-B.json
    β”‚   └── fa_IR/
    β”‚       └── ...
    └── api-cache/ # For API metadata responses
        └── plugins/info/slug=woocommerce.json
    

2. Synchronization Layer

This layer handles fetching updates from WordPress.org and populating the Mirror Repository.

  • Tools:
    • wp-cli: Highly recommended. Custom commands or scripts can automate downloads and syncs.
    • rsync / wget: For basic file transfer and mirroring.
    • Custom Python/Bash scripts: For more advanced logic, API calls, and error handling.
  • Synchronization Strategy:
    • Scheduled Tasks: Use cron (Linux) or Task Scheduler (Windows) to run sync scripts daily or hourly.
    • Delta Sync: Only download changed files or new versions to save bandwidth and time.
    • API Mirroring: Cache responses from api.wordpress.org for plugins/themes info, translations, etc.
  • Suggested wp-cli commands (conceptual):
    wp mirror init --path=/var/www/wp-mirror
    wp mirror sync --core --plugins --themes --translations --api --path=/var/www/wp-mirror
    wp mirror status --path=/var/www/wp-mirror

3. WordPress Integration Layer

This layer involves configuring WordPress installations to use the local mirror.

  • Configuration:
    • wp-config.php: Define constants to point WordPress to the local mirror.
      // Example for a local mirror running on the same server
      define('WP_MIRROR_BASE_URL', 'http://localhost:8080'); // Or 'http://wp-mirror.local' if using hosts file/DNS
      define('WP_USE_MIRROR', true);
      
      // Optional: Define specific mirror base URLs if needed
      // define('WP_CORE_MIRROR_URL', 'http://localhost:8080/core');
      // define('WP_PLUGINS_MIRROR_URL', 'http://localhost:8080/plugins');
      // define('WP_THEMES_MIRROR_URL', 'http://localhost:8080/themes');
    • Network Configuration:
      • hosts file: Manually map api.wordpress.org and downloads.wordpress.org to 127.0.0.1 (or the mirror server's IP).
      • DNS Server: Configure a local DNS server to resolve WordPress.org domains to the mirror IP.
      • Reverse Proxy: Use Nginx, Traefik, or Apache as a reverse proxy that intercepts requests and redirects them to the local mirror when the internet is down.
  • WordPress Hooks:
    • The pre_http_request filter can be used to intercept and redirect HTTP requests.
    • A custom function can check internet connectivity (e.g., via fsockopen or a simple curl check to api.wordpress.org). If offline, it can enable mirror mode.
    • Example PHP snippet (to be placed in a must-use plugin or theme's functions.php):
      function wp_mirror_check_and_redirect( $preempt, $r, $url ) {
          // Check if WP_USE_MIRROR is defined and true, or if we are offline
          if ( ! defined('WP_USE_MIRROR') || ! WP_USE_MIRROR ) {
              // If we want automatic detection, add connectivity check here
              // if (!wp_is_online()) { define('WP_USE_MIRROR', true); } else { return $preempt; }
               return $preempt; // Not using mirror or not offline
          }
      
          $mirror_base = defined('WP_MIRROR_BASE_URL') ? WP_MIRROR_BASE_URL : 'http://wp-mirror.local';
      
          // Redirect core requests
          if ( strpos($url, 'wordpress.org/latest.zip') !== false || strpos($url, 'wordpress.org/wp-includes/version.json') !== false ) {
              $r['url'] = str_replace('https://wordpress.org', $mirror_base . '/core', $url);
              // Important: Ensure HTTPS is handled or switched to HTTP if mirror is HTTP
              $r['sslverify'] = false; // Or handle SSL properly
              $r['headers']['Host'] = parse_url( 'https://wordpress.org', PHP_URL_HOST ); // Pass original host header if needed
              return $r;
          }
      
          // Redirect plugin/theme requests
          if ( strpos($url, 'wordpress.org/plugins/') !== false || strpos($url, 'wordpress.org/themes/') !== false ) {
              $r['url'] = str_replace('https://downloads.wordpress.org', $mirror_base . '/plugins', $url); // Adjust /plugins/ or /themes/ path as needed
              $r['sslverify'] = false;
              $r['headers']['Host'] = parse_url( 'https://downloads.wordpress.org', PHP_URL_HOST );
              return $r;
          }
      
          // Redirect API requests (e.g., for plugin/theme info)
           if ( strpos($url, 'api.wordpress.org') !== false ) {
              $r['url'] = str_replace('https://api.wordpress.org', $mirror_base . '/api', $url); // Assuming your mirror has an /api endpoint for cached responses
              $r['sslverify'] = false;
               $r['headers']['Host'] = parse_url( 'https://api.wordpress.org', PHP_URL_HOST );
              return $r;
          }
      
      
          return $preempt; // Let WordPress handle the request normally
      }
      // Add filter only if WP_USE_MIRROR is defined and true
      if (defined('WP_USE_MIRROR') && WP_USE_MIRROR) {
          add_filter('pre_http_request', 'wp_mirror_check_and_redirect', 10, 3);
      }
      
      // Optional: Function to check online status
      function wp_is_online( $host = 'api.wordpress.org', $port = 80, $timeout = 5 ) {
          $fp = @fsockopen( $host, $port, $errno, $errstr, $timeout );
          if ( !$fp ) {
              return false;
          }
          fclose( $fp );
          return true;
      }

πŸ› οΈ Recommended Tools & Setup

  • Server Environment:
    • Docker + docker-compose: Ideal for containerizing the mirror server, sync scripts, and proxy.
    • Linux Server: Ubuntu, Debian, or CentOS are suitable.
  • Mirror Server Software:
    • Nginx: As a high-performance web server and reverse proxy.
    • Apache: Alternative web server.
    • Simple HTTP Server: Python's http.server for testing or very basic setups.
  • Synchronization Tools:
    • wp-cli: Essential for managing WordPress.
    • rsync: For efficient file synchronization.
    • wget: For downloading files.
    • cron / systemd timers: For scheduling synchronization tasks.
  • Caching:
    • Redis: For caching API responses or transient data.
    • SQLite: Could potentially store metadata if performance is not critical.

πŸ“ˆ Estimating Mirror Size

The total size of free WordPress resources is substantial:

  • WordPress Core: ~50-100 MB per release.
  • Plugins: Tens of thousands of plugins, each averaging 5-20 MB. Total estimated: ~300 GB - 600 GB.
  • Themes: Thousands of free themes, averaging 5-15 MB. Total estimated: ~100 GB - 200 GB.
  • Translations: Relatively small, likely a few GBs.

Total Estimated Mirror Size: ~450 GB to 1 TB+ (This is a rough estimate and can fluctuate).

Recommendation: Start by mirroring essential plugins and themes, then expand as needed.

πŸ“„ How to Contribute

  1. Fork this repository.
  2. Set up a local mirror based on the documentation.
  3. Test the synchronization and provide feedback.
  4. Contribute wp-cli commands or synchronization scripts.
  5. Improve the PHP integration code and documentation.
  6. Share your experience and findings.

βš–οΈ License

This project is intended to complement the WordPress open-source philosophy. All documentation and proposed code snippets are provided under a permissive license (e.g., MIT or GPLv2, aligning with WordPress).

⚠️ Status / Scope

This repository is a proposal and design documentation, not a ready-to-run production implementation.
Real-world implementation is non-trivial: it requires careful work across WordPress update flows (core + plugins + themes), security/verification of mirrored artifacts, robust fallback logic, and long-term maintenance of the sync/repository formats.

To make this truly β€œofficial” and reliable, it would need collaboration with the WordPress core team (and likely WP-CLI/Infrastructure stakeholders) to align with upstream architecture, compatibility guarantees, and security expectations.

About

WordPress Local Mirror System

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors