多环境中的.htaccess

时间:2012-10-14 21:26:01

标签: apache .htaccess mod-rewrite expressionengine environments

我知道之前已经提出了类似的问题,但我没有找到任何针对我情况的具体答案。

我有一个在多个环境(本地,开发,生产)上运行的ExpressionEngine站点,并且每个环境都需要不同的.htaccess规则:

所有环境

开发

  • 使用.htpasswd进行密码保护
  • 强制HTTPS协议
  • 使用X-Robots-Tag
  • 阻止搜索引擎索引

生产

  • 强制HTTPS协议
  • 将非www子域重定向到www

本地

  • 没有独特的规则。

我已经看到很多关于如何为每个模块设置特定环境的示例。与mod_rewrite模块的RewriteCond %{REQUEST_HOST} ^dev.myurl.com和.htpasswd要求的tricks like this类似。

但我真正喜欢的是设置全局环境变量的一些方法,然后在每个环境的.htaccess文件中重用这些变量。以伪javascript为例,如:

var local = 'mysite.local';
var development = 'dev.mysite.com';
var production = 'www.mysite.com';

// Global .htaccess rules

if(environment == local){
   // Local environment .htaccess rules
}

if(environment == development){
   // Development environment .htaccess rules
}

if(environment == production){
   //Production envirotnment .htaccess rules
}

这样,所有特定于环境的规则都被组合在一起,形成一个非常干净的文件,如果环境发生变化,只需要更改一个变量。

我已经看到一些改变Apache配置文件中的设置的引用,但显然如果我正在处理第三方主机,这不是一个可行的选择。

这就是天上一厢情愿的想法,还是可以做到的?

2 个答案:

答案 0 :(得分:11)

Jon的答案很好。不幸的是,并非所有Web主机都允许您控制启动Apache的-D参数。

这是一种在开发和生产中使用单个htaccess文件的方法,但只保护开发站点密码:

# ----------------------------------------------------------------------
# Password protect staging server
# Use one .htaccess file across multiple environments
# (e.g. local, dev, staging, production)
# but only password protect a specific environment.
# ----------------------------------------------------------------------

SetEnvIf Host staging.domain.com passreq
AuthType Basic
AuthName "Password Required"
AuthUserFile /full/path/to/.htpasswd
Require valid-user
Order allow,deny
Allow from all
Deny from env=passreq
Satisfy any

答案 1 :(得分:8)

  

这就是天上一厢情愿的想法,还是可以做到的?

IMO,是的。您永远无法根据ENV变量或类似的东西获得可预测的“范围”规则。 apache中不存在任意if(something) { do everything in here }。许多指令在某些范围内不起作用,在以后,当你需要改变某些东西的工作方式时,你更有可能打破你所拥有的东西,而不仅仅是修改它。

最好的方法是not use htaccess files at all

  

如果您有权访问httpd主服务器配置文件,则应该完全避免使用.htaccess文件。使用.htaccess文件会降低Apache http服务器的速度。您可以包含在.htaccess文件中的任何指令都可以在Directory块中更好地设置,因为它会产生相同的效果并具有更好的性能。

为本地,开发和生产创建单独的vhost。根据需要打开或关闭它们,无论它们共享什么全局配置,将其存储在其他地方(例如在名为global.includes的文件中),然后在所有3个虚拟主机中使用Include指令。如果需要将规则应用于特定目录,请使用<Directory>块而不是htaccess文件。

如果您宁愿将所有内容都放在htaccess文件中,那么可以尝试放置所有内容in <IfDefine> blocks,这可能是您在问题中对伪代码最接近的内容。基本上类似于:

# Global htaccess rules
RewriteEngine On
RewriteRule ^foo$ /bar [L]

# Only local
<IfDefine LocalInstance>
    RewriteRule ^local/foo /bar [L]
</IfDefine>

# Only dev
<IfDefine DevInstance>
    RewriteRule ^dev/foo /bar [L]
</IfDefine>

# Only production
<IfDefine ProductionInstance>
    RewriteRule ^dev/foo /bar [L]
</IfDefine>

然后当你启动apache时,你需要传入-DLocalInstance-DDevInstance-DProductionInstance作为命令行参数或使用Define指令(仅限于一个参数)你的vhost配置中的某个地方。这不能保证能够像它应该的那样顺利地工作,我之前遇到了<IfDefine>的无法解释的问题,特别是如果你试图过于花哨。