BBC's guide to development
  • General

    • About
    • Tools
    • Git(hub)
    • Showpad
    • Hosting
    • Maintenance
    • Security
    • Go live checklist
  • Front-end development

    • Bundlers
    • CSS/SCSS
    • Javascript
    • Vue
    • PHP
    • Mails
    • Dev Faq
  • Functions
  • Mixins
  • General

    • OOP Structure
  • Component Classes

    • Accordion
    • App
    • Component
    • HighwayApp
    • Popup
    • PNG Sequencer
    • Tab
  • Manager Classes

    • BountListenerMgr
    • Cache
    • Configuration
    • InViewStateMgr
    • Instance Manager
    • Event dispatcher
  • Factories

    • SwiperFactory
  • PDF

    • AssetLoader
    • BasePdfDoc
    • TemplatePdfDoc
    • CustomPdfDoc
  • Utility functions

    • canvas
    • Connection Status
    • css
    • dev
    • placeholder
    • dom
    • fetch
    • json
    • object
    • scroll
    • scrollbar
    • spreadsheets
    • string
    • url
  • General

    • ComponentMgr
    • ThreeJsViewer
  • Components

    • ComponentMgr
    • GltfModel
    • Snappable
    • Socket
    • ThreeJsViewer
    • ThreeJsViewerCamera
  • Loaders

    • ConfigurationSerializer
    • GltfBlockParser
  • Utils

    • CanvasInputAdapter
    • CollisionManager
    • SocketGridExpander
    • blender
    • headless
  • General

    • Troubleshooting
    • Legacy
  • Components

    • AssetBar
    • ConfigGenerator
    • ShowpadApp
  • Managers

    • Assets
    • AppsDb
    • Config
  • Utils

    • Connection Status
    • general
    • showpad-interactive
    • showpad-upload
  • Components

    • Accordion
    • BackButton
    • Breadcrumb
    • ByltButton
    • Hamburger
    • Icon
    • Logo
    • Loader
    • Modal
    • Popup
    • Prompt
    • ProgressBar
    • TextLoader
  • Composables

    • useDebugMode
    • useConnectionStatus
  • Utils

    • dom
    • props
  • General

    • General
    • Tracking
  • Components

    • Accordion
    • ActionButton
    • AssetItem
    • AssetList
    • BackButton
    • ConfigGenButton
    • Logo
    • Media
    • Modal
    • Popup
    • Prompt
    • SPButton
    • SPRouterView
    • SPTrackedRouterLink
    • TextLoader
    • View
  • Composables

    • useConnectionStatus
  • Stores

    • useAppsDbStore
    • useBreadcrumbStore
    • useShowpadAPIStore
    • useShowpadSDKStore
    • useSpConfigStore
    • useSpStore
    • useSpTrackingStore
  • The New Kit

    • General
    • Installation & Usage
    • ACF Blocks
    • PHPCS
    • Functions
    • Vite
    • WP Config
    • Staging Deployment
  • Best Practices

    • Page Structure
    • Fonts/Typography
  • Todo
