将 Django 部署到 Elastic Beanstalk,迁移失败

Posted

技术标签:

【中文标题】将 Django 部署到 Elastic Beanstalk,迁移失败【英文标题】:Deploying Django to Elastic Beanstalk, migrations failed 【发布时间】:2020-10-08 22:25:49 【问题描述】:

我正在尝试部署一个我一直在使用 django 进行的项目。在开发中,我一直在使用 SQLite,在生产中我正在尝试使用 mysql

通常当我创建 EB 实例时,一切运行正常,并且控制台显示状态正常。在尝试部署(在 ebcli 中运行 eb deploy)时,我遇到了以下错误

2020/06/18 15:59:50.357281 [INFO] Copying file /opt/elasticbeanstalk/config/private/rsyslog.conf to /etc/rsyslog.d/web.conf
2020/06/18 15:59:50.358945 [INFO] Running command /bin/sh -c systemctl restart rsyslog.service
2020/06/18 15:59:50.394223 [INFO] Executing instruction: PostBuildEbExtension
2020/06/18 15:59:50.394243 [INFO] No plugin in cfn metadata.
2020/06/18 15:59:50.394252 [INFO] Starting executing the config set Infra-EmbeddedPostBuild.
2020/06/18 15:59:50.394273 [INFO] Running command /bin/sh -c /opt/aws/bin/cfn-init -s arn:aws:cloudformation:eu-west-2:433403353655:stack/awseb-e-qamgvpp7ft-stack/3e6774d0-b17c-11ea-9476-0a5f6fd32d44 -r AWSEBAutoScalingGroup --region eu-west-2 --configsets Infra-EmbeddedPostBuild
2020/06/18 15:59:50.721919 [ERROR] Error occurred during build: Command 01_migrate failed

2020/06/18 15:59:50.721944 [ERROR] An error occurred during execution of command [app-deploy] - [PostBuildEbExtension]. Stop running the command. Error: Container commands build failed. Please refer to /var/log/cfn-init.log for more details. 

2020/06/18 15:59:50.721949 [INFO] Executing cleanup logic
2020/06/18 15:59:50.722079 [INFO] CommandService Response: "status":"FAILURE","api_version":"1.0","results":["status":"FAILURE","msg":"Engine execution has encountered an error.","returncode":1,"events":[]]

2020/06/18 15:59:50.722249 [INFO] Platform Engine finished execution on command: app-deploy

罪魁祸首似乎是我的db迁移命令,如下,在'.ebextensions'中,命名为'db-migrate.config'

container_commands:
  01_migrate:
    command: "django-admin.py migrate"
    leader_only: true

option_settings:
    aws:elasticbeanstalk:application:environment:
        DJANGO_SETTINGS_MODULE: djangomicroblog.settings

原来的错误信息也指向我来自'/var/log/cfn-init.log的日志,这里看到的错误如下

2020-06-18 14:18:23,279 [ERROR] -----------------------BUILD FAILED!------------------------
2020-06-18 14:18:23,279 [ERROR] Unhandled exception during build: Command 01_migrate failed
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

我已尝试搜索这些错误消息,但结果非常有限且似乎不起作用。

我的settings.py中设置数据库的函数也如下

def get_db():
    try:
        return 
           'default': 
               'ENGINE': 'django.db.backends.mysql',
               'NAME': os.environ['RDS_DB_NAME'],
               'USER': os.environ['RDS_USERNAME'],
               'PASSWORD': os.environ['RDS_PASSWORD'],
               'HOST': os.environ['RDS_HOSTNAME'],
               'PORT': os.environ['RDS_PORT'],
           
        
    except:
        return 
            'default': 
                'ENGINE': 'django.db.backends.sqlite3',
                'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    


DATABASES = get_db()

任何帮助将不胜感激

【问题讨论】:

你解决了吗?我有同样的问题。 我做到了,原来问题是我为 Amazon linux 1 环境设置了应用程序,但我使用的是 amazon linux 2 环境。 Amazon linux 2 似乎很新,我找不到转换我的应用程序的方法,所以我在 amazon linux 1 中重新制作了环境(python 3.6 而不是 3.7)。我的另一篇文章有​​更多细节 解决方法跟我一样!感谢您的回答,祝您有愉快的一天。 【参考方案1】:

我遇到了同样的问题,使用 Amazon Linux 2Python 3.7 就像 OP 一样。 AWS 没有更新他们的文档来支持平台的变化,这使得这非常混乱。我找到了解决方法,虽然我不喜欢它,但这是我的解决方案:

TLDR - 这是我的解决方案。关于我是如何到达那里的,我在调试时粘贴了我的笔记:

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

尽管我不喜欢它,但我已通过 AWS Support 验证这实际上是推荐的方法。您必须获取 python 环境,就像 AL2 一样,他们使用虚拟环境来保持更加一致。


从12月的AWSAnnouncement of Amazon Linux 2发现安装的python环境存放在/var/app/venv/*/..

2020-07-22 19:20:41,376 [ERROR] -----------------------BUILD FAILED!------------------------
2020-07-22 19:20:41,376 [ERROR] Unhandled exception during build: Command 01_migrate failed
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

我发现了一个日志文件,它实际上告诉我更多有用的信息:/var/log/cfn-init-cmd.log

这给了我这个错误:

2020-07-22 21:08:32,757 P1620 [INFO] ============================================================
2020-07-22 21:08:32,757 P1620 [INFO] Command 01_migrate
2020-07-22 21:08:32,771 P1620 [INFO] -----------------------Command Output-----------------------
2020-07-22 21:08:32,772 P1620 [INFO]      File "manage.py", line 17
2020-07-22 21:08:32,772 P1620 [INFO]        ) from exc
2020-07-22 21:08:32,772 P1620 [INFO]             ^
2020-07-22 21:08:32,772 P1620 [INFO]    SyntaxError: invalid syntax
2020-07-22 21:08:32,772 P1620 [INFO] ------------------------------------------------------------
2020-07-22 21:08:32,772 P1620 [ERROR] Exited with error code 1

这很奇怪。这可能意味着我运行了错误的 python 版本。所以我可能需要修改我的命令: 所以...我尝试过的事情是:

    python manage.py migrate python3 manage.py migrate

这给了我更好的错误信息

2020-07-23 14:47:06,906 P14080 [INFO] ============================================================
2020-07-23 14:47:06,906 P14080 [INFO] Command 01_migrate
2020-07-23 14:47:06,936 P14080 [INFO] -----------------------Command Output-----------------------
2020-07-23 14:47:06,936 P14080 [INFO]   Traceback (most recent call last):
2020-07-23 14:47:06,936 P14080 [INFO]     File "manage.py", line 11, in main
2020-07-23 14:47:06,936 P14080 [INFO]       from django.core.management import execute_from_command_line
2020-07-23 14:47:06,936 P14080 [INFO]   ModuleNotFoundError: No module named 'django'
2020-07-23 14:47:06,937 P14080 [INFO]   
2020-07-23 14:47:06,937 P14080 [INFO]   The above exception was the direct cause of the following exception:
2020-07-23 14:47:06,937 P14080 [INFO]   
2020-07-23 14:47:06,937 P14080 [INFO]   Traceback (most recent call last):
2020-07-23 14:47:06,937 P14080 [INFO]     File "manage.py", line 28, in <module>
2020-07-23 14:47:06,937 P14080 [INFO]       main()
2020-07-23 14:47:06,937 P14080 [INFO]     File "manage.py", line 17, in main
2020-07-23 14:47:06,937 P14080 [INFO]       ) from exc
2020-07-23 14:47:06,937 P14080 [INFO]   ImportError: Couldn't import Django. Are you sure it's installed and available on your PYTHONPATH environment variable? Did you forget to activate a virtual environment?
2020-07-23 14:47:06,937 P14080 [INFO] ------------------------------------------------------------
2020-07-23 14:47:06,937 P14080 [ERROR] Exited with error code 1

但是当我使用python3运行时似乎没有安装python库,所以它可能引用系统python3安装而不是虚拟环境。

我在这个问题上留下了一点咆哮:Python on Amazon Linux 2 platform · Issue #15 · aws/elastic-beanstalk-roadmap · GitHub 这是由于。

    ?source /var/app/venv/*/bin/activate &amp;&amp; python3 manage.py migrate? 我在 EC2 实例上找到了环境并手动获取它以强制它使用正确的 python 版本。这似乎已经解决了python环境问题。现在 RDS 似乎没有数据库,但这似乎更容易修复。
