Usando le variabili nei file di configurazione di Apache per ridurre la duplicazione?


67

È possibile utilizzare le variabili nei file di configurazione di Apache?

Ad esempio, quando sto configurando un sito con Django + WSGI, il file di configurazione potrebbe apparire come:

<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

E mi piacerebbe trasformare '/ path / to / foo' in una variabile, quindi deve essere definito in un solo posto. Qualcosa di simile a:

Variable FOO /path/to/foo
…

Grazie!

Risposte:


66

È possibile utilizzare mod_macro , che è stato incluso in Apache httpd dalla versione 2.4

Prima di ciò doveva essere installato separatamente, vedi mod_macro . Ad esempio, su Debian: apt-get install libapache2-mod-macro; a2enmod macro.

Esempio di configurazione

/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, sembra quello di cui ho bisogno. Peccato che non sia integrato ... Ma immagino di poter vivere. Grazie!
David Wolever,

3
Eccellente! Questo fa quello che stavo programmando di fare molto meglio di quanto pensassi fosse possibile fare.
SpoonMeiser,

5
@SpoonMeiser Questo modulo è integrato in Apache HTTP Server dalla versione 2.4.6. httpd.apache.org/docs/current/mod/mod_macro.html
Ludwig

24

Molto più semplice usando la Defineparola chiave. Vedi Definisci Direttiva .

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
Eccellente. Funziona perfettamente.
David Tonhofer,

Nota che The variable is always globally defined and not limited to the scope of the surrounding config section.probabilmente significa (non l'ho provato per ora) che, se hai più host, non puoi usare la stessa variabile (con un valore diverso) per ciascuno.
Pierre-Olivier Vares,

@ Pierre-OlivierVares Corretto, vederli come costanti. ecco perché uso lettere maiuscole. Li definisco globalmente al di fuori del VirtualHost
Mathieu J.

14

Puoi abilitare o disabilitare i bit di configurazione con IfDefine ma probabilmente non farà ciò che desideri. Invece, puoi impostare le variabili di ambiente nello script init di Apache per accedere all'interno della configurazione. Ad esempio, aggiungendo:

HOSTNAME=$(hostname)

a /etc/init.d/httpd(prima della linea che chiama httpd!) su una macchina RHEL passa il nome host della macchina come variabile. Non deve essere l'output di un comando: tutto ciò che imposta una variabile nell'ambiente che si avvia httpdva bene. Le variabili possono essere utilizzate nella configurazione in questo modo:

[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

Naturalmente, non sei limitato alla Headerdirettiva. Le variabili possono essere utilizzate ovunque, come <Directory ${FOO}>ecc.

Se non ti piace (e non è così carino ...) puoi generare una configurazione da un modello usando m4 o qualche altro linguaggio di template.

AGGIUNTIVO :

Hm, un modo per renderlo migliore sarebbe quello di memorizzare tutte le variabili in un file esterno, forse /etc/httpd/conf/variables.txt:

FOO=/path/to/dir
ROLE=development

e poi includili nel tuo init.dscript Apache con:

. /etc/httpd/conf/variables

prima di chiamare httpd. Ancora non brillante ma almeno separa lo script di avvio e le variabili.


hhmm ... Grazie - mentre, come dici tu, questo non è abbastanza bello come speravo, è certamente meglio di niente. Grazie.
David Wolever,

11
Un posto migliore (e più pulito) per queste variabili d'ambiente sarebbe /etc/sysconfig/httpd(RedHat, CentOS) o /etc/apache2/envvars(Ubuntu / Debian). Alcune variabili d'ambiente ci sono già.
Stefan Lasiewski,

7

È possibile utilizzare le variabili di ambiente di sistema con mod_env e la direttiva PassEnv. Vedere qui

Esempio per debian:

Aggiungi la tua variabile a / etc / apache2 / envvars (questo file è usato da apache2ctl per definire le variabili)

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

Passa la tua variabile in apache config

PassEnv HOSTNAME

È quindi possibile accedere alla variabile di ambiente di sistema come se fosse una variabile apache.

Header set Served-By %{HOSTNAME}e

1
grazie mille - anche se questo non mi ha fornito la risposta su apache 2.2 centos 6.4 - mi ha indicato la giusta direzione +1
danday74

Ciò richiede mod_define, non caricato in apache2.2 per impostazione predefinita.
Thomas,

3

Ho avuto lo stesso problema e, dopo alcune ricerche, la soluzione per Apache 2.x che l'ha risolto esattamente per me (e nient'altro) è stata questa:

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

Fai attenzione che dopo aver decompresso il pacchetto dovresti costruirlo in questo modo (la parte di installazione dei documenti sembra aver dimenticato di aderire ad apache2?):

apxs2 -cia mod_define.c

Quindi creare /etc/apache2/mods-available/define.load:

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

Successivamente, abilita il modulo usando a2enmodcome faresti normalmente.

I documenti nel link sopra mostrano come usarlo. Ora puoi semplicemente definire cose e usarle direttamente, tutto nella stessa configurazione di apache2.


Nel caso in cui ciò non sia chiaro, questa stessa identica funzionalità è disponibile per impostazione predefinita in Apache 2.4.
ColinM,

2

incredibile ma su httpd 2.2 su centos 6.4 funziona

esporta le variabili env in / etc / sysconfig / httpd

export mydocroot=/var/www/html

quindi fai semplicemente questo ...

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

poi finalmente ....

service httpd restart;

ciò è probabilmente dovuto al fatto che (parte del) /etc/sysconfig/httpdcontenuto httpd -D(l'equivalente alla definedirettiva) definisce le variabili apache.

1

Puoi cercare in mod_passenger l' apache che può anche ospitare app di django. Lo usiamo con grande successo. Tutto quello che devi fare nel vhost è, hmm, esattamente niente. L'unica cosa di cui hai bisogno è creare una directory "pubblica" nella radice dell'applicazione e creare collegamenti simbolici in "pubblica" alle tue directory statiche come "media" (ciò aumenterà le prestazioni della pubblicazione statica) e puntare DocumentRoot su di essa.

Quindi posizionare il seguente file in "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()

Avvia il tuo browser: funziona!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.