Understanding pantheon.yml Configuration for WordPress on Pantheon

Made on

YAML is not a mark up language and unlike Klingon
July 20, 2010: Klingon Takeover” by SDMTS is licensed under CC BY-NC-ND 2.0 .

Ever notice the pantheon.yml file sitting in your repository root?

Unlike traditional WordPress hosting where you’d modify .htaccess or nginx.conf files, Pantheon uses this YAML configuration file to control platform behavior. But what exactly does it do, and why does Pantheon handle configuration this way?

The pantheon.yml file is your control center for advanced WordPress site configuration on Pantheon’s platform. It manages everything from PHP versions and Redis caching to protected file paths and HTTPS enforcement. Understanding this file is essential for WordPress developers working on Pantheon, yet it remains one of the platform’s most misunderstood features.

This guide explains what pantheon.yml does, how to configure it correctly, and provides a complete reference of available settings with real-world examples.

What is YAML and Why Pantheon Uses It

YAML (YAML Ain’t Markup Language) is a human-readable data serialization format. It uses indentation and simple syntax to represent configuration settings as key-value pairs. Pantheon chose YAML because it’s easier to read than JSON or XML, works well in version control, and can be validated automatically.

Here’s a simple example showing YAML syntax:

yaml

# This is a comment
php_version: 8.3
enforce_https: full
protected_web_paths:
  - /private/
  - /confidential.pdf

The indentation matters in YAML. Settings at the same level must align perfectly, and nested items require consistent spacing (typically 2 spaces per level).

Why Pantheon Uses pantheon.yml Instead of .htaccess

Pantheon runs on a container-based architecture with nginx as the web server, not Apache. This means traditional .htaccess files don’t work. Even if you create one, Pantheon ignores it completely.

Similarly, direct nginx.conf modifications aren’t possible because Pantheon manages the web server configuration at the platform level. The pantheon.yml file provides a way to customize platform behavior without breaking the architecture or requiring manual server configuration.

This approach offers several advantages:

  • Version controlled – Configuration changes deploy with your code
  • Environment specific – Different settings per environment
  • Automated validation – Pantheon rejects invalid configurations before deployment
  • No server access needed – Developers can configure without SSH

pantheon.yml File Location

Place your pantheon.yml file in the root of your site’s code repository. This is the same directory where you’d find wp-config.php and index.php.

If you access your site via SFTP, the file goes in the /code directory. If you’re working locally with Git, it belongs in your project root.

Complete pantheon.yml Configuration Reference

Let’s walk through every available configuration option with practical examples.

api_version (Required)

Every pantheon.yml file must include the api_version property. This tells Pantheon which version of the configuration API you’re using.

yaml

api_version: 1

Currently, 1 is the only valid value. Pantheon will reject commits without this property.

php_version

Override the default PHP version for your site. This setting deploys with your code, allowing you to test PHP upgrades in development before pushing to production.

yaml

api_version: 1
php_version: 8.3

Valid values depend on what Pantheon currently supports. As of this writing, options include:

  • 8.3 (recommended for new sites)
  • 8.2
  • 8.1
  • 8.0
  • 7.4

Important considerations:

  • Test thoroughly in development before changing PHP versions in production
  • Some plugins and themes may not support newer PHP versions
  • Pantheon periodically releases one-click updates for new default PHP versions
  • Remove php_version from pantheon.yml to accept platform defaults

When you override the default PHP version, you take responsibility for testing and upgrading. We recommend only setting this when you need to control the upgrade timing, then removing it to let Pantheon manage updates.

database

Specify which version of MariaDB your site uses. This becomes important when upgrading from older database versions or ensuring compatibility with specific WordPress versions.

yaml

api_version: 1
database:
  version: 10.6

Valid values:

  • 10.6 (current recommended version)
  • 10.4 (stable, widely compatible)
  • 10.3 (legacy, for older sites)

