将Apache文档根目录设置为符号链接(以便轻松部署)

11

我们正在寻找一种将Apache DocumentRoot指向符号链接的方法。

例如,DocumentRoot /var/www/html/finalbuild

finalbuild应该指向某个文件夹,比如/home/user/build3

当我们将新的构建移到/home/user/build4时,我们希望使用一个shell脚本将符号链接“finalbuild”更改为这个新目录/home/user/build4,并进行Apache优雅重启,以便具有较小的风险运行最新的Web应用程序版本。

创建此符号链接并使用shell脚本后续更改此链接的最佳方法是什么?


1
我在考虑执行命令 "rm /var/www/html/finalbuild && ln -s /home/user/build4 /var/www/html/finalbuild"。你甚至可能不需要重新启动Apache。 - user354134
谢谢,我已经更改了docroot并将其指向符号链接,但是Apache似乎没有在监听...我已经成功重启了Apache,有什么想法吗? - Jorre
我也一直在尝试找到答案。Apache只是给了我一个403错误。到目前为止还没有运气。可能是因为在生产环境中这样做是不好的实践。但我只想在我的开发环境中这样做。 - nedned
2个回答

8
我们正在使用Capistrano来实现类似的设置。然而,我们遇到了一些问题:
在切换到这个设置后,一切似乎都很好,但是我们发现,在运行“cap deploy”之后,即使符号链接已被更改以指向最新的版本,浏览器仍然显示旧页面,即使多次刷新和添加不同的GET参数也没有改变。
起初,我们认为这是浏览器缓存的原因,因此在开发过程中,我们通过HTTP头禁用了浏览器缓存,但是这并没有改变任何内容。然后,我检查确保我们没有在服务器端进行全页缓存,经验证我们没有这么做。但是我注意到,如果我删除了符号链接所指向的版本中的文件,我们将收到一个404错误,说明Apache正在提供新页面,但仍然遵循“旧符号链接”,从错误的目录提供页面。
由于这是共享托管,因此我无法重新启动Apache。因此,我尝试每次删除符号链接并创建新的符号链接。这似乎有时能够奏效,但不可靠。它可能有25%到50%的成功率。
最终,我发现如果我:
1. 删除现有的符号链接(删除或重命名); 2. 发出页面请求,导致Apache试图解析符号链接但找不到它(导致404); 3. 然后创建一个新的符号链接指向新目录;
这将使文档根目录大多数时间都能正确更新。但是,即使如此,当部署脚本运行“wget”以重命名旧符号链接后立即获取页面时,仍然有2-5%的几率返回旧页面而不是404。
看起来Apache要么缓存文件系统,要么mv命令只在Apache从磁盘上的文件系统读取时更改内存中的文件系统(这真的没有任何意义)。在任一情况下,我已经采纳了某个人的建议,在符号链接更改后运行“sync”,这应该将磁盘上的文件系统与内存同步,并且也许稍微等待一下也有助于“wget”返回404。

4
若有人能理解这种行为背后的原因并将其记录下来,那将是非常好的。 - ThorSummoner

3
我曾在生产环境中将符号链接用作Apache文档根目录,无需进行优雅重启。总的来说,这个想法应该可行。403错误可能表明与符号链接更改无关的权限错误。你需要添加一个额外的细节使符号链接切换原子化,以便始终存在符号链接。也就是说,在任何时候,符号链接都不存在,即使只有一瞬间。

解决此问题的方法是通过创建新的符号链接,然后将其重命名为旧符号链接。在类Unix系统上,重命名是原子操作,因此符号链接的“更改”也将是原子的。手动执行此过程如下:

$ ln -s new current_tmp && mv -Tf current_tmp current

1
只是为了自相矛盾,我看到这个链接遇到了问题:http://www.mikebrittain.com/blog/2009/05/12/case-against-using-symlinks-for-code-promotion/ - defmikekoh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接