Automated WordPress Install and Configure with WP-Cli
Saying "So Long" to the 5 Minute Install

By codeitadmin April 6, 2018 • Posted in: Automation, Linux, Windows Development, WordPress, WP-CLI, WSL

Something about the WordPress install and configure process just bugs me. I hate doing it. I know it’s only a few minutes, but the repetition is what bothers me. The setup process is virtually the same on every single install I do, so why am I still doing it manually?

Faster WordPress Hosting

The basic tasks that need to be completed every time are:

  1. Create the Database
  2. Download WP
  3. Extract
  4. Setup the config file
  5. Run the installer
  6. Fill out the forms, usually copy-pasted from other forms.
  7. Wait
  8. Log in
  9. Installing and activating the same plugins. Every. Goddamn. Time.
  10. Update everything

That 5 minute install is 10 tasks in between me and what I really want to do. Which is , of course, Write code.

Sure, most hosting control panels offer one-click installs, but I almost always prefer to develop locally and, generally, everything is a little bit faster via command line

Thankfully, with a simple shell script and the WordPress- cli tool, we can automate a lot of the WordPress install and configure process, and get that down to just 4 steps (and about 30 seconds for most installs on my workstation).

  1. Type command
  2. Enter the desired development URL
  3. Name the site
  4. Wait

This walk-through makes a couple of assumptions

  1. That you have installed bash and are comfortable with some light bash scripting – You should never run scripts you don’t understand. Thankfully, bash is pretty easy to learn
  2. That you have a local development server already running
  3. Ubuntu or similar – some steps will need to be modified slightly to work in other distributions

For windows users, I have walk throughs on setting up WSL with Ubuntu, and LAMP stack in WSL.

Part 1: Automating Vhost Creation

The first thing our script needs to do is create a VHOST,  along with setting up the document root, and necessary error logs.

First start by creating a file called wpsetup in your /usr/bin or ~/bin (if you have one) folder

 # This will create the script in your home/bin folder and open it nano. # If your home directly is symlinked to a windows folder correctly, you # can also substitute nano for the windows editor of your choice sudo touch ~/bin/wpsetup && sudo nano ~/bin/wpsetup 

Now add the following

#! /bin/bash

echo -n "Enter full domain name (e.g. example.com): "
read -e DN
echo -n "Enter a unique 'nice' name for the site (e.g. example): "
read -e SN
if [ -d /etc/apache2/sites-available/$SN ]        
    then echo "Error: site already configure using the name $SN"; 
    exit
fi

echo "Creating Apache Site Configuration File"
sudo echo "<VirtualHost *:80>
        ServerName $DN
        ServerAlias www.$DN
        DocumentRoot /var/www/html/$SN        LogLevel warn
        <Directory /var/www/html/$SN>
            Options Indexes FollowSymLinks MultiViews
            AllowOverride All
            Order allow,deny
            allow from all
        </Directory>
        ErrorLog  /var/log/apache2/$SN/error.log
        CustomLog /var/log/apache2/$SN/access.log combined
        #ServerAdmin youradmin@yourdomain
</VirtualHost>" | sudo tee /etc/apache2/sites-available/$SN.conf

echo "Creating Document Root"
sudo mkdir /var/www/html/$SN

echo "Creating Log File Directory"
sudo mkdir /var/log/apache2/$SN

echo "Enabling Site & Reloading Apache (edit /etc/apache2/sites-available/$SN for more options)"
sudo a2ensite $SN
sudo service apache2 restart

What exactly does this do? Let’s break it down a little bit.

#! /bin/bash

Tells the system to run it as a bash script, regardless of extension


echo -n "Enter full domain name (e.g. example.com): "
read -e DN
echo -n "Enter a machine name (e.g. example), this will be used to 
read -e SN

Creates two variables from command line input

DN – which will store our local domain name (ex: somesite.local)

SN -Which stores a safe name, or machine name. We will use this in places where it isn’t necessary print the prefix or TLD

if [ -d /etc/apache2/sites-available/$SN.conf ]        
    then echo "Error: site already configured using the name $SN"; 
    exit
fi

This checks to make sure a site configuration file doesn’t already exist with the same name

echo "Creating the Site Configuration File"
sudo echo "<VirtualHost *:80>
        ServerName $DN
        ServerAlias www.$DN
        DocumentRoot /var/www/html/$SN
	LogLevel warn
        <Directory /var/www/html/$SN>
            Options Indexes FollowSymLinks MultiViews
            AllowOverride All
            Order allow,deny
            allow from all
        </Directory>
        ErrorLog  /var/log/apache2/$SN/error.log
        CustomLog /var/log/apache2/$SN/access.log combined
        #ServerAdmin admin@$SN