WordPress compatibility:

  • WordPress 5.0+ supports MariaDB 10.4 or higher
  • Most modern WordPress sites should use 10.6

Important notes:

  • Always create a backup before changing database versions
  • Test database upgrades in a Multidev environment first
  • Database upgrades are one-way (you can’t easily downgrade)
  • Some older plugins may have compatibility issues with MariaDB 10.6

To upgrade your database version, add or modify the database section in pantheon.yml and commit the change. Pantheon will automatically handle the upgrade process. Monitor the workflow in your dashboard to confirm success.

services (Redis)

Enable and configure Redis object caching for WordPress. Redis dramatically improves performance by caching database queries in memory.

Enabling Redis:

The fastest way to enable Redis is via Terminus:

bash

terminus redis:enable site-name

Alternatively, enable it from your Pantheon Dashboard: Settings > Add Ons > Redis.

Configuring Redis version in pantheon.yml:

yaml

api_version: 1
services:
  redis:
    version: 6.2

Valid Redis versions:

  • 6.2 (recommended)
  • 2.8 (legacy)

Setting up Redis for WordPress:

  1. Enable Redis via Terminus or Dashboard
  2. Install and activate the WP Redis plugin
  3. The plugin automatically creates the object-cache.php drop-in
  4. (Optional) Add custom Redis configuration to wp-config.php for optimization

After enabling Redis, the platform provisions a Redis container for your site. On Pantheon, the WP Redis plugin auto-configures the connection using environment variables, so you typically don’t need manual wp-config.php configuration unless you want to customize caching behavior.

Switching Redis versions:

To upgrade from Redis 2.8 to 6.2, change the version number in pantheon.yml and commit:

yaml

services:
  redis:
    version: 6.2

We recommend testing the Redis version change in a Multidev environment before deploying to production. You can verify the upgrade using redis-cli through the connection information in your Pantheon dashboard.

protected_web_paths

Block public web access to specific files and directories without affecting PHP’s ability to access them. This is particularly useful for protecting sensitive uploads or configuration files.

yaml

api_version: 1
protected_web_paths:
  - /wp-content/uploads/private-documents/
  - /wp-content/uploads/member-files/
  - /private-config.php

How it works:

When a visitor tries to access https://yoursite.com/wp-content/uploads/private-documents/secret.pdf, they receive a 403 Access Denied error. However, your WordPress PHP code can still read these files using filesystem operations.

Important considerations:

  • Paths are case-sensitive
  • Must start with a leading / relative to docroot
  • No wildcards or regex patterns allowed
  • Limited to 24 protected paths maximum
  • Changes take effect within a few seconds
  • Don’t protect /wp-content/uploads entirely (breaks media functionality)

Common use cases:

yaml

protected_web_paths:
  # Form uploads with sensitive data
  - /wp-content/uploads/gravity-forms-uploads/
  # Member-only downloads
  - /wp-content/uploads/members/
  # Backup files
  - /wp-content/backups/

Your WordPress code can still serve these files to authorized users through PHP by reading them from disk and outputting them with proper headers. The protection only blocks direct HTTP access.

enforce_https

Control HTTPS redirection and HSTS (HTTP Strict Transport Security) headers. This determines how aggressively your site enforces HTTPS connections.

yaml

api_version: 1
enforce_https: full

Available options:

Setting HTTPS RedirectHSTS HeaderMax-Ageinclude
Subdomains
Preload
offNoNoNoNo
transitionalYesYes5 mimNoNo
transitional+subdomainsYesYes5 mimYesNo
fullYesYes1 yearNoNo
full+subdomainsYesYes1 YearYesYes
HSTS pantheon.yml settings compared

Choosing the right setting:

Use transitional when first enabling HTTPS to test with a short HSTS duration. Once you confirm everything works, upgrade to full for long-term security.

Only use +subdomains variants if you want to enforce HTTPS on ALL subdomains, including those not hosted on Pantheon. This setting affects blog.example.comshop.example.com, and any other subdomains.

