Використання змінних у конфігураційних файлах Apache для зменшення дублювання?


67

Чи можливо використовувати змінні у конфігураційних файлах Apache?

Наприклад, коли я налаштовую сайт із Django + WSGI, файл конфігурації може виглядати так:

<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

І я хотів би перетворити "/ path / to / foo" в змінну, тому її потрібно визначити лише в одному місці. Щось на зразок:

Variable FOO /path/to/foo
…

Дякую!

Відповіді:


66

Ви можете використовувати mod_macro , який включений в Apache httpd з версії 2.4

До цього його потрібно було встановити окремо, див. Mod_macro . Наприклад, на Debian : apt-get install libapache2-mod-macro; a2enmod macro.

Приклад конфігурації

/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
А, це виглядає як те, що мені потрібно. Соромно, що він не вбудований… Але я думаю, що можу жити. Дякую!
Девід Волвер

3
Відмінно! Це робить те, що я планував зробити набагато краще, ніж я вважав, що це можливо зробити.
SpoonMeiser

5
@SpoonMeiser Цей модуль інтегрований у Apache HTTP Server з версії 2.4.6. httpd.apache.org/docs/current/mod/mod_macro.html
Людвіг

24

Набагато простіше використовувати Defineключове слово. Див. Визначення директиви .

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
Відмінно. Це прекрасно працює.
Девід Тонхофер

Зауважте, що The variable is always globally defined and not limited to the scope of the surrounding config section.це, ймовірно, означає (я цього не перевіряв), що якщо у вас є кілька vhosts, ви не можете використовувати одну і ту ж змінну (з різним значенням) для кожного.
П’єр-Олів'є Варес

@ Pierre-OlivierVares Правильно, розглядайте їх як константи. саме тому я використовую літери CAPITAL. Я визначаю їх у всьому світі за межами VirtualHost
Mathieu J.

14

Ви можете ввімкнути або вимкнути біти конфігурації за допомогою IfDefine, але це, ймовірно, не буде робити те, що ви хочете. Натомість ви можете встановити змінні середовища у своєму скрипті Apache init для доступу до конфігурації. Наприклад, додавання:

HOSTNAME=$(hostname)

до /etc/init.d/httpd(до лінії, яка викликає httpd!) на машині RHEL передає ім'я хоста машини у вигляді змінної. Це не повинно бути результатом команди - все, що встановлює змінну в середовищі, яке запускається, httpdце добре. Змінні можна використовувати в такій конфігурації:

[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

Звичайно, ви не обмежені Headerдирективою. Змінні можуть використовуватися в будь-якому місці, наприклад, <Directory ${FOO}>тощо.

Якщо вам це не подобається (і це не так приємно ..), ви можете створити конфігурацію з шаблону, використовуючи m4 або іншу мову шаблону.

ДОДАТКОВО :

Hrm, одним із способів покращити його було б зберігання всіх змінних у зовнішньому файлі, можливо /etc/httpd/conf/variables.txt:

FOO=/path/to/dir
ROLE=development

а потім включіть їх у свій init.dсценарій Apache :

. /etc/httpd/conf/variables

перед тим, як дзвонити httpd. Все ще не блискуче, але принаймні воно розділяє сценарій запуску та змінні.


ГГХХ ... Спасибі - в той час, як ви говорите, це не зовсім так добре , як я сподівався, що це , безумовно , краще , ніж нічого. Дякую.
Девід Уолвер

11
Кращим (і чистішим) місцем для цих змінних середовищ було б /etc/sysconfig/httpd(RedHat, CentOS) або /etc/apache2/envvars(Ubuntu / Debian). Деякі змінні середовища вже є.
Стефан Ласєвський

7

Ви можете використовувати системні змінні середовища з mod_env та директивою PassEnv. Дивіться тут

Приклад для debian:

Додайте змінну до / etc / apache2 / envvars (цей файл використовується apache2ctl для визначення змінних)

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

Передайте свою змінну в конфігурацію apache

PassEnv HOSTNAME

Потім можна отримати доступ до змінної системного середовища, як, наприклад, якщо це була змінна апаш.

Header set Served-By %{HOSTNAME}e

1
велике спасибі - хоча це не
дало

Для цього потрібен mod_define, не завантажений за замовчуванням в apache2.2.
Томас

3

У мене була така ж проблема, і після деяких досліджень рішення для Apache 2.x, яке саме для мене вирішило (і нічого більше), було таким:

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

Пам’ятайте, що після розпакування вам слід створити його так (частина інсталяції, здається, забула дотримуватися apache2?):

apxs2 -cia mod_define.c

Потім створіть /etc/apache2/mods-available/define.load:

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

Після цього ввімкніть модуль, використовуючи, a2enmodяк зазвичай.

Документи у посиланні вище показують, як ним користуватися. Тепер ви можете дуже просто визначити матеріал і використовувати його безпосередньо, все в тій же конфігурації apache2.


Якщо це не зрозуміло, цей точно такий же функціонал доступний за замовчуванням в Apache 2.4.
ColinM

2

неймовірно, але на httpd 2.2 на centos 6.4 це працює

експортувати env vars в / etc / sysconfig / httpd

export mydocroot=/var/www/html

тоді просто зробіть це ...

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

потім нарешті….

service httpd restart;

це, мабуть, тому, що (частина) /etc/sysconfig/httpdвмісту переходить у httpd -D(еквівалент defineдирективі), який визначає змінні апаші.

1

Ви можете заглянути в mod_passenger для apache, який також може розміщувати програми django. Ми використовуємо його з великим успіхом. Все, що вам потрібно зробити в vhost, це, гм, точно нічого. Єдине, що вам потрібно - це створити "public" dir у корені програми та створити посилання "public" для ваших статичних каталогів типу "media" (це підвищить статичну ефективність обслуговування) та вкажіть на нього DocumentRoot.

Потім розмістіть такий файл у "public /../ airport_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()

Запустіть браузер: він працює!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.