</VirtualHost>" | sudo tee /etc/apache2/sites-available/$SN.conf

This section creates the actual Virtual Host and sets some basic options, including setting our document root to a folder named after our predefined machine name, and creates the server name and alias using our predefined server name, tells apache where to write log files ,and finally writes the wholeblock to a new config file within our sites-available directory.

We use

| sudo tee /etc/apache2/sites-available/$SN.conf

To elevate priveleges and write the file within the context of the script.

There are a lot of options, and nuances available in the VHost see the official Apache documentation for more information about what what else is possible.

Next, we setup directories

# Create the document root
echo "Creating Document Root"
sudo mkdir /var/www/html/$SN

# Create the log file directory
echo "Creating Log File Directory"
sudo mkdir /var/log/apache2/$SN

And finally, we enable the site using the a2ensite command, which creates a symlink from sites-available to sites-enabled, and restart apache


echo "Enabling Site & Reloading Apache (edit /etc/apache2/sites-available/$SN for more options)"
sudo a2ensite $SN
sudo service apache2 restart

If we were to run this script as is, it should give us everything we need to create a new dev site.

Part 2: Automating WordPress Install and Configure

Now that we have a place to serve the site from, we can incorporate wp-cli to help with the actual setup of the database and installation of wp and a few plugins.

Add the following to the end of your wpsetup file


# Switch to the document root
cd /var/www/html/$SN
wp core download
#wp config create --dbname=$SN --dbuser=root --dbpass=mysql

# check to see if MySQL is running, save status in a variable 'UP'
UP=$(service mysql status|grep 'mysql start/running' | wc -l);
if [$UP]; then
	wp config create --dbname=$SN --dbuser=root --dbpass=mysql
	wp db create
else
	sudo service mysql start
	wp config create --dbname=$SN --dbuser=root --dbpass=mysql
	wp db create
fi

wp core install --url=$DN --title=$SN --admin_user=${SN}_admin --admin_password=${SN}_admin --admin_email=me@{$DN)

# Examples of how to install and activate plugins from WordPress.org
wp plugin install contact-form-7 --activate=true
wp plugin install flamingo --activate=true
wp plugin install timber-library --activate=true


echo "Please add 127.0.0.1 $DN to your hosts file"
echo "$SN has been created"

Let’s break that down

# Switch to the document root
cd /var/www/html/$SN
wp core download

Tells bash to switch to your document root, and start downloading WordPress a

# check to see if MySQL is running, save status in a variable 'UP'
UP=$(service mysql status|grep 'mysql start/running' | wc -l);
if [$UP]; then
	wp config create --dbname=$SN --dbuser=root --dbpass=mysql
	wp db create
else
	sudo service mysql start
	wp config create --dbname=$SN --dbuser=root --dbpass=mysql
	wp db create
fi

This section creates a variable that checks and stores the current state of the MySQL service. If the service is running, we generate the wp config file using our safe name as the database name, and the root MySQL user and pass. We need to check the status first, because wp-cli will not create the file if the database is running and accessible

NOTE:Never use the root MySQL user in public facing production scripts. A compromised root user is a guaranteed shitty time for every user in your database.

wp core install --url=$DN --title=$SN --admin_user=${SN}_admin --admin_password=${SN}_admin --admin_email=me@{$DN)

# Examples of how to install and activate plugins from WordPress.org
wp plugin install contact-form-7 --activate=true
wp plugin install flamingo --activate=true
wp plugin install timber-library --activate=true


echo "Please add 127.0.0.1 $DN to your hosts file"
echo "$SN has been created"

Finally, when our database is done and our config file is successfully created, we can run the installer. This uses the domain and site name variables for the url and title and creates a default user and password based on the site name, in this case ‘{site_name}_admin’, where site_name is the SN variable set at the beginning of the script. The three “wp plugin” lines will install three common plugins¬† from wordpress.org, you can make substitutions or additions as required.

One last thing before you fire it up. Be sure to give execute permisions to ~/bin/wpsetup, like so:

sudo chmod +x ~/bin/wpsetup

and restart bash using:

sudo exec bash

And that’s it, you now have a simple bash script you can run from any directory and have a WordPress install up and running in seconds. You could expand this in a few ways and save even more time. For example you could wrap this up in a loop for batch installs, extend it to allow for theme installs and child theme creation, install premium plugins from a directory on your server, add a prompt to make plugin installation dynamic and loads more. I hope to explore some more of these options in later posts.

What tricks do you use to automate your WordPress Workflow? Let me know in the comments.

comments

add comment

Your comment will be revised by the site if needed.