【问题标题】:Looking for a safe way to deploy PHP code寻找一种安全的方式来部署 PHP 代码
【发布时间】:2011-12-16 19:03:48
【问题描述】:

我们现在的工作方式

我们有一个文件服务器(使用 NFS),可以挂载多个 Web 服务器并将这些挂载用作 Web 根目录。当我们部署我们的代码库时,我们将一个存档(tar.gz)SCP 到 NFS 服务器,并直接在文件服务器的“web 目录”中解压缩数据。

问题

在部署过程中,我们看到一些 i/o 错误,主要是在无法读取请求的文件时:Smarty error: unable to read resource: "header.tpl" 这些错误似乎在部署完成后消失了,所以我们假设这是因为直接取消归档数据到 web 目录不是最安全的事情。我猜我们需要一些原子的东西。

我的问题

我们如何以原子方式将新文件复制到现有目录(Web 服务器的根目录)中?

编辑

我们在 web 目录中不妥协的文件并不是该目录中唯一的文件。我们正在将文件添加到已经有文件的目录中。因此,复制目录或使用符号链接不是一种选择(据我所知)。

【问题讨论】:

  • rename is atomic(mv),也可能最好使用软链接,而实际的 web 目录只是 /storage/www.revision.3282378 的链接,例如

标签: php linux deployment


【解决方案1】:

这就是我的工作。

DocumentRoot 是,例如,/var/www/sites/www.example.com/public_html/:

cd /var/www/sites/www.example.com/
svn export http://svn/path/to/tags/1.2.3 1.2.3
ln -snf 1.2.3 public_html

在更改符号链接而不是从 svn 导出之前,您可以轻松地修改它以扩展您的 .tar.gz。重要的部分是更改是符号链接的原子应用。

【讨论】:

    【解决方案2】:

    我认为rsyncscp 更好,只有更改的文件会被同步。但是通过脚本部署代码不方便团队开发,部署错误也不人性化。

    您可以考虑 Capistrano、Magallanes、Deployer,但它们也是脚本。我可能会建议您尝试一下walle-web,这是一个用 PHP 编写的部署工具,开箱即用 yii2。我已经在我们公司托管了几个月,它在部署测试、模拟、生产环境时运行良好。

    它依赖于 bash 工具组、rsync、git、link,但一般来说 web ui 可以很好地操作,试试看:)

    【讨论】:

    • 欢迎来到 Stack Overflow!我注意到到目前为止,您在本网站上的所有五个答案(包括最近删除的两个)都在宣传同一个工具 walle-web。请花点时间阅读我们的guidelines on self-promotion。重要的是,如果您隶属于此工具,则需要在每个答案中披露这一点。此外,您真的不应该在本网站的所有答案中宣传您的工具。
    【解决方案3】:

    您为什么不拥有 2 个具有 2 个不同版本网站的目录。因此,当您在 site_2 中完成部署时,您只需在 Web 服务器配置(例如 apache)中切换站点目录并将所有文件复制到 site_1 目录。然后你可以部署在site_1目录,并用同样的方法从site_2切换到它。

    【讨论】:

    • 我想这里提到的东西是最快的方法。将新内容复制到临时文件夹,然后重命名原始文件夹和新的/临时文件夹(这不会花费太多时间)。
    • 查看我的编辑 - 我们在 Web 根目录中还有其他必须保留的文件(营销网站)和很多(> 40GB 的用户生成内容),我不想一直复制它们。 ..
    【解决方案4】:

    RSync 天生就是为了运行......呃...... 我的意思是做这件事

    RSync 适用于本地文件系统和 ssh - 它非常强大且快速 - 仅发送/复制更改的文件。

    可以将其配置为删除任何已删除的文件(或只是从源中丢失),或者可以将其配置为不理会它们。您可以设置排除列表以在同步时排除某些文件/目录。

    这是link to a tutorial

    回复:原子 - link to another question on SO

    【讨论】:

    • 对于它的价值,过去 2 年我在多个网站上使用它来部署代码,没有任何错误(我记录和电子邮件错误) - 没有丢失文件通知/错误 - 很简单,单命令,命令行脚本部署。
    • 这听起来是个不错的选择,有没有在本地目录上将其作为“一次性”运行的示例,或者 rsync 必须始终作为守护进程运行?
    • 我一直在本地运行 rsync 作为打包谷歌代码项目的脚本的一部分。我很确定我从未配置过 rsyncd - 我在 Mac 上。
    • 与我交谈过的所有网络管理员都说他们亲眼目睹了 rsync 破坏了整个文件系统(启用了删除功能);而且无论 rsync 有多快,如果您曾经操作多个文件,它就不是原子部署。
    • ^ 带有删除标志的 rsync 特别是在(通过)符号链接上操作是不安全的。
    【解决方案5】:

    我喜欢 NFS 的想法。我们确实将我们的代码部署到我们前端 mout 的 NFS 服务器上。事实上,当我们想要发布一个新版本时,我们会运行一个 shell 脚本。我们所做的是使用指向上一个版本目录的符号链接,如下所示:

    /fasmounts/website/current -> /fasmounts/website/releases/2013120301/
    

    而apache的文档根是:

    /fasmounts/website/current/public 
    

    (实际上 apache 文档根目录是 /var/www,它是 /fasmounts/website/current/public 的符号链接)

    在正确上传所有内容后,shell 脚本会将当前符号链接更新到新版本。

    【讨论】:

      猜你喜欢
      • 2021-12-21
      • 1970-01-01
      • 2023-04-07
      • 2012-07-05
      • 1970-01-01
      • 2014-01-09
      • 2017-10-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多