在AWS Elastic Beanstalk上使用Docker进行Django迁移

时间:2015-08-13 03:20:27

标签: amazon-web-services docker elastic-beanstalk

我在AWS Elastic Beanstalk上的单个docker容器中运行了一个django应用程序。我无法让它正常运行迁移,它始终会看到旧的docker镜像并尝试从中运行迁移(但它没有最新的文件)。

我使用我的EBS源包(包含Dockerrun.aws.json文件和.ebextensions目录的zip)打包.ebextensions目录。它有一个setup.config文件,如下所示:

container_commands:
  01_migrate:
    command: "CONTAINER=`docker ps -a --no-trunc | grep aws_beanstalk | cut -d' ' -f1 | head -1` && docker exec $CONTAINER python3 manage.py migrate"
    leader_only: true

this SO question的评论进行部分建模。

如果我只是第二次重新部署应用程序,我已经验证可以正常工作,因为这次上一次运行的图像将包含更新的迁移文件。

有谁知道如何在.ebextensions脚本中访问最新的docker镜像或最新运行的容器?

2 个答案:

答案 0 :(得分:8)

根据Customizing Software on Linux Servers上的AWS文档,container_commands将在您的应用部署之前执行。

  

您可以使用container_commands键为容器执行命令。 container_commands中的命令按名称按字母顺序处理。 它们在应用程序和Web服务器设置之后运行,并且已提取应用程序版本文件,但在部署应用程序版本之前 。他们还可以访问环境变量,例如您的AWS安全凭证。此外,您可以使用leader_only。选择一个实例作为Auto Scaling组的领导者。如果leader_only值设置为true,则该命令仅在标记为领导者的实例上运行。

here中查看我的答案。它在不同的app部署状态下运行一些命令并给出命令结果。

因此,您的问题解决方案可能是创建应用后部署挂钩

<强> .ebextensions / 00_post_migrate.config

files:
  "/opt/elasticbeanstalk/hooks/appdeploy/post/10_post_migrate.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/usr/bin/env bash
      if [ -f /tmp/leader_only ]
      then
        rm /tmp/leader_only
        docker exec `docker ps --no-trunc -q | head -n 1` python3 manage.py migrate
      fi

container_commands:
  01_migrate:
    command: "touch /tmp/leader_only"
    leader_only: true

答案 1 :(得分:3)

我正在使用另一种方法。我所做的是基于新构建的映像运行容器,然后从Elastic Beanstalk传入环境变量并在该容器中运行自定义命令。完成该命令后,它将自行删除并继续部署。

所以这是我放在.ebextensions/scripts/container_command.sh内的脚本(请确保替换&lt;&gt;内的所有内容):

#!/bin/bash

COMMAND=$1

EB_CONFIG_DOCKER_IMAGE_STAGING=$(/opt/elasticbeanstalk/bin/get-config container -k <environment_name>_image)
EB_SUPPORT_FILES=$(/opt/elasticbeanstalk/bin/get-config container -k support_files_dir)

# build --env arguments for docker from env var settings
EB_CONFIG_DOCKER_ENV_ARGS=()

while read -r ENV_VAR; do
    EB_CONFIG_DOCKER_ENV_ARGS+=(--env "${ENV_VAR}")
done < <($EB_SUPPORT_FILES/generate_env)

docker run --name=shopblender_pre_deploy -d \
    "${EB_CONFIG_DOCKER_ENV_ARGS[@]}" \
    "${EB_CONFIG_DOCKER_IMAGE_STAGING}"

docker exec shopblender_pre_deploy ${COMMAND}

# clean up
docker stop shopblender_pre_deploy
docker rm shopblender_pre_deploy

现在,您可以使用此脚本对稍后将部署的容器执行任何自定义命令。

.ebextensions/container_commands.config这样的东西:

container_commands:
    01-command:
        command: bash .ebextensions/scripts/container_command.sh "php app/console doctrine:schema:update --force --no-interaction" &>> /var/log/database.log
        leader_only: true
    02-command:
        command: bash .ebextensions/scripts/container_command.sh "php app/console fos:elastica:reset --no-interaction" &>> /var/log/database.log
        leader_only: true
    03-command:
        command: bash .ebextensions/scripts/container_command.sh "php app/console doctrine:fixtures:load --no-interaction" &>> /var/log/database.log
        leader_only: true

这样您也不必担心最新启动的容器是什么,这是上述解决方案的问题。