wordpress – Sam & Max http://sametmax.com Du code, du cul Wed, 23 Dec 2020 13:35:02 +0000 en-US hourly 1 https://wordpress.org/?v=4.9.7 32490438 Le blog a été migré (enfin presque) http://sametmax.com/le-blog-a-ete-migre-enfin-presque/ http://sametmax.com/le-blog-a-ete-migre-enfin-presque/#comments Tue, 23 Sep 2014 12:18:43 +0000 http://sametmax.com/?p=12217 Max a pris l’hébergement et a setup Varnish (sans lequel le WP s’écroule sous la masse de vos pattes velues), puis j’ai installé WP 4, et migré la DB et les images.

En gros, vous pouvez de nouveau lire vos articles techniques préférés. Et les autres aussi.

Par contre, feu notre ancien thème (snif, il était si… si… attachant…), et donc tous les easter eggs qui vont avec.

Vous noterez donc un blog moins fun, avec des bugs graphiques et surtout, sans plugins, donc ouvert aux 4 vents aux spams mais sans formulaire de contact. Mouarf.

Je vais corriger ça petit à petit, mais je ne me presse pas, l’avantage d’écrire un blog bénévole est qu’on ne doit rien à personne, donc on peut se gratter les couilles.

0bin, multiboards et allthatcount vont suivre. Je vais probablement les migrer avant de m’attaquer à la corrections des petits problèmes du blog d’ailleurs.

La base de données complète a été migrée. Félicitation à l’équipe de WP pour avoir mis en œuvre un outil de conversion des tables d’une version à l’autre parfaitement transparent. C’est pas facile à faire, et ça marche super bien. Mettez l’article en favoris, je ne dirais pas souvent du bien de cet outil.

Ça signifie que vos commentaires sont là, les pages statiques aussi, et bien entendu, pour les contributeurs, leurs comptes utilisateurs également. Il y a eu un bug de login ce matin, mais c’est réparé.

Si vous voyez des trucs qui pètent, merci de les lister en comment ici que je puisse avoir une check list à jour et sans doublons. Avec les URLS c’est mieux.

Parmi les problèmes que je vois venir : les iframes qui marchent pas, la barre de menu de droite qui déconne, et autres joyeusetés, des médias de mauvaise taille.

Et bonne lecture :)

]]>
http://sametmax.com/le-blog-a-ete-migre-enfin-presque/feed/ 27 12217
Initiation à Varnish – Accélerer un blog WordPress http://sametmax.com/initiation-a-varnish-accelerer-un-blog-wordpress/ http://sametmax.com/initiation-a-varnish-accelerer-un-blog-wordpress/#comments Sun, 31 Mar 2013 08:54:54 +0000 http://sametmax.com/?p=4416 Varnish est un service qui permet de mettre en cache (sur disque ou en mémoire) certains contenus de votre site. Beaucoup de gros sites l’utilisent pour sa puissance et ses options de configuration.
Il est plutôt facile à installer mais ça se corse lorsqu’il faut le configurer car il peut ne rien cacher du tout, surtout avec la config par défaut.

Nous allons voir ici une configuration pour un site sous WordPress avec un serveur Nginx, Varnish étant placé en Front c’est à dire devant Nginx (il y a aussi le mode sandwich Nginx / Varnish / Backend).

Installation de Varnish sous ubuntu:

sudo apt-get install varnish

Il y a 2 fichiers qu’il faut retenir pour Varnish, le fichier avec les règles et le fichier de config du service.

Configurer le service, On va faire en sorte que Varnish écoute sur le port 80:

vi /etc/default/varnish
DAEMON_OPTS="-a :80 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -S /etc/varnish/secret \
             -s malloc,256m"

Trouvez cette ligne dans le fichier de conf et mettez 80 pour l’option -a.
malloc va sauver le cache en mémoire à hauteur de 256 MB, on peut sauvegarder sur disque si on a un SSD (ex: -s file,/var/lib/varnish/varnish_storage.bin,1G”).

Configurer les règles de cache:

vi /etc/varnish/default.vcl
#
# Varnish 3 configuration for WordPress
#
# On Debian OS:  /etc/varnish/default.vcl
#
# Nicolas Hennion (aka) Nicolargo
#

# Set the default backend (Nginx server for me)
backend default {
	# My Nginx server listen on IP address 127.0.0.1 and TCP port 8080
	.host = "127.0.0.1";
	.port = "8080";
	# Increase guru timeout
	# http://vincentfretin.ecreall.com/articles/varnish-guru-meditation-on-timeout
	.first_byte_timeout = 300s;
}