GitHub
  • General

    • About
    • Tools
    • Git(hub)
    • Showpad
    • Hosting
    • Maintenance
    • Security
    • Go live checklist
  • Front-end development

    • Bundlers
    • CSS/SCSS
    • Javascript
    • Vue
    • PHP
    • Mails
    • Dev Faq
  • Functions
  • Mixins
  • General

    • OOP Structure
  • Component Classes

    • Accordion
    • App
    • Component
    • HighwayApp
    • Popup
    • PNG Sequencer
    • Tab
  • Manager Classes

    • BountListenerMgr
    • Cache
    • Configuration
    • InViewStateMgr
    • Instance Manager
    • Event dispatcher
  • Factories

    • SwiperFactory
  • PDF

    • AssetLoader
    • BasePdfDoc
    • TemplatePdfDoc
    • CustomPdfDoc
  • Utility functions

    • canvas
    • Connection Status
    • css
    • dev
    • placeholder
    • dom
    • fetch
    • json
    • object
    • scroll
    • scrollbar
    • spreadsheets
    • string
    • url
  • General

    • ComponentMgr
    • ThreeJsViewer
  • Components

    • ComponentMgr
    • GltfModel
    • Snappable
    • Socket
    • ThreeJsViewer
    • ThreeJsViewerCamera
  • Loaders

    • ConfigurationSerializer
    • GltfBlockParser
  • Utils

    • CanvasInputAdapter
    • CollisionManager
    • SocketGridExpander
    • blender
    • headless
  • General

    • Troubleshooting
    • Legacy
  • Components

    • AssetBar
    • ConfigGenerator
    • ShowpadApp
  • Managers

    • Assets
    • AppsDb
    • Config
  • Utils

    • Connection Status
    • general
    • showpad-interactive
    • showpad-upload
  • Components

    • Accordion
    • BackButton
    • Breadcrumb
    • ByltButton
    • Hamburger
    • Icon
    • Logo
    • Loader
    • Modal
    • Popup
    • Prompt
    • ProgressBar
    • TextLoader
  • Composables

    • useDebugMode
    • useConnectionStatus
  • Utils

    • dom
    • props
  • General

    • General
    • Tracking
  • Components

    • Accordion
    • ActionButton
    • AssetItem
    • AssetList
    • BackButton
    • ConfigGenButton
    • Logo
    • Media
    • Modal
    • Popup
    • Prompt
    • SPButton
    • SPRouterView
    • SPTrackedRouterLink
    • TextLoader
    • View
  • Composables

    • useConnectionStatus
  • Stores

    • useAppsDbStore
    • useBreadcrumbStore
    • useShowpadAPIStore
    • useShowpadSDKStore
    • useSpConfigStore
    • useSpStore
    • useSpTrackingStore
  • The New Kit

    • General
    • Installation & Usage
    • ACF Blocks
    • PHPCS
    • Functions
    • Vite
    • WP Config
    • Staging Deployment
  • Best Practices

    • Page Structure
    • Fonts/Typography
  • Todo
GitHub
  • Staging Deployment Script

Staging Deployment Script

This CLI deploys your local WordPress site or theme to a remote staging server over SSH using rsync, with optional database push via WP-CLI. It’s configurable, safe by default (dry runs, excludes), and interactive when needed.

SSH First Time Setup


What It Does

  • Files: Deploys either the entire WordPress site or one theme directory
  • DB: Optionally exports local DB, uploads to remote, imports, and does URL search-replace
  • Config: Reads defaults from deploy.config.json, allows CLI overrides
  • Safety: Dry-run, verbose logs, optional --delete to mirror exact state
  • Smart: Auto-detects your theme name (if only one non-twenty* theme exists)
  • Interactive: Guided setup when staging not configured (e.g., BBCDEV or custom SSH target)
  • Build step: Asks if you want to run npm run build in your theme before pushing

Requirements

  • Local & Remote: ssh, rsync
  • WP-CLI: Needed for DB pushes (both local and remote)
  • Auth: SSH key-based access to the remote server

Preconfigured NPM scripts (package.json)

{
    "scripts": {
        "deploy": "node ./scripts/deploy.js",
        "deploy:theme": "node ./scripts/deploy.js --theme-only",
        "deploy:full": "node ./scripts/deploy.js --full --push-db --include-uploads",
        "deploy:db-only": "node ./scripts/deploy.js --db-only"
    }
}

What Each Script Does

  • npm run deploy
    Full site files only (no DB).

    • Mode: Full (because no --theme-only)
    • Uploads: excluded (default)
    • DB: not pushed
    • Use when: you want to sync code/config/theme/plugin changes without touching media or DB.
  • npm run deploy:theme
    Push only the active theme folder.

    • Mode: Theme-only (--theme-only)
    • Targets: wp-content/themes/<theme>/
    • Use when: you changed only theme code (safe, fast, minimal).
  • npm run deploy:full
    Push entire site + database, and include uploads.

    • Mode: Full (--full)
    • Uploads: included (--include-uploads)
    • DB: pushed (--push-db) with optional search-replace (if localUrl/stagingUrl set)
    • Use when: you’re syncing a full snapshot (code + media + DB) to staging.
  • npm run deploy:db-only
    Only push the database.

    • Mode: DB-only (--db-only)
    • Files: untouched
    • Use when: content or settings changed locally and you want them on staging, but files are already up to date.

Configuration

  • Defaults (can be overridden by deploy.config.json or flags):

    • localPath: local WP root (www)
    • remotePath: server WP root (/var/www/html)
    • host, user, port: SSH target
    • themeName: null (auto-detect if possible)
    • delete: false (rsync --delete disabled by default)
    • excludeUploads: true (skip uploads/cache on full deploys)
    • wpCli: wp
    • localUrl, stagingUrl: used for DB search-replace
    • wpEnvLocal: local, wpEnvRemote: staging
  • Interactive target setup (when stagingUrl missing):

    • Choose BBCDEV or Custom
    • Automatically fills remotePath/stagingUrl for BBCDEV subsites
    • Writes your choices back to deploy.config.json

