17👍
Amazon Linux 2 has a fundamentally different setup than AL1, and the current documentation as of Jul 24, 2020 is out of date. django-admin
of the installed environment by beanstalk does not appear to be on the path, so you can source the environment to activate and make sure it is.
I left my answer here as well which goes into much more detail in how I arrived at this answer, but the solution (which I don’t love) is:
container_commands:
01_migrate:
command: "source /var/app/venv/*/bin/activate && python3 manage.py migrate"
leader_only: true
Even though I don’t love it, I have verified with AWS Support that this is in fact the recommended way to do this. You must source the python environment, as with AL2 they use virtual environments in an effort to stay more consistent.
12👍
The answer from @nick-brady is great, and it provides the basic solution.
However, the AWS docs on migrating to Amazon Linux 2 suggest that we should do things like this using .platform
hooks:
We recommend using platform hooks to run custom code on your environment instances. You can still use commands and container commands in
.ebextensions
configuration files, but they aren’t as easy to work with. For example, writing command scripts inside a YAML file can be cumbersome and difficult to test.
and from the AWS Knowledge Center:
… it’s a best practice to use platform hooks instead of providing files and commands in
.ebextension
configuration files.
As a bonus, output from the platform hooks is collected in a separate log file (/var/log/eb-hooks.log
), which is included in bundle and tail logs by default. This makes debugging a bit easier.
The basic idea is to create a shell script in your application source bundle, e.g. .platform/hooks/postdeploy/01_django_migrate.sh
. This is described in more detail in the platform hooks section in the docs for extending EB linux platforms.
The file must be executable, so: chmod +x .platform/hooks/postdeploy/01_django_migrate.sh
The file content could look like this (based on @nick-brady’s answer):
#!/bin/bash
source "$PYTHONPATH/activate" && {
# log which migrations have already been applied
python manage.py showmigrations;
# migrate
python manage.py migrate --noinput;
}
You can do the same with collectstatic
etc.
Note that the path to the Python virtual environment is available to platform hooks as the environment variable PYTHONPATH
. You can verify this by inspecting the file /opt/elasticbeanstalk/deployment/env
on your instance, e.g. via ssh. Also see AWS knowledge center.
For those wondering, the &&
in the shell script is a kind of conditional execution: only do the following if the preceding succeeded.
See e.g. here.
Leader only
During deployment, there should be an EB_IS_COMMAND_LEADER
environment variable, which can be tested in order to implement leader_only
behavior in .platform
hooks (based on 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
...
- Is there a way to render a html page without view model?
- Override Django allauth signup "next" redirect URL
1👍
in my case worked this .config
container_commands:
01_migrate:
command: "django-admin.py migrate"
leader_only: true
02_collectstatic:
command: "django-admin.py collectstatic –noinput"
i had this command: "source /var/app/venv/*/bin/activate && python3 manage.py config until 4 Jan and suddenly i got a deployment error
- Django form validation: making "required" conditional?
- How to get coverage data from a django app when running in gunicorn
- Facebook, Django, and Google App Engine
- How do I reply to an email using the Python imaplib and include the original message?
0👍
I ran into this issue as well. @nick-brady answer was the solution until recently when I started to get the error again.
The issue seemed to be that when AL2 ran python manage.py migrate
it didn’t have access to my environment variables storing the database connection info.
The solution was to add another file to .ebextensions
with the following code:
commands:
setvars:
command: /opt/elasticbeanstalk/bin/get-config environment | jq -r 'to_entries | .[] | "export \(.key)=\"\(.value)\""' > /etc/profile.d/sh.local
packages:
yum:
jq: []
I named this file setvars.config
Source: https://repost.aws/knowledge-center/elastic-beanstalk-env-variables-shell
- Django models across multiple projects/microservices. How to?
- Multiple USERNAME_FIELD in django user model
- Django/Celery multiple queues on localhost – routing not working
- Why does docker-compose build not reflect my django code changes?