# This function is used when a request is send by a HTTP client (Browser) 
sub vcl_recv {
	# Block the forbidden IP addresse
	if (client.ip ~ forbidden) {
        	error 403 "Forbidden";
	}

	# Only cache the following sites
	if ((req.http.host ~ "(sametmax.com)")) { 
		set req.backend = default; 
	} else { 
		return (pass); 
	}

	# Normalize the header, remove the port (in case you're testing this on various TCP ports)
	set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");

	# Post requests will not be cached
	if (req.http.Authorization || req.request == "POST") {
		return (pass);
	}

	# --- WordPress specific configuration
	
	# Did not cache the RSS feed
	if (req.url ~ "/feed") {
		return (pass);
	}

	# Blitz hack
        if (req.url ~ "/mu-.*") {
                return (pass);
        }

	
	# Did not cache the admin and login pages
	if (req.url ~ "/wp-(login|admin)") {
		return (pass);
	}

	# Remove the "has_js" cookie
	set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", "");

	# Remove any Google Analytics based cookies
	set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");

	# Remove the Quant Capital cookies (added by some plugin, all __qca)
	set req.http.Cookie = regsuball(req.http.Cookie, "__qc.=[^;]+(; )?", "");

	# Remove the wp-settings-1 cookie
	set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-1=[^;]+(; )?", "");

	# Remove the wp-settings-time-1 cookie
	set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-time-1=[^;]+(; )?", "");

	# Remove the wp test cookie
	set req.http.Cookie = regsuball(req.http.Cookie, "wordpress_test_cookie=[^;]+(; )?", "");

	# Are there cookies left with only spaces or that are empty?
	if (req.http.cookie ~ "^ *$") {
		    unset req.http.cookie;
	}
	
	# Cache the following files extensions 
	if (req.url ~ "\.(css|js|png|gif|jp(e)?g|swf|ico)") {
		unset req.http.cookie;
	}

	# Normalize Accept-Encoding header and compression
	# https://www.varnish-cache.org/docs/3.0/tutorial/vary.html
	if (req.http.Accept-Encoding) {
		# Do no compress compressed files...
		if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
			   	remove req.http.Accept-Encoding;
		} elsif (req.http.Accept-Encoding ~ "gzip") {
		    	set req.http.Accept-Encoding = "gzip";
		} elsif (req.http.Accept-Encoding ~ "deflate") {
		    	set req.http.Accept-Encoding = "deflate";
		} else {
			remove req.http.Accept-Encoding;
		}
	}

	# Check the cookies for wordpress-specific items
	if (req.http.Cookie ~ "wordpress_" || req.http.Cookie ~ "comment_") {
		return (pass);
	}
	if (!req.http.cookie) {
		unset req.http.cookie;
	}
	
	# --- End of WordPress specific configuration

	# Did not cache HTTP authentication and HTTP Cookie
	if (req.http.Authorization || req.http.Cookie) {
		# Not cacheable by default
		return (pass);
	}

	# Define the default grace period to serve cached content
	set req.grace = 30s;
	
	# Cache all others requests
	return (lookup);
}
 
sub vcl_pipe {
	return (pipe);
}
 
sub vcl_pass {
	return (pass);
}
 
# The data on which the hashing will take place
sub vcl_hash {
 	hash_data(req.url);
 	if (req.http.host) {
     	hash_data(req.http.host);
 	} else {
     	hash_data(server.ip);
 	}

	# If the client supports compression, keep that in a different cache
    	if (req.http.Accept-Encoding) {
        	hash_data(req.http.Accept-Encoding);
	}
     
	return (hash);
}
 
# This function is used when a request is sent by our backend (Nginx server)
sub vcl_fetch {
	# Remove some headers we never want to see
	unset beresp.http.Server;
	unset beresp.http.X-Powered-By;

	# For static content strip all backend cookies
	if (req.url ~ "\.(css|js|png|gif|jp(e?)g)|swf|ico") {
		unset beresp.http.cookie;
	}

	# Only allow cookies to be set if we're in admin area
	if (beresp.http.Set-Cookie && req.url !~ "^/wp-(login|admin)") {
        	unset beresp.http.Set-Cookie;
    	}

	# don't cache response to posted requests or those with basic auth
	if ( req.request == "POST" || req.http.Authorization ) {
        	return (hit_for_pass);
    	}
 
    	# don't cache search results
	if ( req.url ~ "\?s=" ){
		return (hit_for_pass);
	}
    
	# only cache status ok
	if ( beresp.status != 200 ) {
		return (hit_for_pass);
	}

	# A TTL of 24h
	set beresp.ttl = 24h;
	
	return (deliver);
}
 