Modes

  • Full site: --full (default if --theme-only not passed)
  • Theme only: --theme-only (syncs only wp-content/themes/<theme>)
  • DB only: --db-only (no file sync; just push DB)
  • DB push after files: add --push-db to full/theme

Safety & Logging

  • --dry-run: print commands and rsync plan without changing anything
  • --verbose / -v: more detailed output
  • Preflight checks: verifies ssh, rsync (and wp if needed), confirms paths exist
  • SSH probe: quick connection test before running

File Deployment (rsync)

Full Site (--full)

  • Flags: archive+compress, partial, progress, protect-args
  • Excludes (by default): .git, node_modules, logs, temporary folders, theme vendor/, src/, tooling files, etc.
  • Uploads: skipped unless you pass --include-uploads
  • Delete: opt-in with --delete to mirror exact state
  • Remote path: ensures directory exists before rsync

Theme Only (--theme-only)

  • Syncs only wp-content/themes/<theme>/
  • Ensures remote theme directory exists before rsync

Database Push (Local → Staging)

Triggered by --push-db (after files) or --db-only.

Flow:

  1. Export local DB to www/_db/local-YYYYMMDD-HHMMSS.sql (adds DROP TABLE)
  2. Rsync dump → remote _db/ directory (creates it if needed)
  3. Remote import via wp db import
  4. URL search-replace (skips GUIDs) if both localUrl and stagingUrl are set
    • Disable with --no-search-replace
  5. Cleanup: removes remote dump after import

Env vars: sets WP_ENV=local for local WP-CLI, WP_ENV=staging for remote (configurable)


Default File Excludes

The deploy script skips certain files and folders by default to:

  • Avoid sending unnecessary or local-only files
  • Prevent overwriting sensitive server files (like media or configs)

Always Excluded

  • macOS/OS junk: .DS_Store
  • Version control: .git/
  • Local dependencies: node_modules/
  • Temp folders: _temp/
  • Logs: *.log
  • Local build/config files:
    package.json, package-lock.json, composer.json, composer.lock
  • Theme vendor dirs: wp-content/themes/*/vendor/
  • Local tooling files: vite.config.js, .phpcs.xml.dist, .postcssrc
  • Source folders: /src/ (unbuilt assets)

Uploads & Cache

If excludeUploads is true (default), also skips:

  • wp-content/uploads/ (media library)
  • wp-content/cache/
  • wp-content/upgrade/

This prevents large media syncs or accidental overwrites of staging uploads.

Tip

  • To include uploads on a full deploy, use the --include-uploads flag
    (e.g., npm run deploy:full already does this).
  • You can modify this exclude list in the script to match your project’s needs.

Prompts & Convenience

  • Build theme? Optional npm run build inside your theme prior to deploy
  • Deploy summary: Prints a clear run-down (mode, paths, delete/exclude flags, DB options) and asks to confirm before executing

Useful CLI Flags

  • Scope: --full, --theme-only, --db-only, --push-db
  • Safety: --dry-run, --verbose, --delete, --no-search-replace
  • Paths/Target: --host, --user, --port, --path (remote), --local (local root)
  • Theme: --theme <name>
  • DB/URLs: --wp-cli <cmd>, --local-url <url>, --staging-url <url>

(Any of these override config file values for the current run.)


Examples

  • Full deploy (files only):
    ./deploy.js --full

  • Theme only:
    ./deploy.js --theme-only

  • Full deploy + DB:
    ./deploy.js --full --push-db

  • DB only:
    ./deploy.js --db-only

  • Dry run + verbose:
    ./deploy.js --full --dry-run --verbose

  • Custom target just for this run:
    ./deploy.js --full --host ssh.example.com --user deploy --path /var/www/html --port 2222


Tips

  • Keep uploads excluded on full pushes unless you really intend to overwrite remote media
  • Use --delete only when you want the remote to exactly match local (dangerous on shared targets)
  • Set localUrl/stagingUrl in deploy.config.json to automate post-import URL rewrites
  • For repeated targets, let the interactive setup write persistent values to deploy.config.json

Edit this page
Last Updated: 4/27/26, 12:56 PM
Contributors: Nicolas Jaenen