Używasz zmiennych w plikach konfiguracyjnych Apache, aby ograniczyć powielanie?

67

Czy można używać zmiennych w plikach konfiguracyjnych Apache?

Na przykład, gdy konfiguruję witrynę za pomocą Django + WSGI, plik konfiguracyjny może wyglądać następująco:

<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

I chciałbym zamienić '/ path / to / foo' w zmienną, więc trzeba ją zdefiniować tylko w jednym miejscu. Coś jak:

Variable FOO /path/to/foo
…

Dzięki!

David Wolever
źródło

Odpowiedzi:

66

Możesz użyć mod_macro , który jest zawarty w Apache httpd od wersji 2.4

Wcześniej musiał być zainstalowany osobno, patrz mod_macro . Na przykład na Debianie: apt-get install libapache2-mod-macro; a2enmod macro.

Przykładowa konfiguracja

/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
źródło
1
Ach, to wygląda na to, czego potrzebuję. Szkoda, że ​​nie jest wbudowany… Ale myślę, że mogę żyć. Dzięki!
David Wolever,
3
Doskonały! Robi to, co planowałem zrobić o wiele lepiej, niż myślałem, że będzie to możliwe.
SpoonMeiser
5
@SpoonMeiser Ten moduł jest zintegrowany z serwerem HTTP Apache od wersji 2.4.6. httpd.apache.org/docs/current/mod/mod_macro.html
Ludwig
24

Znacznie prostsze przy użyciu Definesłowa kluczowego. Zobacz Definicja dyrektywy .

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.
źródło
2
Doskonały. Działa to doskonale.
David Tonhofer,
Zauważ, że The variable is always globally defined and not limited to the scope of the surrounding config section.prawdopodobnie oznacza to (na razie tego nie testowałem), że jeśli masz wiele vhostów, nie możesz użyć tej samej zmiennej (o innej wartości) dla każdego.
Pierre-Olivier Vares
@ Pierre-OlivierVares Poprawnie, zobacz je jako stałe. dlatego używam wielkich liter. Definiuję je globalnie poza VirtualHost
Mathieu J.
14

Możesz włączyć lub wyłączyć bity konfiguracji za pomocą IfDefine, ale prawdopodobnie nie zrobi to, co chcesz. Zamiast tego można ustawić zmienne środowiskowe w skrypcie inicjującym Apache, aby uzyskać dostęp w konfiguracji. Na przykład dodanie:

HOSTNAME=$(hostname)

do /etc/init.d/httpd(przed linią, która wywołuje httpd!) na maszynie RHEL przekazuje nazwę hosta maszyny jako zmienną. Nie musi to być wynik polecenia - wszystko, co ustawia zmienną w uruchamianym środowisku, httpdjest w porządku. Zmienne mogą być używane w konfiguracji w następujący sposób:

[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

Oczywiście nie jesteś ograniczony do tej Headerdyrektywy. Zmienne mogą być używane w dowolnym miejscu, np <Directory ${FOO}>.

Jeśli ci się to nie podoba (i to nie jest tak miłe ..) możesz wygenerować konfigurację z szablonu za pomocą m4 lub innego języka szablonów.

DODATKOWE :

Hrm, jednym ze sposobów na ulepszenie byłoby przechowywanie wszystkich zmiennych w pliku zewnętrznym, być może /etc/httpd/conf/variables.txt:

FOO=/path/to/dir
ROLE=development

a następnie dołącz je do init.dskryptu Apache za pomocą:

. /etc/httpd/conf/variables

przed dzwonieniem httpd. Nadal nie jest genialny, ale przynajmniej oddziela skrypt startowy i zmienne.

markdrayton
źródło
hhmm ... Dzięki - podczas gdy, jak mówisz, to nie jest całkiem tak miły, jak miałem nadzieję, że to na pewno lepsze niż nic. Dzięki.
David Wolever,
11
Lepszym (i czystszym) miejscem dla tych zmiennych środowiskowych byłoby /etc/sysconfig/httpd(RedHat, CentOS) lub /etc/apache2/envvars(Ubuntu / Debian). Niektóre zmienne środowiskowe już tam są.
Stefan Lasiewski
7

Możesz używać zmiennych środowiskowych systemu z mod_env i dyrektywą PassEnv. Spójrz tutaj

Przykład dla debiana:

Dodaj swoją zmienną do / etc / apache2 / envvars (ten plik jest używany przez apache2ctl do definiowania zmiennych)

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

Przekaż zmienną do konfiguracji apache

PassEnv HOSTNAME

Następnie możesz uzyskać dostęp do systemowej zmiennej środowiskowej, tak jakby to była zmienna apache.

Header set Served-By %{HOSTNAME}e
Hadrien
źródło
1
bardzo dziękuję - chociaż to nie dało mi odpowiedzi na Apache 2.2 centos 6.4 - wskazało mi właściwy kierunek +1
danday74
Wymaga to mod_define, domyślnie nie ładowanego do apache2.2.
Thomas
3

Miałem ten sam problem i po kilku badaniach rozwiązanie dla Apache 2.x, które dokładnie go rozwiązało (i nic więcej), brzmiało:

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

Uważaj, że po rozpakowaniu powinieneś zbudować go w taki sposób (wydaje się, że część instalacyjna dokumentów zapomniała stosować się do apache2?):

apxs2 -cia mod_define.c

Następnie utwórz /etc/apache2/mods-available/define.load:

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

Następnie włącz moduł a2enmodtak, jak zwykle.

Dokumenty w powyższym linku pokazują, jak z niego korzystać. Teraz możesz bardzo łatwo zdefiniować rzeczy i używać ich bezpośrednio, wszystko w tej samej konfiguracji apache2.

Geradeausanwalt
źródło
Jeśli nie jest to jasne, ta sama funkcjonalność jest domyślnie dostępna w Apache 2.4.
ColinM,
2

niewiarygodne, ale na httpd 2.2 na centos 6.4 działa

eksportuj zmienne env do / etc / sysconfig / httpd

export mydocroot=/var/www/html

to po prostu zrób to ...

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

potem w końcu ....

service httpd restart;
danday74
źródło
/etc/sysconfig/httpddzieje się tak prawdopodobnie dlatego, że (część) treści wchodzi w httpd -D(odpowiednik definedyrektywy), które definiują zmienne apache.
1

Możesz zajrzeć do mod_passenger w poszukiwaniu apache, który może również hostować aplikacje django. Używamy go z wielkim sukcesem. Wszystko, co musisz zrobić w vhost, to, hmm, dokładnie nic. Wystarczy utworzyć katalog „public” w katalogu głównym aplikacji i utworzyć dowiązania symboliczne „public” do swoich katalogów statycznych, takich jak „media” (zwiększy to wydajność wyświetlania statycznego) i skierować do niego DocumentRoot.

Następnie umieść następujący plik w „public /../ pasażer_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()

Uruchom przeglądarkę: działa!

hurikhan77
źródło