Annonce

Faites la différence entre le service WordPress.com et l'application libre WordPress.

Mettez-vous à jour ! WordPress 3.3.2 est disponible en français.

Annonce 1 : Le Codex en français a besoin de vous pour avancer !
Annonce 2 : Avant de poster, n'oubliez pas de faire une petite recherche et de lire les règles de ce forum.
Annonce 3 : Lisez notre blog, il regorge de bonnes informations.
Annonce 4 : Rejoignez-nous sur Facebook, Google + et sur Twitter

#1 01-09-2011 10:48:28

dvanzan
Membre WP
Date d'inscription: 01-09-2011
Messages: 1

Synchroniser 2 serveurs Wordpress avec wget (serveurs linx)

Synchroniser 2 instances de wordpress sur 2 serveurs distincts.

Pour ceux que ça interesse, j'ai écrit un petit script php permettant de synchroniser 2 sites wordpress sur 2 serveurs distincts avec chacun leur base de données Mysql.
Vous pouvez le lancer périodiquement via crontab toutes les 2 heures par exemple.
La synchonisation est unilatérale mais rien n'empêche de créer et adapter un second script sur le serveur principal mais je déconseille. Il vaut mieux avoir un serveur principal et un serveur qui servira de backup.
Ainsi, à n'importe quel moment il vous suffit de créer une redirection du nom de domaine du premier serveur vers le nom de domaine du second seveur, en cas de défaillance ou maintenance.
Le script tel quel utilise wget en FTP pour synchroniser le dossiers wp-content (le dossier le plus dynamique de wordpress), mettre à jour la configuration du plugin WP super cache avec les nouveaux chemin de cache, synchroniser les 2 bases de données en modifiant les urls
Vous pouvez l'adapter à votre goût, par exemple si vous utilisez des extensions comme WP better security qui modifient les fichiers .htaccess avec des Rewrite rules appellant le nom de domaine en dur ou encore le fichier wp-config.php (mais en général ce fichier ne change pas trop)

Ce qui est souvent modifié ce sont les posts dans la base de données, les uploads et les plugins (quoique...)
La particularité du plugin WP Super Cache est qu'il écrit un fichier /wp-content/advanced-cache.php contenant les chemins d'accès en dur de fichiers de config.
Cela pose probleme lorsqu'on met à jour les 2 sites distants car les chemins ne seront pas identiques.

Admettons que vous aillez 2 hébergements :
mon.serveur1.com (prod) et mon.serveur2.com (secours)
les bases de données sont respectivement db1 et db2
Je pars du principe que l'accès à distance de mysql est désactivé (c'est bien souvent le cas pour les hébergements mutualisés)
il va falloir ruser pour récupérer une sauvegarde récente de la base de données. Pour cela, sur mon serveur de prod (mon.serveur1.com), je crée une tâche cron qui exécute un export de la base mysql vers un dossier backupsql
je vais pouvoir récupérer le fichier d'export via ftp depuis le serveur de secours.

Créer un dossier sync à la racine de votre site de secours (mon.serveur2.com) : mkdir /home/user2/public_html/sync/

Placer un fichier php.ini contenant la config suivante dans le dossier sync à la racine du site distant:
(/home/user2/public_html/sync/php.ini)

Code: html

safe_mode = Off

Ceci est nécessaire pour pouvoir exécuter les commandes exec depuis le script php qui va suivre

Créer le script sync.php dans un dossier sync à la racine du site distant
(/home/user2/public_html/sync/sync.php)

Code: html

<?php
//la synchro peut prendre beaucoup de temps donc on prévoit une marge de 4heures
if( !ini_get('safe_mode') ){
	set_time_limit(14400);
}

//Permet de remplacer des chaines de caractères dans un fichier en index d'un tableau par d'autres en contenu de tableau
// syntaxe replace_string_in_file(nom de fichier, tableau associatif)
function replace_string_in_file($filename, $data) {
    $stringData = file_get_contents($filename);
    foreach ($data as $key => $value) {
        $stringData = str_replace($key, $value, $stringData);
    }
    $fh = fopen($filename, 'w') or die("can't open file");
	fwrite($fh, $stringData);
	fclose($fh);
}


//récupère le chemin réel de la racine du serveur web sur le serveur
$rootpath = getenv("DOCUMENT_ROOT");

//**********************************************
//Configuration des variables
//**********************************************
//nom du fichier d'export de mysql sur le serveur de prod
$sql_filename = "backup_db.sql";
//nom complet FTP du fichier d'export de mysql sur le serveur de prod
$sqlfile = "ftp://mon.serveur1.com/public_html/sync/".$sql_filename;

//Dossier source wp-content
$source = "ftp://mon.serveur1.com/public_html/wp-content/";

//dossier Destination (serveur de secours)
$destination = "../wp-content";
//FTP username
$ftpuser = "login ftp";

//FTP password
$ftppwd = "mot de passe ftp";

//Limite la bande passante en Ko/s
$limitrate = "30k";

//fichiers de log
$logfile = "sync.log";
$sql_logfile = "sql.log";

//Temps d'attente entre 2 essais en cas d'echec
$waitretry = 30;

//nombre de tentatives en cas d'échec
$retry = 3;

//Profondeur maxi des dossiers enfants
$depth = 5;

//niveau de troncature des dossiers sources
//Normalement la commande wget va restaurer les dossiers sources depuis la racine. Ici on veut juste récupérer les dossiers à partir du chemin wp-content. Adapter selon votre configuration
$cutdir=2
//fin Configuration

//commande pour l'export de wp-content
$cmd = "wget --limit-rate=$limitrate --ftp-user=$ftpuser --ftp-password=$ftppwd -o $logfile --tries=$retry --waitretry=$waitretry -P$destination -r -l$depth -N --no-parent -nH --cut-dirs=$cutdir \"$source\" &";

