Tengo un proyecto Django que se implementa en Elastic Beanstalk Amazon Linux 2 AMI. Instalé PyMySQL para conectarme a la base de datos y agregué estas líneas a settings.py como a continuación;
import pymysql pymysql.version_info = (1, 4, 6, "final", 0) pymysql.install_as_MySQLdb()Y también tengo un archivo .config para migrar la base de datos;
container_commands: 01_migrate: command: "django-admin.py migrate" leader_only: true option_settings: aws:elasticbeanstalk:application:environment: DJANGO_SETTINGS_MODULE: mysite.settings Normalmente, estaba usando mysqlclient en mi AMI de Linux con este archivo .config, pero no funciona en la AMI de Linux 2, así que instalé PyMySQL. Ahora, estoy tratando de implementar la versión actualizada de mi proyecto, pero recibo un error como el siguiente;
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¿Cómo puedo solucionar este problema?
Amazon Linux 2 tiene una configuración fundamentalmente diferente a AL1, y la documentación actual al 24 de julio de 2020 está desactualizada. django-admin del entorno instalado por beanstalk no parece estar en la ruta, por lo que puede obtener el entorno para activarlo y asegurarse de que lo esté.
Dejé mi respuesta aquí también, que detalla mucho más cómo llegué a esta respuesta, pero la solución (que no me encanta) es:
container_commands: 01_migrate: command: "source /var/app/venv/*/bin/activate && python3 manage.py migrate" leader_only: trueAunque no me encanta, he verificado con AWS Support que, de hecho, esta es la forma recomendada de hacerlo. Debe obtener el entorno de python, ya que con AL2 usan entornos virtuales en un esfuerzo por ser más consistentes.
en mi caso funciono este .config
container_commands: 01_migrate: comando: "django-admin.py migrar" leader_only: verdadero 02_collectstatic: comando: "django-admin.py collectstatic --noinput"
tenía este comando: "source /var/app/venv/*/bin/activate && python3 manage.py config hasta el 4 de enero y de repente recibí un error de implementación
La respuesta de @nick-brady es excelente y proporciona la solución básica.
Sin embargo, los documentos de AWS sobre la migración a Amazon Linux 2 sugieren que deberíamos hacer cosas como esta usando ganchos .platform :
Recomendamos usar enlaces de plataforma para ejecutar código personalizado en las instancias de su entorno. Todavía puede usar comandos y comandos de contenedor en archivos de configuración
.ebextensions, pero no es tan fácil trabajar con ellos. Por ejemplo, escribir scripts de comandos dentro de un archivo YAML puede ser engorroso y difícil de probar.
y del Centro de conocimiento de AWS :
... es una buena práctica usar ganchos de plataforma en lugar de proporcionar archivos y comandos en archivos de configuración
.ebextension.
Como beneficio adicional, la salida de los ganchos de la plataforma se recopila en un archivo de registro separado ( /var/log/eb-hooks.log ), que se incluye en los registros de paquetes y colas de forma predeterminada. Esto hace que la depuración sea un poco más fácil.
La idea básica es crear un script de shell en el paquete fuente de su aplicación, por ejemplo, .platform/hooks/postdeploy/01_django_migrate.sh . Esto se describe con más detalle en la sección de enlaces de plataforma en los documentos para extender las plataformas EB Linux .
El archivo debe ser ejecutable, entonces: chmod +x .platform/hooks/postdeploy/01_django_migrate.sh
El contenido del archivo podría verse así (basado en la respuesta de @nick-brady ):
#!/bin/bash source "$PYTHONPATH/activate" && { # log which migrations have already been applied python manage.py showmigrations; # migrate python manage.py migrate --noinput; } Puedes hacer lo mismo con collectstatic , etc.
Tenga en cuenta que la ruta al entorno virtual de Python está disponible para enlaces de plataforma como la variable de entorno PYTHONPATH . Puede verificar esto inspeccionando el archivo /opt/elasticbeanstalk/deployment/env en su instancia, por ejemplo, a través de ssh. Consulte también el centro de conocimientos de AWS .
Para aquellos que se preguntan, el && en el script de shell es una especie de ejecución condicional: solo haga lo siguiente si lo anterior tuvo éxito. Véase, por ejemplo , aquí .
Durante la implementación, debe haber una variable de entorno EB_IS_COMMAND_LEADER , que se puede probar para implementar el comportamiento leader_only en .platform hooks (basado en esta publicación ):
... 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 ...