Skip to content

Deployment

Jon Imms edited this page Jun 25, 2026 · 1 revision

Deployment

Ship a StrataWP theme from local development to production with one command — SFTP, FTP, or SSH — plus automatic backups, cache flushing, and post-deploy validation.

StrataWP ships a built-in deployment system driven by the stratawp CLI. You configure an environment once, then deploy with a single command. SSH deployments add a full post-deploy automation pass (cache flush, OPcache reset, backup cleanup, validation) while still connected to the server.

This page is the practical, step-by-step guide. For deeper scenarios — passphrase-protected SSH keys, FSE database template sync, and plugin deploys — deep-link to the two canonical guides:

Related wiki pages: Environment Sync & Rollback, CLI Reference, Testing & Quality.


Prerequisites

Before deploying, make sure you have:

  • A working StrataWP theme that builds cleanly (pnpm build succeeds). See Installation & Quick Start.
  • Connection details for your target server: host, port, username, and either a password or an SSH private key.
  • The remote theme path (for example, /public_html/wp-content/themes/my-theme or /var/www/html/wp-content/themes/my-theme).
  • For SSH post-deploy automation and FSE template sync: WP-CLI installed on the remote server.

Tip: Run all stratawp deployment commands from inside your theme directory. The examples below use pnpm stratawp ..., which runs the project-local CLI.


Deployment types at a glance

Type Best for Notes
SFTP Shared hosting (cPanel, Plesk) Secure, encrypted file transfer. Recommended for shared hosts. Typically port 22.
FTP Legacy / basic hosts Widely supported but unencrypted. Use SFTP when possible. Typically port 21.
SSH/rsync VPS and cloud servers rsync-accelerated. Unlocks post-deploy automation: cache flush, OPcache reset, backup cleanup, validation, and FSE template sync.
Git Managed WordPress hosting Not yet available — shown in the setup wizard but disabled, and listed as "coming soon" in the deployment guide.

Tip: If your server has SSH access, choose SSH — it is the only type that runs the full post-deploy automation pass.


Pre-flight checklist

Run through this before your first production deploy:

  • pnpm build completes without errors.
  • You have host, port, username, and password or SSH key for the target.
  • You know the exact remote theme path.
  • Credentials are stored in a .env file referenced with ${VAR_NAME} syntax (see Keep credentials out of version control).
  • .env is listed in .gitignore.
  • You ran pnpm stratawp deploy:test production and the connection succeeds.
  • You ran pnpm stratawp deploy production --dry-run and reviewed the file list.
  • Backups are enabled (the default) so a rollback snapshot is created before changes.

Step 1 — Configure an environment

Run the interactive setup wizard from your theme directory:

cd /path/to/your-theme
pnpm stratawp deploy:setup

The wizard walks you through:

  1. Choosing an environment name (production, staging, etc.).
  2. Selecting the deployment type. SFTP, FTP, and SSH/rsync are available today; Git is listed but disabled (planned for a later phase).
  3. Entering connection details (host, port, username, password).
  4. Configuring build and database migration settings.

Example SFTP answers (shared hosting):

Environment: production
Type: SFTP
Host: ftp.example.com
Port: 22
Username: your-username
Remote Path: /public_html/wp-content/themes/my-theme

Example SSH answers (VPS/cloud):

Environment: production
Type: SSH
Host: ssh.example.com
Port: 22
Username: your-username
Private Key: ~/.ssh/id_rsa
Remote Path: /var/www/html/wp-content/themes/my-theme

Where configuration lives

File Scope
~/.stratawp/deploy-config.json Global — all environments, shareable across projects.
.stratawp-deploy.json Project-specific — overrides the global config for this theme.

A minimal SSH config with post-deploy automation enabled looks like this:

{
  "version": "1.0",
  "environments": {
    "production": {
      "type": "ssh",
      "host": "ssh.example.com",
      "port": 22,
      "username": "deploy",
      "privateKey": "~/.ssh/id_rsa",
      "passphrase": "${STRATAWP_SSH_PASSPHRASE}",
      "remotePath": "/var/www/html/wp-content/themes/my-theme",
      "buildBefore": true,
      "backup": {
        "enabled": true,
        "keepLast": 1
      },
      "postDeploy": {
        "clearCache": true,
        "resetOpcache": true,
        "wpCliCommands": []
      },
      "database": {
        "enabled": true,
        "localUrl": "http://localhost:8888",
        "remoteUrl": "https://example.com"
      }
    }
  }
}

