Skip to content

Instantly share code, notes, and snippets.

@erikhansen
Last active November 11, 2022 23:31
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save erikhansen/26e59f8c8de749790d146bb48a7d6946 to your computer and use it in GitHub Desktop.
Save erikhansen/26e59f8c8de749790d146bb48a7d6946 to your computer and use it in GitHub Desktop.
Magento 2 script to push DB and `pub/media` changes from prod>stage
#!/bin/bash
# stop on errors
set -e
# turn on debugging if you're running into issues
#set -x
# Static variables
ENVIRONMENT=$1
RED='\033[0;31m'
NC='\033[0m' # No Color
#########################
# Overview
#########################
# Magento 2 script to push DB and pub/media changes from prod>stage
# This script lives on the prod SSH user and pushes the DB and `pub/media` files to stage.
# Before using this script you should:
# [] Update the "Variables" section below
# [] Ensure https://github.com/netz98/n98-magerun2 is installed on the server and is aliased to `mr`
# [] Either remove or update the "Anonymize emails" section
# [] Add the script on the prod SSH user and test it thoroughly
#########################
# Variables
#########################
SOURCE_DB_NAME=example_prod
SOURCE_DB_HOST="localhost"
SOURCE_MAGENTO_ROOT="/var/www/prod/current/"
SOURCE_URL='www.example.com'
TIMESTAMP=$(date +"%F_%H-%M-%S")
DESTINATION_SSH_USER=www-stage
DESTINATION_SSH_HOST='stage.example.com'
DESTINATION_MAGENTO_ROOT="/var/www/stage/current/"
DESTINATION_URL='staging.example.com'
#########################
# Validation checks
#########################
if [ ! -d "$SOURCE_MAGENTO_ROOT" ]; then
printf "${RED}The ${SOURCE_MAGENTO_ROOT} directory doesn't exist. Please confirm you've connected to the correct SSH user. ${NC}";
exit;
fi
if [ -z "$SSH_AUTH_SOCK" ]; then
printf "${RED}You need to connect with user agent forwarding. Disconnect this SSH session and then reconnect with the '-A' flag.${NC}";
exit;
fi
if [ -z "$STY" ]; then
printf "${RED}You need to run this script within a screen (just type 'screen') so that in case your current session disconnects, the sync process doesn't break${NC}";
exit;
fi
printf "${RED}################# IMPORTANT #################
Are you sure you want to update the ${ENVIRONMENT} DB and media directory with content from prod?
#############################################${NC}"
read -p "Type 'y' or 'n' " -n 1 -r
if [[ ! $REPLY =~ ^[Yy]$ ]]
then
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 # handle exits from shell or function but don't exit interactive shell
fi
#########################
# Sync commands
#########################
echo "## Backing up stage database"
# Create dump of DB in the "current" directory. This will naturally get cleaned up by Capistrano once this release is purged
ssh -C $DESTINATION_SSH_USER@$DESTINATION_SSH_HOST " mr --root-dir=${DESTINATION_MAGENTO_ROOT} db:dump --strip=@stripped backup_prior_to_sync_from_prod_${TIMESTAMP} "
echo "## Dumping production database"
mr --root-dir=$SOURCE_MAGENTO_ROOT db:dump --stdout --strip=@stripped | pv | gzip > ~/tmp/${SOURCE_DB_NAME}_$TIMESTAMP.sql.gz
echo "## Importing data"
scp ~/tmp/${SOURCE_DB_NAME}_$TIMESTAMP.sql.gz $DESTINATION_SSH_USER@$DESTINATION_SSH_HOST:~/tmp/${SOURCE_DB_NAME}_$TIMESTAMP.sql.gz
rm ~/tmp/${SOURCE_DB_NAME}_$TIMESTAMP.sql.gz
ssh -C $DESTINATION_SSH_USER@$DESTINATION_SSH_HOST "
${DESTINATION_MAGENTO_ROOT}/bin/magento maintenance:enable
${DESTINATION_MAGENTO_ROOT}/bin/magento cache:flush
mr --root-dir=${DESTINATION_MAGENTO_ROOT} db:import --compression=gzip ~/tmp/${SOURCE_DB_NAME}_${TIMESTAMP}.sql.gz
rm ~/tmp/${SOURCE_DB_NAME}_${TIMESTAMP}.sql.gz
"
echo "## Cleaning DB"
ssh -C $DESTINATION_SSH_USER@$DESTINATION_SSH_HOST -p $DESTINATION_SSH_PORT << EOSSH
cd ${DESTINATION_MAGENTO_ROOT}
mr db:query "UPDATE core_config_data SET value = REPLACE(value, 'www.$SOURCE_URL', '$DESTINATION_URL');"
mr db:query "UPDATE core_config_data SET value = REPLACE(value, '$SOURCE_URL', '$DESTINATION_URL');"
EOSSH
echo "## Import config settings"
ssh -C $DESTINATION_SSH_USER@$DESTINATION_SSH_HOST "mr --root-dir=${DESTINATION_MAGENTO_ROOT} app:config:import"
echo "## Enabling stage configuration settings"
# Alternatively you can configure these settings in the `app/etc/env.php` file on stage
ssh -C $DESTINATION_SSH_USER@$DESTINATION_SSH_HOST "
mr --root-dir=${DESTINATION_MAGENTO_ROOT} config:set google/analytics/active 0
mr --root-dir=${DESTINATION_MAGENTO_ROOT} config:set carriers/freeshipping/active 1
mr --root-dir=${DESTINATION_MAGENTO_ROOT} config:set payment/checkmo/active 1
"
#########################
# Anonymize emails - Either remove or generate content from https://gist.github.com/erikhansen/aa30947f2df263a95a054d51c5277692
# UPDATE: Use this instead: https://github.com/elgentos/masquerade
#########################
echo "## Anonymizing emails"
ssh -T -C $DESTINATION_SSH_USER@$DESTINATION_SSH_HOST -p $DESTINATION_SSH_PORT << EOSSH
set -x
cd ${DESTINATION_MAGENTO_ROOT}
mr db:query 'UPDATE quote SET customer_email = REPLACE(customer_email, SUBSTRING(customer_email, LOCATE("@", customer_email)), CONCAT("+", SUBSTRING(MD5(SUBSTRING(customer_email, LOCATE("@", customer_email))) FROM 1 FOR 6), "@example.com")) WHERE customer_email NOT LIKE "%@krakencommerce.com" AND customer_email NOT LIKE "%@universalmedicalinc.com";'
mr db:query 'UPDATE quote_address SET email = REPLACE(email, SUBSTRING(email, LOCATE("@", email)), CONCAT("+", SUBSTRING(MD5(SUBSTRING(email, LOCATE("@", email))) FROM 1 FOR 6), "@example.com")) WHERE email NOT LIKE "%@krakencommerce.com" AND email NOT LIKE "%@universalmedicalinc.com";'
mr db:query 'UPDATE sales_creditmemo_grid SET customer_email = REPLACE(customer_email, SUBSTRING(customer_email, LOCATE("@", customer_email)), CONCAT("+", SUBSTRING(MD5(SUBSTRING(customer_email, LOCATE("@", customer_email))) FROM 1 FOR 6), "@example.com")) WHERE customer_email NOT LIKE "%@krakencommerce.com" AND customer_email NOT LIKE "%@universalmedicalinc.com";'
mr db:query 'UPDATE sales_invoice_grid SET customer_email = REPLACE(customer_email, SUBSTRING(customer_email, LOCATE("@", customer_email)), CONCAT("+", SUBSTRING(MD5(SUBSTRING(customer_email, LOCATE("@", customer_email))) FROM 1 FOR 6), "@example.com")) WHERE customer_email NOT LIKE "%@krakencommerce.com" AND customer_email NOT LIKE "%@universalmedicalinc.com";'
mr db:query 'UPDATE sales_order SET customer_email = REPLACE(customer_email, SUBSTRING(customer_email, LOCATE("@", customer_email)), CONCAT("+", SUBSTRING(MD5(SUBSTRING(customer_email, LOCATE("@", customer_email))) FROM 1 FOR 6), "@example.com")) WHERE customer_email NOT LIKE "%@krakencommerce.com" AND customer_email NOT LIKE "%@universalmedicalinc.com";'
mr db:query 'UPDATE sales_order_address SET email = REPLACE(email, SUBSTRING(email, LOCATE("@", email)), CONCAT("+", SUBSTRING(MD5(SUBSTRING(email, LOCATE("@", email))) FROM 1 FOR 6), "@example.com")) WHERE email NOT LIKE "%@krakencommerce.com" AND email NOT LIKE "%@universalmedicalinc.com";'
mr db:query 'UPDATE sales_order_grid SET customer_email = REPLACE(customer_email, SUBSTRING(customer_email, LOCATE("@", customer_email)), CONCAT("+", SUBSTRING(MD5(SUBSTRING(customer_email, LOCATE("@", customer_email))) FROM 1 FOR 6), "@example.com")) WHERE customer_email NOT LIKE "%@krakencommerce.com" AND customer_email NOT LIKE "%@universalmedicalinc.com";'
mr db:query 'UPDATE sales_shipment_grid SET customer_email = REPLACE(customer_email, SUBSTRING(customer_email, LOCATE("@", customer_email)), CONCAT("+", SUBSTRING(MD5(SUBSTRING(customer_email, LOCATE("@", customer_email))) FROM 1 FOR 6), "@example.com")) WHERE customer_email NOT LIKE "%@krakencommerce.com" AND customer_email NOT LIKE "%@universalmedicalinc.com";'
EOSSH
echo "## Running upgrade scripts and re-indexing"
ssh -C $DESTINATION_SSH_USER@$DESTINATION_SSH_HOST "
${DESTINATION_MAGENTO_ROOT}bin/magento -q setup:upgrade --keep-generated
${DESTINATION_MAGENTO_ROOT}bin/magento -q indexer:reindex
${DESTINATION_MAGENTO_ROOT}/bin/magento maintenance:disable
${DESTINATION_MAGENTO_ROOT}bin/magento -q cache:flush
"
echo "## Syncing Media"
rsync -avz --exclude=import --exclude=catalog/product/cache $SOURCE_MAGENTO_ROOT"pub/media/" $DESTINATION_SSH_USER@$DESTINATION_SSH_HOST:$DESTINATION_MAGENTO_ROOT"pub/media/"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment