Dynamically creating WordPress Minisites On-The-Fly

By Matt Dunlap on June 22nd, 2010
Clip to Evernote Tags: , , , ,

If you are going to bookmark one tutorial this year, you should bookmark this one and this one.

pimp cup

The Holy Grail for WordPress

This is what I consider the holy grail of WordPress. The ability to use WordPress’s multisite functions (WPMU) with top level domains AND dynamic top-level domain set up. dynamic top-level domain setup is accomplished by accessing webserver (Apache) files. Normally these files are off limits because of permissions, but in this tutorial, I’ll show you how to edit the httpd.conf file, then restart Apache from the web.

You will need full access to a webserver. This will not work on a shared host. I’ve written tutorials for WPMU and Godaddy here. You can still run WPMU, or WordPress 3.0 multisites on Godaddy (or any other shared host), you just can’t do it dynamically. Here is my tutorial for deploying a cloud server in 5 minutes

If you want to try this tutorial but need a server, I recommend the Rackspace cloud… I use them

Of course, dynamically creating websites is not restricted to WordPress. This tutorial will work for any PHP installation that needs to create websites on the FLY!

To start, you need to understand a PHP function called shell_exec

Shell_exec allows your PHP files to access server files. For example, here is a simple shell_exec that performs an ls command (list files in a folder)

echo shell_exec("ls");

Create a php file in your website folder and add the above line of code. You should get an output of all the files in your website folder.

You can access server functions that are available to all users, but you can’t access functions that are protected… like useradd

This will output an error:

echo shell_exec("useradd billy 2>&1");

You should get
sh: /usr/sbin/useradd: Permission denied

It’s just like you are on the server giving it linux commands. You need to have the proper permission to perform certain functions. You can grant users permissions with “sudo”

Sudo (su “do”) allows a system administrator to delegate authority to give certain users (or groups of users) the ability to run some (or all) commands as root or another user while providing an audit trail of the commands and their arguments.

So, it’s obvious right… in order to run commands you need to add the webserver user to the sudoers list. the webserver user is probably going to be apache, nobody, or web.

Adding Apache user to sudoers list

You add sudo users with the visudo command. I’m not going to give a tutorial on visudo, if you need that click here. I’m only going to give you enough knowledge to get this job done.

using visudo, give the Apache user permissions to access files

## Allow root to run any commands anywhere
root    ALL=(ALL)       ALL
# add apache
apache  ALL=NOPASSWD: ALL

Find the section where root has full access. Add Apache to that section. In the above example I have given Apache full control with no password prompt. Please note that you have to give Apache access without prompting for password, because you cannot provide the password when calling shell_exec.

You’re probably saying, “Matt, isn’t it dangerous to give Apache full access?” You’re damn right it is! That is why the above example is just that an example. Use it to see if it works, on a non production machine. Now I’m going to show you how to allow Apache to access only the files needed to perform a job.

Log into the server and make 2 test files. I made test and test2. In test, add this:

#!/bin/sh
useradd test</pre>
In test2 add this
<pre class="php">#!/bin/sh
useradd test2

Make sure you chmod them 755 to make them executable

go back to visudo and update the Apache user permissions

## Allow root to run any commands anywhere
root    ALL=(ALL)       ALL
# add apache
apache  ALL=NOPASSWD: /path/to/test

make sure you point to the location of your test file.
Now update your shell_exec command in the php file to:

echo shell_exec("/usr/bin/sudo /test/test /test/test2 2&gt;&amp;1");

Basically, you are now going to execute both test and test2… But remember, you only gave Apache access to test in visudo… Let’s see what happens.

I admit, it wasn’t very exciting. You should see that a new user has been added with the name of test… user test2 has not been added. So it works.

here is access to both test and test2

## Allow root to run any commands anywhere
root    ALL=(ALL)       ALL
# add apache
apache  ALL=NOPASSWD: /path/to/test, /path/to/test2

Separate all the files or commands with commas.

## END OF VISUDO TUTORIAL

Onto real world examples

To add domain names on the fly you need to park the domain, then restart apache.

To park a domain, you need to add the domain name as a server alias to the main website’s virtual directory. I use a simple linux sed command

#!/bin/sh
site_domain=$1;
new_site=$2;
# insert the new domain name
cat /etc/httpd/conf/httpd.conf | sed  "/ServerName $site_domain/a\   \ServerAlias *.$new_site $new_site" &gt; /etc/httpd/conf/httpd.conf.back
mv /etc/httpd/conf/httpd.conf.back /etc/httpd/conf/httpd.conf
/usr/sbin/apachectl -k restart

This simply looks for the main website servername, and then adds the new domain name as a server alias. Makes a backup copy of the httpd.conf file and then overwrites the httpd.conf file.

You can take the above code and create a new file on the webserver. Chmod it 755. Give Apache access to the file with visudo, then call the command with shell_exec.

$main_domain = 'maindomain.com';
$new_domain = 'anotherdomain.com';
shell_exec("/usr/bin/sudo /add_new_website $main_domain $new_domain  $ &gt; /dev/null &amp;");

As you can see I pass the main and new domain names, then sed takes over updating the httpd.conf file. The shell_exec command outputs to null “/dev/null” and runs in the background “&” so it doesn’t hang the webserver.
Go hit the new domain name in the browser and you should see the main site come up because it is parked.

Some notes about what just happened.

Make sure to run in background because if you restart the Apache server while trying to load the webpage, you will get an error… because the webserver is restarting.

I use a separate file to restart Apache because that allows me to park multiple websites at the same time without restarting the server.

That’s it… I know this probably went over the heads of a lot of WordPress users, but if you play with it a little, you’ll understand how awesome it is. Combine it with my other tutorials for adding top-level-domains to WordPress and you’ll create a kick-ass website that allows people to make host their blogs with real domain names.


My next post is going to be awesome... Subscribe to my feed so you don't miss it

Large RSS Feed Button


Previous Post Next Post

Post a Comment

Name:   
Email:   
Website:   
Comments:   
alert icon Do you need help with your website? I can offer full system admin, website development and Internet marketing services
Domain Name Deals
.COM for $1.99
With any non domain name purchase
Free Private Registration - When you buy or transfer 5 domains at opendls.com
Domain Name Reseller Accounts
Low buy rates - Very Profitable
Matt Dunlap on Why am I getting redirect loop errors with FireFox 3.6.8?
Hi, thanks for the heads up... Have you experienced this problem with any other websites? It's reall[...]
Stacy on Why am I getting redirect loop errors with FireFox 3.6.8?
I was attempting to follow your links to these tutorials from your youtube video, and I was using th[...]
Matt Dunlap on 301 redirects will lower your Google Pagerank
You want 301 redirect on same site redirects mainly to eliminate duplicate content. For example, if [...]
Kate Mag on 301 redirects will lower your Google Pagerank
great info. Does this mean that only affecting 301 redirect to another domain. I have 301 redirect t[...]
Mike Johnson - Real Estate Agent on Why is making extra money a bad habit?
Hey man, this is some great stuff. The only thing I can't figure out is why this sort of thing isn'[...]

Top Guest Bloggers

LoneWolf
View Posts | RSS

Guest Bloggers Welcome!


Powered By: Free Premium WordPress Theme | Copyright 2007 - 2010 mattdunlap.org Sitemap