Utilisation de variables dans les fichiers de configuration Apache pour réduire les doublons?

67

Est-il possible d'utiliser des variables dans les fichiers de configuration Apache?

Par exemple, lorsque je configure un site avec Django + WSGI, le fichier de configuration peut ressembler à ceci:

<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

Et j'aimerais transformer le '/ path / to / foo' en une variable afin qu'il ne soit défini qu'à un seul endroit. Quelque chose comme:

Variable FOO /path/to/foo
…

Merci!

David Wolever
la source

Réponses:

66

Vous pouvez utiliser mod_macro , inclus dans Apache httpd depuis la version 2.4.

Avant cela, il devait être installé séparément, voir mod_macro . Par exemple sur Debian: apt-get install libapache2-mod-macro; a2enmod macro.

Exemple de configuration

/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
Graham Dumpleton
la source
1
Ah, ça ressemble à ce dont j'ai besoin. Dommage que ce ne soit pas intégré… Mais je suppose que je peux vivre. Merci!
David Wolever
3
Excellent! Cela fait ce que je prévoyais de faire pour beaucoup mieux que je pensais être possible de faire.
SpoonMeiser
5
@SpoonMeiser Ce module est intégré à Apache HTTP Server à partir de la version 2.4.6. httpd.apache.org/docs/current/mod/mod_macro.html
Ludwig
24

Beaucoup plus simple en utilisant le Definemot-clé. Voir Définir la directive .

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
Mathieu J.
la source
2
Excellent. Cela fonctionne parfaitement bien.
David Tonhofer
Notez que The variable is always globally defined and not limited to the scope of the surrounding config section.cela signifie probablement (je ne l'ai pas encore testé) que, si vous avez plusieurs hôtes virtuels, vous ne pouvez pas utiliser la même variable (avec une valeur différente) pour chacun.
Pierre-Olivier Vares le
@ Pierre-OlivierVares Correct, voyez-les comme des constantes. c'est pourquoi j'utilise des lettres capitales. Je les définis globalement en dehors de VirtualHost
Mathieu J.
14

Vous pouvez activer ou désactiver des éléments de configuration avec IfDefine, mais cela ne fera probablement pas ce que vous voulez. Au lieu de cela, vous pouvez définir les variables d’environnement de votre script d’init Apache pour y accéder dans la configuration. Par exemple, ajouter:

HOSTNAME=$(hostname)

to /etc/init.d/httpd(avant la ligne qui appelle httpd!) sur une machine RHEL transmet le nom d'hôte de la machine sous forme de variable. Il n'est pas nécessaire que ce soit le résultat d'une commande - tout ce qui définit une variable dans l'environnement qui se lance httpdest correct. Les variables peuvent être utilisées dans la configuration comme suit:

[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

Bien sûr, vous n'êtes pas limité à la Headerdirective. Les variables peuvent être utilisées n'importe où, comme <Directory ${FOO}>etc.

Si vous n'aimez pas cela (et que ce n'est pas très agréable ..), vous pouvez générer une configuration à partir d'un modèle utilisant m4 ou un autre langage de modèle.

SUPPLÉMENTAIRE :

Hrm, une façon de l’améliorer serait de stocker toutes les variables dans un fichier externe, par exemple /etc/httpd/conf/variables.txt:

FOO=/path/to/dir
ROLE=development

et ensuite les inclure dans votre init.dscript Apache avec:

. /etc/httpd/conf/variables

avant d'appeler httpd. Toujours pas brillant mais au moins ça sépare le script de démarrage et les variables.

Markdrayton
la source
hhmm ... Merci - tout, comme vous le dites, ce n'est pas tout à fait aussi bien que j'espérais, il est certainement mieux que rien. Merci.
David Wolever
11
Un endroit meilleur (et plus propre) pour ces variables d’environnement serait /etc/sysconfig/httpd(RedHat, CentOS) ou /etc/apache2/envvars(Ubuntu / Debian). Certaines variables d'environnement sont déjà là.
Stefan Lasiewski
7

Vous pouvez utiliser des variables d'environnement système avec mod_env et la directive PassEnv. Vois ici

Exemple pour debian:

Ajoutez votre variable à / etc / apache2 / envvars (ce fichier est utilisé par apache2ctl pour définir des variables)

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

Passez votre variable dans apache config

PassEnv HOSTNAME

Vous pouvez ensuite accéder à la variable d’environnement système comme s’il s’agissait d’une variable apache.

Header set Served-By %{HOSTNAME}e
Hadrien
la source
1
merci beaucoup - bien que cela ne me fournisse pas la réponse sur apache 2,2 centos 6,4 - il m'a mis dans la bonne direction +1
danday74
Cela nécessite mod_define, qui n'est pas chargé par défaut dans apache2.2.
Thomas
3

J'ai eu le même problème et, après quelques recherches, la solution pour Apache 2.x qui le résolvait exactement pour moi (et rien de plus) était la suivante:

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

Attention, après le déballage, construisez-le comme ceci (la partie installation de la documentation semble avoir oublié d'adhérer à apache2?):

apxs2 -cia mod_define.c

Puis créez /etc/apache2/mods-available/define.load:

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

Ensuite, activez le module a2enmodcomme vous le feriez normalement.

La documentation dans le lien ci-dessus montre comment l'utiliser. Maintenant, vous pouvez très simplement définir des éléments et les utiliser directement, le tout dans la même configuration apache2.

Geradeausanwalt
la source
Si ce n'est pas clair, cette même fonctionnalité est disponible par défaut dans Apache 2.4.
ColinM
2

incroyable, mais sur httpd 2.2 sur centos 6.4 cela fonctionne

Exporter env vars dans / etc / sysconfig / httpd

export mydocroot=/var/www/html

alors simplement faire ceci ...

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

finalement ....

service httpd restart;
danday74
la source
ceci est probablement dû au fait qu'une partie du /etc/sysconfig/httpdcontenu est insérée dans httpd -D(l'équivalent de la definedirective) qui définit les variables Apache.
1

Vous voudrez peut-être examiner mod_passenger pour apache, qui peut également héberger des applications Django. Nous l'utilisons avec beaucoup de succès. Tout ce que vous devez faire dans le serveur virtuel est, hmm, exactement rien. La seule chose dont vous avez besoin est de créer un répertoire "public" dans la racine de l'application et de créer des liens symboliques "publics" vers vos répertoires statiques tels que "media" (cela améliorera les performances de la distribution statique) et d'y pointer votre DocumentRoot.

Puis placez le fichier suivant dans "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()

Lancez votre navigateur: ça marche!

hurikhan77
la source