# The routine when we deliver the HTTP request to the user
# Last chance to modify headers that are sent to the client
sub vcl_deliver {
	if (obj.hits > 0) { 
		set resp.http.X-Cache = "cached";
	} else {
		set resp.http.x-Cache = "uncached";
	}

	# Remove some headers: PHP version
	unset resp.http.X-Powered-By;

	# Remove some headers: Apache version & OS
	unset resp.http.Server;

	# Remove some heanders: Varnish
	unset resp.http.Via;
	unset resp.http.X-Varnish;

	return (deliver);
}
 
sub vcl_init {
 	return (ok);
}
 
sub vcl_fini {
 	return (ok);
}

Avant toute chose voici la doc :) : https://www.varnish-cache.org/docs/3.0/
Ce qu’il faut retenir de ce fichier de règles c’est les parties normalisation, enlever les cookies inutiles (car si cookie alors pas de cache) et ne pas mettre en cache l’admin. Cette config tourne actuellement sur S&M.

Un point intéressant c’est le debug, vous pouvez mettre un set resp.http.X-Cache = “cached”; et vérifier les headers de votre serveur dans le debug de votre navigateur pour savoir si oui ou non la page servie est en cache.

L’admin varnish en ligne de commande:
Varnish possède une admin en ligne de commande où l’on peut par exemple purger le cache d’une ou plusieurs pages.
Tapez varnishadm dans le shell:

varnishadm
200        
-----------------------------
Varnish Cache CLI 1.0
-----------------------------
Linux,3.2.0-25-virtual,x86_64,-smalloc,-smalloc,-hcritbit

Type 'help' for command list.
Type 'quit' to close CLI session.

varnish> ban.url /toto/ma-page.php

Pour purger une page on va utiliser la commande ban.url et y ajouter une partie de l’url à purger. On peut utiliser un ban en appelant également une url de purge avec Curl ou Wget pour les automations, il y a un excellent article sur la purge ici.

Configurer Nginx:
Une fois varnish installé, on va modifier un peu nginx pour que la liaison puisse se faire. Ci-dessous l’exemple de notre conf nginx.


server {
    listen      8080;
    server_name  sametmax.com  ;
    root         /unrep/sametmax/;  # absolute path to your WordPress installation
    index index.php index.html;
    set_real_ip_from        127.0.0.1;
    real_ip_header          X-Forwarded-For;

    location ~ \.php$ {
        include        /etc/nginx/fastcgi_params;
        fastcgi_pass   127.0.0.1:53217;
        fastcgi_index index.php;
        fastcgi_buffers 8 16k;
        fastcgi_buffer_size 32k;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    }

Pour PHP on utilise spawn-fcgi que l’on gère avec supervisor dont voici la conf dans /etc/supervisord.conf

[program:php5-cgi]
command=/usr/local/bin/spawn-fcgi -u adolf -n -a 127.0.0.1 -p 53217 -P /tmp/fastcgi-php.pid -F 4 -- /usr/bin/php-cgi
redirect_stderr=true          ; redirect proc stderr to stdout (default false)
user=sametmax
autostart=true
autorestart=true
startsecs=10
startretries=9999999999999
stdout_logfile=/var/log/php5-cgi/php5-cgi.log
stdout_logfile_maxbytes=10MB   ; max # logfile bytes b4 rotation (default 50MB)

Pour résumer:

Dans cette configuration Varnish est en front end et va décider quand servir une page prise dans le cache (disque dur ou RAM) et quand interroger le backend pour servir une nouvelle page.
Sur d’autres sites à fort trafic on a mis Nginx en front end car il encaisse beaucoup plus les hits et qu’il fait très bien le boulot pour servir des pages statiques.

Attention!
Même si Varnish n’est pas compliqué à installer il peut être un vrai casse-tête quand il s’agit de cacher des pages. Pensez donc bien à normaliser vos headers (user-agent, gzip, etc), utilisez le debug.
Bien configuré Varnish vous booste un serveur avec une réélle efficacité, il nous a sauvé 2 sites jusqu’à présent, ça sera d’ailleurs un standard sur nos prochains sites.

]]>
http://sametmax.com/initiation-a-varnish-accelerer-un-blog-wordpress/feed/ 6 4416
Migrer wordpress d’un serveur à un autre – Pense-bête http://sametmax.com/migrer-wordpress-dun-serveur-a-un-autre-pense-bete/ http://sametmax.com/migrer-wordpress-dun-serveur-a-un-autre-pense-bete/#comments Wed, 09 Jan 2013 08:59:03 +0000 http://sametmax.com/?p=4050 Si on veut changer de serveur sans se taper la réinstall de wordpress ça peut devenir casse-tête si on oublie deux trois trucs…

