Verwenden Sie Variablen in Apache-Konfigurationsdateien, um Doppelungen zu vermeiden?

67

Ist es möglich, Variablen in Apache-Konfigurationsdateien zu verwenden?

Wenn ich beispielsweise eine Site mit Django + WSGI einrichte, sieht die Konfigurationsdatei möglicherweise folgendermaßen aus:

<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

Und ich möchte das '/ path / to / foo' in eine Variable verwandeln, damit es nur an einer Stelle definiert werden muss. So etwas wie:

Variable FOO /path/to/foo
…

Vielen Dank!

David Wolever
quelle

Antworten:

66

Sie können mod_macro verwenden , das seit Version 2.4 in Apache httpd enthalten ist

Vorher musste es separat installiert werden, siehe mod_macro . Zum Beispiel auf Debian: apt-get install libapache2-mod-macro; a2enmod macro.

Beispielkonfiguration

/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
quelle
1
Ah, das sieht aus wie das, was ich brauche. Schade, dass es nicht eingebaut ist ... Aber ich glaube, ich kann leben. Vielen Dank!
David Wolever
3
Ausgezeichnet! Das tut, was ich vorhatte, weitaus besser, als ich es für möglich gehalten hätte.
SpoonMeiser
5
@SpoonMeiser Dieses Modul ist ab Version 2.4.6 in Apache HTTP Server integriert. httpd.apache.org/docs/current/mod/mod_macro.html
Ludwig
24

Viel einfacher mit DefineSchlüsselwort. Siehe Richtlinie definieren .

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.
quelle
2
Ausgezeichnet. Das funktioniert einwandfrei.
David Tonhofer
Beachten The variable is always globally defined and not limited to the scope of the surrounding config section.Sie, dass dies wahrscheinlich bedeutet (ich habe es im Moment nicht getestet), dass Sie bei mehreren vhosts nicht für jede Variable dieselbe Variable (mit einem anderen Wert) verwenden können.
Pierre-Olivier Vares
@ Pierre-OlivierVares Richtig, sehe sie als Konstanten. deshalb benutze ich GROSSBUCHSTABEN. Ich definiere sie global außerhalb des VirtualHost
Mathieu J.
14

Sie können Konfigurationsbits mit IfDefine aktivieren oder deaktivieren, aber das wird wahrscheinlich nicht das tun, was Sie wollen. Stattdessen können Sie Umgebungsvariablen in Ihrem Apache-Init-Skript festlegen, auf die innerhalb der Konfiguration zugegriffen werden soll. Zum Beispiel hinzufügen:

HOSTNAME=$(hostname)

to /etc/init.d/httpd(vor der httpdaufrufenden Zeile !) auf einem RHEL-Computer übergibt den Hostnamen des Computers als Variable. Es muss nicht die Ausgabe eines Befehls sein - alles, was eine Variable in der Umgebung festlegt, die gestartet wird, httpdist in Ordnung. Variablen können in der Konfiguration wie folgt verwendet werden:

[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

Natürlich sind Sie nicht auf die HeaderRichtlinie beschränkt. Die Variablen können überall verwendet werden, wie z <Directory ${FOO}>.

Wenn Sie dies nicht mögen (und es ist nicht so schön ..), können Sie eine Konfiguration aus einer Vorlage mit m4 oder einer anderen Vorlagensprache generieren .

ZUSÄTZLICHE :

Hrm, eine Möglichkeit, es besser zu machen, wäre, alle Variablen in einer externen Datei zu speichern, vielleicht /etc/httpd/conf/variables.txt:

FOO=/path/to/dir
ROLE=development

und fügen Sie diese dann in Ihr Apache- init.dSkript ein:

. /etc/httpd/conf/variables

bevor Sie anrufen httpd. Immer noch nicht brillant, aber es trennt zumindest das Startskript und die Variablen.

Markdrayton
quelle
hhmm ... Danke - während das, wie Sie sagen, nicht ganz so schön ist, wie ich es mir erhofft hatte, ist es auf jeden Fall besser als nichts. Vielen Dank.
David Wolever
11
Ein besserer (und sauberer) Ort für diese Umgebungsvariablen wäre /etc/sysconfig/httpd(RedHat, CentOS) oder /etc/apache2/envvars(Ubuntu / Debian). Einige Umgebungsvariablen sind bereits vorhanden.
Stefan Lasiewski
7

Sie können Systemumgebungsvariablen mit mod_env und der PassEnv-Direktive verwenden. Siehe hier

Beispiel für debian:

Fügen Sie Ihre Variable zu / etc / apache2 / envvars hinzu (diese Datei wird von apache2ctl verwendet, um Variablen zu definieren)

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

Übergeben Sie Ihre Variable an Apache Config

PassEnv HOSTNAME

Sie können dann auf die Systemumgebungsvariable zugreifen, als wäre es eine Apache-Variable.

Header set Served-By %{HOSTNAME}e
Hadrien
quelle
1
vielen dank - obwohl dies für mich auf apache 2.2 centos 6.4 keine antwort lieferte - zeigte es mich in die richtige richtung +1
danday74
Dies erfordert mod_define, das standardmäßig nicht in apache2.2 geladen wird.
Thomas
3

Ich hatte das gleiche Problem und nach einigen Nachforschungen war die Lösung für Apache 2.x, die es für mich genau löste (und nicht mehr):

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

Beachten Sie, dass Sie es nach dem Entpacken so erstellen sollten (der Install-Teil der Dokumentation scheint vergessen zu haben, sich an Apache2 zu halten?):

apxs2 -cia mod_define.c

Dann erstelle /etc/apache2/mods-available/define.load:

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

Aktivieren Sie danach das Modul a2enmodwie gewohnt.

Die Dokumente im obigen Link zeigen, wie man es benutzt. Jetzt können Sie ganz einfach Dinge definieren und direkt verwenden, alles innerhalb derselben apache2-Konfiguration.

Geradeausanwalt
quelle
Falls dies nicht klar ist, steht in Apache 2.4 standardmäßig genau dieselbe Funktionalität zur Verfügung.
ColinM
2

Unglaublich, aber auf httpd 2.2 auf Centos 6.4 funktioniert dies

Exportieren Sie env-Dateien in / etc / sysconfig / httpd

export mydocroot=/var/www/html

dann mach einfach das ...

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

dann endlich ....

service httpd restart;
danday74
quelle
Dies liegt wahrscheinlich daran, dass (ein Teil des) /etc/sysconfig/httpdInhalts in httpd -D(das Äquivalent zur defineDirektive) geht, die Apache-Variablen definieren.
1

Vielleicht möchten Sie in mod_passenger nach Apache suchen, das auch Django-Apps hosten kann. Wir setzen es mit großem Erfolg ein. Alles, was Sie im vhost tun müssen, ist genau nichts. Sie müssen lediglich ein "öffentliches" Verzeichnis im Anwendungsstamm erstellen und Symlinks in "public" zu Ihren statischen Verzeichnissen wie "media" erstellen (dies steigert die Leistung der statischen Bereitstellung) und Ihren DocumentRoot darauf verweisen.

Legen Sie dann die folgende Datei in "public /../ passenger_wsgi.py" ab:

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()

Starten Sie Ihren Browser: Es funktioniert!

hurikhan77
quelle