This article will show the steps needed to install and utilize lsyncd to sync multiple web servers in a cloud environment. I have set this up in various production environments, from 2 to 12+ servers. This can be used for many purposes, for this article I will use it to sync a pair of wordpress web servers since its a very common application that I have setup for many of my clients. For this demo I will show you how to do it on CentOS.
First setup the file systems on all the web servers, including a user with same UID/GID to use for the ownership of the transferred locations (this part of the configuration is not required to make lsyncd work, but I think a uniform simplistic approach is best). For this example we will use a default web layout of /var/www/html owned by a regular user bob (UID 501, GID 501)
#adduser bob -d /var/www/html#passwd bob#chown -R bob:bob /var/www/html
Next we will setup passwordless SSH from master to slave system for user root (I don’t care for this part from a security standpoint, but have not figured out how to run demon as a regular user yet).
Generate SSH keypair on master:
# ssh-keygen -t rsa
Then copy /root/.ssh/id_rsa.pub on master to /root/.ssh/authorized_keys on the slave server
Then ensure the following lines are uncommitted in /etc/ssh/sshd_config on the slave server
PermitRootLogin yes RSAAuthentication yes PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys
Then make sure to restart SSH after making changes to the configuration. Then test SSH access from master to slave to ensure entry is working correctly.
Before we can install the demon you will need to ensure you have all the dependencies in place, most likely the following command will get everything you need.
# yum install lua lua-devel pkgconfig
Then grab the source from http://code.google.com/p/
Untar the file and run the standard ‘./configure && make && make install’ to create and install the binaries.
The source code install does not add the init.d script or configuration file by default, those have to be manually added after installation. Create the init.d script from template below.
/etc/init.d/lsyncd
#!/bin/bash # # lsyncd: Starts the lsync Daemon # # chkconfig: 345 99 90 # description: Lsyncd uses rsync to synchronize local directories with a remote # machine running rsyncd. Lsyncd watches multiple directories # trees through inotify. The first step after adding the watches # is to, rsync all directories with the remote host, and then sync # single file buy collecting the inotify events. # processname: lsyncd # . /etc/rc.d/init.d/functions config="/etc/lsyncd.lua" lsyncd="/usr/local/bin/lsyncd" lockfile="/var/lock/lsyncd" prog="lsyncd" RETVAL=0 RETVAL=0 start() { if [ -f $lockfile ]; then echo -n $"$prog is already running: " echo else echo -n $"Starting $prog: " $lsyncd $config RETVAL=$? echo [ $RETVAL = 0 ] && touch $lockfile return $RETVAL fi }stop() { echo -n $"Stopping $prog: " killall $lsyncd RETVAL=$? echo [ $RETVAL = 0 ] && rm -f $lockfile return $RETVAL }case "$1" in start) start ;; stop) stop ;; restart) stop start ;; status) status $lsyncd ;; *) echo "Usage: lsyncd {start|stop|restart|status}" exit 1 esac exit $?
Set permissions and ownership on init.d file:
# chmod 775 /etc/init.d/lsyncd # chown root:root /etc/init.d/lsyncd
Lsyncd configuration file examples. /etc/lsyncd.lua
Here is an example of a master, single slave configuration file (1.1.1.1 is the IP of the slave server).
settings = {logfile = "/var/log/lsyncd.log",statusFile = "/var/log/lsyncd-status.log",statusInterval = 20 }sync{default.rsyncssh,source="/var/www/html",host="1.1.1.1",targetdir="/var/www/html",rsyncOpts="-avz" }
Here is an example for a master with two slave configuration (1.1.1.1 first slave, 2.2.2.2 second slave)
settings = {logfile = "/var/log/lsyncd.log",statusFile = "/var/log/lsyncd-status.log",statusInterval = 20 }sync{default.rsyncssh,source="/var/www/html",host="1.1.1.1",targetdir="/var/www/html",rsyncOpts="-avz" }sync{default.rsyncssh,source="/var/www/html",host="2.2.2.2",targetdir="/var/www/html",rsyncOpts="-avz" }
There is a huge amount that can be done using the configuration file, including execution of lau and bash scripts triggered by events in the configuration files. Here is the manual for configuration http://code.google.com/p/
Sample exclude file – /etc/lsyncd-excludes.txt:
cache/
uploads/
dontcopymebro/
Then a sample configuration file with the exclude file included – /etc/lsyncd.lua:
settings = {logfile = "/var/log/lsyncd.log",statusFile = "/var/log/lsyncd-status.log",statusInterval = 20 }sync{default.rsyncssh,source="/var/www/html",host="1.1.1.1",targetdir="/var/www/html",excludeFrom="/etc/lsyncd-excludes.txt",rsyncOpts="-avz" }
Once the init script and the configuration file are in place, run the following command to setup run on boot:
chkconfig lsyncd on
Make sure to look over your log files to ensure that everything is working, the most common problem other than SSH login is running out of inodes if your file structure is large. This can be adjusted in /proc/sys/fs/inotify/max_user_
Now I mentioned at the first of this article that this is a one way synchronization program so all disk writes have to be done on the master web server or this will break sync. Now using a CMS like wordpress this is pretty easy to do. The way I recommend to my clients is to force SSL login/admin access. by adding the following lines to your wp-config.php. In my opinion this is a good standard security step anyways.
define('FORCE_SSL_ADMIN', true);define(‘FORCE_SSL_LOGIN’, true);
This forces all logins to the control panel, which is where all writes are done to SSL. Then you just have to configure whatever load balancing solution your using to send all SSL traffic to your master server only.
Now there are plenty of other things that need to be done to setup a multi-server CMS configuration such as session handling and Apache optimization but that’s another article.
Hope you find this article helpful.
- Nomad