Note: For passphrase-protected SSH keys and the ssh-agent alternative, see SSH Deployment with Passphrase-Protected Keys in the advanced guide.


Step 2 — Test the connection

Verify your credentials before deploying anything:

pnpm stratawp deploy:test production

To list every environment you have configured:

pnpm stratawp deploy:list

If this fails:

  • Verify host, port, and credentials.
  • Confirm SFTP/SSH is enabled on your server (port 21 for FTP, 22 for SFTP/SSH).
  • For SSH, test manually: ssh -p 22 -i ~/.ssh/id_rsa username@ssh.example.com "echo Connected".
  • Contact your hosting provider if issues persist.

Step 3 — Preview with a dry run

Always preview before the first real deploy. A dry run shows exactly which files would be uploaded without changing the server:

pnpm stratawp deploy production --dry-run

Review the file list. If you see files you did not expect (or expected files missing), adjust your .deployignore — see What gets deployed.


Step 4 — Deploy

When the dry run looks right, deploy for real:

pnpm stratawp deploy production

StrataWP will:

  • Build your theme automatically (when buildBefore is enabled).
  • Upload only the necessary files (see Change detection).
  • Create a backup on the remote server.
  • Flush WordPress cache and OPcache (SSH deployments).
  • Clean up old backups automatically.
  • Validate the deployment (file checks, WP health, HTTP health — SSH deployments).
  • Print a detailed deployment summary.

Useful deploy flags

Flag Effect
--dry-run Preview the changes without uploading.
--force Skip the confirmation prompt.
--fresh Upload all files, ignoring the manifest (use when the server is out of sync).
--no-backup Skip the pre-deploy snapshot.
--no-build Deploy without building first.
--verbose Show detailed debug output.
# Preview changes
pnpm stratawp deploy production --dry-run

# Deploy without the confirmation prompt
pnpm stratawp deploy production --force

# Re-upload everything when the manifest is out of sync
pnpm stratawp deploy production --fresh

# Deploy without creating a backup
pnpm stratawp deploy production --no-backup

Warning: --no-backup skips the pre-deploy snapshot, which removes your automatic rollback point for that deploy. Only use it when you have another recovery plan.


Change detection

StrataWP tracks each environment's deployed state in a manifest at ~/.stratawp/deployments/{environment}.json. On the next deploy, it compares your local files against the manifest and uploads only what changed — keeping deploys fast and incremental.

If the manifest drifts out of sync with the server (for example, a failed upload that was recorded as successful, or manual changes on the server), you may see "0 files deployed" even after editing files. Two fixes:

# Bypass the manifest and upload everything, then save a fresh manifest
pnpm stratawp deploy production --fresh
# Or delete the manifest so the next deploy treats all files as new
rm ~/.stratawp/deployments/production.json

What gets deployed

Included Excluded
dist/ (built JS/CSS) node_modules/
*.php (functions, templates) src/ (TypeScript/JS sources)
theme.json, style.css .git/
templates/, parts/, patterns/ package.json, tsconfig.json, vite.config.ts
vendor/ (PHP dependencies) .env files and logs
assets/ (images, static files) IDE/development files

Customize this with a .deployignore file in your theme directory (same syntax as .gitignore).


Post-deploy automation (SSH)

SSH deployments run an automated post-deploy pass while still connected to the server. After files upload, StrataWP performs, in order:

  1. WordPress cache flush — runs wp cache flush and wp transient delete --all via WP-CLI.
  2. PHP OPcache reset — creates and executes a temporary PHP script to invalidate OPcache.
  3. Backup cleanup — removes old backup folders, keeping the most recent N (configurable).
  4. Custom WP-CLI commands — runs anything listed in postDeploy.wpCliCommands.
  5. Validation — checks critical files exist, runs a WP-CLI health check, and an HTTP health check.

Configure these in your environment config:

{
  "postDeploy": {
    "clearCache": true,
    "resetOpcache": true,
    "wpCliCommands": ["wp rewrite flush"],
    "wpRootPath": "/custom/path/to/wordpress"
  },
  "backup": {
    "enabled": true,
    "keepLast": 1
  }
}
Option Default Purpose
clearCache true Run wp cache flush + wp transient delete --all.
resetOpcache true Invalidate PHP OPcache.
wpCliCommands [] Extra WP-CLI commands to run after deployment.
wpRootPath auto WordPress root path (auto-detected from remotePath if unset).
backup.keepLast 1 Number of backups to retain (0 = keep all).

A successful SSH deploy ends with a summary like this:

✓ Deployment complete!

✓ Deployment Summary:
  Deployed: 42 files (1.2 MB)
  Backup: /path/to/backup-2026-02-05T10-30-00
  Duration: 8.2s

🔧 Post-Deploy Actions:
  ✓ WordPress cache flushed
  ✓ PHP OPcache reset
  ✓ Cleaned up 2 old backup(s)

✅ Validation:
  ✓ File: style.css — exists
  ✓ File: theme.json — exists
  ✓ WordPress loads — OK
  ✓ Site responds — HTTP 200

✓ Deployment successful!

Note: Full details, including the deployment-output walkthrough, live in Post-Deploy Automation.


Keep credentials out of version control

Store secrets in environment variables, not in committed config files. Create a .env file in your theme directory:

STRATAWP_DEPLOY_PROD_PASSWORD=your_secure_password
STRATAWP_DEPLOY_LOCAL_URL=http://localhost:8888
STRATAWP_DEPLOY_REMOTE_URL=https://example.com

Reference each value in your config using ${VAR_NAME} syntax:

{
  "password": "${STRATAWP_DEPLOY_PROD_PASSWORD}"
}

Warning: Add .env to .gitignore. Keep ~/.stratawp/deploy-config.json out of version control, restrict it with chmod 600, and ensure ~/.stratawp/ is chmod 700. Use a dedicated deployment SSH key rather than your personal key.


Safety and rollback

Every deploy creates a pre-deploy snapshot by default, so you can recover if something goes wrong.

  • List snapshots: stratawp rollback:list
  • Compare two snapshots by index: stratawp rollback:diff 1 2
  • Mark a known-good snapshot as stable: stratawp rollback:mark-stable 1

Warning: Do not pass --no-backup on production unless you have an alternative recovery plan — it skips the automatic rollback point for that deploy.

Full snapshot, restore, and database-sync workflows are covered in Environment Sync & Rollback.


FSE templates and plugins (deep links)

Two things the standard file deploy does not cover:

  • FSE Site Editor templates are stored in the database (wp_posts, post_type = 'wp_template'), not in files. Use stratawp sync:templates to deploy Site Editor customizations:

    pnpm stratawp sync:templates production --all
    pnpm stratawp sync:templates production --template=home
    pnpm stratawp sync:templates:list production
    pnpm stratawp sync:templates production --all --dry-run

    See WordPress FSE Template Sync for the full sync workflow, manual export/import, and automation scripts.

  • Custom plugins are outside the theme deploy. The advanced guide shows an rsync-based workflow, including passphrase handling. See Plugin Deployment.

A complete local-to-production pass (theme → plugins → templates) is documented in Complete Deployment Workflow.


Troubleshooting

Symptom Fix
unknown command 'deploy' The globally installed CLI is stale. From the repo root: cd packages/cli, pnpm build, npm install -g ., then verify with stratawp --help.
Connection failed Re-check host/port/credentials; confirm SFTP/SSH is enabled (port 21 FTP, 22 SFTP/SSH).
Build failed Ensure a valid vite.config.ts exists, run pnpm install, and confirm pnpm build works.
Permission denied Verify the user has write permissions and the remote path exists.
Files not deploying / "0 files deployed" Manifest is out of sync — run with --fresh, or delete ~/.stratawp/deployments/production.json. Also check .deployignore and that dist/ is built.
Encrypted private OpenSSH key detected, but no passphrase given Add a passphrase field to the config (use ${STRATAWP_SSH_PASSPHRASE}), or load the key with ssh-agent.
Production looks different from local Site Editor template changes live in the database — sync them with stratawp sync:templates.

Note: The full troubleshooting list, including Site Editor "Invalid content" and "Block recovery" issues, is in the advanced guide.


Next steps

Clone this wiki locally