Improving Kinsta’s deploy to staging using WP-CLI

Kinsta, a relatively new managed WordPress web host, has been consistently rolling out new features. While I’ve been impressed with their improvements, their production to staging deployment is a hassle to work with. Luckily this can be resolved with a custom WP-CLI script using WP-CLI over ssh.

Kinsta’s dashboard can get you started

Within Kinsta’s dashboard there is a button to generate a staging copy of your website, which is based on a snapshot of the current website.

While there is a button to push staging back to production, there is not a button to push from production to staging. The only workaround is to create a new production backup snapshot and restore that backup to staging. Using their restore method is painful as it regenerates the staging sftp access info.

Preserving SFTP info by utilizing WP-CLI

Once the staging site is created there is no need to recreate. The following script will take a fresh production database snapshot and will incrementally sync over files using Rclone. The following script assumes you added sftp credentials into Rclone for both production and staging sites.

deploy_kinsta_staging() {

  # Prep ssh info for production and staging sites
  remoteserver_production="-oStrictHostKeyChecking=no $username@$address -p $production_port"
  remoteserver_staging="-oStrictHostKeyChecking=no $username@$address -p $staging_port"

  # Sync production to staging
  rclone sync sftp-$website:$homedir/wp-content/ sftp-$website-staging:$homedir/wp-content/ --exclude .DS_Store --exclude *timthumb.txt --verbose=1

  # Fetch home directory
  homedir=`ssh $remoteserver_production "pwd"`

  # Make database backup on production
  ssh $remoteserver_production 'cd public/ && wp db export --skip-plugins --skip-themes --add-drop-table - > wp-content/mysql.sql && chmod 600 wp-content/mysql.sql'

  # Sync production to staging
  rclone sync sftp-$website:$homedir/public/wp-content/ sftp-$website-staging:$homedir/public/wp-content/ --exclude .DS_Store --exclude *timthumb.txt --verbose=1

  # Import database on staging
  ssh $remoteserver_staging 'cd public/ && wp db import wp-content/mysql.sql --skip-plugins --skip-themes'

  # Find and replace urls
  ssh $remoteserver_staging "cd public/ && wp search-replace //$domain //staging-$ --all-tables --skip-plugins --skip-themes"
  ssh $remoteserver_staging "cd public/ && wp search-replace //www.$domain //staging-$ --all-tables --skip-plugins --skip-themes"

  # Enable search privacy
  ssh $remoteserver_staging "cd public/ && wp option update blog_public 0 --skip-plugins --skip-themes"

  # Disable email on staging site
  ssh $remoteserver_staging 'cd public/ && wp plugin install log-emails disable-emails --skip-plugins --skip-themes && wp plugin activate log-emails disable-emails --skip-plugins --skip-themes'