AWS Elastic Beanstalk 容器命令失败

Posted

技术标签:

【中文标题】AWS Elastic Beanstalk 容器命令失败【英文标题】:AWS Elastic Beanstalk Container Commands Failing 【发布时间】:2020-10-08 01:14:49 【问题描述】:

我一直在努力尝试将我的 Django Web 应用程序成功部署到 AWS 的 Elastic Beanstalk。在我在 .ebextensions 文件夹中添加 container_commands 配置文件列表之前,我可以在本地计算机上从 EB CLI 部署我的应用程序,这完全没有问题。

这是我的配置文件的内容:

container_commands:
  01_makeAppMigrations:
    command: "django-admin.py makemigrations"
    leader_only: true
  02_migrateApps:
    command: "django-admin.py migrate"
    leader_only: true
  03_create_superuser_for_django_admin:
    command: "django-admin.py createfirstsuperuser"
    leader_only: true
  04_collectstatic:
    command: "django-admin.py collectstatic --noinput"

我深入研究了日志,发现 cfn-init-cmd.log 中的这些消息最有帮助:

2020-06-18 04:01:49,965 P18083 [INFO] Config postbuild_0_DjangoApp_smt_prod
2020-06-18 04:01:49,991 P18083 [INFO] ============================================================
2020-06-18 04:01:49,991 P18083 [INFO] Test for Command 01_makeAppMigrations
2020-06-18 04:01:49,995 P18083 [INFO] Completed successfully.
2020-06-18 04:01:49,995 P18083 [INFO] ============================================================
2020-06-18 04:01:49,995 P18083 [INFO] Command 01_makeAppMigrations
2020-06-18 04:01:49,998 P18083 [INFO] -----------------------Command Output-----------------------
2020-06-18 04:01:49,998 P18083 [INFO]   /bin/sh: django-admin.py: command not found
2020-06-18 04:01:49,998 P18083 [INFO] ------------------------------------------------------------
2020-06-18 04:01:49,998 P18083 [ERROR] Exited with error code 127

我不确定为什么它在这个最新的环境中找不到该命令。 我已经将具有相同配置文件的相同应用程序部署到先前的 beanstalk 环境中,完全没有问题。现在唯一的区别是这个新环境是在 VPC 中启动的,并且使用的是最新的推荐平台。

旧 Beanstalk 环境平台:在 64 位 Amazon Linux/2.9.3 上运行的 Python 3.6

新的 Beanstalk 环境平台:在 64 位 Amazon Linux 2/3.0.2 上运行的 Python 3.7

在此迁移过程中,我遇到了与此最新平台的语法更新相关的其他问题。我希望这个问题也只是一个简单的语法问题,但我挖得很远却没有运气......

如果有人能指出我在这里遗漏的明显内容,我将不胜感激! 如果我能提供一些额外的信息,请告诉我!

【问题讨论】:

django 安装了吗?登录实例后,可以手动运行这些命令吗? @Marcin 当我关注这篇文章时:***.com/a/20070161/3814008 在通过 SSH 将这些命令运行到实例中时,我无法通过第 2 步。运行“source /opt/python/run/venv/ bin/activate”返回一个“-bash:/opt/python/run/venv/bin/activate:没有这样的文件或目录”当我在以前的环境中执行这些相同的步骤时,我没有问题。在我的 requirements.txt 文件中,我确实列出了 Django 2.2.6。我不记得为了让 Django 安装 AWS 实例而必须做任何其他事情? 我想指出,在上面链接的帖子中,我看到有人在答案下评论说,答案对于 Beanstalk 中最新的 Python 3.7、Amazon 2 平台不再有效。为什么会这样? 使用在 64 位 Amazon Linux 2/3.0.2 上运行的最新环境 Python 3.7 时,我遇到了同样的问题。 @WaheedAhmed 我终于能够在最新的 Beanstalk 平台上启动并运行它。在下面查看我的答案!希望能帮到你! 【参考方案1】:

在深入了解 AWS 文档和论坛之后,终于弄清了这一切......

基本上,随着 Beanstalk 从 Amazon Linux 迁移到 Amazon Linux 2,发生了很多变化。here 含糊提及了很多这些变化。

上面链接中提到的 Python 平台的一个主要区别是“您的环境的 Amazon EC2 实例上的应用程序目录的路径是 /var/app/current。它是 /opt/python/current/app在 Amazon Linux AMI 平台上。”这对于您尝试创建 Django 迁移脚本(我将在下面进一步详细解释)或您 eb ssh 进入 Beanstalk 实例并自行导航时至关重要。

