¿Usa variables en los archivos de configuración de Apache para reducir la duplicación?


67

¿Es posible usar variables en los archivos de configuración de Apache?

Por ejemplo, cuando configuro un sitio con Django + WSGI, el archivo de configuración podría verse así:

<Directory /path/to/foo/>
    Order allow,deny
    Allow from all
</Directory>
Alias /foo/static /path/to/foo/static
WSGIScriptAlias /foo /path/to/foo/run_wsgi

Y me gustaría convertir el '/ path / to / foo' en una variable, por lo que solo necesita definirse en un lugar. Algo como:

Variable FOO /path/to/foo
…

¡Gracias!

Respuestas:


66

Puede usar mod_macro , que se ha incluido en Apache httpd desde la versión 2.4

Antes de eso tenía que instalarse por separado, ver mod_macro . Por ejemplo en Debian: apt-get install libapache2-mod-macro; a2enmod macro.

Configuración de ejemplo

/etc/apache2/conf.d/vhost.macro

<Macro VHost $host $port>
  <VirtualHost $host:$port>

    ServerName $host
    DocumentRoot /var/vhosts/$host

    <Directory /var/vhosts/$host>
      # do something here...
    </Directory>
  </VirtualHost>
</Macro>

/etc/apache2/sites-available/vhost.mysite.com

Use VHost vhost.mysite.com 80

1
Ah, eso se parece a lo que necesito. Es una pena que no esté incorporado ... Pero supongo que puedo vivir. ¡Gracias!
David Wolever

3
¡Excelente! Esto hace lo que estaba planeando hacer mucho mejor de lo que pensaba que sería posible hacer.
SpoonMeiser

55
@SpoonMeiser Este módulo está integrado en Apache HTTP Server desde la versión 2.4.6. httpd.apache.org/docs/current/mod/mod_macro.html
Ludwig

24

Mucho más simple usando Definepalabras clave. Ver Definir Directiva .

Define RVM_ROOT /opt/rvmdir/gems
Define RUBY_18 ruby-1.8.7-head

...

SetEnv GEM_HOME ${RVM_ROOT}/${RUBY_18}@typo55
SetEnv GEM_PATH ${RVM_ROOT}/${RUBY_18}@typo55:${RVM_ROOT}/${RUBY_18}@global

2
Excelente. Esto funciona perfectamente bien.
David Tonhofer

Tenga en cuenta que The variable is always globally defined and not limited to the scope of the surrounding config section.probablemente signifique (no lo probé por ahora) que, si tiene varios vhosts, no puede usar la misma variable (con un valor diferente) para cada uno.
Pierre-Olivier Vares

@ Pierre-OlivierVares Correcto, verlos como constantes. Por eso uso letras mayúsculas. Los defino globalmente fuera del VirtualHost
Mathieu J.

14

Puede habilitar o deshabilitar bits de configuración con IfDefine, pero eso probablemente no hará lo que quiere. En su lugar, puede establecer variables de entorno en su script de inicio Apache para acceder dentro de la configuración. Por ejemplo, agregando:

HOSTNAME=$(hostname)

a /etc/init.d/httpd(antes de la línea que llama httpd) en una máquina RHEL pasa el nombre de host de la máquina como una variable. No tiene que ser la salida de un comando; cualquier cosa que establezca una variable en el entorno que se inicie httpdestá bien. Las variables se pueden usar en la configuración de la siguiente manera:

[root@dev ~]# cat /etc/httpd/conf.d/test.conf
Header set X-Hostname ${HOSTNAME}

[root@dev ~]# GET -Sed http://localhost
GET http://localhost --> 200 OK
Connection: close
Date: Fri, 11 Sep 2009 20:47:13 GMT
Server: Apache/2.2.3 (Red Hat)
Content-Length: 525
Content-Type: text/html;charset=ISO-8859-1
Client-Date: Fri, 11 Sep 2009 20:47:13 GMT
Client-Peer: 127.0.0.1:80
Client-Response-Num: 1
Title: Index of /
X-Hostname: dev.local

