User Documentation

Customize WordPress for

Sign up for Upsun

Get your free trial by clicking the link below.

Get your Upsun free trial

Deploying WordPress without Composer on isn’t recommended, but should you wish to do so there are a few additional modifications you need to make to your repository.

Place WordPress core into a subdirectory Anchor to this heading

Keeping WordPress core up-to-date is made much easier when it resides in a subdirectory of your repository and it makes the recommended transition to using Composer simpler. It also makes defining WordPress as a submodule possible if you choose to do so.

Place all code for WordPress core into a subdirectory called wordpress, including your wp-config.php file.

Core, themes, and plugins can also be submodules Anchor to this heading validates and retrieves submodules in the first stages of its build process, so it’s possible to manage your code entirely this way. This modifies the update steps from what’s listed below, so visit the Git submodules documentation for more information.

.environment Anchor to this heading provides multiple environments for your projects, that can be customized (with different values for staging and development), but that inherit features from the production environment. One clear case where this can be useful is environment variables. Each environment on comes with a set of pre-defined variables that provide information about the branch you are working on, the application’s configuration, and the credentials to connect to each service defined in .platform/services.yaml.

Service credentials reside in a base64 encoded JSON object variable called PLATFORM_RELATIONSHIPS, which you can use to define your database connection to the MariaDB container. To make each property (username, password, and so on) more accessible to wp-config.php, you can use the pre-installed jq package to clean the object into individual variables.

# .environment

export DB_NAME=$(echo $PLATFORM_RELATIONSHIPS | base64 --decode | jq -r ".database[0].path")
export DB_HOST=$(echo $PLATFORM_RELATIONSHIPS | base64 --decode | jq -r ".database[0].host")
export DB_PORT=$(echo $PLATFORM_RELATIONSHIPS | base64 --decode | jq -r ".database[0].port")
export DB_USER=$(echo $PLATFORM_RELATIONSHIPS | base64 --decode | jq -r ".database[0].username")
export DB_PASSWORD=$(echo $PLATFORM_RELATIONSHIPS | base64 --decode | jq -r ".database[0].password")

export WP_HOME=$(echo $PLATFORM_ROUTES | base64 --decode | jq -r 'to_entries[] | select(.value.primary == true) | .key')
export WP_SITEURL="${WP_HOME}wp"
export WP_DEBUG_LOG=/var/log/app.log
if [ "$PLATFORM_ENVIRONMENT_TYPE" != production ] ; then
    export WP_ENV='development'
    export WP_ENV='production'

As you can see above, you can define a number of environment-specific or project-wide variable settings in this file that are applied when deployed on but not locally.

wp-config.php Anchor to this heading

Now that your database credentials have been cleaned up and WP_HOME defined, you can pull these values into wp-config.php to configure WordPress for deployment on a environment.

Below is the wp-config.php file from the WordPress template using the variables defined in the previous section. Many other WordPress settings are pre-defined in this file for you, so consult the inline comments for more information.


// Set default scheme and hostname.
$site_scheme = 'http';
$site_host = 'localhost';

// Update scheme and hostname for the requested page.
if (isset($_SERVER['HTTP_HOST'])) {
  $site_host = $_SERVER['HTTP_HOST'];
  $site_scheme = !empty($_SERVER['HTTPS']) ? 'https' : 'http';


		// Avoid PHP notices on CLI requests.
		if (php_sapi_name() === 'cli') {

		// We are using the first relationship called "database" found in your
		// relationships. Note that you can call this relationship as you wish
		// in your `` file, but 'database' is a good name.
		define( 'DB_NAME', getenv('DB_NAME'));
		define( 'DB_USER', getenv('DB_USER'));
		define( 'DB_PASSWORD', getenv('DB_PASSWORD'));
		define( 'DB_HOST', getenv('DB_HOST'));
		define( 'DB_CHARSET', 'utf8' );
		define( 'DB_COLLATE', '' );

		// Debug mode should be disabled on Set this constant to true
		// in a wp-config-local.php file to skip this setting on local development.
		if (!defined( 'WP_DEBUG' )) {
			define( 'WP_DEBUG', false );

		// Set all of the necessary keys to unique values, based on the
		// entropy value.
			$keys = [
			$entropy = getenv('PLATFORM_PROJECT_ENTROPY');
			foreach ($keys as $key) {
				if (!defined($key)) {
					define( $key, $entropy . $key );
else {
  // Local configuration file should be in project root.
  if (file_exists(dirname(__FILE__, 2) . '/wp-config-local.php')) {
    include(dirname(__FILE__, 2) . '/wp-config-local.php');

// Do not put a slash "/" at the end.
// define( 'WP_HOME', $site_scheme . '://' . $site_host );
define( 'WP_HOME', getenv('WP_HOME'));
// Do not put a slash "/" at the end.
define( 'WP_SITEURL', WP_HOME );
define( 'WP_CONTENT_DIR', dirname( __FILE__ ) . '/wp-content' );
define( 'WP_CONTENT_URL', WP_HOME . 'wp-content' );

// Disable WordPress from running automatic updates
define( 'WP_AUTO_UPDATE_CORE', false );

// Since you can have multiple installations in one database, you need a unique
// prefix.
$table_prefix  = 'wp_';

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

/** Sets up WordPress vars and included files. */
require_once(ABSPATH . 'wp-settings.php');

Up to this point, this guide should give you the following project structure:

โ”œโ”€โ”€ .platform
โ”‚ย ย  โ”œโ”€โ”€ services.yaml
โ”‚ย ย  โ””โ”€โ”€ routes.yaml
โ”œโ”€โ”€ wordpress
โ”‚ย ย  โ”œโ”€โ”€ wp-admin
โ”‚ย ย  โ”œโ”€โ”€ wp-content
โ”‚ย ย  โ”œโ”€โ”€ wp-includes
โ”‚ย ย  โ”œโ”€โ”€ ...
โ”‚   โ”œโ”€โ”€ wp-cli.yml
โ”‚   โ””โ”€โ”€ wp-config.php

Is this page helpful?