Without preload: First HTTP request is vulnerable, then the browser learns about HSTS, then future requests protected

With preload: Browser already knows about HSTS from built-in list, then even first request uses HTTPS, then all requests protected

The key insight: preload moves the HSTS knowledge from “learned on first visit” to built into the browser before you ever visit. Google says HSTS/preload has no direct ranking benefit. Browsers skip straight to HTTPS, eliminating one redirect. This saves maybe 100-300ms on first page load. Users see the padlock, no security warnings, faster initial load. Lower bounce rates and better user signals can indirectly help SEO.

Important warnings:

The full and full+subdomains settings should be treated as permanent commitments. Browsers cache HSTS headers for the specified duration (1 year). If you later need to serve content over HTTP, visitors using cached HSTS headers won’t be able to access your site.

Do you use staging servers with subdomains, that don’t use any certificates? Or some legacy internal tools without SSL certs? If so, then do not use preload!

Test with transitional first, then upgrade to full only after verifying your site works completely over HTTPS.

web_docroot

Enable nested docroot by serving your site from a /web subdirectory instead of the repository root. This is required for Composer-based workflows and Bedrock installations.

yaml

api_version: 1
web_docroot: true

When enabled, Pantheon looks for WordPress in /web instead of the root directory. Your repository structure would look like:

/
├── pantheon.yml
├── composer.json
├── web/
│   ├── wp-config.php
│   ├── wp-content/
│   └── index.php

When to use nested docroot:

  • Composer-based WordPress installations
  • WordPress Bedrock
  • Sites following modern project structure conventions
  • When you want to keep vendor dependencies outside docroot

Most traditional WordPress sites should leave this setting disabled.

build_step

Enable Integrated Composer, which allows Pantheon to automatically run composer install during deployment.

yaml

api_version: 1
build_step: true

This setting works in conjunction with nested docroot for Composer-managed WordPress installations. When enabled, Pantheon:

  1. Detects changes to composer.json or composer.lock
  2. Runs composer install --no-dev during deployment
  3. Includes the vendor directory in the deployed artifact

Integrated Composer requires specific repository structure and is primarily for advanced WordPress installations using Composer for dependency management.

drush_version

Configure which Drush version to use for remote Drush commands (Drupal sites only). While pantheon.yml exists in WordPress repositories, this setting only applies to Drupal.

yaml

api_version: 1
drush_version: 11

WordPress sites can ignore this setting.

search_and_replace (WordPress Multisite)

Enable search-and-replace functionality during code deployment for WordPress Multisite installations.

yaml

api_version: 1
search_and_replace: true

This setting only applies to WordPress Multisite configurations. Single-site WordPress installations should not enable this.

pantheon.upstream.yml vs pantheon.yml

If you maintain a Custom Upstream (a starting point template for multiple WordPress sites), you can define default configurations in pantheon.upstream.yml. This file lives in your upstream repository and sets defaults for all downstream sites.

Individual sites can override upstream settings by defining the same property in their own pantheon.yml file. Site-level settings always take precedence over upstream defaults.

Most WordPress developers only need to know about pantheon.yml. The upstream file is relevant only if you’re building Custom Upstreams for your organization.

Creating Your pantheon.yml Template

Here’s a complete starter template with common WordPress configurations:

yaml

api_version: 1

# Set PHP version
php_version: 8.3

# Use MariaDB 10.6
database:
  version: 10.6

# Enable Redis 6.2 for object caching
services:
  redis:
    version: 6.2

# Enforce HTTPS with long-duration HSTS
enforce_https: full

# Protect sensitive upload directories
protected_web_paths:
  - /wp-content/uploads/private/
  - /wp-content/uploads/wpcf7_uploads/

Start with this template and customize based on your specific needs. Not every site requires Redis or protected paths, so only include settings you actually need.

Validating Your pantheon.yml File

