Development Deployments – WP CLI FTW

One of the most repetitive tasks for developers is standing up a new development site, if your like me then you always are looking for ways to get consistent results and save time. Obviously one way is it make a “core” and zip it and always deploy from the zip. That works, but you then have to go through and find and replace a bunch of values in the db, update the plugins and if you’re doing all that from within the admin takes time, which could be better spent starting to theme the site or adding test content and building out some pages to see how everything is going to layout on the screen.

Solution: WP CLI and a little bit of bash scripting

So let’s get down to it.

Prerequisites: a subdomain, mysql databse/user/password set ( we use project numbers for a subdomain )

#!/bin/bash
#############################
# add your comments
# CHANGELOG
# track your changes
#############################
# prompt --
echo "To use this script the following should already be completed"
echo "subdomain, database, database user, database password"
echo ""
# prompt for the project number
echo "what project number do we need to deploy?"
read -r PROJNUM
echo ""
# prompt for the site name
echo "what is the site name for this deployment?"
echo "if you need spaces please enclose the value in \"name here\""
read -r SITENAME
# prompt for the db creds to use
echo "provide the db credentials to use for this deployment:"
read -p 'dbname: ' DBNAME
read -p 'dbuser: ' DBUSER
read -p 'dbpass: ' DBPASS
# prompt to verify the settings given
echo "please verify the following are correct, if not hit ctrl+c and start again"
echo "project number: $PROJNUM"
echo "site name: $SITENAME"
echo "dbname: $DBNAME"
echo "dbuser: $DBUSER"
echo "dbpass: $DBPASS"
echo ""
# todo:: add in prompt to continue
# change into the project root
echo "changing into the project root and proceeding with deployment"
echo ""
cd ~/public_html/$PROJNUM
# clean up the project root adjust for your environment
rm -rf index.html .htaccess
echo "downloading wp core"
echo ""
# adjust for your language
wp core download --locale=en_US
echo "creating wp-config with addtional settings"
echo ""
wp config create --dbname=$DBNAME --dbuser=$DBUSER --dbpass=$DBPASS --extra-php <<PHP
#define( 'FORCE_SSL_LOGIN', true ); // force ssl logins
#define( 'FORCE_SSL_ADMIN', true ); // force ssl for admin
#define( 'WP_SITEURL', 'www.domain.com' ); // we typically don't define this
#define( 'COOKIE_DOMAIN', '.domain.com' ); // often defined going into production
define( 'MEDIA_TRASH', true );
define( 'WPLANG', 'en_US' );
define( 'FS_CHMOD_DIR', (0755 & ~umask()) ); // update directory permissions
define( 'FS_CHMOD_FILE', (0644 & ~umask()) ); // update file permissions
define( 'IMAGE_EDIT_OVERWRITE', true ); // overwrite images
define( 'EMPTY_TRASH_DAYS', 7 ); // empty items in trash after 7 days
define( 'WP_POST_REVISIONS', 5 ); // set the max number of post revisions to 5
// developer debug
define( 'WP_DEBUG', false );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', true );
define( 'SCRIPT_DEBUG', true );
define( 'SAVEQUERIES', false );
// memory limits
define( 'WP_MEMORY_LIMIT', '64M' ); // adjust for your server
define( 'WP_MAX_MEMORY_LIMIT', '128M' ); // adjust for your server
// cache and compression and cron
define( 'WP_CACHE', false );
define( 'COMPRESS_CSS', true ); // compress css
define( 'COMPRESS_SCRIPTS', true ); // compress js
define( 'CONCATENATE_SCRIPTS', false ); // if your admin theme goes wonky this is prolly set true
define( 'ENFORCE_GZIP', true );
define( 'DISABLE_WP_CRON', true ); // ever have issues with scheduled posts, run cron yourself instead of when someone visits
define( 'WP_CRON_LOCK_TIMEOUT', 300 );
// update what do you consider safe
define( 'WP_AUTO_UPDATE_CORE', 'minor' ); // auto update wp core
define( 'DISALLOW_FILE_MODS', false ); // stop file modifications ( .htaccess etc )
define( 'DISALLOW_FILE_EDIT', true ); // from the gui don't allow file modifications
define( 'ALLOW_UNFILTERED_UPLOADS', false ); // set to true if encountering "Sorry, this file type is not permitted for security reasons."
PHP
echo "installing wordpress"
echo ""
# you will need to update the domain in the url, and the admin_user per your needs
wp core install --url=$PROJNUM.domain.com --title=$SITENAME --admin_user=jimjones --admin_password=SomeRandomPass --admin_email=email@domain.com
#
# probably one of the biggest time saving features for a development house with teams
# add/alter the following block per your needs
echo "creating groupname accounts"
echo ""
wp user create username user@emailaddress --user_pass=UserPass --role=rolename
#
# now for some of the other fun, where to go with this is up to you
echo "removing unwanted default content, plugins"
echo ""
wp comment delete 1 --force
wp post delete {1,2,3} --force
wp widget delete block-{2,3,4,5,6}
wp plugin deactivate hello
wp plugin delete akismet hello
# lots more you can do, watch for some supplemental posts and extend per your needs
echo "setting the blogname"
echo ""
wp option update blogname "$SITENAME"
wp option update blogdescription ""
wp option update show_on_front page
wp option update posts_per_page 12
wp option update posts_per_rss 12
echo "updating comment settings"
echo ""
wp option update {comment_previously_approved,comment_registration} 1
wp option update {default_comment_status,comments_notify,moderation_notify} 0
echo "fixing directory and file permissions"
echo ""
find . -type d -exec chmod 755 '{}' \; && find . -type f -exec chmod 644 '{}' \;
# you can cleanup/install themes, set the active theme, download/activate plugins
# watch for an upcoming post for some more commands to add here
echo "generate some content for blog posts with the following command:"
echo "curl http://loripsum.net/api/5 | wp post generate --post_content --count=15 --post_type=post"
echo ""

That should get you started, the above script should have saved a decent bit of time, our shop has 10 staff so creating 13 accounts (each dev gets one as administrator and one as editor) on each site in the admin takes a bit of time where the script does it in seconds, we also install/enable our standard plugin pack, install a custom theme from a git repo, cleanup the base themes we will never use, and import starting form templates, plugin settings and more. So a script that may take a few minutes to run, saves easily 15 minutes per site, at about 50 sites a year, that adds up to a nice time savings, and the consistency is most important.