Procédure de sauvegarde/copie et restauration d’une application TYPO3

5 mai 2008

Description d’une situation type, avec 2 serveurs identiques, 1 pour le site en production (prod-server) et 1 pour le site en développement/tests (dev-server). Chaque serveur prend en charge les fichiers et les bases de données (Apache/PHP + MySQL).

L’utilisateur système utilisé est user.

Les fichiers du site sont dans /var/www/dev-site sur le serveur de dev-server et dans /var/www/prod-site sur prod-server

En situation mono-serveur, le principe est strictement identique sauf que les copies de fichiers se font par cp (attention aux optionsde préservation des permissions) au lieu de scp et les chemins d’accès ne comprennent plus la partie de connextion ssh au serveur distant.

Les bases de données s’appellent typo3_dev et typo3_prod et sont accessibles par l’utilisateur mysql typo3, avec le mot de passe typo3.
Il est important que cet utilisateur ait le droit FILE dans les privilèges de MySQL pour pouvoir faire des imports/exports de/vers des fichiers.

Sauvegarde ponctuelle

La base de données

prod-server: mkdir -p /var/backup/typo3/DUMPDIR/typo3_prod
prod-server: cd /var/backup/typo3/DUMPDIR
prod-server: chmod a+w /var/backup/typo3/DUMPDIR/typo3_prod
prod-server: mysqldump -u typo3 -ptypo3 -Q --tab=typo3_prod typo3_prod
prod-server: tar -czf typo3_prod.tgz typo3_prod

A ce stade, la base typo3_prod est totalement sauvegardée, dans une archive compressée /var/backup/typo3/DUMPDIR/typo3_prod.tgz.
Cette archive contient autant de fichiers que de tables dans la base. Un fichier ma_table.sql contient la structure de la table et un fichier ma_table.txt contient les données de la table. Cette séparation permet de recréer la structure sans les données et/ou d’injécter les donénes sans toucher à la structure.

 

Il est conseillé de nommer les archives avec la date du jour, par exemple typo3_prod-20080501.tgz, cela permet de conserver plusieurs versions de sauvegardes et de savoir à quelle date exactement elles ont été faites, indépendamment de la date de création du fichier.

Les fichiers du site et ceux de TYPO3

prod-server: cd /var/www/
prod-server: tar -xzf /var/backup/typo3/prod-site.tgz prod-site

Les fichiers du site sont alors sauvegardés et compressés sur la partition de sauvegarde.

 

Si les fichiers du cœur de TYPO3 n’ont pas été changés, il suffit de copier l’archive officielle de TYPO3, qui reste normalement à côté de sa version décompressée. Par exemple :

prod-server: cp typo3_src.4.1.1.tar.gz /var/backup/typo3/typo3_src.4.1.1.tar.gz

Sinon, on recrée l’archive contenant nos fichiers sources et on la copie

prod-server: tar -xzf /var/backup/typo3/typo3_src.4.1.1.mod.tar.gz typo3_src

Sauvegarde régulière

la procédure est identique, mais on peut l’automatiser dans un script shell, déclenché régulièrement par un tâche CRON.

Restauration d’une sauvegarde

Si les données sauvegardées sont stockées sur un autre serveur que celui sur lequel elles doivent être restaurées, il faut d’abord les rapatrier. Imaginons qu’elles soient sur le dev-server et qu’elles doivent être mises sur prod-server.

prod-server: mkdir -p /var/backup/typo3/DUMPDIR

 

dev-server: cd /var/backup/typo3/
dev-server: scp ./DUMPDIR/typo3_prod.tgz user@prod-server:/var/backup/typo3/DUMPDIR/typo3_prod.tgz
dev-server: scp ./typo3_prod.tgz user@prod-server:/var/backup/typo3/typo3_prod.tgz
dev-server: scp ./typo3_src.4.1.1.mod.tar.gz user@prod-server:/var/backup/typo3/typo3_src.4.1.1.mod.tar.gz

La base de données

On restaure la structure de la base. Ici les tables existantes dans la sauvegardes seront détruites avant d’être recrées

