I have a Django service running inside Docker that I deploy to AWS Elastic Beanstalk.
I would like to run my database migrations at deploy-time
If I were deploying to EB as "a Python project", I could have the following in my .ebextensions
:
$ cat .ebextensions/01run.config
container_commands:
01migrate:
command: "python manage.py migrate --noinput"
leader_only: true
However, container_commands
are for the EC2 instances - and it's inside the Docker container that I have my code etc.
I can't just add it to my Dockerfile
, because applying migrations is all about operating on the attached RDS instance (supplied by the environment) - not really "part of building the Docker image"
There doesn't seem to be anything useful I can add to Dockerrun.aws.json
I could perhaps identify the Docker image name inside my container_commands
and then do docker run -ti $container-name python manage.py migrate
etc., but no idea how and it feels awfully hacky
I could run the migrations by hand
I could replace CMD gunicorn $etc
with CMD $script
, where $script
applies migrations and then starts gunicorn.
Ideas very much welcomed please!
This platform branch offers both single-container and multi-container support. Elastic Beanstalk deploys a Docker image and source code to EC2 instances on this platform branch. Use the Docker Compose tool on the Docker platform to simplify your application configuration, testing, and deployment.
You could add a post deploy script in your .ebextensions like so:
files:
"/opt/elasticbeanstalk/hooks/appdeploy/post/10_migrate.sh":
mode: "000755"
owner: root
group: root
content: |
#!/usr/bin/env bash
if [ -f /tmp/leader_only ]; then
echo "Running Migrations"
container_id=`docker ps -q --no-trunc --filter label="com.amazonaws.ecs.container-name=MY_CONTAINER_NAME" | head -n 1`
docker inspect $container_id
docker exec $container_id /entrypoint.sh python manage.py migrate --noinput
fi
"/opt/elasticbeanstalk/hooks/appdeploy/post/90_rm_leader_only.sh":
mode: "000755"
owner: root
group: root
content: |
#!/usr/bin/env bash
if [ -f /tmp/leader_only ]; then
echo "Deleting leader_only file"
rm /tmp/leader_only
fi
container_commands:
01_touch_the_leader:
command: |
#!/usr/bin/env bash
touch /tmp/leader_only
leader_only: true
I have included the leader only bit in case you might be using a load balanced environment, it won't run migrations on multiple servers at once. This can also be used for the collectstatic
command.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With