题 在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
…

谢谢!


60
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此模块从2.4.6版本集成到Apache HTTP Server中。 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

19
2018-06-01 01:47



优秀。这非常有效。 - David Tonhofer


您可以启用或禁用配置位 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

然后将这些包含在Apache中 init.d 脚本:

. /etc/httpd/conf/variables

在打电话之前 httpd。仍然没有辉煌但至少它将启动脚本和变量分开。


14
2017-09-11 20:54



嗯...谢谢 - 虽然如你所说,但事实并非如此 相当 和我希望的一样好,它肯定比什么都好。谢谢。 - David Wolever
这些环境变量的更好(和更清洁)的地方 /etc/sysconfig/httpd (RedHat,CentOS)或 /etc/apache2/envvars (Ubuntu的/ Debian的)。一些环境变量已经存在。 - Stefan Lasiewski


您可以将系统环境变量与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
这需要mod_define,默认情况下不在apache2.2中加载。 - Thomas


我遇到了同样的问题,并经过一些研究后得到了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 on centos 6.4上这是有效的

在/ etc / sysconfig / httpd中导出env变量

export mydocroot=/var/www/html

然后干脆就这样做......

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

然后终于....

service httpd restart;

2
2018-04-14 14:25





你可能想要研究一下 mod_passenger 对于也可以托管django应用程序的apache。我们用它取得了巨大的成功。你需要在vhost中做的只是,嗯,什么都没有。你需要的只是在应用程序根目录中创建一个“公共”目录,并在“public”中创建符号链接到静态目录,如“media”(这将提高静态服务性能)并将DocumentRoot指向它。

然后将以下文件放在“public /../ 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()

启动浏览器:它有效!


1
2017-09-11 22:03



嗯,这很好知道 - 谢谢。 - David Wolever