Virtualmin Templates

Is it possible to setup a template in the GPL version where files are preinstalled in the home directory and a database is installed?

What I’m ideally looking to do is install WordPress with various plugins and the database setup so I can get a WordPress site setup in a short period of time.

If the above isn’t possible, anything that saves time like just having the files preinstalled when a new server is created would be a start.


This can be done in the Pro version.
To get the files in place at least, use the /etc/skel directory
build the structure /etc/skel/public_html and place your files in there.
Then in the server template make sure that /etc/skel is activated for use.

Thanks Ronald, been testing the concept in the GPL version and working so far.

Made a new template, copied the skel folder into another folder (skel2) since I still want to be able to create default servers as well.

Copied the WordPress files into:


Edited the template settings so replacing variables was on.

Added various variables (list here,template_variable_listing) to the .htaccess file and the wp-config.php file (main WordPress config file) so all file type work is created automatically.

In terms of the public_html directory got exactly what I wanted which is a big improvement on what I normally do.

That just leaves the database. Is it possible to automatically use an existing database as the database for a new server with various parts of the database replaced with the variables from the page I linked to above? Basically I don’t want WordPress to install the database from scratch, I want to use a WordPress database I installed, activated a bunch of plugins, got all the settings exactly how I want them (which takes 20+ minutes per domain!). In this way I create a new Virtualmin server, go to the domain URL and WordPress is setup with all the plugins I use etc… on ready to make posts (would only have to change the name of the site rather than edit 30+ settings!).


Hit a slight snag with the Replacing Variables option.

It works, but looks like there are WordPress files I’ve placed in the folder /etc/skel2/public_html that coincidentally use the same formatting as the Replacing Variables option uses!

The files are placed in the correct folder etc… when I create a new domain with the new server template, and the two files I’ve added variables like $(PASS) to have their variables replaced correctly, but WordPress is broken (won’t install).

I think what’s happening is one or more WordPress files coincidentally have variables with the format $(VARIABLE) and one or more of these match a variable that Virtualmin is replacing. I’ve not found the specific files that’s an issue yet.

Turning replacing variable off and adding the database settings manually to the WordPress config file results in WordPress installing correctly strongly suggesting it’s what I think above.

Is there a way to replace variables only within files I specify?



There might be a (somewhat advanced) method to do what you desire.

You can export the pre-made WP database into an SQL file that will get the SQL commands to re-create the table structure and data. Then put variable placeholders in that file where you need stuff for the new domain replaced. Then let VM create the database as usual during domain creation.

There is a setting in Virtualmin: System Settings / Virtualmin Configuration / Actions upon server and user creation / Command to run after making changes to a server.

You might use that to run a script that takes the SQL file, adjusts the placeholders to stuff you need (use some Linux text replacement command like SED), and run the MySQL client to import the SQL file into the new database.

The link you posted with the available variables in scripts should have everything you need to do that. It might be somewhat tricky though. :slight_smile:


A similar method like the one I suggested before for the database thingy might help here: Use the Virtualmin “Command to run after making changes to a server” feature to do a bit of manual SED placeholder replacement in the respective file, so you can use a custom syntax for that which does not collide with Virtualmin’s/WP’s syntax.

Eric pointed this thread out to me today, and I realized that it would make sense for users to have a way to not perform substitution on all files in /etc/skel . So in Virtualmin 3.82 there will be a template option to specify file patterns to skip, like *.php or something.php .

Your post was a really helpful point in the right direction :slight_smile:

Not wrote a shell script before, do you think this would work:

#!/bin/sh if [ "$VIRTUALSERVER_ACTION" = "CREATE_DOMAIN" ]; then sed 's/WPRuser123/$VIRTUALSERVER_USER/g' $VIRTUALSERVER_HOME/public_html/wp-config.php sed 's/WPRpass123/$VIRTUALSERVER_PASS/g' $VIRTUALSERVER_HOME/public_html/wp-config.php sed 's/WPRdom123/$VIRTUALSERVER_DOM/g' $VIRTUALSERVER_HOME/public_html/.htaccess sed 's/WPRdom123/$VIRTUALSERVER_DOM/g' $VIRTUALSERVER_HOME/public_html/wptemplate.sql mysql -u $VIRTUALSERVER_USER -p -h localhost $VIRTUALSERVER_USER < $VIRTUALSERVER_HOME/public_html/wptemplate.sql fi

I’d put the default WordPress database sql file in the skel public_html folder along with the other WordPress files so it’s copied to the new servers public_html folder with the text WPRuser123 for the username, WPRdom123 for the domain name etc… within the files wp-config.php etc…

Then run that script via the Command to run after making changes to a server.

Have I understood correctly by using the if statement with “$VIRTUALSERVER_ACTION” = “CREATE_DOMAIN” this will only activate on the creation of a new virtualmin server? Basically don’t want to test this with a new vm server and find it messes up the old vm servers or messes servers I’m modifiying!

This would add usernames, domain names, passwords etc… that’s specific for each new virtualmin server only.

I guess I’d want to delete the wptemplate.sql file in the public_html folder after it’s used to create the database so it can’t be downloaded by others.


This is the script I’ve created:

sed ‘s/WPRuser123/$VIRTUALSERVER_USER/g’ $VIRTUALSERVER_HOME/public_html/wp-config.php
sed ‘s/WPRpass123/$VIRTUALSERVER_PASS/g’ $VIRTUALSERVER_HOME/public_html/wp-config.php
sed ‘s/WPRdom123/$VIRTUALSERVER_DOM/g’ $VIRTUALSERVER_HOME/public_html/.htaccess
sed ‘s/$VIRTUALSERVER_DOM/g’ $VIRTUALSERVER_HOME/public_html/wprb.sql
mysql -u $VIRTUALSERVER_USER -p -h localhost $VIRTUALSERVER_USER < $VIRTUALSERVER_HOME/public_html/wprb.sql
rm $VIRTUALSERVER_HOME/public_html/wprb.sql

Plan to call this via the “Command to run after making changes to a server” with


I have a server template that copies all WordPress files plus the wprb.sql file which is a backup of a WordPress database with the settings as I want them. After looking through the wprb.sql file all that needs changing is the domain name, so didn’t even have to edit it to add placeholders as can simply search/replace the via the script above.

This should create a vm server with WordPress already setup and running with the only setting needing manually changing is the title of the site and I could automate that later.

Only minor issues is the admin WordPress login for all domains created this way have the same password, but since it’s only for my use it’s not a major problem (easy to manually change a password).

Not tried this sort of thing before, so before trying the above looking for confirmation it’s unlikely to break anything on the rest of the virtualservers that are installed?


Decided to try the shell script option as looked relatively safe.

Ran into issues like having to run dos2unix on the shell script file as I’d created it with a text editor, fixed some of them but still not working.

this is my script:

#!/bin/sh sed 's/wprdom123/'$VIRTUALSERVER_DOM'/g' $VIRTUALSERVER_HOME/public_html/.htaccess sed 's/wpruser123/'$VIRTUALSERVER_USER'/g' $VIRTUALSERVER_HOME/public_html/wp-config.php sed 's/wprpass123/'$VIRTUALSERVER_PASS'/g' $VIRTUALSERVER_HOME/public_html/wp-config.php sed 's/'$VIRTUALSERVER_DOM'/g' $VIRTUALSERVER_HOME/public_html/wprb.sql mysql -u $VIRTUALSERVER_USER -p $VIRTUALSERVER_PASS -h localhost $VIRTUALSERVER_USER < $VIRTUALSERVER_HOME/public_html/wprb.sql

I’ve set Virtualmin to show the output so can see what’s going on, first thing that comes up after a new visrtual server is created is:

Post-creation command failed : followed by the contents of the .htaccess with the wprdom123 text replaced as expected.

There is nothing listed about the wp-config.php file.

The sql file is listed in it’s entirety followed by:

Distrib 5.0.77, for redhat-linux-gnu (x86_64) using readline 5.1 Copyright © 2000-2008 MySQL AB This software comes with ABSOLUTELY NO WARRANTY. and what looks like the help contents.

I was never sure about the format for importing the sql file, so assume I got that wrong.

When I check the contents of the three files above in the new virtualservers public folder they have been unchanged.

For the remaining parts of the script it looks like I’ve got the formatting partially correct, but the changes to the files are not being saved and for the wp-config.php file that’s not even showing in the output so presumably that’s not being changed at all.

Any thoughts where I’m going wrong?


It looks to me like you’re just on the right track there. :slight_smile: About the password issue, maybe you can find out how WP encodes the password (is it open-source?), then you could e.g. generate a random new password, encode it and put it in the SQL file, then mail the password to the virtual server admin.

Unfortunately I can’t really say more about it as in “script is okay or has errors”, or if it will break your other virtual servers, since I’m myself rather a newbie in terms of Virtualmin and Linux scripting stuffs. I’m learning quickly, but don’t know enough yet to evaluate your stuffs. :slight_smile:

So my suggestion would be - as is always useful - to make a backup of your stuffs and then try it until it works. Or, like I’m doing it, test it on a virtual machine with Virtualmin installed. VMWare works great there!

Hmm, looking at your file, two things come to mind:

“sed” produces its output on std-out, not in the file given as parameter. So you’d need to direct the text it produces to a new file using “>”. Not sure if you can direct it to the same file, or if you need to create a new one and “rm / mv” it afterwards.

“mysql” requires a database name to operate on. If your SQL script does not contain a “use” command, you need to add the db name before your “<” file. See “man mysql” for details.

As for “dos2unix”: I tend to use a text editor on Windows that can produce files with unix-style line endings right away. :slight_smile: UltraEdit in my case.

“ACTION statement”: Yes, as far as I understood the Virtualmin documentation, you can query that variable the way you correctly do it in your script.

“Messing with existing stuff”: Suggestion is, like I posted elsewhere, to test such stuffs in a VMWare virtual machine. :slight_smile: Then you can be sure that you don’t mess up anything if things go down the drain.

“Deleting wptemplate.sql”: I’d suggest so too, yeah, at least if the replaced password is in there. :slight_smile: To be on the safe side (chances exist, even if very slim, that someone requests the file during the short timespan after it is copied and before it is deleted), you might want to create that file elsewhere. The skeleton directory contains the whole ~ for the new domain user, not only the public_html directory.

Thanks for another great point in the right direction, solved stage one of what I’m trying to do:

#!/bin/sh if [ "$VIRTUALSERVER_ACTION" = "CREATE_DOMAIN" ]; then sed 's/wprdom123/'$VIRTUALSERVER_DOM'/g' $VIRTUALSERVER_HOME/public_html/.htaccess1 > tmp_file mv tmp_file "$VIRTUALSERVER_HOME/public_html/.htaccess" rm $VIRTUALSERVER_HOME/public_html/.htaccess1 sed 's/wpruser123/'$VIRTUALSERVER_USER'/g' $VIRTUALSERVER_HOME/public_html/wp-config1.php > tmp_file mv tmp_file "$VIRTUALSERVER_HOME/public_html/wp-config2.php" sed 's/wprpass123/'$VIRTUALSERVER_PASS'/g' $VIRTUALSERVER_HOME/public_html/wp-config2.php > tmp_file mv tmp_file "$VIRTUALSERVER_HOME/public_html/wp-config.php" rm $VIRTUALSERVER_HOME/public_html/wp-config1.php rm $VIRTUALSERVER_HOME/public_html/wp-config2.php fi

Was quite straight forward of starting with different filenames than I’d end with, so renamed the .htaccess file in the skel folder to .htaccess1 and then deleting the ‘wrongly’ named files after the correctly named files are saved/created by sed.

On to importing the database now.


Got it working :slight_smile:

