Menggunakan variabel dalam file konfigurasi Apache untuk mengurangi duplikasi?

67

Apakah mungkin menggunakan variabel dalam file konfigurasi Apache?

Misalnya, ketika saya menyiapkan situs dengan Django + WSGI, file konfigurasi mungkin terlihat seperti:

<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

Dan saya ingin mengubah '/ path / ke / foo' menjadi variabel sehingga hanya perlu didefinisikan di satu tempat. Sesuatu seperti:

Variable FOO /path/to/foo
…

Terima kasih!

David Wolever
sumber

Jawaban:

66

Anda dapat menggunakan mod_macro , yang telah disertakan dalam Apache httpd sejak versi 2.4

Sebelum itu harus diinstal secara terpisah, lihat mod_macro . Misalnya pada Debian: apt-get install libapache2-mod-macro; a2enmod macro.

Contoh konfigurasi

/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
sumber
1
Ah, sepertinya itu yang saya butuhkan. Malu itu tidak dibangun di ... Tapi kurasa aku bisa hidup. Terima kasih!
David Wolever
3
Luar biasa! Ini melakukan apa yang saya rencanakan untuk dilakukan jauh lebih baik daripada yang saya pikir mungkin untuk dilakukan.
SpoonMeiser
5
@SpoonMeiser Modul ini terintegrasi ke dalam Apache HTTP Server dari versi 2.4.6. httpd.apache.org/docs/current/mod/mod_macro.html
Ludwig
24

Lebih mudah menggunakan Definekata kunci. Lihat Define 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.
sumber
2
Luar biasa. Ini bekerja dengan sangat baik.
David Tonhofer
Perhatikan bahwa The variable is always globally defined and not limited to the scope of the surrounding config section.Ini mungkin berarti (saya tidak mengujinya untuk saat ini) bahwa, jika Anda memiliki beberapa vhost, Anda tidak dapat menggunakan variabel yang sama (dengan nilai yang berbeda) untuk masing-masing.
Pierre-Olivier Vares
@ Pierre-OlivierVares Benar, lihat mereka sebagai konstanta. ini sebabnya saya menggunakan huruf MODAL. Saya mendefinisikannya secara global di luar VirtualHost
Mathieu J.
14

Anda dapat mengaktifkan atau menonaktifkan bit konfigurasi dengan IfDefine tetapi itu mungkin tidak akan melakukan apa yang Anda inginkan. Sebagai gantinya, Anda dapat mengatur variabel lingkungan di skrip init Apache Anda untuk mengakses dalam konfigurasi. Misalnya, menambahkan:

HOSTNAME=$(hostname)

to /etc/init.d/httpd(sebelum baris yang memanggil httpd!) pada mesin RHEL meneruskan nama host mesin sebagai variabel. Itu tidak harus menjadi output dari perintah - apa pun yang menetapkan variabel di lingkungan yang diluncurkan httpdbaik-baik saja. Variabel dapat digunakan dalam konfigurasi seperti:

[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

Tentu saja, Anda tidak terbatas pada Headerarahan. Variabel dapat digunakan di mana saja, seperti <Directory ${FOO}>dll.

Jika Anda tidak suka ini (dan itu tidak baik ..), Anda dapat membuat konfigurasi dari template menggunakan m4 atau bahasa template lainnya.

TAMBAHAN :

Hrm, salah satu cara untuk membuatnya lebih baik adalah menyimpan semua variabel dalam file eksternal, mungkin /etc/httpd/conf/variables.txt:

FOO=/path/to/dir
ROLE=development

dan kemudian sertakan ini ke dalam init.dskrip Apache Anda dengan:

. /etc/httpd/conf/variables

sebelum menelepon httpd. Masih tidak brilian tetapi setidaknya memisahkan skrip startup dan variabel.

markdrayton
sumber
hhmm ... Terima kasih - sementara, seperti yang Anda katakan, ini bukan cukup bagus seperti yang saya harapkan, itu pasti lebih baik daripada tidak. Terima kasih.
David Wolever
11
Tempat yang lebih baik (dan lebih bersih) untuk variabel lingkungan ini adalah /etc/sysconfig/httpd(RedHat, CentOS) atau /etc/apache2/envvars(Ubuntu / Debian). Beberapa variabel lingkungan sudah ada.
Stefan Lasiewski
7

Anda dapat menggunakan variabel lingkungan sistem dengan mod_env dan arahan PassEnv. Lihat disini

Contoh untuk debian:

Tambahkan variabel Anda ke / etc / apache2 / envvars (file ini digunakan oleh apache2ctl untuk mendefinisikan variabel)

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

Pass variabel Anda ke konfigurasi apache

PassEnv HOSTNAME

Anda kemudian dapat mengakses variabel lingkungan sistem seperti jika itu adalah variabel apache.

Header set Served-By %{HOSTNAME}e
Hadrien
sumber
1
terima kasih banyak - walaupun ini tidak memberikan jawaban untuk saya di apache 2,2 centos 6.4 - itu memang mengarahkan saya ke arah yang benar +1
danday74
Ini membutuhkan mod_define, tidak dimuat di apache2.2 secara default.
Thomas
3

Saya memiliki masalah yang sama dan, setelah beberapa penelitian, solusi untuk Apache 2.x yang benar - benar menyelesaikannya untuk saya (dan tidak lebih) adalah ini:

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

Berhati-hatilah bahwa setelah membongkar Anda harus membangunnya seperti itu (bagian instal dokumen tampaknya telah lupa untuk mematuhi apache2?):

apxs2 -cia mod_define.c

Kemudian buat /etc/apache2/mods-available/define.load:

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

Setelah itu, aktifkan modul menggunakan a2enmodseperti biasa.

Dokumen di tautan di atas menunjukkan cara menggunakannya. Sekarang Anda dapat dengan mudah mendefinisikan hal-hal dan menggunakannya secara langsung, semua dalam konfigurasi apache2 yang sama.

Geradeausanwalt
sumber
Dalam hal ini tidak jelas, fungsi yang sama persis ini tersedia secara default di Apache 2.4.
ColinM
2

sulit dipercaya tetapi pada httpd 2.2 pada centos 6.4 ini bekerja

ekspor env vars di / etc / sysconfig / httpd

export mydocroot=/var/www/html

maka cukup lakukan ini ...

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

akhirnya ....

service httpd restart;
danday74
sumber
ini mungkin karena (sebagian) /etc/sysconfig/httpdkonten masuk ke httpd -D(setara dengan definedirektif) yang mendefinisikan variabel apache.
1

Anda mungkin ingin melihat mod_passenger untuk apache yang juga dapat meng-host aplikasi Django. Kami menggunakannya dengan sukses besar. Yang perlu Anda lakukan di vhost adalah, hmm, tepatnya tidak ada. Satu-satunya hal yang Anda perlukan adalah membuat direktori "publik" di root aplikasi dan membuat tautan di "publik" ke direktori statis Anda seperti "media" (ini akan meningkatkan kinerja penyajian statis) dan arahkan DocumentRoot Anda ke sana.

Kemudian letakkan file berikut di "publik /../ 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()

Nyalakan browser Anda: Ini berfungsi!

hurikhan77
sumber