命令 01_migrate 在 Amazon Linux 2 AMI 上失败

问题描述 投票:0回答:4

我有一个部署到 Elastic Beanstalk Amazon Linux 2 AMI 的 Django 项目。我安装了 PyMySQL 来连接到数据库,并将这些行添加到 settings.py 中,如下所示;

import pymysql

pymysql.version_info = (1, 4, 6, "final", 0)
pymysql.install_as_MySQLdb()

我还有一个用于迁移数据库的 .config 文件;

container_commands:
  01_migrate:
    command: "django-admin.py migrate"
    leader_only: true
option_settings:
  aws:elasticbeanstalk:application:environment:
    DJANGO_SETTINGS_MODULE: mysite.settings

通常,我在我的 Linux AMI 上使用

mysqlclient
和这个 .config 文件,但它在 Linux 2 AMI 上不起作用,所以我安装了 PyMySQL。现在,我正在尝试部署项目的更新版本,但收到如下错误;

Traceback (most recent call last):
  File "/opt/aws/bin/cfn-init", line 171, in <module>
    worklog.build(metadata, configSets)
  File "/usr/lib/python2.7/site-packages/cfnbootstrap/construction.py", line 129, in build
    Contractor(metadata).build(configSets, self)
  File "/usr/lib/python2.7/site-packages/cfnbootstrap/construction.py", line 530, in build
    self.run_config(config, worklog)
  File "/usr/lib/python2.7/site-packages/cfnbootstrap/construction.py", line 542, in run_config
    CloudFormationCarpenter(config, self._auth_config).build(worklog)
  File "/usr/lib/python2.7/site-packages/cfnbootstrap/construction.py", line 260, in build
    changes['commands'] = CommandTool().apply(self._config.commands)
  File "/usr/lib/python2.7/site-packages/cfnbootstrap/command_tool.py", line 117, in apply
    raise ToolError(u"Command %s failed" % name)
ToolError: Command 01_migrate failed

我该如何解决这个问题?

django amazon-elastic-beanstalk pymysql amazon-linux amazon-linux-2
4个回答
17
投票

Amazon Linux 2 的设置与 AL1 根本不同,截至 2020 年 7 月 24 日的当前文档已过时。 beanstalk 安装的环境的

django-admin
似乎不在路径上,因此您可以获取要激活的环境并确保它在路径上。

我也在这里留下了我的答案,其中更详细地说明了我如何得出这个答案,但解决方案(我不喜欢)是: container_commands: 01_migrate: command: "source /var/app/venv/*/bin/activate && python3 manage.py migrate" leader_only: true

尽管我不喜欢它,但我已向 AWS Support 核实,这实际上是推荐的执行此操作的方法。您
必须

获取Python环境,就像AL2一样,他们使用虚拟环境来保持更加一致。


12
投票

答案很棒,它提供了基本的解决方案。 但是,有关

迁移到 Amazon Linux 2

的 AWS 文档建议我们应该使用 .platform 钩子执行类似的操作:


我们建议使用平台挂钩在您的环境实例上运行自定义代码。您仍然可以在
.ebextensions

配置文件中使用命令和容器命令,但它们并不那么容易使用。例如,在 YAML 文件中编写命令脚本可能很麻烦且难以测试。


以及来自
AWS 知识中心

...最好的做法是使用平台挂钩,而不是在
.ebextension

配置文件中提供文件和命令。


作为奖励,平台钩子的输出被收集在单独的日志文件(
/var/log/eb-hooks.log

)中,默认情况下包含在捆绑包和尾部日志中。这使得调试变得更容易一些。

基本思想是在应用程序源包中创建一个 shell 脚本,例如

.platform/hooks/postdeploy/01_django_migrate.sh

扩展 EB Linux 平台的文档
中的平台挂钩部分对此进行了更详细的描述。 该文件必须是可执行的,因此:

chmod +x .platform/hooks/postdeploy/01_django_migrate.sh

文件内容可能如下所示(基于 

@nick-brady 的回答

): #!/bin/bash source "$PYTHONPATH/activate" && { # log which migrations have already been applied python manage.py showmigrations; # migrate python manage.py migrate --noinput; }

您可以对
collectstatic

等进行同样的操作

请注意,Python 虚拟环境的路径可作为环境变量 

PYTHONPATH

供平台挂钩使用。您可以通过检查实例上的文件

/opt/elasticbeanstalk/deployment/env
来验证这一点,例如通过 ssh。另请参阅
AWS 知识中心
对于那些想知道的人来说,shell 脚本中的

&&

是一种条件执行:仅当前面的操作成功时才执行以下操作。 参见例如

这里
仅限领导者

在部署期间,应该有一个

EB_IS_COMMAND_LEADER

环境变量,可以对其进行测试,以便在

leader_only
钩子中实现
.platform
行为(基于
this post
): ... if [[ $EB_IS_COMMAND_LEADER == "true" ]]; then python manage.py migrate --noinput; python manage.py collectstatic --noinput; else echo "this instance is NOT the leader"; fi ...



1
投票

容器命令: 01_迁移: 命令:“django-admin.py 迁移” 仅领导者:正确 02_收集静态: 命令:“django-admin.pycollectstatic--noinput”

我有这个命令:“source /var/app/venv/*/bin/activate && python3 manage.py config 直到 1 月 4 日,突然出现部署错误


0
投票

问题似乎是当 AL2 运行时

python manage.py migrate

它无法访问我存储数据库连接信息的环境变量。

解决方案是使用以下代码将另一个文件添加到

.ebextensions

    commands:
    setvars:
        command: /opt/elasticbeanstalk/bin/get-config environment | jq -r 'to_entries | .[] | "export \(.key)=\"\(.value)\""' > /etc/profile.d/sh.local
packages:
    yum:
        jq: []

我将此文件命名为
setvars.config

来源:

https://repost.aws/knowledge-center/elastic-beanstalk-env-variables-shell

© www.soinside.com 2019 - 2024. All rights reserved.