#!/bin/sh if [ "$VIRTUALSERVER_ACTION" = "CREATE_DOMAIN" ]; then sed 's/wprdom123/'$VIRTUALSERVER_DOM'/g' $VIRTUALSERVER_HOME/public_html/.htaccess1 > tmp_file mv tmp_file "$VIRTUALSERVER_HOME/public_html/.htaccess" rm $VIRTUALSERVER_HOME/public_html/.htaccess1 sed 's/wpruser123/'$VIRTUALSERVER_USER'/g' $VIRTUALSERVER_HOME/public_html/wp-config1.php > tmp_file mv tmp_file "$VIRTUALSERVER_HOME/public_html/wp-config2.php" sed 's/wprpass123/'$VIRTUALSERVER_PASS'/g' $VIRTUALSERVER_HOME/public_html/wp-config2.php > tmp_file mv tmp_file "$VIRTUALSERVER_HOME/public_html/wp-config.php" rm $VIRTUALSERVER_HOME/public_html/wp-config1.php rm $VIRTUALSERVER_HOME/public_html/wp-config2.php sed 's/'$VIRTUALSERVER_DOM'/g' $VIRTUALSERVER_HOME/public_html/wprb.sql > tmp_file mv tmp_file "$VIRTUALSERVER_HOME/public_html/wprb2.sql" mysql --user=$VIRTUALSERVER_USER --password=$VIRTUALSERVER_PASS --database=$VIRTUALSERVER_USER < $VIRTUALSERVER_HOME/public_html/wprb2.sql rm $VIRTUALSERVER_HOME/public_html/wprb.sql rm $VIRTUALSERVER_HOME/public_html/wprb2.sql fi

Thanks Locutus for the help, really appreciated.


Well played!

So, if there are updates to the WP extensions, you’ll just update the skel files?

What about the existing sites?

I’m interested in this, because I’ve been considering a similar approach for Joomla. In the absence of a true multi-site solution, maintenance can get messy.


I didn’t set out to be able to update sites running WordPress and the above process won’t work to update a site since it runs when a site is created, so to use this you’d have to delete the site first and that would loose your database (all your content would be deleted)!

That being said I have the same problem you have, updating multiple sites with exactly the same files is a pain manually!!! A shell script can be run when a server is updated, so I’m thinking about ways to automatically update my WordPress sites (have about 70 and 50+ more planned) by simply updating a VM server and having it copy the new files over the existing ones. No idea how you’d do that, but I’m sure it’s going to be possible and a lot faster than using FTP to upload WordPress 70+ times.

Right now I’m just glad the 50+ sites I have planned are going to take a few minutes each to get online with WordPress running and ready to add content rather than the usual hour or so to upload the files via FTP, add database settings to the config file, set all the plugins up etc…


What precisely does “updating WordPress” involve, in terms of changing files and database content?

In the GPL version, VirtualMin actually has no built-in “responsibility” for the contents of a server, after initial copy of the skeleton directory that is. So you can basically make a script as you wish to auto-update WP, if the necessary operations can be formulated as a script.

Virtualmin control, that takes care of updates to the core application for you, which means one less thing to write, and only the patching of the components or extensions used is necessary.

Found a slight issue with my setup I listed above.

To recap I’ve setup a Virtualmin template so all WordPress files and plugins etc… are installed when a new domain is created an a shell script is run that adds that virtualservers specific details (username etc…) to a few files so it works without having to edit any files manually.

The problem I have is the files that have variables replaced within them are eventually renamed to the filename I want them to be called:

So start with wp-config1.php, change some variables and save it as wp-config,php then delete wp-config1.php to clean up the folder. This is achieved using a shell script like the ones listed above.

The problem is the file wp-config,php has the wrong user and group, it’s set to root root.

Didn’t realise at first as everything works fine (other than editing those files as the user of that virtualserver).

Any way to force editing these files during virtualserver setup as the group/user that’s assigned to that virtualserver (I log in to Virtualmin as root) or change the settings after by using the shell script?