Scripts for a WordPress Weblog Farm [en]

A first step to WordPress-farming: a shell script and a PHP script which allow you to easily install a whole lot of WordPress weblogs in only a few minutes (I installed over 30 in less than 5 minutes). Scripts require adapting to your environment, of course.

Update 03.11.06: Batiste made me realise I should point the many people landing here in the search of multi-user WordPress to WordPress MU. All that I describe in this post is very pretty, but nowadays completely obsolete.

Here is the best solution I’ve managed to come up with in half a day to finally install over 30 WordPress weblogs in under 5 minutes (once the preparation work was done).

A shell script copies the image of a WordPress install to multiple directories and installs them. A PHP script then changes a certain number of options and settings in each weblog. It can be used later to run as a “patch” on all installed weblog if a setting needs modifying globally.

Here are the details of what I did.

I first downloaded and unzipped WordPress into a directory.

tar -xzvf latest.tar.gz
mv wordpress wp-farm-image

I cleaned up the install (removing wp-comments-popup.php and the import*.php files, for example), added a language directory (as I’m wp-farming in French) and modified index.php to my liking; in particular, I edited the import statement for the stylesheet so that it looked like this:

@import url( );

The styles directory is a directory in which I place a bunch of WordPress styles. I don’t need the style switcher capability, but I do need to styles. Later, users will be able to change styles simply by editing that line in their index.php (or I can do it for them).

Another very important thing I did was rename wp-config-sample.php to config-sample and fill in the database and language information. I replaced wp_ by xxx_ so that I had $table_prefix = 'xxx_';.

To make it easier to install plugins for everyone, correct the language files, and edit whatever may be in wp-images, I moved these three directories out of the image install and replaced them with symbolic links, taking inspiration from Shelley’s method for installing multiple WordPress weblogs.

mv image/wp-content common
mv image/wp-images common
mv image/wp-includes/languages common
ln -s common/wp-content image/wp-content
ln -s common/wp-images image/wp-images
ln -s common/languages image/wp-includes/languages

I also added an .htaccess file (after some painful tweaking on a test install).

Once my image was ready, I compiled a list of all the users I had to open weblogs for (one username per line) in a file named names.txt, which I placed in the root directory all the weblog subfolders were going to go in.

I then ran this shell script (many thanks to all those of you who helped me with it — you saved my life):

for x in `cat names.txt`
cp -rv /home/edublogs/wp-farm/image/ $x
cat $x/wp-config.php | sed "s/xxx/${x}/" > config.tmp
mv config.tmp $x/wp-config.php

This assumes that my WordPress install image was located in /home/edublogs/wp-farm/image/ and that the weblog addresses were of the form

This script copies the image to a directory named after the user, edits wp-config to set the table prefix to the username, and then successively wgets the install URLs to save me from loading them all in my browser.

