Usando variáveis ​​nos arquivos de configuração do Apache para reduzir a duplicação?

67

É possível usar variáveis ​​nos arquivos de configuração do Apache?

Por exemplo, quando estou configurando um site com Django + WSGI, o arquivo de configuração pode se parecer com:

<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

E eu gostaria de transformar o '/ path / to / foo' em uma variável para que ele precise ser definido em um único local. Algo como:

Variable FOO /path/to/foo
…

Obrigado!

David Wolever
fonte

Respostas:

66

Você pode usar o mod_macro , que foi incluído no Apache httpd desde a versão 2.4

Antes disso, ele precisava ser instalado separadamente, consulte mod_macro . Por exemplo, no Debian: apt-get install libapache2-mod-macro; a2enmod macro.

Exemplo de configuração

/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
Graham Dumpleton
fonte
11
Ah, isso parece o que eu preciso. Que pena que não foi construído ... Mas acho que posso viver. Obrigado!
David Wolever 12/09/09
3
Excelente! Isso faz o que eu estava planejando fazer muito melhor do que eu pensava que seria possível.
SpoonMeiser 7/11/2009
5
@SpoonMeiser Este módulo está integrado ao Apache HTTP Server a partir da versão 2.4.6. httpd.apache.org/docs/current/mod/mod_macro.html
Ludwig
24

Muito mais simples usando Definepalavras-chave. Consulte Definir diretiva .

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
Mathieu J.
fonte
2
Excelente. Isso funciona perfeitamente bem.
David Tonhofer 30/08/2015
Observe que The variable is always globally defined and not limited to the scope of the surrounding config section.provavelmente significa (não testei por enquanto) que, se você tiver vários vhosts, não poderá usar a mesma variável (com um valor diferente) para cada um.
Pierre-Olivier Vares 04/07
@ Pierre-OlivierVares Correto, veja-os como constantes. é por isso que uso letras maiúsculas. Eu os defino globalmente fora do VirtualHost
Mathieu J.
14

Você pode ativar ou desativar bits de configuração com o IfDefine, mas isso provavelmente não fará o que você deseja. Em vez disso, você pode definir variáveis ​​de ambiente no script init do Apache para acessar dentro da configuração. Por exemplo, adicionando:

HOSTNAME=$(hostname)

para /etc/init.d/httpd(antes da linha que chama httpd!) em uma máquina RHEL passa o nome do host da máquina como uma variável. Não precisa ser a saída de um comando - tudo o que define uma variável no ambiente que inicia httpdé bom. As variáveis ​​podem ser usadas na configuração da seguinte maneira:

[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

Claro, você não está restrito à Headerdiretiva. As variáveis ​​podem ser usadas em qualquer lugar, como <Directory ${FOO}>etc.

Se você não gosta disso (e isso não é legal ..), você pode gerar uma configuração a partir de um modelo usando m4 ou alguma outra linguagem de modelo.

ADICIONAIS :

Hum, uma maneira de torná-lo melhor seria armazenar todas as variáveis ​​em um arquivo externo, talvez /etc/httpd/conf/variables.txt:

FOO=/path/to/dir
ROLE=development

e inclua-os no seu init.dscript Apache com:

. /etc/httpd/conf/variables

antes de ligar httpd. Ainda não é brilhante, mas pelo menos separa o script de inicialização e as variáveis.

markdrayton
fonte
hhmm… Obrigado - enquanto, como você diz, isso não é tão bom quanto eu esperava, é certamente melhor do que nada. Obrigado.
David Wolever 11/09/09
11
Um local melhor (e mais limpo) para essas variáveis ​​de ambiente seria /etc/sysconfig/httpd(RedHat, CentOS) ou /etc/apache2/envvars(Ubuntu / Debian). Algumas variáveis ​​de ambiente já estão lá.
Stefan Lasiewski
7

Você pode usar variáveis ​​de ambiente do sistema com mod_env e a diretiva PassEnv. Veja aqui

Exemplo para debian:

Inclua sua variável em / etc / apache2 / envvars (esse arquivo é usado pelo apache2ctl para definir variáveis)

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

Passe sua variável para a configuração do apache

PassEnv HOSTNAME

Você pode acessar a variável de ambiente do sistema como se fosse uma variável apache.

Header set Served-By %{HOSTNAME}e
Hadrien
fonte
11
muito obrigado - embora este não forneceu a resposta para mim no Apache 2.2 centos 6.4 - ele me apontar na direção certa +1
danday74
Isso requer mod_define, não carregado no apache2.2 por padrão.
Thomas
3

Eu tive o mesmo problema e, depois de algumas pesquisas, a solução para o Apache 2.x que resolveu exatamente para mim (e nada mais) foi a seguinte:

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

Lembre-se de que, após descompactar, você deve compilá-lo assim (a parte de instalação dos documentos parece ter esquecido de aderir ao apache2?):

apxs2 -cia mod_define.c

Então crie /etc/apache2/mods-available/define.load:

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

Depois disso, ative o módulo usando a2enmodcomo faria normalmente.

Os documentos no link acima mostram como usá-lo. Agora você pode simplesmente definir coisas e usá-las diretamente, tudo dentro da mesma configuração do apache2.

Geradeausanwalt
fonte
Caso isso não esteja claro, essa mesma funcionalidade está disponível por padrão no Apache 2.4.
ColinM 7/13
2

inacreditável, mas no httpd 2.2 no centos 6.4 isso funciona

exportar envios em / etc / sysconfig / httpd

export mydocroot=/var/www/html

então simplesmente faça isso ...

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

então finalmente ....

service httpd restart;
danday74
fonte
isso provavelmente ocorre porque (parte do) /etc/sysconfig/httpdconteúdo entra httpd -D(o equivalente à definediretiva) que define variáveis ​​apache.
1

Você pode procurar no mod_passenger o apache, que também pode hospedar aplicativos django. Nós o usamos com grande sucesso. Tudo o que você precisa fazer no vhost é, hmm, exatamente nada. A única coisa que você precisa é criar um diretório "público" na raiz do aplicativo e criar links simbólicos em "público" para seus diretórios estáticos como "mídia" (isso aumentará o desempenho da veiculação estática) e aponte seu DocumentRoot para ele.

Em seguida, coloque o seguinte arquivo em "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()

Ligue o seu navegador: Funciona!

hurikhan77
fonte