Elastic Beanstalk 在配置更改时删除生成的文件

Elastic Beanstalk deleting generated files on config changes

在 Elastic Beanstalk 上,使用基于 AWS Linux 2 的环境,更新环境的环境属性(即环境变量)会导致所有生成的文件被删除。它也没有 运行 container_commands 作为此更新的一部分。

因此,例如,我有一个 Django 项目,在容器命令中包含 collectstatic

05_collectstatic:
  command: |
    source $PYTHONPATH/activate
    python manage.py collectstatic --noinput --ignore *.scss

这会将静态文件收集到名为 staticfiles 的文件夹中作为部署的一部分。但是当我更新环境变量时,staticfiles 被删除了。这会导致应用程序上的所有静态文件在我重新部署之前被破坏,这是非常不可取的。

此行为不会发生在基于 AWS Linux 1 的环境中。区别似乎是基于 AWS Linux 2 的环境在环境变量更改期间替换了 /var/app/current 文件夹,而基于 AWS Linux 1 的环境没有这样做。

我该如何解决这个问题?

研究

我可以通过监视 /var/log/cfn-init.log 来验证在环境变量更改期间容器命令没有被 运行;此日志中未添加新条目。

滚动更新类型“已禁用”和“不可变”都会发生这种情况。

即使我将环境命令转换为 platform hook,也会发生这种情况,尽管更新环境属性时挂钩被列为 运行ning。

在我看来有两种可能的解决方案,但我不知道 Elastic Beanstalk 中的任何一种设置:

  1. 保留环境变量更改 /var/app/current 而不是替换它。
  2. 更改环境变量 运行 容器命令。

Elastic Beanstalk docs on container commands say“Leader-only 容器命令仅在环境创建和部署期间执行,而其他命令和服务器自定义操作在每次配置或更新实例时执行。”这是 Elastic Beanstalk 中的错误吗?

相关问题:EB: Trigger container commands / deploy scripts on configuration change

解决方案是对任何更改部署目录中文件的命令使用 Configuration deployment platform hook。请注意,这与应用程序部署平台挂钩不同。

以 collectstatic 命令为例,最好的办法是将其从容器命令移至一对挂钩,一个用于标准部署,一个用于配置更改。

为此,删除 collectstatic 容器命令。然后,制作两个相同的文件:

  • .platform/confighooks/predeploy/predeploy.sh
  • .platform/hooks/predeploy/predeploy.sh

每个文件都应包含以下代码:

#!/bin/bash
source $PYTHONPATH/activate
python manage.py collectstatic --noinput --ignore *.scss

你需要两个看似多余的文件,因为不同的hook触发条件不同。部署应用程序时 hooks 运行 中的脚本,而更改应用程序配置时 confighooks 运行 中的脚本。

确保根据 git 使这两个文件可执行,否则您将 . You can check if they are executable via git ls-files -s .platform; you should see 100755 before any shell files in the output of this command. If you see 100644 before any of your shell files, run git add --chmod=+x -- .platform/*/*/*.sh 使它们可执行。