-
Notifications
You must be signed in to change notification settings - Fork 0
Environment Sync and Rollback
How to move content and FSE templates safely between WordPress environments — and recover when something goes wrong.
StrataWP includes built-in tooling (powered by the @stratawp/sync package) for three related jobs:
| Task | What it moves | Direction | Key commands |
|---|---|---|---|
| FSE template sync | Site Editor templates stored in the database | local ↔ remote |
sync:templates, sync:templates:list
|
| Database sync | MySQL tables (posts, options, etc.) | pull or push |
sync:db:pull, sync:db:push
|
| Rollback / snapshots | Theme files + database dumps | restore from history |
rollback:list, rollback:diff, rollback:mark-stable
|
Warning Database and template sync overwrite data in the destination environment. A pull replaces local data; a push replaces remote (often production) data. Always run with
--dry-runfirst, and never push to production without a recent snapshot. See Deployment for the deploy flow that creates snapshots automatically.
- A StrataWP theme created with Installation & Quick Start.
- The
stratawpCLI available (provided by@stratawp/cli). Verify withstratawp --version. - A
.stratawp-sync.jsonconfig file in your project root defining your environments (see Configuration below). - For most production databases (which only accept connections from
127.0.0.1), SSH access to the remote server with WP-CLI installed there.
All sync commands read environments from .stratawp-sync.json in your project root. Create it once.
Most production databases only allow connections from localhost (127.0.0.1), so direct MySQL access fails. SSH-based sync runs the dump/restore on the remote server over an SSH tunnel.
{
"environments": {
"local": {
"name": "local",
"url": "http://local.test",
"database": {
"host": "localhost",
"port": 3306,
"user": "root",
"password": "",
"database": "wordpress"
}
},
"production": {
"name": "production",
"url": "https://example.com",
"ssh": {
"host": "ssh.example.com",
"port": 22,
"user": "deploy",
"key": "~/.ssh/id_rsa"
},
"wpPath": "/var/www/html",
"database": {
"host": "127.0.0.1",
"user": "prod_user",
"password": "prod_pass",
"database": "wp_production"
}
}
}
}SSH options:
| Option | Description |
|---|---|
ssh.host |
SSH server hostname |
ssh.port |
SSH port (default: 22) |
ssh.user |
SSH username |
ssh.key |
Path to private key (supports ~ expansion) |
ssh.passphrase |
Passphrase for encrypted keys (optional) |
wpPath |
WordPress installation path on the remote server |
wpCliPath |
Custom WP-CLI path (optional, defaults to wp) |
Tip For encrypted SSH keys, prefer the
STRATAWP_SSH_PASSPHRASEenvironment variable (ideal for CI/CD) over puttingpassphrasein the config file. If neither is set, you'll be prompted.
For databases that allow public/remote connections (typically development or staging servers), you can skip SSH:
{
"environments": {
"staging": {
"name": "staging",
"url": "https://staging.example.com",
"database": {
"host": "db.staging.example.com",
"user": "staging_user",
"password": "staging_pass",
"database": "wp_staging"
}
}
}
}Full Site Editing templates edited in the Site Editor are stored in the database, not as theme files. This means a Git deploy of your theme does not carry over Site Editor changes. Use sync:templates to move those database-stored templates between environments via WP-CLI over SSH.
Before changing anything, see what exists on each side:
stratawp sync:templates:list productionThis lists the FSE templates in your local database alongside those on production, so you can see what would change.
stratawp sync:templates production --all --dry-runTip
--dry-runshows exactly what would be synced without writing anything. Make it a habit before every real sync.
Sync everything:
stratawp sync:templates production --allOr sync a single template by slug:
stratawp sync:templates production --template=homeIf WP-CLI isn't at the default wp path, or your local WordPress root needs to be specified explicitly, override them per command:
stratawp sync:templates production --wp-cli=/path/wp # Path to local WP-CLI binary
stratawp sync:templates production --wp-path=/wp/root # Local WordPress root pathBoth flags are also accepted by sync:templates:list.
If this fails: confirm WP-CLI is installed on the remote host (stratawp sync:templates:list production exercises the same SSH + WP-CLI path) and that wpPath in your config points at the WordPress install. Add --verbose to sync:templates for detailed output.
Move full MySQL data (posts, options, metadata, and more) between environments. URLs are automatically rewritten so the destination site works at its own domain.
Warning A database sync replaces the destination database.
sync:db:pull productionoverwrites your local data with production's.sync:db:pushoverwrites the remote database — for production this is destructive and irreversible without a snapshot. Always run--dry-runfirst, and ensure a snapshot exists before pushing (see Rollback & snapshots).
This is the common, low-risk direction: bring production content down to your machine.
Step 1 — Preview:
stratawp sync:db:pull production --dry-runStep 2 — Pull:
stratawp sync:db:pull productionWarning Pushing overwrites the target environment's database. Double-check the environment name. Only push to
stagingunless you fully intend to replace production content.
stratawp sync:db:push staging| Option | Effect | Applies to |
|---|---|---|
--tables=wp_posts,wp_postmeta |
Sync only the listed tables (comma-separated) | pull, push |
--no-url-replace |
Skip automatic URL replacement | pull, push |
--dry-run |
Preview without making changes | pull, push |
--force |
Skip the confirmation prompt | push only |
Examples:
stratawp sync:db:pull production --tables=wp_posts,wp_postmeta
stratawp sync:db:pull production --no-url-replaceWordPress stores serialized PHP arrays in the database, where each string is prefixed with its byte length (e.g. s:24:"..."). A naive find-and-replace of a URL changes the string length and corrupts serialization. StrataWP's UrlReplacer recalculates those lengths automatically:
Before: s:24:"https://old-domain.com/path"
After: s:27:"http://new-domain.test/path"
Use --no-url-replace only when you explicitly want the raw data preserved (for example, syncing into an identical domain).
A snapshot captures your theme files plus a database dump at a point in time. StrataWP creates one automatically before every deployment (unless you pass --no-backup), along with the current Git commit hash and branch. You can list, compare, and protect snapshots from the CLI.
Note Snapshots are stored in
.stratawp-snapshots/in your project root. Each snapshot directory contains amanifest.json, a compressedtheme.tar.gz, and a compresseddatabase.sql.gz. Thesnapshots.jsonfile indexes them all.
stratawp rollback:listFilter or expand the output:
stratawp rollback:list --environment=production # Only production snapshots
stratawp rollback:list --limit=20 # Show more entries (default: 10)See what changed between two points in time — added/deleted/modified files and SQL table differences:
stratawp rollback:diff 1 2 # By index (from rollback:list)
stratawp rollback:diff snapshot-id-1 snapshot-id-2 # By snapshot IDMark a known-good snapshot as stable so it isn't removed by automatic backup cleanup:
stratawp rollback:mark-stable 1Tip After a successful, verified deployment, mark that snapshot stable. It becomes a reliable recovery point even after many later deploys.
- Run
stratawp rollback:listto find the snapshot you want to return to (note its index or ID). - Run
stratawp rollback:diff <good> <current>to confirm what changed. - Mark your last-known-good snapshot stable with
stratawp rollback:mark-stable <index>so it survives cleanup. - Restore using your deploy workflow — see Deployment for redeploying a previous theme state, and use
sync:db:pull/sync:db:pushto restore database content as needed.
Note Snapshots integrate with
stratawp deploy: a pre-deploy snapshot is created on every deployment unless you pass--no-backup. For the full deployment lifecycle, see Deployment.
Before any sync that touches a shared or production environment:
-
.stratawp-sync.jsondefines the correct environment and URL. - You ran the command once with
--dry-runand reviewed the output. - A recent snapshot exists (run
stratawp rollback:listto confirm). - You're pulling, not pushing — unless you genuinely intend to overwrite the remote.
- URL replacement is enabled (omit
--no-url-replace) when moving between different domains.
- Deployment — push theme files to production with automatic pre-deploy snapshots.
- CLI Reference — full command and flag reference.
-
Architecture & Packages — how
@stratawp/syncfits into the framework. - Testing & Quality — verify changes before you deploy or sync.
For the canonical package docs, see packages/sync/README.md and the advanced deployment guide.
StrataWP v2.0.0 · GPL-3.0-or-later · Built by Jon Imms Repository · README
Start here
Building themes
Shipping
Extending & contributing
Help