WordPress Multi-Environment: Setting Up SitePoint

Share this article

If you’ve ever set up WordPress, you know that it’s super easy and fast to install. However, if you’ve ever tried to set up WordPress on multiple servers, deploying automatically from a repository or running on different environments, you know that these kind of tasks are a different story. In this article, I’ll explain how we’ve set up WordPress for the build and deployment of the new SitePoint to adapt to various environments, namely development, staging and production.

The problem

WordPress has a central place for its configuration: wp-config.php. This file contains all the basic information for the blog to work, such as how to connect to the database. Now, when you download WordPress, you’ll get a file called wp-config-sample.php, which needs to be copied to wp-config.php and adjusted to your setup. This works if you have just one environment (you’re not editing your files on the server, are you?) or if you take care never to overwrite the production configuration with your development one. If you have an additional staging setup, it gets quite tricky to manage. Ideally, we would want different configuration files for every environment, automatically loaded by WordPress. Moreover, it would be great if no files actually contain any passwords or other sensitive data so that the files can be stored safely in a repository.

The solution

Let’s start by creating one configuration file for every environment. Usually, you’ll have at least three: Development, Staging and Production. I’m calling these wp-config-production.php, wp-config-staging.php and wp-config-development.php. Every one of those files will contain the configuration for that specific environment. We’ll come to the content of the files later, first we need to tell WordPress how to find the right configuration file for the environment. The problem here is that WordPress does not know which one to load, it just loads wp-config.php. We don’t want to change the behavior of WordPress, so we’ll have to include our environment-specific configuration file from wp-config.php. In order to do that, we’ll modify wp-config.php to look like this:
< ?php
/**
 * The base configurations of the WordPress.
 */

/** Absolute path to the WordPress directory. */
if ( !defined('ABSPATH') )
  define('ABSPATH', dirname(__FILE__) . '/');

/** Include environment specific configuration. */
define('WP_ENV', (getenv('WP_ENV') ?: 'production'));
require_once(ABSPATH . 'wp-config-' . WP_ENV . '.php');

/** Sets up WordPress vars and included files. */
require_once(ABSPATH . 'wp-settings.php');
Basically, we remove all content between ABSPATH
and the inclusion of wp-settings.php. In between, we load the right configuration file. How does this work? The name of the environment is stored in a so-called environment variable. Environment variables are set in the virtual host configuration, which might look like this:
<VirtualHost *:80>
        SetEnv WP_ENV "development"
        ServerName  blog.vm
        ServerAlias blog.vm

        <Directory /var/www/blog>
                ...
        </Directory>

</VirtualHost>
WP_ENV can be read in PHP via getenv('WP_ENV'). In our example, we store that value in a constant called WP_ENV. require_once(ABSPATH . 'wp-config-' . WP_ENV . '.php'); will load the correct configuration file. We now need to copy all settings (except ABSPATH and the inclusion of wp-settings.php) from wp-config-sample.php into each configuration file. However, as I stated earlier, it would be preferable to not just enter the sensitive data directly in the file. We have two options:

Option 1: Environment variables

We’ve used an environment variable already to determine which environment we’re in. In the same way, we can set the database password etc. in environment variables as well and read them in via getenv. For example:
define('DB_NAME', getenv('DB_NAME') ?: 'blog');
This reads DB_NAME
from the environment and falls back to use blog. Providing fallbacks is especially helpful when sharing the codebase with other developers. If they set up their database using the default values, everything will “just work”, without the need to change anything. On the other hand, if they prefer a different setup, it’s easy to change the environment values without having to touch the code, which is vital if you want to work on the same codebase.

Option 2: Write on build

If you’re using a build system to deploy your code, you could also use placeholders which are replaced during build, such as:
define('DB_NAME', '##DB_NAME##');
However, this option only works for the staging and production configurations, it’s not suited for your development configuration file. When you choose to use environment variables everywhere, you could even use just one configuration file that reads all values via getenv. However, I prefer having separate files. This makes it easier to see which configuration is in use for which environment. Also, you typically have some constants you only need in development, such as debugging:
define('WP_DEBUG', true);
That covers the setup for different configuration files. One other thing that I found really helpful when dealing with multiple environments was to set WP_HOME and WP_SITEURL in the configuration file instead of reading it from the database.

Conclusion

To wrap up, here are the advantages of this setup:
  • It’s easy to see how a specific environment is configured
  • New environments can be added easily
  • Environments can use different constants
  • All configuration files can safely be committed to a repository
  • Using the environment variable setup, no credentials are stored at any time in a file

Frequently Asked Questions about WordPress Multi-Environment Setup

What is the purpose of a WordPress multi-environment setup?

A WordPress multi-environment setup is designed to provide a structured and safe environment for developing and testing your WordPress site. It allows you to create separate environments for development, staging, and production. This means you can make changes, test new features, and fix bugs in the development or staging environment without affecting the live site. Once you’re satisfied with the changes, you can then push them to the production environment.

How do I set up a WordPress multi-environment?

Setting up a WordPress multi-environment involves creating separate directories for each environment and configuring your wp-config.php file to recognize these environments. You’ll also need to set up separate databases for each environment. This can be done manually or using a tool like WP-CLI.

What is the WP_ENV variable and what does it do?

The WP_ENV variable is used to define the current environment in a WordPress multi-environment setup. It can be set to ‘development’, ‘staging’, or ‘production’, and is typically defined in the wp-config.php file. This variable is used to control which settings are loaded for each environment.

How do I manage WordPress configuration across multiple environments?

Managing WordPress configuration across multiple environments can be done using a combination of the wp-config.php file and environment-specific configuration files. The wp-config.php file is used to set up global settings, while environment-specific files are used to override these settings for each environment.

What are the benefits of using a WordPress multi-environment setup?

A WordPress multi-environment setup offers several benefits. It allows you to test changes in a safe environment before deploying them to the live site. It also makes it easier to manage configuration settings across different environments, and can help to prevent issues with plugin and theme compatibility.

Can I use a WordPress multi-environment setup with a local development environment?

Yes, a WordPress multi-environment setup can be used with a local development environment. This allows you to develop and test your site locally before deploying changes to the staging or production environments.

How do I deploy changes from one environment to another?

Deploying changes from one environment to another can be done using a variety of methods, including manual file transfer, Git, or a deployment tool like DeployHQ or Capistrano.

What is the difference between the staging and production environments?

The staging environment is a replica of the production environment used for testing changes before they’re deployed to the live site. The production environment is the live site that users interact with.

How do I handle database synchronization across multiple environments?

Database synchronization can be handled using a tool like WP Migrate DB Pro, which allows you to push and pull your database between different environments.

What should I do if I encounter errors in my WordPress multi-environment setup?

If you encounter errors in your WordPress multi-environment setup, the first step is to check your error logs. This can help you identify the source of the problem. If you’re unable to resolve the issue, you may need to seek help from a WordPress developer or a support forum.

Michael SauterMichael Sauter
View Author

Michael Sauter is a German web developer at SitePoint. He's maintaining the backend of the various SitePoint sites and works on new features and products. Usually working with Ruby or PHP - currently interested in Go and Docker.

Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week