After this step, I had a bunch of installed but badly configured weblogs (amongst other things, as I short-circuited the form before the third install step, they all think their siteurl is

Entered the PHP patch which tweaks settings directly in the database. I spent some time with a test install and PHPMyAdmin to figure out which fields I wanted to change and which values I wanted to give them, but overall it wasn’t too complicated to do. You’ll certainly need to heavily edit this file before using it if you try and duplicate what I did, but the basic structure and queries should remain the same.

I edited the user list at the top of the file, loaded it in my browser, and within less than a few seconds all my weblogs were correctly configured. I’ll use modified versions of this script later on when I need to change settings for all the weblogs in one go (for example, if I want to quickly install a plugin for everyone).

In summary:

  1. compile list of users
  2. prepare image install
  3. run shell script
  4. run PHP script

If you try to do this, I suggest you start by putting only two users in your user list, and checking thoroughly that everything installs and works correctly before doing it for 30 users. I had to tweak the PHP script quite a bit until I had all my settings correctly configured.

Hope this can be useful to some!

Update 29.09.2005: WARNING! Hacking WordPress installs to build a farm like this one is neat, but it gets much less neat when your weblog farm is spammed with animal porn comments. You then realise (oh, horror!) that none of the anti-spam plugins work on your beautiful construction, so you weed them out by hand as you can, armed with many a MySQL query. And then the journalist steps in — because, frankly, “sex with dogs” on a school website is just too good to be true. And then you can spend half a day writing an angry reaction to the shitty badly-researched article.

My apologies for the bad language. Think of how you’re going to deal with spam beforehand when you’re setting up a school blog project.

38 thoughts on “Scripts for a WordPress Weblog Farm [en]

  1. That’s a great way to handle the passwords! That was one of my biggest curiousities since you steamrolled past them with the wget commands 🙂

  2. Doing a bit of the same stuff, only I whip up a virtual server with its own IP adress, its own webserver and FreeBSD install, using the jail functionality in FreeBSD. Record so far, 1500 webservers on a host computer. Painful, but still lots of fun. 🙂 Now I’m down to ~250 webservers pr server, and all is playing way to nice. Installing wordpress and having it set up is a matter of selecting an option

  3. Make sure you keep a 1.2 tarball around, 1.3 will requires an email address in the installer.

  4. ok — I’ve got a “generic” e-mail address for those blogs anyway, as we don’t want the kids giving out their private e-mail addresses (yet).

  5. Hahaha.. I’ve been following your blog and was wondering what on earth was all these focus on WordPress… and who’d know, months later, there I was… sitting and looking to install word press multiple user…

    … and voila, it links back to your blog. 😀

  6. I’m having trouble with some plugins, because of the decentralized nature of my set-up. I thought it would make things simpler, but in fact it doesn’t. I’m probably going to upgrade all the weblogs to 1.5, and I’ll give them each a complete customized install (just using the batch scripts to do it).

  7. Réponse à  Luc-Olivier Erard (La Côte)

    Un article relativement peu flatteur pour le projet de weblogs scolaires que j'ai initié avec mes classes est paru ce matin dans La Côte. Voici ce que j'ai à  en dire….

  8. Hi, I’m interested in setting this up at my work, but I notice that your PHP-Patch script has an included file which I can’t find anywhere – include(‘../connect-stprex.php’);

    Can you either link to this file, or drop me an email with it? Thanks!

  9. Hi,

    Thanks for the wonderful post. I am also interested in making this work. Can you please help with the file below?


    Many thanks.

  10. That’s just a file with the connection information — it’s below the web root because I don’t want to make my db connection information public.

    It looks something like:

    $connect = mysql_connect(“”, “username”, “password”)
    or die(“Could not connect to mysql server.”);
    mysql_select_db(“your_db”, $connect)
    or die (“Could not connect to database.”);

    See for details.

  11. very nice i want you to help me setting up the word press it is really not a 5 minutes problems

  12. I have a blog setup that I will call my ‘base-installation’, which has all the proper settings, plugins and templates. Next time I need to setup a blog, I want to duplicate this base-install, then customize a few things for that customer.

    A theory I have to do this is as follows:

    1. Using my base-install of the perfect blog, download the files and database.

    2. When I do the next install, I install WordPress as I always have.

    3. After the install of the original program, upload my base-install files, import the database, and I would see a duplicate blog of my base-install.

    Any suggestions?

    Would my theory work?

  13. @ Jeremy

    Make a PHP script that:

    1. Recolect the new blog dir, title and desc,
      username and password
    2. Create the new blog dir (I’ll use here “lucasblog”)
    3. Copy “base-install” to “lucasblog”
    4. Open wp config and change the values concerning
      user and blog data
    5. Create the database and fill the tables using
      a mysql dump made from “base-install” database
    6. Modify SQL for all needed values to reflect the new
      blog “lucasblog”
    7. Inform user that the blog is on.

    I think this will be enough.

    If possible, instead of copying, symlink the part concerning WordPress — less config, themes and plugins dir — because your maintenance task is easier.

    Upgrades and new addons are faster too, altough using WordPress will harden your control over what users install, being that new themes or plugins.

    Don’t symlink the themes directory because if a user modifies his/her theme you will have awfull problems with all the other guys that use the same theme.

    Of course, you can always use WordPress Mu and most of this will be solved 🙂

  14. For multiple once a time creation:

    1. Recolect the new blog dir, title and desc,
      username and password from a file.
    2. Reapeat until there is a blog to create:
      a. Create each “new-blog” dir
      b Copy “base-install” to “new-blog”
      c. Open wp config and change the values concerning
      user and blog data
      d. Create the database and fill the tables using
      a mysql dump made from “base-install” database
      e. Modify SQL for all needed values to reflect each new
      blog “new-blog”


  15. These are becoming more popular as people figure out ways to create mutliple WordPress installations under one domain name and automate the addition process. The scalability concern is real.

  16. Interesting way of overcoming the problem of managing multiple blogs – I guess the same process can be used for updating (be simpler with the incremental updates. However as I am only running a couple of individual blogs, it probably isn’t worth it.

    I felt for you over the Spam issue, and while my French isn’t up to much, I gathered that the majority of the comments were supportive of you. SO annoying. I look on it as a compliment that my site is getting visibility when it does get spammed – all first time posts go into moderation for me, so at least I cath them before they are posted. Have you tried Askimmet?

    Best wishes for your project!


  17. Hi, I presume that this method works only for wordpress 1.2.1 Its technically great work, I really enjoyed reading it. I wonder if at the moment am I better using lyceum or wordpress mu for a secure multi-user blog.

  18. Hello,

    I am reading your instruction gow to install multiple blog farm on home server. I am new at this thing and must admit that i can not follow your step by step guide, because i can understand it. This is samething very new to me. Can you please send me some detailed instruction so i can follow it? I would be very happy if you can do this. Many thanks

    Best regards

    I have:
    Win srv2003 std
    php 4.4
    mysql 5.0

  19. Sorry to disappoint you, but I put up these instructions just in case they came in handy to anybody. If you can’t find your way through them… well, you need to try to find another solution.

    I’m not sending out more detailed instructions to anybody.

  20. My main concern is that you can’t guarantee every page of your website will be included in the SERPs. Considering I’m constantly adding new products to my company’s website, I need to be sure that customers can find them as soon as possible.

Comments are closed.