2020-07-23 15:26:32,016 P14702 [INFO] ============================================================
2020-07-23 15:26:32,016 P14702 [INFO] Command 01_migrate
2020-07-23 15:26:32,426 P14702 [INFO] -----------------------Command Output-----------------------
2020-07-23 15:26:32,427 P14702 [INFO]   Traceback (most recent call last):
2020-07-23 15:26:32,427 P14702 [INFO]     File "/var/app/venv/staging-LQM1lest/lib/python3.7/site-packages/django/db/backends/base/base.py", line 220, in ensure_connection
2020-07-23 15:26:32,427 P14702 [INFO]       self.connect()
2020-07-23 15:26:32,427 P14702 [INFO]     File "/var/app/venv/staging-LQM1lest/lib/python3.7/site-packages/django/utils/asyncio.py", line 26, in inner
2020-07-23 15:26:32,427 P14702 [INFO]       return func(*args, **kwargs)
2020-07-23 15:26:32,427 P14702 [INFO]     File "/var/app/venv/staging-LQM1lest/lib/python3.7/site-packages/django/db/backends/base/base.py", line 197, in connect
2020-07-23 15:26:32,427 P14702 [INFO]       self.connection = self.get_new_connection(conn_params)
2020-07-23 15:26:32,427 P14702 [INFO]     File "/var/app/venv/staging-LQM1lest/lib/python3.7/site-packages/django/utils/asyncio.py", line 26, in inner
2020-07-23 15:26:32,427 P14702 [INFO]       return func(*args, **kwargs)
2020-07-23 15:26:32,427 P14702 [INFO]     File "/var/app/venv/staging-LQM1lest/lib/python3.7/site-packages/django/db/backends/postgresql/base.py", line 185, in get_new_connection
2020-07-23 15:26:32,427 P14702 [INFO]       connection = Database.connect(**conn_params)
2020-07-23 15:26:32,428 P14702 [INFO]     File "/var/app/venv/staging-LQM1lest/lib64/python3.7/site-packages/psycopg2/__init__.py", line 127, in connect
2020-07-23 15:26:32,428 P14702 [INFO]       conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
2020-07-23 15:26:32,428 P14702 [INFO]   psycopg2.OperationalError: FATAL:  database "ebdb" does not exist

对我来说,此时我知道 migrate 命令已经成功,所以解决方案就是:

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

当然,我必须连接到 RDS 实例并创建数据库,但它从这里开始工作。

【讨论】:

它对我有用。只是为了强调现在不需要“option_settings”部分。 @DavidWeinberg 你的意思是我可以删除.config 文件中option_settings 下的所有内容吗? @FawwazYusran 我想是的。 非常感谢您的解释。部署时迁移总是给我错误,并且日志根本没有帮助。我真的不明白为什么官方文档给了我们一个根本不起作用的命令。非常感谢。 我使用()而不是双引号“”。 command: (source /var/app/venv/*/bin/activate &amp;&amp; python3 manage.py migrate)

以上是关于将 Django 部署到 Elastic Beanstalk,迁移失败的主要内容,如果未能解决你的问题,请参考以下文章

ModuleNotFoundError:部署到 Elastic Beanstalk 时没有名为“django”的模块

ALLOWED_HOSTS 在部署到 Elastic Beanstalk 的 Django 应用程序中不起作用

Elastic Beanstalk 上的 Docker + Django

无法在 Elastic Beanstalk 上部署 Django 应用程序

Django 在部署到 Elastic Beanstalk 时看不到环境变量

使用 WhiteNoise 在生产模式下将 django 部署到 Elastic Beanstalk