Syntax errors in pantheon.yml will cause deployment failures. Pantheon automatically validates the file during git commits and rejects invalid configurations with an error message.

Before committing, validate your YAML syntax using online tools:

Common validation errors:

Incorrect indentation:

yaml

# Wrong - misaligned indentation
services:
   redis:
  version: 6.2

yaml

# Correct - consistent 2-space indentation
services:
  redis:
    version: 6.2

Missing api_version:

yaml

# Wrong - no api_version
php_version: 8.3

yaml

# Correct - api_version required
api_version: 1
php_version: 8.3

Invalid property values:

yaml

# Wrong - invalid PHP version
php_version: 9.0

yaml

# Correct - valid PHP version
php_version: 8.3

Deploying pantheon.yml Changes

Once you’ve created or modified your pantheon.yml file, commit it to your repository:

bash

git add pantheon.yml
git commit -m "Configure pantheon.yml for PHP 8.3 and Redis 6.2"
git push origin master

Pantheon detects the configuration file and applies settings automatically. For most changes, you’ll see a notice in your dashboard indicating configuration changes were detected and applied.

Important notes about deployment:

  • Changes to pantheon.yml deploy like any other code
  • Test changes in Dev or Multidev environments first
  • Some changes (like database upgrades) trigger background workflows
  • Monitor the Workflows section in your dashboard for status

Multidev Considerations

If you create a new Multidev by pushing a branch with pantheon.yml changes, the configuration might not apply immediately. To ensure Multidev picks up your configuration:

  1. Push your branch to create the Multidev
  2. Make a small additional commit to pantheon.yml (even just a comment)
  3. Push again to trigger configuration detection

Alternatively, push pantheon.yml changes to the Dev environment first, then create Multidevs from that updated codebase.

Troubleshooting Common Issues

“Changes to pantheon.yml detected, but there was an error while processing it”

This error means your YAML syntax is invalid. Common causes:

  • Indentation errors (use 2 spaces, not tabs)
  • Missing required api_version property
  • Invalid values for configuration options
  • Typos in property names

Run your pantheon.yml through a YAML validator to identify the specific syntax problem.

PHP Version Not Changing in Multidev

If you modify php_version in pantheon.yml but your Multidev still shows the old version, make an additional commit to the file. Any change (even adding a comment) will trigger configuration detection:

yaml

api_version: 1
php_version: 8.3
# Trigger config update

Configuration Changes Not Applied

Pantheon’s standard deployment process handles pantheon.yml automatically. However, if you manually create Git tags or deploy as hotfixes, configuration changes might not apply.

Always deploy using either:

  • Dashboard deploy workflow
  • terminus env:deploy command

These methods ensure Pantheon processes configuration changes correctly.

Protected Paths Not Working

Verify your paths:

  • Start with / and are relative to docroot
  • Match case exactly (paths are case-sensitive)
  • Don’t include wildcards or regex patterns
  • Don’t exceed 24 total paths

Changes to protected paths take effect within a few seconds but aren’t instant. Wait 10-15 seconds and test again.

Real-World Configuration Examples

High-Traffic WordPress Site

yaml

api_version: 1
php_version: 8.3
database:
  version: 10.6
services:
  redis:
    version: 6.2
enforce_https: full

This configuration uses the latest stable PHP and MariaDB versions, enables Redis for object caching, and enforces HTTPS with long-duration HSTS headers.

WordPress Site with Protected Member Uploads

yaml

api_version: 1
php_version: 8.3
protected_web_paths:
  - /wp-content/uploads/members/
  - /wp-content/uploads/woocommerce_uploads/
  - /wp-content/uploads/private/
enforce_https: full

Blocks direct access to member files and WooCommerce uploads while allowing WordPress to serve them through authenticated download scripts.

Composer-Based WordPress (Bedrock)

yaml

api_version: 1
web_docroot: true
build_step: true
php_version: 8.3
database:
  version: 10.6
