Sugerencias para settings.php: desarrollo local, servidor de desarrollo, servidor en vivo

80

Básicamente, una de las preguntas más importantes de todos los tiempos: ¿Cuáles son algunas de las formas en que usa settings.php en su flujo de trabajo de desarrollo / preparación?

En este momento, tengo mi archivo settings.php configurado de la siguiente manera, y baso mi desarrollo en la directiva $ HOST del servidor, lo que significa que puedo trabajar en dev.example.com para el servidor de desarrollo (compartido), local.example. com para mi computadora local (y el pago de código local de otros desarrolladores) y www.example.com (o simplemente example.com) para el sitio en vivo.

(Este código se encuentra en la sección 'Configuración de la base de datos' de settings.php):

$host = $_SERVER['HTTP_HOST'];
$base_url = 'http://'.$host;
$cookie_domain = $host;

switch($host) {
  case 'example.com': # Production server
    $db_url = 'mysqli://prod_sql_user:[email protected]/prod_db';
    $update_free_access = FALSE;
    $conf = array (
      // Set production config options here...
      'example_setting' => 0,
    );
    break;

  case 'dev.example.com': # Development server
    $db_url = 'mysqli://dev_sql_user:[email protected]/dev_db';
    $update_free_access = FALSE;
    $conf = array (
      // Set production config options here...
      'example_setting' => 0,
    );
    break;

  case 'local.example.com': # Local server
    $db_url = 'mysqli://local_sql_user:[email protected]/local_db';
    $update_free_access = FALSE;
    $conf = array (
      // Set production config options here...
      'example_setting' => 0,
      // Turn off most core caching.
      'cache_inc' => 'includes/cache.inc',
      'cache' => CACHE_DISABLED,
    );
    break;

}
?>

Esto funciona bastante bien para la mayoría de los propósitos, pero significa que tenemos un montón de código extraño en nuestro archivo settings.php compartido ... ¿hay una mejor manera?

geerlingguy
fuente
Debe usar la solución de sitios múltiples Drupal drupal.org/node/290768
sobi3ch

Respuestas:

66

Lo que hago es separar ese archivo en settings.php y local.settings.php.

Al final de settings.php se encuentra el siguiente código:

if (file_exists(dirname(__FILE__) . '/local.settings.php')) {
  include dirname(__FILE__) . '/local.settings.php';
}

El archivo local se excluye de cualquier VCS que esté utilizando. La ventaja es que puede poner configuraciones que son comunes en todas las instancias en settings.php y tenerlas versionadas / distribuidas automáticamente y mantener las cosas locales en local.settings.php.

Berdir
fuente
2
Esta es en realidad la estrategia utilizada en drupal.org y la usamos constantemente en Palantir.net. Para una bicicleta, recomiendo usar 'settings.local.php' como nombre de archivo, ya que coincide con el patrón establecido por 'settings.default.php'.
Dave Reid
1
He creado una esencia para esto: gist.github.com/1235389 desde que he estado usando esto cada vez con más frecuencia
chrisjlee
44
Nota: Drupal 8 ahora ha agregado un fragmento similar al archivo de configuración de forma predeterminada, solo necesita descomentarlo: drupal.org/node/1118520
Berdir
1
@DaveReid: el patrón se establece por ' default.settings.php ' no por 'settings.default.php'.
iconoclasta
1
Para las diversiones que podrías usar en (__DIR__)lugar de dirname(__FILE__). Son equivalentes .
cdmo
26

Parece que está reinventando la funcionalidad multisitio integrada de Drupal.

Personalmente, guardo todos los temas y módulos estándar para el sitio sites/all, y luego tengo sites/dev.example.comy sites/example.com.

Como filesbeneficio adicional, puede tener diferentes carpetas para cada sitio, y también puede agregar cualquier módulo de desarrollo sites/dev.example.com/modules.

Paul Jones
fuente
Eso tiene sentido, pero tengo algunos sitios donde ya hay 5-10 carpetas multisitio, y tener todos los temas para esos sitios en sitios / todos / temas puede ser bastante molesto. Sin mencionar mi uso típico de custom.module para cada sitio. Supongo que podría usar sitename_custom.module en su lugar: - /
geerlingguy
2
Siempre se podría tratar de usar enlaces simbólicos desde el sites/dev.example.com/modulesasites/example.com/modules
Paul Jones
Al aceptar esta respuesta, voy a probar esto en el sitio en el que estoy trabajando actualmente. Parece un buen ajuste para mi flujo de trabajo.
geerlingguy
99
Creo que esta es realmente una forma pobre de manejar entornos de desarrollo y preparación porque en realidad no son sitios diferentes / separados, solo diferentes versiones del mismo sitio. En este caso, querrás evitar tener archivos separados para cada sitio. Recomiendo mucho usar el método mencionado a continuación, donde settings.php está versionado y la configuración específica de cada sitio (configuración de DB) se coloca en un local.settings.php que no está versionado.
Mikey P
1
@Mikey P: ambas soluciones son válidas. Creo que depende principalmente de las preferencias personales / de equipo aquí ... en mi opinión, hay compensaciones con cualquier enfoque.
geerlingguy 03 de
10