另一个主要区别是引入了平台钩子,在这篇精彩的文章here中提到了这一点。根据这篇文章,“平台挂钩是应用程序包内的一组目录,您可以使用脚本填充这些目录。”本质上,这些脚本现在将处理 .ebextensions 配置文件中之前的 container_commands 处理的内容。以下是这些平台挂钩的目录结构:

知道了这一点,并浏览了这个论坛here,优秀的社区成员在填补亚马逊文档中的空白处遇到了麻烦,我能够通过以下文件设置成功部署:

(请注意,“MDGOnline”是我的 Django 应用程序的名称)

.ebextensions\01_packages.config

packages:
  yum:
    git: []
    postgresql-devel: []
    libjpeg-turbo-devel: []

.ebextensions\django.config

container_commands:
  01_sh_executable:
    command: find .platform/hooks/ -type f -iname "*.sh" -exec chmod +x  \;
option_settings:
  aws:elasticbeanstalk:application:environment:
    DJANGO_SETTINGS_MODULE: MDGOnline.settings
  aws:elasticbeanstalk:environment:proxy:staticfiles:    
    /static: static
    /static_files: static_files
  aws:elasticbeanstalk:container:python:
    WSGIPath: MDGOnline.wsgi:application

.platform\hooks\predeploy\01_migrations.sh

#!/bin/bash

source /var/app/venv/*/bin/activate
cd /var/app/staging

python manage.py makemigrations
python manage.py migrate
python manage.py createfirstsuperuser
python manage.py collectstatic --noinput

请注意,“.sh”脚本需要基于 linux。我遇到了一段时间部署失败的错误,并在日志中提供了此消息:.platform\hooks\predeploy\01_migrations.sh failed with error fork/exec .platform\hooks\predeploy\01_migrations.sh: no such file or directory 。 原来这是因为我在我的 Windows 开发环境中创建了这个脚本。我的解决方案是在 linux 环境中创建它,然后将其复制到我在 Windows 中的开发环境目录中。我敢肯定,有一些方法可以将 DOS 转换为 Unix。这个看起来很有前途dos2unix!

我真的希望 AWS 能够更好地记录此迁移,但我希望此答案可以为某人节省我为使此部署成功所花费的无数时间。

请随时要求我澄清以上任何内容!

编辑:我在上面的配置文件中添加了一个“container_command”,因为我注意到另一个用户在部署时也遇到了平台挂钩的“权限被拒绝”错误。此“01_sh_executable”命令用于对应用程序 hooks 目录中的所有 .sh 脚本进行 chmod,以便 Elastic Beanstalk 可以在部署过程中拥有执行它们的适当权限。我在这个论坛here找到了这个容器命令解决方案:

【讨论】:

我收到此错误:Stderr:.platform/hooks/predeploy/01_migrations.sh: line 3: /var/app/env/*/bin/activate: No such file or directory。看来他们改变了实例结构。 @DavidWeinberg 嘿,大卫,这个错误听起来像我在上面的答案中提到的错误。你是在windows环境下创建的.sh脚本吗? @Adam 我很高兴听到它对其他人有用! :) 爱你!!!!几天来我一直在寻找解决方案,它奏效了!谢谢! @YamenAlghrer 是的,最终成功解决了这个问题,谢谢【参考方案2】:

这可能有效 .ebextensions/django.config

   option_settings:
  aws:elasticbeanstalk:container:python:
    WSGIPath: mysite.wsgi:application
  aws:elasticbeanstalk:environment:proxy:staticfiles:
    /static: static
packages: 
  yum:
    python3-devel: []
    mariadb-devel: []
container_commands:
  01_collectstatic:
    command: "source /var/app/venv/staging-LQM1lest/bin/activate && python manage.py collectstatic --noinput"
  02_migrate:
    command: "source /var/app/venv/staging-LQM1lest/bin/activate && python manage.py migrate --noinput"
    leader_only: true

【讨论】:

【参考方案3】:

这对我有用。

container_commands:
  01_migrate:
    command: "source /var/app/venv/*/bin/activate && python /var/app/staging/manage.py migrate --noinput"
    leader_only: true

【讨论】:

以上是关于AWS Elastic Beanstalk 容器命令失败的主要内容,如果未能解决你的问题,请参考以下文章

AWS Elastic Beanstalk 容器命令失败

AWS Elastic Beanstalk - 多容器 Docker

AWS Elastic Beanstalk:将容器日志流式传输到 CloudWatch 问题

使用 Dockerrun.aws.json 和 Elastic Beanstalk 命名 Docker 容器

AWS Elastic Beanstalk Docker 环境变量

如何解决 AWS Elastic Beanstalk 中的“容器命令构建失败”一般错误?