Voici un petit pense-bête avec pour exemple une config Nginx / WordPress / php5-cgi sur Ubuntu.

serveura.com = serveur sur lequel se trouve l’ancien WordPress à migrer
serveurb.com = nouveau serveur qui va accueillir WordPress

1. on sauve la db et on l’upload sur le nouveau serveur (on peut le faire à la fin si le blog a pas mal d’activité)
Sur le serveur A:

mysqldump -u user_toto -ppass_toto base_a_toto > /tmp/base_a_toto.sql
rsync -P -azc /tmp/base_a_toto.sql user@serveurb.com:/tmp/base_a_toto.sql

2. On copie wordpress sur le nouveau serveur
Sur le serveur A:

rsync -P -azc /home/monsite/wordpress/ user@serveurb.com:/home/monsite/

3. Setup et configuration du nouveau serveur
Sur le serveur B:
Installer les packets necessaires:

apt-get install php5-cgi php5-mysql mysql-server nginx spawn-fcgi sendmail

Il faut lancer les services nginx et spawn-cgi (pour ce dernier on peut utiliser supervisord)

Nginx:
Editer le fichier /etc/nginx/conf.d/monsite.conf . Attention à bien indiquer le chemin absolu vers votre site pour root

server {
    listen      80;
    server_name  monsite.com www.monsite.com;                   # your domain name
    root         /home/monsite/wordpress;  # absolute path to your WordPress installation
    index index.php index.html;
    
    error_log "/var/log/nginx_error.log";
    access_log  "/var/log/nginx_access.log";

    try_files $uri $uri/ /index.php;

    location ~ \.php$ {
        include        /etc/nginx/fastcgi_params;
        fastcgi_pass   127.0.0.1:53217;
        fastcgi_index index.php;
        fastcgi_buffers 8 16k;
        fastcgi_buffer_size 32k;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    }

location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
}

# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
}

# Deny access to any files with a .php extension in the uploads directory
location ~* ^/wp-content/uploads/.*.php$ {
        deny all;
        access_log off;
        log_not_found off;
}

# Deny access to any files with a .php extension in the uploads directory for multisite
location ~* /files/(.*).php$ {
        deny all;
        access_log off;
        log_not_found off;
}

}

Spawn-Fcgi: C’est lui qui va lancer php5-cgi pour faire la liaison entre php et nginx. on va le lancer avec supervisor comme si c’était un service mais mieux.

Installation de Supervisor:

apt-get install python-setuptools
easy_install supervisor
echo_supervisord_conf > /etc/supervisord.conf

Editez le fichier /etc/supervisord.conf pour y rajouter spawn-fcgi, c’est mieux de lancer php5-cgi avec un user autre que root (www-data ou autre) :

[program:php5-cgi]
command=/usr/local/bin/spawn-fcgi -n -a 127.0.0.1 -p 53217 -u www-data -f /usr/bin/php5-cgi
redirect_stderr=true 
stdout_logfile=/var/log/php5-cgi.log
stdout_logfile_maxbytes=10MB 

Pour lancer Spawn-fcgi:

supervisorctl restart php5-cgi

Mysql: on ajoute mysql au demarrage et on le lance

chkconfig mysql on
service mysql start

Dump de la DB: il faut créer un user et une base sur la nouvelle install, si possible le même que sur l’ancien serveur pour faciliter la transition.
Sur le serveur B:

mysql -u root -prootpass
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 42
Server version: 5.5.28-0ubuntu0.12.04.3 (Ubuntu)

Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database base_a_toto;
Query OK, 1 row affected (0.00 sec)

mysql> GRANT ALL PRIVILEGES ON base_a_toto.* TO "user_toto"@"localhost" identified by "pass_toto";

Query OK, 0 rows affected (16.16 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

Et on importe la base de données de serveura.com:

mysql -u user_toto -ppass_toto base_a_toto < /tmp/base_a_toto.sql 

4. Changer les dns
des fois on oublie :) alors changez les dns et attendez un peu, normallement ça devrait crystalliser...

Ca prend pas 5 minutes, même avec les paquets tous prêts. on peut avoir de mauvaises surprises en route. Moi par exemple erreur 500 , pour m'aperçevoir au bout de 2 heures que j'avais pas installé php5-mysql d'où ce tuto ;)

]]>
http://sametmax.com/migrer-wordpress-dun-serveur-a-un-autre-pense-bete/feed/ 14 4050
WordPress, je te hais http://sametmax.com/wordpress-je-te-hais/ http://sametmax.com/wordpress-je-te-hais/#comments Wed, 18 Jul 2012 16:29:31 +0000 http://sametmax.com/?p=1203 Cherchant à rendre le formulaire commentaires de Sam et Max plus ergonomique, j’ai jeté un coup d’oeil sur le template lié.

L’intégralité du code qui génère le formulaire pourri que vous voyez sous l’article est ici:

comment_status) : ?>
         esc_attr__( 'Submit Comment', 'Minimal' ), 'title_reply' => '' . esc_attr__( 'Leave a Reply', 'Minimal' ) . '', 'title_reply_to' => esc_attr__( 'Leave a Reply to %s' )) ); ?>



 

Je vous passe le commentaire amical qui stipule “si vous supprimez ceci le ciel vous tombera sur la tête” et toute remarque désobligeante sur le formatage absolument bordélique de l’intégralité du fichier.

Non, je reste optimise, je vois un comment_form qui encapsule la génération du formulaire. Peut être une API propre ? J’ai bon espoir (mais le fait que ce soit une fonction et non une classe aurait du me mettre la puce à l’oreille).

Je trouve un très bon article qui explique où on trouve ce merveilleux comment_form (ben oui parceque les includes et autoloads en PHP c’est pas vraiment le truc le plus top pour retrouver la chaîne de dépendances). Et là, je n’ai rien supprimé, mais le ciel m’est quand même tombé sur la gueule. Et toute la couche d’ozone avec.

La valeur par défaut d’UN des paramètres de la fonction qui génère le formulaire, c’est ça :

 apply_filters( 'comment_form_default_fields', array(
    'author' => '

' . ' ' . ( $req ? '*' : '' ) . '' . '

', 'email' => '', 'url' => '

' .

'' . '' . ' ' ) ), 'comment_field' => '

' . '' . '' . '

', 'must_log_in' => ' ', 'logged_in_as' => '

' . sprintf( __( 'Logged in as %s. Log out?

' ), admin_url( 'profile.php' ), $user_identity, wp_logout_url( apply_filters( 'the_permalink', get_permalink( $post_id ) ) ) ), 'comment_notes_before' => '

' . __( 'Your email is never published nor shared.' ) . ( $req ? __( ' Required fields are marked *' ) : '' ) . '

', 'comment_notes_after' => '
' . __( 'You may use these HTML tags and attributes:' ) . '
' . allowed_tags() . '
', 'id_form' => 'commentform', 'id_submit' => 'submit', 'title_reply' => __( 'Leave a Reply' ), 'title_reply_to' => __( 'Leave a Reply to %s' ), 'cancel_reply_link' => __( 'Cancel reply' ), 'label_submit' => __( 'Post Comment' ), ); ?>

Je ne sais pas ce qui me rend le plus malade.

L’absence totale de la notion de template ?

Le fait qu’on passe l’intégralité du code HTML en PARAMETRE à une fonction qui est censée générer le formulaire ?

Le fait que le code est absolument inmodifiable car c’est un mélange de concaténations, d’arrays et d’appels à gettext ?

Je voulais juste modifier le HTML du formulaire de comments bordel !

BANG !

]]>
http://sametmax.com/wordpress-je-te-hais/feed/ 4 1203
Le backup wordpress du pauvre http://sametmax.com/le-backup-wordpress-du-pauvre/ Wed, 18 Jul 2012 15:36:09 +0000 http://sametmax.com/?p=1198

Backup’s, can’t live with them, can’t live without them.

Mais quand c’est le blog que vous faites pour le fun, vous n’avez pas envie de mettre en place un système compliqué pour faire un backup facile à restaurer.

Typiquement, SamEtMax est là pour le lulz, pas pour la corvée. Ce n’est pas grâve si il se fait pirater, defaced ou whatever. Pas besoin d’un truc hyper secure. Juste de quoi le remettre sur les rails rapidement, avec le minimum d’effort.

La solution inspirée par la méthode Rache:

  • Dans le cron: 28 22 * * 1 mysqldump -u user -ppassword database > /chemin/vers/site/backup.sql
  • Un petit git init, git add ., git commit -m "OSEF";
  • Un petit git pull sur son laptop (histoire d’avoir le code sous la main offline)

Avec les thêmes le premier fetch fait quand même 250 Mo, le coquin.

Ensuite, un cron sur un autre server qui bouffe pas de BP (genre un server d’encoding) avec le git pull dedans, et voilà. Sauvegarde complète, automatique et facile à restaurer.

]]>
1198