Prefiero ignorar el archivo localmente (usando un .gitignorearchivo en git) y luego mantener versiones separadas si el archivo en cada host.

ack
fuente
1
Esta es una solución interesante, aunque me gusta rastrear settings.php en git (algunos errores que he tenido que cosechar se deben a cambios en setting.php ...). ¿Hay alguna manera de que mi caja local de git reemplace ese archivo con el mío (además de tener que copiar en mi propio archivo)?
geerlingguy
1
Eso es lo que yo hago también. Los archivos con datos de configuración, especialmente con credenciales de base de datos, no tienen cabida en el VCS.
mmartinov
@geerlingguy sí puedes. Por favor, lea mi actualización (si será publicada;)
sobi3ch
@martin Estoy de acuerdo, ¡pero no olvidemos que podemos tener un repositorio especial ESPECIAL solo para ESTE archivo! Puedes leerlo en mi actualización.
sobi3ch
7

Siempre tiendo a configurar DNS o entradas de archivos de host y uso

dev.example.com
staging.example.com

y

example.com

Luego tengo directorios de archivos de configuración completamente separados con diferentes directorios de archivos. Por ejemplo ./sites/dev.example.com/files

Stewart Robinson
fuente
El problema que veo con ese enfoque es que a menudo tengo un directorio / themes / y / modules / que uso para cada sitio (a menudo en una configuración multisitio), y dado que necesito usar esos módulos y temas específicos del sitio para , desarrollo y producción, no puedo hacer hosts / multisitios así: - /
geerlingguy
Buen punto. Supongo que dejé de lado que enlazo esas cosas.
Stewart Robinson
Puede crear un enlace simbólico y compartir temas y carpetas de módulos de esa manera. Básicamente, su carpeta principal será una carpeta de producción y luego, a partir de ella, puede crear enlaces simbólicos para organizar, desarrollar y local.
Gansbrest
5

¿Por qué no tener algunas carpetas basadas en el nombre del host de desarrollo?

Ejemplo

  • sitios / dev1.domain.com
  • sitios / dev2.domain.com
  • sitios / dev3.domain.com
  • sitios / www.dominio.com

Cada uno con su propio archivo de configuración y db_url.

Kevin
fuente
Posible problema: los archivos guardados / cargados en una carpeta del sitio no serán accesibles para otra.
Greg
Vea mi respuesta a @Stewart :)
geerlingguy
Crear enlaces simbólicos a la carpeta de archivos central
Kevin
2

Si lo único que cambia son las credenciales de la base de datos, puede establecer variables de entorno en su configuración de host virtual local (y preparación / producción) o en una carpeta .htaccess sobre su raíz web. Aquí hay un ejemplo simple:

/var/www/example.com/drupal-resides-here

Entonces puedo crear un archivo .htaccess aquí:

/var/www/example.com/.htaccess

que tiene el siguiente código:

SetEnv DB1_USER my_local_user
SetEnv DB1_PASS my_local_pass
SetEnv DB1_HOST my_local_host
SetEnv DB1_NAME my_local_dbname

Luego, en /var/www/example.com/drupal-resides-here/sites/default/settings.php(o lo que sea) puede obtener las credenciales de db como:

$db_url = "mysql://{$_SERVER['DB1_USER']}:{$_SERVER['DB1_PASS']}@{$_SERVER['DB1_HOST']}:{$_SERVER['DB1_PORT']}/{$_SERVER['DB1_NAME']}";

Esto permite que varios desarrolladores ejecuten cosas localmente y puede avanzar a la puesta en escena / producción mientras sigue rastreando settings.php (hay más cosas allí que solo las credenciales de la base de datos ...). Tampoco tendría que realizar un seguimiento de múltiples archivos settings.php.

Charlie Schliesser
fuente
Personalmente, creo que este es el mejor camino a seguir. Sin embargo, nuestra configuración agregamos las instrucciones SetEnv a la configuración de apache. Lo hace un poco más seguro.
Scott Joudry
Es un uso interesante para .htaccess y almacenamiento variable. ¿Pero qué pasa cuando corres drush up --y? Eso sobrescribirá su archivo base .htaccess.
Screenack
Esto se hace en un .htaccessarchivo un nivel por encima de webroot. Por ejemplo, /var/www/.htaccessalmacena estas directivas, y /var/www/drupal/.htaccesssería de Drupal .htaccess. También podría simplemente ponerlo en la configuración de host virtual de Apache, que es aún mejor. Independientemente de todo eso, casi siempre tenemos cosas personalizadas en el webroot .htaccessy, por lo tanto, si actualizamos Drupal, debemos comparar los .htaccesscambios con Git.
Charlie Schliesser
0

La solución más simple y eficiente que es solo una línea es la siguiente. Simplemente inclúyalo en la última línea de su archivo settings.php:

@include('settings.local.php');

El símbolo @ en el frente solo significa que no muestra ningún error, incluso si no encuentra ese archivo. Las configuraciones típicas como esta implican un condicional para verificar si el archivo está allí. Esto lo logra en una línea sin él.

http://php.net/manual/en/language.operators.errorcontrol.php

También conocido como el operador PHP STFU .

Patoshi パ ト シ
fuente
Simple, pero no creo que sea el más eficiente. seanmonstar.com/post/909029460/…
AyeshK