Sử dụng các biến trong tệp cấu hình Apache để giảm trùng lặp?


67

Có thể sử dụng các biến trong các tệp cấu hình Apache không?

Ví dụ: khi tôi thiết lập trang web với Django + WSGI, tệp cấu hình có thể trông như sau:

<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

Và tôi muốn biến '/ path / to / foo' thành một biến để nó chỉ cần được xác định ở một nơi. Cái gì đó như:

Variable FOO /path/to/foo
…

Cảm ơn!

Câu trả lời:


66

Bạn có thể sử dụng mod_macro , đã được đưa vào Apache httpd kể từ phiên bản 2.4

Trước đó, nó phải được cài đặt riêng, xem mod_macro . Ví dụ trên Debian : apt-get install libapache2-mod-macro; a2enmod macro.

Cấu hình ví dụ

/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-av Available / vhost.mysite.com

Use VHost vhost.mysite.com 80

1
Ah, có vẻ như những gì tôi cần. Xấu hổ vì nó không được xây dựng trong trò chơi Nhưng tôi đoán tôi có thể sống. Cảm ơn!
David Wolever

3
Xuất sắc! Đây là những gì tôi đã dự định làm tốt hơn nhiều so với tôi nghĩ sẽ có thể làm được.
SpoonMeiser

5
@SpoonMeiser Mô-đun này được tích hợp vào Máy chủ HTTP Apache từ phiên bản 2.4.6. httpd.apache.org/docs/civerse/mod/mod_macro.html
Ludwig

24

Sử dụng Definetừ khóa đơn giản hơn nhiều . Xem Xác định Chỉ thị .

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
Xuất sắc. Điều này hoạt động hoàn toàn tốt.
David Tonhofer

Lưu ý rằng điều The variable is always globally defined and not limited to the scope of the surrounding config section.đó có nghĩa là (tôi đã không kiểm tra ngay bây giờ) rằng, nếu bạn có nhiều vhost, bạn không thể sử dụng cùng một biến (với một giá trị khác nhau) cho mỗi biến.
Pierre-Olivier Vares

@ Pierre-OlivierVares Đúng, xem chúng là hằng số. đây là lý do tại sao tôi sử dụng chữ viết hoa. Tôi xác định chúng trên toàn cầu bên ngoài Virtualhost
Mathieu J.

14

Bạn có thể bật hoặc tắt các bit cấu hình bằng IfDefine nhưng điều đó có thể sẽ không làm những gì bạn muốn. Thay vào đó, Bạn có thể đặt các biến môi trường trong tập lệnh init Apache của bạn để truy cập trong cấu hình. Ví dụ: thêm:

HOSTNAME=$(hostname)

đến /etc/init.d/httpd(trước dòng gọi httpd!) trên máy RHEL chuyển tên máy chủ của máy thành một biến. Nó không phải là đầu ra của một lệnh - bất cứ điều gì đặt một biến trong môi trường khởi chạy httpdđều ổn. Các biến có thể được sử dụng trong cấu hình như vậy:

[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

Tất nhiên, bạn không bị hạn chế trong Headerchỉ thị. Các biến có thể được sử dụng ở bất cứ đâu, như <Directory ${FOO}>vv

Nếu bạn không thích điều này (và nó không hay lắm ..) bạn có thể tạo cấu hình từ một mẫu bằng cách sử dụng m4 hoặc một số ngôn ngữ mẫu khác.

BỔ SUNG :

Hrm, một cách để làm cho nó tốt hơn là lưu trữ tất cả các biến trong một tệp bên ngoài, có lẽ /etc/httpd/conf/variables.txt:

FOO=/path/to/dir
ROLE=development

và sau đó đưa chúng vào init.dtập lệnh Apache của bạn với:

. /etc/httpd/conf/variables

trước khi gọi httpd. Vẫn không xuất sắc nhưng ít nhất nó phân tách tập lệnh khởi động và các biến.


hhmm cảm ơn - trong khi, như bạn nói, điều này không hoàn toàn tốt như tôi mong đợi, nó chắc chắn tốt hơn không có gì. Cảm ơn.
David Wolever

11
Một nơi tốt hơn (và sạch hơn) cho các biến môi trường này sẽ là /etc/sysconfig/httpd(RedHat, CentOS) hoặc /etc/apache2/envvars(Ubuntu / Debian). Một số biến môi trường đã có.
Stefan Lasiewski

7

Bạn có thể sử dụng các biến môi trường hệ thống với mod_env và chỉ thị PassEnv. Xem tại đây

Ví dụ cho debian:

Thêm biến của bạn vào / etc / apache2 / envvars (tệp này được apache2ctl sử dụng để xác định biến)

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

Truyền biến của bạn vào cấu hình apache

PassEnv HOSTNAME

Sau đó, bạn có thể truy cập biến môi trường hệ thống như thể đó là biến apache.

Header set Served-By %{HOSTNAME}e

1
cảm ơn rất nhiều - mặc dù điều này không cung cấp câu trả lời cho tôi về apache 2.2 centos 6.4 - nó đã chỉ cho tôi đi đúng hướng +1
danday74

Điều này yêu cầu mod_define, không được tải trong apache2.2 theo mặc định.
Thomas

3

Tôi đã có cùng một vấn đề và, sau một số nghiên cứu, giải pháp cho Apache 2.x đã giải quyết chính xác nó cho tôi (và không có gì nữa) là:

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

Xin lưu ý rằng sau khi giải nén, bạn nên xây dựng nó như vậy (phần cài đặt của tài liệu dường như đã quên tuân thủ apache2?):

apxs2 -cia mod_define.c

Sau đó tạo /etc/apache2/mods-available/define.load:

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

Sau đó, kích hoạt mô-đun bằng cách sử dụng a2enmodnhư bạn thường làm.

Các tài liệu trong liên kết ở trên cho thấy cách sử dụng nó. Bây giờ bạn có thể rất đơn giản xác định công cụ và sử dụng nó trực tiếp, tất cả trong cùng một cấu hình apache2.


Trong trường hợp điều này không rõ ràng, chức năng chính xác này có sẵn theo mặc định trong Apache 2.4.
ColinM

2

không thể tin được nhưng trên httpd 2.2 trên centos 6.4, công việc này

xuất env vars trong / etc / sysconfig / httpd

export mydocroot=/var/www/html

sau đó chỉ cần làm điều này ...

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

rồi cuối cùng ....

service httpd restart;

điều này có thể là do (một số) /etc/sysconfig/httpdnội dung đi vào httpd -D(tương đương với definechỉ thị) xác định các biến apache.

1

Bạn có thể muốn xem xét mod_pasbah cho apache cũng có thể lưu trữ các ứng dụng django. Chúng tôi sử dụng nó với thành công lớn. Tất cả những gì bạn cần làm trong vhost là, hmm, chính xác là không có gì. Điều duy nhất bạn cần là tạo một thư mục "công khai" trong thư mục gốc của ứng dụng và tạo các liên kết tượng trưng trong "công khai" tới các thư mục tĩnh của bạn như "phương tiện" (điều này sẽ tăng hiệu suất phục vụ tĩnh) và trỏ DocumentRoot của bạn vào đó.

Sau đó đặt tệp sau vào "công khai /../ hành khách_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()

Kích hoạt trình duyệt của bạn: Nó hoạt động!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.