//commande pour l'export de la base de données
$cmd_db = "wget --limit-rate=$limitrate --ftp-user=$ftpuser --ftp-password=$ftppwd -o $sql_logfile --tries=$retry --waitretry=$waitretry -r -N -nd \"$sqlfile\" &";


//WP super cache fix
// Pour corriger les chemins inscrits en durs dans le plugin WP super cache. Normalement il vous faut désactiver puis réactiver ce genre de plugins mais je n'avais pas envie de me taper de manips supplémentaires. Adapter selon vos besoins.
echo "<p>Fixing Path for WP super cache plugin</p>";
$fix_path = Array("/home/user1/public_html/wp-content/plugins/wp-super-cache/" => $rootpath . "/wp-content/plugins/wp-super-cache/");
replace_string_in_file($rootpath . "/wp-content/advanced-cache.php", $fix_path);

echo "<p>Fixed Path for WP super cache plugin</p>";
 

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>WGET Sync script</title>
<style type="text/css">
html{ background-color:#ccc;}
body{ font-family:Verdana, Geneva, sans-serif; font-size:14px; color:#777;}
h2 { font-size:16px; font-weight:bold;}
#loader{display:block; width:100%; height:200px; vertical-align:middle; margin:auto; text-align:center;}
#log{ border:1px solid #CCC; padding: 1em; color:#AAA; background-color:#555;}
</style>
</head>

<body>

<?php
echo '<div id="loader"><p><h2>Processing files. Please wait. Do not close the window.</h2></p></div>';

exec ($cmd);
exec ($cmd_db);


//Restore Mysql Original
/*
 * Restore MySQL dump using PHP
 * (c) 2006 Daniel15
// Big up à Daniel15 pour ce script trouvé sur le net
 * Last Update: 9th December 2006
 * Version: 0.2
 * Edited: Cleaned up the code a bit.
 *
 * Please feel free to use any part of this, but please give me some credit :-)
 */
  
// MySQL host
$mysql_host = 'localhost';
// MySQL username
$mysql_username = 'user2';
// MySQL password
$mysql_password = 'password2';
// Database name
$mysql_database = 'database2';

$replace_array = Array("mon.serveur1.com" => 'mon.serveur2.com');
//Remplace toutes les occurences au nom de domaine du serveur de prod par le nom de domaine du serveur de secours.
replace_string_in_file($sqlfilename, $replace_array);
  
// Connect to MySQL server
mysql_connect($mysql_host, $mysql_username, $mysql_password) or die('Error connecting to MySQL server: ' . mysql_error());
// Select database
mysql_select_db($mysql_database) or die('Error selecting MySQL database: ' . mysql_error());
 
// Temporary variable, used to store current query
$templine = '';
// Read in entire file
$lines = file($sqlfilename);
// Loop through each line
foreach ($lines as $line)
{
    // Skip it if it's a comment
    if (substr($line, 0, 2) == '--' || $line == '')
        continue;
 
    // Add this line to the current segment
    $templine .= $line;
    // If it has a semicolon at the end, it's the end of the query
    if (substr(trim($line), -1, 1) == ';')
    {
        // Perform the query
        mysql_query($templine) or print('Error performing query \'<strong>' . $templine . '\': ' . mysql_error() . '<br /><br />');
        // Reset temp variable to empty
        $templine = '';
    }
}


// Affiche les logs
echo "<p>Command : <b>$cmd</b></p>";
echo '<p><div id="log">';
echo nl2br(file_get_contents($logfile));
echo '</div></p>';

echo "<p>Command : <b>$cmd_db</b></p>";
echo '<p><div id="log">';
echo nl2br(file_get_contents($sql_logfile));
echo '</div></p>';

echo '<script language="javascript">document.getElementById("loader").style.display="none";</script>';


?>
</body>
</html>

à noter que la commande wget telle qu'utilisé dans ce script ne traitera que les nouveaux fichiers ou ceux dont la taille a changé entre les 2 serveurs. (parametre -N)
Rien ne vous empeche d'adapter le script afin de de modifier d'autres fichiers en utilisant la fonction replace_string_in_file
Astuce: Pour obtenir le chemin réel de votre racine web, utiliser ceci:

Code: html

echo getenv("DOCUMENT_ROOT");

Il faut maintenant créer sur le serveur de prod, le script /home/user1/scripts/backupdb.sh qui permettra d'exporter un fichier sql périodiquement
Exemple:

Code: html

#!/bin/sh
BACKUPDIR=/home/user1/public_html/sync
BACKUPSQLFILE=backup_db.sql
DBNAME="db1"
DBUSER="user1"
DBPASSWORD="password1"
DBSERVER="localhost"

#Deleting old files
rm -f $BACKUPDIR/$BACKUPSQLFILE

#Backup Mysql database
mysqldump --host=$DBSERVER --user=$DBUSER --password=$DBPASSWORD --add-drop-table --default-character-set=utf8 $DBNAME -r $BACKUPDIR/$BACKUPSQLFILE

Programmez une tâche cron sur ce serveur afin que l'export soit crée toutes les 2 heures par exemple (tout dépend de la fréquence de vos updates)

Code: html

0 */2 * * * /bin/sh /home/user1/scripts/backupdb.sh

Programmez une tâche cron pour exécuter le script sync.php toutes les 2 ou 3 heures sur le serveur de secours

Code: html

0 */3 * * * /usr/bin/php -f /home/user2/public_html/sync/sync.php

Voilà

Ciao

Hors ligne

 

Pied de page des forums

Propulsé par PunBB 1.2.23
© Copyright 2005-2006 WordPress France

[ Generated in 0.022 seconds, 8 queries executed ]