enforce_https: full

Enables nested docroot and Integrated Composer for Bedrock-style WordPress installations with Composer dependency management.

How pantheon.yml Fits Into Your Workflow

Think of pantheon.yml as part of your site’s infrastructure code. It deploys alongside your theme files, plugins, and wp-config.php. This means:

  • Configuration changes follow your standard development workflow
  • Test in Dev, deploy to Test, push to Live
  • Configuration is version-controlled and documented
  • Team members can review configuration changes in pull requests

When planning WordPress site architecture on Pantheon, consider pantheon.yml settings early. Decisions about Redis, PHP versions, and protected paths affect how you structure your code and configure WordPress.

Conclusion

The pantheon.yml file solves a fundamental problem: how do you configure platform behavior when you can’t modify .htaccess or nginx.conf files? Pantheon’s answer—configuration as code, deployed through version control—turns a limitation into an advantage.

Understanding pantheon.yml means understanding how to properly architect WordPress sites on Pantheon. PHP versions, database configurations, Redis caching, and protected paths all work together to create secure, performant WordPress sites. The configuration sits in your repository, deploys with your code, and can be tested before production.

Start simple. Add api_version: 1 and the specific settings you need. Validate your YAML. Test in Dev. Deploy with confidence. The pantheon.yml file gives you precise control without the complexity of server administration.


Knihter specializes in WordPress development on Pantheon, from complex migrations to custom theme development and performance optimization. Need WordPress help? Reach out, we help agencies and enterprises build fast, secure WordPress sites that scale.


FAQ

Does pantheon.yml work for Drupal sites too?

Yes. The pantheon.yml configuration works identically for both WordPress and Drupal sites on Pantheon. Some settings like drush_version are Drupal-specific.

Can I use pantheon.yml to create redirect rules?

No. Pantheon doesn’t support .htaccess or nginx.conf access. For redirects, Pantheon recommends adding PHP redirect logic to wp-config.php, which is parsed early in the bootstrap process and performs well. You can also use plugins like Redirection for managing redirects through the WordPress admin interface.

What happens if I don’t have a pantheon.yml file?

Pantheon applies default settings based on your upstream (standard WordPress). Your site works fine without pantheon.yml, but you can’t customize platform configuration.

Can I have different pantheon.yml settings per environment?

No. The pantheon.yml file deploys with your code, so all environments in your deployment pipeline (Dev → Test → Live) use the same configuration. For environment-specific settings, use wp-config.php with environment detection.

Why does Pantheon reject my pantheon.yml commit?

Common causes: missing api_version, invalid YAML syntax (usually indentation), or unsupported configuration values. Run your file through a YAML validator to identify syntax problems.

How do I enable Redis object caching for WordPress?

Add the services section to pantheon.yml with Redis configuration, commit and deploy the change, then install the WP Redis plugin and configure wp-config.php to connect to Redis.

or…

Enable Redis using Terminus: terminus redis:enable site-name. Alternatively, enable it from the Pantheon dashboard under Settings > Add Ons. After Redis is enabled, install the WP Redis plugin and add the object-cache.php drop-in. On Pantheon, the plugin auto-configures the connection, but you may want to add additional Redis configuration to wp-config.php for optimization.

Can I use wildcards in protected_web_paths?

No. Each path must be explicitly specified. Pantheon doesn’t support regex patterns or wildcards in protected paths.

What’s the difference between pantheon.yml and pantheon.upstream.yml?

The upstream file sets defaults in Custom Upstream repositories. The regular pantheon.yml file exists in individual site repositories and can override upstream defaults.

How long does it take for pantheon.yml changes to apply?

Most changes apply immediately upon deployment. Database version changes trigger background workflows that may take a few minutes. Protected path changes take effect within a few seconds.

Should I commit pantheon.yml to git?

Yes. The pantheon.yml file is part of your codebase and should be version-controlled like any other configuration file.