Creating a good development environment is obviously very important for any new development project, and with database-driven applications, it’s often a hassle to keep files and data in sync. With this in mind, I tried to come up with an efficient method of pushing a local development copy of this site to its live server.
The Development Environment
The production environment for the project runs on LAMP (Linux, Apache, MySQL and PHP), and uses WordPress for the blog / CMS duties. LAMP and WordPress are a snap to set up on OS X and Windows, so I won’t go into the details here. For Windows, you can even install a self-contained and self-installing package with all of the technologies, like XAMPP. If you need help, check google for current instructions.
Synching the Files
In the initial stages of development, it’s common to a multitude of changes throughout the site, and as such it can be inefficient to use simple FTP for pushing changes live. I was looking for an easy way to instantly sync the development and production servers, and I wasn’t worried about version control or multiple developers have access to the same code. If I was, I could have used Subversion, but that seemed a little too much for this simple task.
So instead, I used rsync over SSH:
rsync -rve ssh [mylocaldirectory] [myuser]@[myserver]:[myremotedirectory] --exclude-from=[exclude-file]
… and stored the command in a file named update-files.sh so I could execute it whenever I needed to. You’ll have to enter your SSH password when you run it, but it’s considerably more secure this way. Some notes on the command:
-rmakes it recursive (obviously need that)-vmakes it verbose (helpful)-eallows you to include a remote shell--exclude-fromallows you to specify an exclude file with patterns to ignore in the transfer. This is helpful because you can exclude domain specific configuration files,.DS_Store files, etc. Just make a separate file, and include filenames / patterns to ignore one to each line.
That’s it! In this example you’ll need remote shell access via ssh, which may be difficult to obtain if you run on a shared host. If you run into problems you can use rsh or run a rsync server… check the rsync man page for more details.
You’ll also need access to a Unix / Linux command line, which isn’t a problem for Mac users. For Windows users, get Cygwin.
Synching the Database
Given the nature of WordPress, to maintain a similar copy of the database across domains would basically require:
- Backing up the database to be moved
- Copying the database backup to the other domain
- Restoring the database backup on the other domain
- Replacing the domain specific mentions in the WordPress DB
Fortunately, all this is easily scripted. I used two files, first, on my local (development) machine, I created a file named update-db.sh:
mysqldump -u [db_user] -p [db_password] [db_name] > current.sql
ftp ftp://[username]:[password]@[remote_domain] <<**
cd updater
put current.sql
exit
**
ssh [username]@[domain] 'updater/update-my-db.sh'
Breaking it down:
mysqldump -u [db_user] -p [db_password] [db_name] > current.sql
Dumps the current development database to a .sql file.
ftp ftp://[username]:[password]@[remote_domain] <<**
cd updater
put current.sql
exit
**
Connects via ftp, moves into the updater directory and transfers the sql backup.
ssh [username]@[domain] 'updater/update-my-db.sh'
Connects via ssh to the remote shell, and executes update-my-db.sh, which should look like this:
mysql --user=[db_user] --password=[db_password] [db] < ~/updater/current.sql;
mysql -e "UPDATE wp_options SET option_value = '[live domain]' WHERE option_name = 'home'" --user=[db_user] --password=[db_password] [db]
mysql -e "UPDATE wp_options SET option_value = '[live domain + path to wordpress' WHERE option_name = 'siteurl'" --user=[db_user] --password=[db_password] [db]
mysql -e "UPDATE wp_posts SET guid = REPLACE (guid,'[local domain]','[live domain]')" --user=[db_user] --password=[db_password] [db]
exit
This file needs to be on the remote machine so it can interact with mysql. Basically, it takes the domain-specific mentions and changes them to point to the live server instead of the development one.
And that's it! Just run update-db.sh on your development machine and any WordPress changes (posts, pages, options, etc.) should be replicated on the live server.