How to set up a staging environment
A subdomain, its own database, and a safe way to copy data across — what a staging environment needs before you can trust it.
A staging environment is a working copy of a site — same code, same data, same server environment as far as possible — that nobody but you actually depends on. Its entire purpose is to be the place a change breaks something, rather than the live site. Anything with a genuine cost of failure — a PHP upgrade, a major plugin update, a schema change — belongs on staging first, tested there, and only then applied to the site that matters.
Step 1: create a subdomain
The most common structure is a subdomain such as staging.yourdomain.com, created through your control panel and pointed at its own folder, separate from the live site's folder entirely. This keeps the two completely independent — a change to staging's files cannot accidentally touch the live folder, because they are not the same folder.
Step 2: copy the files across
rsync is a natural fit here, since it only transfers what has changed on subsequent syncs rather than the whole site every time:
rsync -avz -e ssh youraccount@yourserver.example.com:~/public_html/ ~/staging.yourdomain.com/
Note the direction — this pulls a copy of the live site into the staging folder, which is the direction you want when setting staging up or refreshing it later to match what is actually live.
Step 3: give staging its own database
Staging must never share a database with the live site. If it did, testing a data-modifying change on staging would modify live data at the same time, which defeats the entire purpose of having a separate environment in the first place. Create a new database through your control panel, then export the live database and import it into the new one:
mysqldump -u liveuser -p livedatabase > live-export.sql
mysql -u staginguser -p stagingdatabase < live-export.sql
Step 4: point the copied site at the new database
Edit the staging copy's configuration file — wp-config.php for WordPress, .env for Laravel, or whatever your application's equivalent is — so the database name, username and password point at the staging database rather than the live one. This is the single most important step in the whole process, and the one worth double-checking directly rather than assuming the copy carried it over correctly.
Before running a migration, a bulk update, or anything else you specifically built staging to test safely, verify the site is actually reading from the staging database — a quick check of a config value, or looking for a row you know only exists in one of the two databases, is enough. A staging environment quietly still pointed at the live database provides none of the protection it was set up for.
Step 5: keep it private
A staging site is not meant to be found, indexed, or used by anyone but you and your team. Two layers, used together, cover this properly:
- Block search engines with a
noindexmeta tag or a rule inrobots.txtscoped to the staging subdomain specifically, not the live site's own file. - Password-protect the whole folder at the server level, using HTTP basic authentication through your control panel or an
.htaccessrule — see using .htaccess for the syntax. This is the layer that actually stops an uninvited visitor from reaching the content at all, rather than just asking search engines politely not to list it.
Keeping staging useful over time
A staging environment that has drifted far from what is actually live tells you less than one refreshed recently — a test that passes against six-month-old data does not guarantee the same result against what the live site holds today. Refresh the files and database periodically, particularly before testing anything significant such as a PHP version upgrade, so what you are testing against is close enough to reality to be trusted.
What staging is for, and what it is not
Staging is for catching a breaking change before it reaches visitors — a plugin update, a code change, a configuration edit, a version upgrade. It is not a substitute for a backup, and it is not the same thing as a full disaster-recovery copy kept somewhere separate from the live server; those solve a different problem entirely. Use staging to test changes deliberately, and keep proper backups for the case where something goes wrong despite the testing.
Once the environment exists, it becomes the natural home for testing far more than just the occasional big upgrade — a new plugin, an edited template, a database search-and-replace — anything you would rather get wrong on a copy nobody else sees than on the site your visitors are using right now.
Related reading
Check compatibility, test on staging, then switch the live version over — the order that keeps a PHP upgrade from taking your site down.
How to deploy your website with rsyncThe rsync flags that matter, a dry run before the real one, and how to stop it overwriting files it should have left alone.
How to create a staging copy of your siteA private copy of your site on a subdomain, so changes and updates can be tested somewhere that is not the live website.
How to call an external API from PHPcURL, an authentication header and a decoded JSON response — the three parts of calling any external API from a PHP script.