python - AWS Elastic Beanstalk 容器命令失败
问题描述
我一直在努力尝试将我的 Django Web App 成功部署到 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
在此迁移过程中,我遇到了与此最新平台的语法更新相关的其他问题。我希望这个问题也只是一个简单的语法问题,但我已经挖得很远,没有运气......
如果有人能指出我在这里遗漏的一些明显的东西,我将不胜感激!如果我能提供一些额外的信息,请告诉我!
解决方案
在深入了解 AWS 文档和论坛之后,终于找到了这一切……
本质上,随着 Beanstalk 从 Amazon Linux 迁移到 Amazon Linux 2,发生了很多变化。其中很多变化在这里被模糊地提及。
上面链接中提到的 Python 平台的一个主要区别是“您环境的 Amazon EC2 实例上应用程序目录的路径是 /var/app/current。在 Amazon Linux 上是 /opt/python/current/app AMI 平台。” 这对于您尝试创建 Django 迁移脚本(我将在下面进一步详细解释)或您eb ssh
进入 Beanstalk 实例并自行导航时至关重要。
另一个主要区别是引入了 Platform hooks,在这篇精彩的文章中提到了。根据这篇文章,“平台挂钩是应用程序包内的一组目录,您可以使用脚本填充这些目录。” 本质上,这些脚本现在将处理 .ebextensions 配置文件中之前的 container_commands 处理的内容。以下是这些平台挂钩的目录结构:
知道了这一点,并浏览了这个论坛,优秀的社区成员在填补亚马逊文档中的空白时遇到了麻烦,我能够通过以下文件设置成功部署:
(请注意,“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 可以在部署过程中拥有执行它们的适当权限。我在这个论坛中找到了这个容器命令解决方案:
推荐阅读
- shinyproxy - shinyproxy 无法使用默认用户和密码登录
- android - 在 Flutter FireBase 谷歌签名中,如何为我的给定代码维护持久性签名
- python - 如果键之一是或字典中的“0”,如何获取键
- java - How to test & parse brackets from a String?
- autohotkey - 何时在 AutoHotKey 中使用 % 或 %variable%?
- reactjs - 如何使用 react 和 typescript 使用 usecontext react 钩子创建可重用的 /common 对话框组件?
- php - 通过 php 和 sql 的交易系统
- linux - 使 strlcpy 在 linux 中可用
- c++ - 用于检查容器类中是否存在函数的 C++ 概念和隐式推导规则
- lua - Lua如何在不使用循环的情况下将二维表的第一个成员放入新表?