Вопрос: Использование переменных в конфигурационных файлах Apache для уменьшения дублирования?


Можно ли использовать переменные в файлах конфигурации 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
…

Благодаря!


59
2017-09-11 20:33


Источник




Ответы:


Вы можете использовать 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

61
2017-09-12 07:12



Ах, похоже, что мне нужно. Позор, он не построен ... Но я думаю, что я могу жить. Благодаря! - David Wolever
Отлично! Это делает то, что я планировал сделать намного лучше, чем я думал, что это возможно. - SpoonMeiser
@SpoonMeiser Этот модуль интегрирован в HTTP-сервер Apache с версии 2.4.6. httpd.apache.org/docs/current/mod/mod_macro.html - Ludwig


Гораздо проще использовать 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

17
2018-06-01 01:47



Отлично. Это работает отлично. - David Tonhofer


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

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

а затем включить их в свой Apache init.d скрипт с:

. /etc/httpd/conf/variables

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


14
2017-09-11 20:54



hhmm ... Спасибо - пока, как вы говорите, это не довольно так приятно, как я надеялся, это, безусловно, лучше, чем ничего. Благодарю. - David Wolever
Лучшим (и более чистым) местом для этих переменных окружения было бы /etc/sysconfig/httpd (RedHat, CentOS) или /etc/apache2/envvars (Ubuntu / Debian). Некоторые переменные среды уже существуют. - Stefan Lasiewski


Вы можете использовать переменные системы environement с mod_env и директивой PassEnv. Глянь сюда

Пример для debian:

Добавьте переменную в / etc / apache2 / envvars (этот файл используется apache2ctl для определения переменных)

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

Передайте переменную в конфигурацию apache

PassEnv HOSTNAME

Затем вы можете получить доступ к переменной системной среды, как если бы она была переменной apache.

Header set Served-By %{HOSTNAME}e

7
2017-11-10 10:05



Большое спасибо - хотя это не предоставило мне ответ на apache 2.2 centos 6.4 - он указал мне в правильном направлении +1 - danday74


У меня была та же проблема, и после некоторых исследований было установлено решение для 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.


3
2018-01-24 16:39



В случае, если это не ясно, эта точно такая же функциональность доступна по умолчанию в Apache 2.4. - ColinM


невероятно, но на httpd 2.2 на centos 6.4 это работает

экспортировать env vars в / etc / sysconfig / httpd

export mydocroot=/var/www/html

то просто сделайте это ...

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

то наконец ....

service httpd restart;

2
2018-04-14 14:25





Вы можете посмотреть в mod_passenger для apache, который также может размещать приложения django. Мы используем его с большим успехом. Все, что вам нужно сделать в хореоте, это, хм, точно ничего. Единственное, что вам нужно - это создать «общедоступный» каталог в корне приложения и создать символические ссылки в «общедоступных» для ваших статических каталогов, таких как «media» (это повысит производительность статической службы) и указать на него DocumentRoot.

Затем поместите следующий файл в «public /../ пассажир_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()

Запустите свой браузер: он работает!


1
2017-09-11 22:03



ах, это хорошо знать - спасибо. - David Wolever