Настройка wp-config.php для работы с несколькими окружениями: локальное, тест, продакшн

При разработке продуктов на WordPress рано или поздно встает вопрос о правильной настройке процесса. Сюда входит все: начиная от выбора локального окружения, отладки, тестирования и заканчивая настройкой развертывания (деплоя) итогового кода на сервер. От того, как работает каждое звено, зависит итоговая скорость появления новых фич на сайте, поэтому лучше ответственно подойти к задаче с самого начала.

Я не буду подробно рассматривать сейчас настройки собственно локального окружения, потому что это слишком обширная тема. Просто скажу, что есть 3 основных подхода, каждый со своими плюсами и минусами: Vagrant, Local by Flywheel и Docker. Код, предлагаемый в этой статье, подходит для первых двух окружений. Также, нет смысла в предлагаемой структуре проекта для разработки плагинов или тем — ведь они в принципе должны работать на любых окружения.

Инфраструктура как код

Но что если у вас продуктовый сайт с собственной темой, уникальным функционалом и командой, которая над ним работает? Хорошо бы сделать так, чтобы все разработчики работали над одним и тем же кодом, с одной и той же базой, могли показывать свои коммиты на тестовом сервере (например, для QA) и при этом держали все изменения в git? Особенно если эти изменения в wp-config.php.

Перепробовав довольно много вариантов, я не нашел ничего лучше, чем положить в git вообще весь сайт, вместе с локальным окружением и сопутствующими настройками. Это значительно упростило ввод новых разработчиков, а также позволило контролировать вообще все изменения в проекте, включая оптимизации локальной версии. Но если у нас один код, который работает локально, на тестовом сайте и на живом проекте — как быть с базой данных? Что будет в wp-config.php? А вот что:

wp-config.php

if ( file_exists( __DIR__ . '/wp-content/.local' ) ) {

        # Настройки локального окружения (присутствует файл .local)

	define( 'WP_LOCAL_DEV', true );
	define( 'WP_CLI_CONFIG_PATH', '~/.wp-cli/config.yml' );

	if ( defined( 'WP_CLI' ) and 'WP_CLI' ) {

	# Дебаг через WP CLI, пишем ошибки в логи
		define( 'WP_DEBUG', true );
		define( 'WP_DEBUG_LOG', true );
		define( 'WP_DEBUG_DISPLAY', false );

		$_SERVER['HTTP_HOST'] = 'dev.site.com';

	} else {

	# Дебаг через PHP FPM and HTTP, пишем и показываем ошибки
		define( 'WP_DEBUG', true );
		define( 'WP_DEBUG_LOG', true );
		define( 'WP_DEBUG_DISPLAY', false );
	}

	define( 'WP_CACHE', false );
	define( 'DB_NAME', 'local' );
	define( 'DB_USER', 'local' );
	define( 'DB_PASSWORD', 'password' );
	define( 'DB_HOST', 'localhost' );
	define( 'DB_HOST_SLAVE', '127.0.0.1' );
	define( 'WP_HOME', 'http://dev.site.com' );
	define( 'WP_SITEURL', 'http://dev.site.com' );

} elseif ( file_exists( __DIR__ . '/wp-content/.test' ) ) {

	# Настройки тестового окружения

	define( 'WP_CACHE', false );
	define( 'DB_NAME', 'test' );
	define( 'DB_USER', 'test' );
	define( 'DB_PASSWORD', 'password' );
	define( 'DB_HOST', 'localhost' );
	define( 'WP_HOME', 'https://test.site.com' );
	define( 'WP_SITEURL', 'https://test.site.com' );
	define( 'WP_DEBUG', true );
	define( 'WP_DEBUG_LOG', true );
	define( 'WP_DEBUG_DISPLAY', false );
	error_reporting( E_STRICT );

} else {

        # Настройки продакшн-окружения

	define( 'WP_CACHE', true );
	define( 'DB_NAME', 'database' );
	define( 'DB_USER', 'user' );
	define( 'DB_PASSWORD', 'password' );
	define( 'DB_HOST', 'localhost' );
	define( 'WP_HOME', 'https://site.com' );
	define( 'WP_SITEURL', 'https://site.com' );
	define( 'WP_DEBUG', false );
	define( 'WP_DEBUG_LOG', false );

}

По-сути, мы добавляем настройки всех сайтов в wp-config.php, а переключение реализуем на основе наличия определенных файлов-ключей. Если в wp-content лежит файлик .local — активируются настройки локального окружения и константа WP_LOCAL_DEV становится true. Наличие файла .test говорит wp-config.php о том, что мы на тестовом сервере и нужно использовать соответствующие настройки базы. А если никаких файлов нет, значит, мы не продакшене.

Стоит упомянуть, что файлы .test и .local добавлены в файл исключений .gitignore и не попадают в репозиторий. Для начала работы их нужно создавать вручную. Самое простой способ сделать это — с помощью командной строки, подключившись к серверу по SSH:

cd wp-content
touch .test

А если не хранить доступы в Git?

Для некоторых проектов такой подход плох тем, что все доступы хранятся в общем репозитории и могут быть доступны любому участнику команды. В таком случае можно вынести все в отдельные файлы, например local.php, live.php, stage.php и подключать их в php для каждого окружения, вот так:

if ( file_exists( __DIR__ . '/wp-content/local.php' ) ) {

        # Настройки локального окружения
	require_once(__DIR__ . '/wp-content/local.php');


} elseif ( file_exists( __DIR__ . '/wp-content/test.php' ) ) {

	# Настройки тестового окружения
	require_once(__DIR__ . '/wp-content/test.php');

} else {

        # Настройки продакшн-окружения
	require_once(__DIR__ . '/wp-content/live.php');

}

Доступы будут лежать в отдельных файлах и их можно исключить из репозитория, добавив в .gitignore. Но тогда придется вручную создавать их на каждом сервере.

<?php   # Настройки продакшн-окружения

	define( 'WP_CACHE', true );
	define( 'DB_NAME', 'database' );
	define( 'DB_USER', 'user' );
	define( 'DB_PASSWORD', 'password' );
	define( 'DB_HOST', 'localhost' );
	define( 'WP_HOME', 'https://site.com' );
	define( 'WP_SITEURL', 'https://site.com' );
	define( 'WP_DEBUG', false );
	define( 'WP_DEBUG_LOG', false );

?>

Спасибо uptimizt за идею и наводку на подход Infrastructure as code.

Если у вас есть вопросы по применению этого кода, критика или идеи по его улучшению — пишите их в комментариях. Любая обратная связь приветствуется!

Павел Федоров

Создатель этого сайта и многих других (на WordPress, конечно же). Любит WordPress и делает на нем всякие сумасшедшие сложные штуки, которые никто в здравом уме делать не станет. Умеет работать на фрилансе, в офисе, без офиса, без оглядки и без сна. Один из немногих участников программы FSA/FLEX, кого выдворили из Америки за плохое поведение. С тех пор умеет слушать. Обожает Star Wars, Ведьмака, горные лыжи, байдарку, пешие прогулки, спонтанные путешествия и хорошую компанию. Больше не боится vim.

Добавить комментарий

%d такие блоггеры, как: