Wordpress backup and restore - 2026

Sunday, 12 April 2026
By Prasanna Kulkarni | Tags: wordpress, backup, restore, docker, cloudflare, ai-website-builder

Get the backup files, I used updraft plugin mysql and wordpress containers must be running wordpress-bbct: image: wordpress:latest container_name: wordpress-bbct networks: - cloudflare_app_net ports: ...

wordpress-bbct: image: wordpress:latest container_name: wordpress-bbct networks: - cloudflare_app_net ports: - "8089:80" restart: unless-stopped environment: WORDPRESS_DB_HOST: mysql-bbct:3306 WORDPRESS_DB_NAME: bbct_wp WORDPRESS_DB_USER: bbct_user WORDPRESS_DB_PASSWORD: bbct_pass WORDPRESS_TABLE_PREFIX: wp_cce4ht_ volumes: - wordpress_bbct_data:/var/www/html - ./clients/UpdraftPlus_bbct:/backup:ro - ./clients/restore_bbct_wp.sh:/restore.sh:ro depends_on: - mysql-bbct #!/bin/bash # ============================================================================ # UpdraftPlus Backup Restore Script for BBCT WordPress # Run INSIDE the wordpress-bbct container: # docker exec -it wordpress-bbct bash /restore.sh # # Prerequisites: Both mysql-bbct and wordpress-bbct containers must be running # and MySQL must have finished initialising (wait ~30s after first start). # ============================================================================ set -e BACKUP_DIR="/backup" WP_DIR="/var/www/html" WP_CONTENT="${WP_DIR}/wp-content" DB_HOST="mysql-bbct" DB_NAME="bbct_wp" DB_USER="bbct_user" DB_PASS="bbct_pass" echo "============================================" echo " BBCT WordPress UpdraftPlus Restore" echo "============================================" # --- 0. Install required tools --- echo "" echo "[0/5] Installing unzip and mysql-client..." apt-get update -qq && apt-get install -y -qq unzip default-mysql-client > /dev/null 2>&1 echo " Done." # --- 1. Restore Database --- echo "" echo "[1/5] Restoring database..." DB_FILE=$(ls ${BACKUP_DIR}/*-db.gz 2>/dev/null | head -1) if [ -z "$DB_FILE" ]; then echo " ERROR: No database backup (*-db.gz) found in ${BACKUP_DIR}" exit 1 fi echo " Extracting: $(basename $DB_FILE)" gunzip -c "$DB_FILE" | mysql --skip-ssl -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" echo " Database restored." # --- 2. Restore Plugins --- echo "" echo "[2/5] Restoring plugins..." # Use grep -v to ensure we ignore mu-plugins.zip PLUGINS_FILE=$(ls ${BACKUP_DIR}/*-plugins.zip 2>/dev/null | grep -v "mu-plugins" | head -1) if [ -n "$PLUGINS_FILE" ]; then echo " Extracting: $(basename $PLUGINS_FILE)" unzip -o -q "$PLUGINS_FILE" -d "${WP_CONTENT}/" echo " Plugins restored." else echo " SKIP: No plugins backup found." fi # --- 3. Restore MU-Plugins --- echo "" echo "[3a/5] Restoring mu-plugins..." MU_FILE=$(ls ${BACKUP_DIR}/*-mu-plugins.zip 2>/dev/null | head -1) if [ -n "$MU_FILE" ]; then mkdir -p "${WP_CONTENT}/mu-plugins" echo " Extracting: $(basename $MU_FILE)" # mu-plugins zip usually doesn't have a top level folder, or it's mu-plugins/ unzip -o -q "$MU_FILE" -d "${WP_CONTENT}/" echo " MU-plugins restored." else echo " SKIP: No mu-plugins backup found." fi # --- 3b. Restore Themes --- echo "" echo "[3b/5] Restoring themes..." THEMES_FILE=$(ls ${BACKUP_DIR}/*-themes.zip 2>/dev/null | head -1) if [ -n "$THEMES_FILE" ]; then echo " Extracting: $(basename $THEMES_FILE)" unzip -o -q "$THEMES_FILE" -d "${WP_CONTENT}/" echo " Themes restored." else echo " SKIP: No themes backup found." fi # --- 4. Restore Uploads (multiple split zips) --- echo "" echo "[4/5] Restoring uploads..." UPLOAD_FILES=$(ls ${BACKUP_DIR}/*-uploads*.zip 2>/dev/null) if [ -n "$UPLOAD_FILES" ]; then # mkdir -p "${WP_CONTENT}/uploads" # unzip will create it for UF in $UPLOAD_FILES; do echo " Extracting: $(basename $UF)" unzip -o -q "$UF" -d "${WP_CONTENT}/" done echo " Uploads restored ($(echo "$UPLOAD_FILES" | wc -l) archives)." else echo " SKIP: No uploads backup found." fi # --- 5. Restore Others --- echo "" echo "[5/5] Restoring others..." OTHERS_FILE=$(ls ${BACKUP_DIR}/*-others.zip 2>/dev/null | head -1) if [ -n "$OTHERS_FILE" ]; then echo " Extracting: $(basename $OTHERS_FILE)" unzip -o -q "$OTHERS_FILE" -d "${WP_CONTENT}/" echo " Others restored." else echo " SKIP: No others backup found." fi # --- 6. Fix ownership --- echo "" echo "Fixing file ownership..." chown -R www-data:www-data "${WP_CONTENT}" echo "Done." # --- 7. Update site URL in database to localhost:8088 --- echo "" echo "Detecting database table prefix..." OPTIONS_TABLE=$(mysql --skip-ssl -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" -N -e "SHOW TABLES LIKE '%options';" | grep -v "pys_options" | head -1) if [ -n "$OPTIONS_TABLE" ]; then echo "Updating status in $OPTIONS_TABLE to http://localhost:8088..." mysql --skip-ssl -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" -e " UPDATE $OPTIONS_TABLE SET option_value = 'http://localhost:8088' WHERE option_name IN ('siteurl', 'home'); " echo "Site URL updated in $OPTIONS_TABLE." else echo "ERROR: Could find options table. Manual URL update required." fi echo "" echo "============================================" echo " Restore complete!" echo " Visit: http://localhost:8088" echo "============================================"

  1. Get the backup files, I used updraft plugin
  2. mysql and wordpress containers must be running
  3. Restoring a managed WordPress site locally via UpdraftPlus into a Docker environment comes with several unexpected hurdles. First, beware of lingering managed hosting plugins like Object Cache Pro; without a configured Redis instance, you'll need to manually delete the object-cache.php drop-in and deactivate the plugin directly in the database. Don't expect standard command-line tools to save you, as the official WordPress Docker image lacks both WP-CLI and pdo_mysql, forcing you to rely on raw PHP with mysqli for ad-hoc database operations. Furthermore, Windows developers should avoid passing complex inline bash scripts to docker exec via PowerShell due to frustrating quoting limitations; writing local scripts and transferring them via docker cp is far more reliable. You'll also want to double-check your .htaccess file, as UpdraftPlus restores can sometimes leave out the standard mod_rewrite rules, breaking your pretty permalinks with 404 errors until manually replaced. Finally, if you're eventually taking the site live via a Cloudflare Tunnel, remember to update the siteurl and home database options, relying on the official Docker image's built-in X-Forwarded-Proto handling to seamlessly manage SSL detection.
  4. Below is the script to restore the backup files. Good luck!