Використання змінних у конфігураційних файлах 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.