prod-server: cat /var/backup/typo3/DUMPDIR/*.sql | mysql -u typo3 -ptypo3 typo3_prod

Puis on restaure les données dans la base. Attention au chemin d’accès qui, ici, doit être absolu.

prod-server: mysqlimport -u typo3 -ptypo3 typo3_prod /var/backup/typo3/DUMPDIR/*.txt

Les données sont injectées table après table dans la base de données, avec un arrêt en cas d’erreur sur une table.
La progression est indiquées, avec le nombre de lignes traitées, ainsi que le nombre d’avertissements et d’erreurs.

 

Lorsqu’on n’a pas procédé à la ré-initiamisation des tables, il est possible de fournir des options à mysqlimport, telles que :

  • -r (ou—replace) permet de remplacer les lignes qui comportent la même clé (et donc ne provoque pas d’erreur et d’arrêt de l’import). C’est à utiliser lorsqu’on veut mettre à jour la table en conservant ce qui n’existe pas dans l’import.
  • -d (ou—delete) permet de vider la table avant la lecture du fichier d’import. C’est à utiliser lorsqu’on veut totalement remplacer le contenu des tables.

Le cœur de TYPO3

La restauration du cœur de TYPO3 n’est nécessaire que si les fichiers sources ont été corrompus.

cd /var/www/
mv typo3_src typo3_src_trashed
tar -xzf /var/backup/typo3/typo3_src.4.1.1.mod.tar.gz

Si tout est OK, on peut supprimer typo3_src_trashed

rm -rf typo3_src_trashed

Restauration des fichiers du site

Le principe est identique, sauf qu’il risque d’être beaucoup plus long selon le nombre de fichiers stockés dans le site.

cd /var/www/
mv prod-site prod-site_trashed
tar -xzf /var/backup/typo3/prod-site.tgz

Si tout est OK, on peut supprimer prod-site_trashed

rm -rf prod-site_trashed

Mise en production d’un site préparé en développement

Compression et transfert

Il faut commencer par exécuter toutes les étapes de la sauvegarde ponctuelle.
Cette fois, la sauvegarde de la base se fait dans le répertoire du site ce qui nous permet de tout compresser et transférer de dev-server à prod-server en une seule fois

dev-server: mkdir -p /var/www/typo3_dev/DUMPDIR/typo3_dev
dev-server: cd /var/www/typo3_dev/DUMPDIR
dev-server: chmod a+w /var/www/typo3_dev/DUMPDIR/typo3_dev
dev-server: mysqldump -u typo3 -ptypo3 -Q --tab=typo3_dev typo3_dev
dev-server: cd /var/www/
dev-server: tar -czf typo3_dev.tgz typo3_dev
dev-server: scp typo3_dev.tgz user@prod-server:/var/www/

Restauration

prod-server: cd /var/www/
prod-server: tar -xzf typo3_dev.tgz
prod-server: cd typo3_dev

Avant toute chose, il faut faire pointer cette copie vers la base de données de prod.
Cette config se situe dans typo3_dev/typo3conf/localconf.php.
La variable à vérifier est : $typo_db
On peut aussi vérifier les autres variables d’accès à la base : $typo_db_host, $typo_db_password et $typo_db_username

 

Il faut restaurer la base de données :

prod-server: chmod a+r ./DUMPDIR/*
prod-server: cat ./DUMPDIR/*.sql | mysql -u typo3 -ptypo3 typo3_prod
prod-server: mysqlimport -u typo3 -ptypo3 typo3_prod /var/www/typo3_dev/DUMPDIR/*.txt

Si les sources de TYPO3 ont été modifiées, il faut aussi les transférer :

dev-server: cd /var/www/
dev-server: tar -xzf typo3_src.4.1.1.mod.tgz typo3_src
dev-server: scp typo3_src.4.1.1.mod.tgz user@prod-server:/var/www/

 

prod-server: cd /var/www/
prod-server: tar -xzf typo3_src.4.1.1.mod.tgz

Dans tous les cas, il faut vérifier si le lien symbolique qui est dans typo3_dev pointe bien vers le dossier du cœur de TYPO3

 

Ensuite on renomme :

prod-server: mv typo3_prod typo3_prod_old
prod-server: mv typo3_dev typo3_prod

On vérifie en ligne si le changement est bien fait.
Si tout est OK, on supprime l’ancien dossier.

prod-server: rm -rf typo3_prod_old

Ajustements dans TYPO3

Dans l’interface d’admin de TYPO3, il y a quelques points à vérifier et adapter le cas échéant.

  • vider tous les caches (2 liens en bas de la colonne de gauche)
  • vérifier les paramètres baseURL des configs TYPOScript de chaque site
  • vérifier les domaines de réponse si on a plusieurs sites (enregistrements de type “domaine” sur la première page de chaque site)
  • dans le cas de la recherche indexée des pages, vérifier les paramètres baseURL dans la “configuration TS de la page” (sur la première page de chaque site)

Mise à jour du 6 mai :

Avant de faire un mysqldump, il faut vérifier si le dossier cible est accessible en écriture à l’utilisateur système “mysql” ainsi que l’utilisateur courant. Pour faciliter celà, j’ai ajouté l’écriture à tout le monde. Après tout, ça n’est qu’un répertoire de dump, très éphémère.

Mise à jour du 8 mai :

Il n’est pas nécessaire de donner les droits en lecture sur les dumps à tout le monde. Par contre il est impératif d’avoir le droit FILE dans les privilèges MySQL, aussi bien pour la phase d’export (mysqldump) que pour la phase d’import (mysqlimport).


Gérer les dossiers de stockages de données

29 avril 2008

Voici une petite note à mon attention, directement inspirée de l’article de Jamis Buck et du code source de attachement_fu (un superbe plugin Rails pour l’upload de fichiers joints).

Dans une application qui stocke des fichiers uploadés par les utilisateurs, je souhaite que les fichiers soient organisés proprement et que chaque compte ait son propre dossier de premier niveau au lieu de tout mélanger + ou - en vrac.

Le principe de attachement_fu est celui-ci, avec par exemple un fichier ayant l’ID 12345 dans la base de données : 

/0001/2345/mon_fichier.jpg

NB : tout est relatif à “RAILS_ROOT/public/fichiers_joints”

Comme chaque fichier est lié à un enregistrement dans la base de données, il n’y a pas de risque d’écrasement, mais si je dois sortir rapidement tous les fichiers d’un compte par FTP, je suis très embêté.

J’aimerai faire ceci :

/compte_482/0001/2345/mon_fichier.jpg

Mais comme les fichiers sont eux-mêmes classés par “groupe” au sein d’un compte et que le nombre de fichiers ne devrait pas excéder quelques petits milliers par groupe (le plus souvent quelques centaines), je peux simplifier

/compte_482/groupe_047/12345/mon_fichier.jpg

La limite est donc à ~100 000 fichiers par groupe, ~1 000 groupes par compte et ~1 000 comptes.
Si ma petite appli atteint 5% de ces volumes je serais déjà assez riche.

Et puis après tout, si se limiter à 100 000 fichiers par groupe est trop réducteur, reprenons le découpage en sous-dossiers selon l’ID sur x chiffres.
Et si le nombre de groupes par client ou le nombre de client devait exploser, on y ferait de même.

Bon, passons au choses sérieuses ; coder la méthode qui va surclasser celle de attachement_fu (exemple avec des découpes à 6 chiffres).


# La méthode doit renvoyer un tableau où chaque élément
# est un segment du path à utiliser, à partir du dossier
# principal de stockage "RAILS_ROOT/public/fichiers_joints/".
# "attachment_path_id" est une méthode interne du plugin
def partitioned_path(*args)
  a = []
  a << ("%06d" % @client_id).scan(/…/)
  a << ("%06d" % @group_id).scan(/…/)
  a << ("%06d" % attachment_path_id).scan(/…/)
  a <<  args
end

Du code dans un post

23 avril 2008

Et oui, je me suis bien pris la tête à chercher un thème pour WordPress.com qui affiche correctement le code source.

Il suffisait de chercher dans la FAQ pour trouver.

En gros il suffit d’encadrer son code par \[sourcecode language='css'\]…[/sourcecode] (sans les \) et le tour est joué, en plus ça marche avec tous les thèmes (a priori).


Bannir des IP avec Ruby

23 avril 2008

J’ai souvent besoin de bannir des adresses IP pour la connexion SSH sur mes serveurs.

Au delà de la question du choix de ne pas (plus) utiliser d’outils à la Fail2ban, je propose un petit script qui permet de facilement ajouter des adresses dans la blacklist de iptables. Je le poste ici tant pour m’en souvenir que pour le partager en vue d’améliorations possibles.

Pourquoi Ruby ? Parce que je suis pas assez fort en bash (ou autre shell) pour faire le test de regexp avec, alors qu’avec Ruby, de toutes façons installé sur mes serveurs) j’y arrive assez rapidement.

#!/usr/bin/env ruby

IPT_CTL = "/sbin/iptables"

REGEXP = /\A(?:25[0-5]|(?:2[0-4]|1\d|[1-9])?\d)(?:\.(?:25[0-5]|(?:2[0-4]|1\d|[1-9])?\d)){3}\z/

def ban(ip)
  if ip.match(REGEXP)
    system IPT_CTL + " -A INPUT -s #{ip} -p tcp -m tcp –dport 22 -j DROP"
    puts "L'adresse IP '#{ip}' a été blacklistée."
  else
    puts "L'adresse IP '#{ip}' n'est pas valide, rien n'a été fait."
  end
end

if ARGV.size > 1
  ARGV.each {|ip| ban(ip)}
else
  ban(ARGV[0])
end

Il lui manque certainement quelques test d’erreurs, un test sur l’utilisateur qui l’exécute, … Je suis tout ouïe.


Retrouvez le PLUG à La Boate le 2 mai 2008

22 avril 2008

Le PLUG tient sa réunion mensuelle à La Bo[a]te le 2 mai 2008 à partir de 19h00, en cette période de jours fériés et de ponts où vous aurez l’esprit libre pour passer une bonne soirée.

C’est l’occasion, entre autre, de venir discuter des usages de l’informatique dans tous les domaines et de ce que les logiciels libres peuvent nous apporter.

Discussions informelles autour des traditionnelles pizzas/sodas/bières où se rencontrent des étudiants en informatiques, des développeurs et professionnels de l’informatique, ainsi que des débutants avides de conseils et coups de main.

C’est dans cette atmosphère confortable de La Boate que les canapés moëlleux et le bar équipé (et rempli par les participants) se marient avec la technologie (wifi ouvert, videoprojecteur, postes en libre service, …).

Tous les détails sont sur le site du PLUG et sur celui de La Bo[a]te


Mémo : gestion de branches dans SVN

29 février 2008

Voici un petit récap pour utiliser les branches de développement lorsque le code source est géré avec SVN.

Cet exemple est une version simplifiée/clarifiée d’un PowerPoint, disponible ici : http://subversion.tigris.org/servlets/ProjectDocumentList

Developer copies trunk to a new branch and notes revision of trunk
% svn cp –m “Creating branch”
http://my.repository.com/trunk
http://
my.repository.com/branches/MY-BRANCHE
% svn log -v http://
my.repository.com/branches/MY-BRANCHE
# Prints revision number, say 123
% svn co http://my.repository.com/branches/MY-BRANCHE

Work progresses in the branch. Time to merge work into trunk. But first, merge trunk changes to branch
% svn merge –r 123:HEAD http://my.repository.com/trunk .
# Test new code.
% svn commit –m "message"
# Revision 256.

Tree admin now merge changes into trunk
% cd /tmp
% svn co
http://my.repository.com/trunk
% cd project
% svn merge .
http://my.repository.com/branches/MY-BRANCHE
% svn commit –m "message"


Mémo Rake

18 février 2008

Rake est un outil puissant et extensible, distribué avec Rails. Il permet d’automatiser toutes sortes d’actions. EN voici un rappel de quelques unes peu citées dans les tutorial commun mais pour autant très utiles :

rake db:migrate:redo
Rollbacks the database one migration and re migrate up. If you want to rollback more than one step, define STEP=x
rake db:migrate:reset
Resets your database using your migrations for the current environment
rake db:reset
Drops and recreates the database from db/schema.rb for the current environment.
rake db:rollback
Rolls the schema back to the previous version. Specify the number of steps with STEP=n
rake db:schema:dump
Create a db/schema.rb file that can be portably used against any DB supported by AR
rake db:schema:load
Load a schema.rb file into the database
rake log:clear
Truncates all *.log files in log/ to zero bytes
rake tmp:cache:clear
Clears all files and directories in tmp/cache
rake tmp:clear
Clear session, cache, and socket files from tmp/
rake tmp:create
Creates tmp directories for sessions, cache, and sockets
rake tmp:pids:clear
Clears all files in tmp/pids
rake tmp:sessions:clear
Clears all files in tmp/sessions
rake tmp:sockets:clear
Clears all files in tmp/sockets
rake notes
Enumerate all annotations
rake notes:fixme
Enumerate all FIXME annotations
rake notes:optimize
Enumerate all OPTIMIZE annotations
rake notes:todo
Enumerate all TODO annotations
rake rails:freeze:edge
Lock to latest Edge Rails or a specific revision with REVISION=X (ex: REVISION=4021) or a tag with TAG=Y (ex: TAG=rel_1-1-0)
rake rails:freeze:gems
Lock this application to the current gems (by unpacking them into vendor/rails)
rake rails:unfreeze
Unlock this application from freeze of gems or edge and return to a fluid use of system gems
rake rails:update
Update both configs, scripts and public/javascripts from Rails
rake rails:update:configs
Update config/boot.rb from your current rails install
rake rails:update:javascripts
Update your javascripts from your current rails install
rake rails:update:scripts
Add new scripts to the application script/ directory
rake routes
Print out all defined routes in match order, with names.

Mémo Simscan

9 janvier 2008

De temps en temps je pique une crise de nerfs quand je vois le nombre de spams que je reçois dans mes boites POP. Je peux pas non plus dire que je vive l’enfer car j’ai SpamAssasin sur mon serveur et un logiciel qui utilise des filtres bayesiens donc c’est mon dossier Junk qui se rempli, pas ma boite de réception. Mais quand cette boite Junk déborde de 3000 mails en quelques jours, je crise.
Sur mon serveur mail j’utilise notamment Simscan pour le filtrage avant l’arrivée du mail dans ma boite. C’est bien, je peux paramétrer les filtres par défaut, par domaine et par compte mail. Mais comme souvent avec D. J. Bernstein, il y a une base de données CDB au milieu de tout ça et à chaque changement de réglage, il faut “recompiler” la base.

Je me connais, j’oublie facilement ce qui n’est pas crucial et/ou ce qui ne m’enthousiasme pas, donc j’oublie systématiquement comment faire cette petite opération pourtant toute simple. Alors voilà :

Pour éditer le fichier des règles :


# cd /var/qmail/control
# vi simcontrol

Puis on relance simscan :


# /var/qmail/bin/simscanmk
simscan cdb file built. /var/qmail/control/simcontrol.cdb
# /var/qmail/bin/simscanmk -g
simscan versions cdb file built. /var/qmail/control/simversions.cdb
# qmailctl cdb
Reloaded /etc/tcp/smtp.

Et voilà, on a nos nouveaux réglages qui sont pris en compte.

PS : j’ai utilisé l’article suivant http://wiki.qmailtoaster.com/index.php/Simscan


Le Comptoir de la Bo[a]te #8

7 janvier 2008

Une fois n’est pas coutume, ce mois-ci le Comptoir de La Bo[a]te
se réunit le troisième jeudi du mois, Jeudi 17 janvier, mais
toujours à partir de 18h

Pourquoi ? Mais simplement parce que c’est le jour de l’Assemblée
Générale de Medinsoft
, et que “carte blanche” lui est donnée pour
ce Comptoir qui réunit comme chaque mois celles et ceux qui font
l’innovation dans le web, les technologies et les réseaux.

Medinsoft est le réseau méditerranéen des créateurs de logiciels ;
il regroupe 80 sociétés et organismes professionnels et défend
les intérêts de la filière du logiciel.

Ce Comptoir sera aussi l’occasion de faire le point sur cette
nouvelle année pour l’innovation et les innovateurs en Paca, sur
le partenariat avec Buzz2biz et sur le programme des événements
de La Bo[a]te.

Au Comptoir de la Bo[a]te on vient pour échanger sans formalisme
et partager projets, idées, nouveautés entre amis, collègues,
partenaires, concurrents, entrepreneurs, investisseurs,
chercheurs, créatifs, agences web, communicants connectés,
entrepreneurs et dirigeants commerciaux, et bien d’autres …

Sur les écrans du Comptoir vous retrouverez le trombinoscope des
participants, avec leurs coordonnées pour plus facilement les
rencontrer.

Comment participer ? C’est très simple, en arrivant, entre 18h et
21h, chacun reçoit un verre, et paie 5 € (en espèces uniquement)
pour sa participation aux frais. Et on peut repartir avec son
verre si on veut.

Il n’est pas obligatoire de s’inscrire, mais c’est une bonne
idée. C’est ici.

Coordonnées :
La Bo[a]te 35 rue de la Paix-Marcel Paul 13001
Marseille
Parkings Estienne d’Orves et Monthyon Métro Vieux Port

Plan : http://www.laboate.com


Du gigabit sur des câbles cat5 ; à savoir

2 janvier 2008

Il y a quelques mois j’avais acheté un beau switch 3com 2824-sfp (24 ports gigabit) manageable. Je savais que j’allais le sous-exploiter pendant un temps, ayant un vieux cablage mural, mais j’ai voulu prévoir un tout petit peu l’avenir.

Ces derniers jours j’ai acheté un petit switch D-Link 1008D (8 ports gigabit) non manageable. Je débale, je branche 2 ordis (avec et sans cartes ethernet gigabit), OK, les LEDs s’allument (une jaune pour le 100, l’autre verte pour le 1000, normal). Mais lorsque je le branche à la prise murale, rien. Je vais vois le 3com et je vois que la LED “duplex” clignote et la LED “status” reste éteinte. Je trouve rien dans la doc, ce clignotement n’est même pas référencé dans les statuts possibles /o\

Je teste mes divers câbles et j’en arrive à la conclusion que ça marche pas lorsque mon câblage mural est utilisé. En fait j’en ai 2 ; un qui date de presque 15 ans, et l’autre que j’ai fait poser en 5+ (avant la normalisation de la cat6) il y a presque 7 ans. Dans les 2 cas ça marchait pas.

J’ai pensé à un problème de négociation de vitesse. Les 2 switch prétendent auto-négocier la vitesse et être MDI/MDI-X. Comme le 3com est manageable, je vais forcer le port utilisé en 100BT et d’un coup tout se met à fonctionner. J’en déduis que les 2 tentaient une connexion gigabit mais n’y parvenaient pas et ne retombaient pas en 100 automatiquement. Peut-être une faiblesse dans le protocole de dialogue, mais peu importe.

N’empêche que ça me plaît pas trop d’avoir à forcer la vitesse d’un port du switch. Qui sait si le petit switch va pas être changé de prise murale, si le brassage du gros switch va as changer, … je voudrais pas avoir à tout revoir à chaque fois.

Google étant mon ami, je farfouille dans quelques forums jusqu’à trouver un post d’un gars qui dit qu’il arrive à faire passer du gigabit sur des câbles en catégorie 5 pourvu que les 4 paires soient utilisées. Je cours alors démonter une prise murale (du vieux câblage et je vois que seules 2 paires sont câblées sur la prise). Qu’à cela ne tienne, je refais les branchements. Evidemment ça continue de fonctionner car ça passe en 100, je remets alors le port en mode “auto” et là, la petite lumière passe du jaune au vert indiquant une négociation en gigabit \o/

J’ai eu une première réaction de pitié en pensant au gars de l’entreprise qui a posé du câble 4 paires (de très bonne qualité apparemment ; bien blindé, …) sur des belles prises murales Legrand, mais qui n’a branché que la moitié des paires.

Par contre ma seconde réaction était de colère en démontant les prises du câblage plus récent et en voyant que tout était tout beau tout propre (Legrand aussi) sauf que les câbles étaient des 2 paires. Ce charlatan m’avait assuré qu’il n’y aurait pas de soucis à faire du gigabit sans rien n’avoir à toucher, qu’il avait certifié le câblage, … Heureusement pour lui que j’ai perdu la facture, et surtout son nom, parce que sinon, je l’aurai enflammé en public.

En tous cas, j’ai rebranché toutes les prises que je pouvais et je vais migrer mes petits 10/100 en gigabit maintenant que la plupart des ordi ont des cartes adaptées. À 45 euros le switch 8 ports, on va pas faire le difficile et surtout y’a pas à retirer des lignes et changer les prises murales, ouf !