Por supuesto, no estás restringido a la Headerdirectiva. Las variables se pueden usar en cualquier lugar, como <Directory ${FOO}>etc.

Si no le gusta esto (y no es tan agradable ...) puede generar una configuración a partir de una plantilla usando m4 o algún otro lenguaje de plantilla.

ADICIONAL :

Hrm, una forma de mejorarlo sería almacenar todas las variables en un archivo externo, tal vez /etc/httpd/conf/variables.txt:

FOO=/path/to/dir
ROLE=development

y luego inclúyalos en su init.dscript Apache con:

. /etc/httpd/conf/variables

antes de llamar httpd. Todavía no es brillante, pero al menos separa el script de inicio y las variables.


hhmm ... Gracias, aunque, como dices, esto no es tan bueno como esperaba, sin duda es mejor que nada. Gracias.
David Wolever

11
Un lugar mejor (y más limpio) para estas variables de entorno sería /etc/sysconfig/httpd(RedHat, CentOS) o /etc/apache2/envvars(Ubuntu / Debian). Algunas variables de entorno ya están allí.
Stefan Lasiewski

7

Puede usar variables de entorno del sistema con mod_env y la directiva PassEnv. Mira aquí

Ejemplo para debian:

Agregue su variable a / etc / apache2 / envvars (apache2ctl utiliza este archivo para definir variables)

...
export APACHE_PID_FILE=/var/run/apache2.pid
export HOSTNAME=$(hostname)

Pase su variable a la configuración de Apache

PassEnv HOSTNAME

Luego puede acceder a la variable de entorno del sistema como si fuera una variable apache.

Header set Served-By %{HOSTNAME}e

1
muchas gracias, aunque esto no me dio la respuesta en apache 2.2 centos 6.4 - me
indicó la

Esto requiere mod_define, no cargado en apache2.2 por defecto.
Thomas

3

Tuve el mismo problema y, después de investigar un poco, la solución para Apache 2.x que me resolvió exactamente (y nada más) fue esta:

http://people.apache.org/~rjung/mod_define/

Tenga en cuenta que después de desempaquetar, debe compilarlo así (¿parece que la parte de instalación de los documentos se ha olvidado de adherirse a apache2?):

apxs2 -cia mod_define.c

Luego crea /etc/apache2/mods-available/define.load:

LoadModule define_module /usr/lib/apache2/modules/mod_define.so

Después de eso, habilite el módulo usando a2enmodcomo lo haría normalmente.

Los documentos en el enlace de arriba muestran cómo usarlo. Ahora puede definir cosas de manera muy simple y usarlas directamente, todo dentro de la misma configuración de apache2.


En caso de que esto no esté claro, esta misma funcionalidad está disponible de forma predeterminada en Apache 2.4.
ColinM

2

increíble pero en httpd 2.2 en centos 6.4 esto funciona

exportar env vars en / etc / sysconfig / httpd

export mydocroot=/var/www/html

entonces simplemente haz esto ...

<VirtualHost *:80>
  DocumentRoot ${mydocroot}
</VirtualHost>

entonces finalmente ....

service httpd restart;

Esto probablemente se deba a que (parte del) /etc/sysconfig/httpdcontenido entra httpd -D(el equivalente a la definedirectiva) que define las variables apache.

1

Es posible que desee buscar en mod_passenger para apache, que también puede alojar aplicaciones django. Lo usamos con gran éxito. Todo lo que necesitas hacer en el vhost es, mmm, exactamente nada. Lo único que necesita es crear un directorio "público" en la raíz de la aplicación y crear enlaces simbólicos en "público" a sus directorios estáticos como "medios" (esto aumentará el rendimiento del servicio estático) y apunte su DocumentRoot hacia él.

Luego coloque el siguiente archivo en "public /../ passenger_wsgi.py":

import sys, os
current_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(current_dir)
sys.path.append('/PATH/TO/PACKAGES') # optional
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

Enciende tu navegador: ¡Funciona!

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.