Updating a plugin on a live shop and finding out at checkout that it broke something is an avoidable way to spend an afternoon. A staging site is a private copy where the update, the theme change or the PHP version bump happens first. On DirectAdmin there are two ways to get one: the panel's WordPress tooling, and a manual method that works on any account with a spare subdomain and database. We covered the Plesk workflow in WordPress staging on Plesk; this is the DirectAdmin version.
What you need before you start
A staging copy costs one subdomain, one database and roughly the disk space of the live site. Check all three before you begin. On our WordPress plans the smallest tier has 2 databases and 5 subdomains, so one live site plus one staging copy uses the whole database allowance; the larger tiers have 10 and 25.
Check the size of what you are about to duplicate:
du -sh ~/domains/example.com/public_html
du -sh ~/domains/example.com/public_html/wp-content/uploadsTip: if uploads are most of the site, you rarely need them all on staging. Skipping old year folders can cut the copy from gigabytes to megabytes; pages will just show missing images for old posts.
The quick way: staging from the panel
Our shared and WordPress plans list staging and cloning for WordPress, alongside WordPress Manager in DirectAdmin and the Softaculous installer. In Softaculous the feature sits in the installations list: each WordPress install has a Clone action and a Staging action. Staging asks for a target (pick a subdomain you have already created, or a subdirectory) and a database name, then copies files and database and rewrites the URLs for you. A staging install later shows a Push to Live action, with a default push and a customised one where you choose files and database separately.
Exact labels move between versions, so trust what your panel shows rather than a screenshot in a tutorial. If your WordPress site was installed by hand, import it into Softaculous first so it appears in the list.
The panel method is the right default. The manual method below is for when you want to control exactly what gets copied, or when something in the automated copy fails and you need to know what it was doing.
The manual way: subdomain, files, database
1. Create the subdomain and its database
Add staging under the domain in DirectAdmin (adding subdomains covers the screens), then create a new database and user on the MySQL page. DirectAdmin prefixes both with your username, for example user_stg.
By default DirectAdmin puts a subdomain's files in a folder inside the main site: ~/domains/example.com/public_html/staging. That has two consequences worth knowing. The copy is also reachable at example.com/staging/, and a careless file copy will try to copy staging into itself.
2. Copy the files
Over SSH, if your account has it:
cd ~/domains/example.com/public_html
rsync -a --exclude 'staging/' --exclude 'wp-content/cache/' ./ staging/Without SSH, compress the site in the DirectAdmin File Manager, extract it into the subdomain folder, and use phpMyAdmin for the database steps.
3. Export and import the database
With WP-CLI:
cd ~/domains/example.com/public_html
wp db export ~/live-$(date +%F).sqlOr with mysqldump, using the live credentials from wp-config.php:
mysqldump --single-transaction --no-tablespaces -u user_wp -p user_wp > ~/live-$(date +%F).sql
mysql -u user_stg -p user_stg < ~/live-2026-10-15.sql--single-transaction takes a consistent dump of InnoDB tables without locking the live site. --no-tablespaces avoids a privilege error that ordinary hosting database users hit on current MySQL versions.
Tip: write dumps to your home directory, never inside public_html. A .sql file in the web root is a full copy of your customer data that anyone who guesses the name can download.
4. Point the copy at its own database
cd ~/domains/example.com/public_html/staging
wp config set DB_NAME user_stg
wp config set DB_USER user_stg
wp config set DB_PASSWORD 'the-new-password'
wp db checkDo this before anything else. Until wp-config.php is changed, every WP-CLI command you run in the staging folder is operating on the live database.
5. Replace the URLs
wp search-replace 'https://example.com' 'https://staging.example.com' \
--all-tables-with-prefix --skip-columns=guid --dry-runRead the count, then run it again without --dry-run. WP-CLI unserialises PHP data before replacing, which a find-and-replace in a text editor does not, and that is why edited dumps produce broken widgets and lost theme settings. Include the scheme in the search string: replacing a bare example.com also rewrites every email address on the domain. If the live site uses www, run a second pass for https://www.example.com.
Finish with wp cache flush and wp rewrite flush. If wp is not installed on the server, download wp-cli.phar from wp-cli.org into your home directory and run it as php ~/wp-cli.phar instead.
The staging hostname also needs a certificate. Add it to the domain's certificate as described in free Let's Encrypt SSL in DirectAdmin.
Keep staging private and quiet
Three things, all on the staging copy:
wp option update blog_public 0
wp config set WP_ENVIRONMENT_TYPE staging
wp config set DISABLE_WP_CRON true --rawThe first asks search engines not to index it. That is a request, not a lock, so add a password. DirectAdmin has a Password Protected Directories page; protect the staging folder there. The equivalent by hand, on Apache or LiteSpeed:
AuthType Basic
AuthName "Staging"
AuthUserFile /home/user/domains/example.com/.htpasswd
Require valid-userCreate the password file outside the web root with htpasswd -c ~/domains/example.com/.htpasswd yourname. Because the folder itself is protected, this covers both staging.example.com and example.com/staging/.
Tip: a copied shop still has live payment keys, live webhooks and real customer email addresses. Switch the gateway to test mode and stop outgoing mail on staging before you place a test order. Disabling cron, as above, stops scheduled emails and subscription renewals from firing twice.
Push changes back without losing data
The live site kept changing while you worked. Orders came in, users registered, someone uploaded images. So the rule is the same as on any platform: code goes to live, content stays on live.
| Copy from staging to live | Never overwrite on live |
|---|---|
| Themes and child themes you changed | wp-content/uploads |
| Plugins you updated or added | wp-config.php |
| Must-use plugins | Users: wp_users, wp_usermeta |
Orders: wp_wc_orders* tables, or wp_posts and wp_postmeta on older shops |
|
| Comments and form entries |
Back up live first, then preview the file copy:
cd ~/domains/example.com/public_html
wp db export ~/pre-push-$(date +%F-%H%M).sql
rsync -a --delete --dry-run staging/wp-content/themes/mytheme/ wp-content/themes/mytheme/Remove --dry-run when the list looks right. For plugin updates it is often cleaner not to copy at all: having proved the update on staging, run wp plugin update plugin-name on live. Plugins that change the database run their own migration on live that way.
A full database push only makes sense for a site with no live writes, or a rebuild where you accept a content freeze. Then: wp maintenance-mode activate on live, export staging, import into live, run the search-replace in the opposite direction, flush caches, deactivate maintenance mode. For a shop, do not do this. Repeat the settings changes by hand on live.
Clean up afterwards
A forgotten staging copy is an unpatched WordPress install with a full copy of your data. When the work is done:
- Delete the subdomain in DirectAdmin and check the folder is gone.
- Delete the staging database and its user.
- Remove the
.sqldumps and the.htpasswdfile from your home directory. - If you plan to reuse staging, refresh it from live each time rather than testing against a three-month-old copy.
Tip: test PHP version changes on staging too. DirectAdmin lets you select the PHP version per domain, and a version bump that breaks an old plugin is far cheaper to discover on a copy than on the site that takes the orders.