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

谢谢!

Answers:


66

您可以使用mod_macro,此版本2.4版以来已包含在Apache httpd中

在此之前,它必须单独安装,请参见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
啊,看起来像我需要的。可惜它不是内置的...但是我想我可以活下去。谢谢!
David Wolever 09年

3
优秀的!这比我原本打算做的要好得多。
SpoonMeiser

5
@SpoonMeiser该模块从版本2.4.6集成到Apache HTTP Server中。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
优秀的。这工作得很好。
David Tonhofer,2015年

请注意,The variable is always globally defined and not limited to the scope of the surrounding config section.这可能意味着(我暂时未对其进行测试),如果您有多个虚拟主机,则不能为每个虚拟主机使用相同的变量(值不同)。
Pierre-Olivier Vares

@ Pierre-OlivierVares正确,将其视为常量。这就是为什么我使用大写字母。我全局定义他们虚拟主机的外
马修J.

14

您可以使用IfDefine启用或禁用某些配置,但这可能无法满足您的要求。相反,您可以在Apache初始化脚本中设置环境变量以在配置中进行访问。例如,添加:

HOSTNAME=$(hostname)

到RHEL机器上的/etc/init.d/httpd(在调用httpd!的行之前)将机器的主机名作为变量传递。它不必是命令的输出-在启动的环境中设置变量的任何东西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。仍然不够出色,但是至少它将启动脚本和变量分开了。


HHMM ...感谢-同时,就像你说的,这是不是相当的不错,因为我所期待的,它肯定比没有好。谢谢。
David Wolever 09年

11
这些环境变量的更好(更干净)的地方是/etc/sysconfig/httpd(RedHat,CentOS)或/etc/apache2/envvars(Ubuntu / Debian)。已经有一些环境变量。
Stefan Lasiewski 2011年

7

您可以将系统环境变量与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

1
非常感谢-尽管这不能为我提供关于Apache 2.2 centos 6.4的答案-它的确为我指明了正确的方向+1
danday74 '16

这需要mod_define,默认情况下未在apache2.2中加载。
托马斯(Thomas)

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

令人难以置信,但在centos 6.4的httpd 2.2上可以正常工作

在/ etc / sysconfig / httpd中导出环境变量

export mydocroot=/var/www/html

然后简单地做到这一点...

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

然后终于....

service httpd restart;

这可能是因为(某些)/etc/sysconfig/httpd内容进入了httpd -D(等同于define指令)定义了Apache变量的内容。

1

您可能要研究mod_passenger for apache,它也可以托管django应用程序。我们成功地使用了它。在虚拟主机中您需要做的就是,完全没有任何事情。您唯一需要做的就是在应用程序根目录中创建一个“ public”目录,并在“ 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()

启动您的浏览器:它有效!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.