【问题标题】:Deploy-time commands inside Docker on Elastic Beanstalk在 Elastic Beanstalk 上的 Docker 中部署时命令
【发布时间】:2015-07-31 01:54:29
【问题描述】:

我有一个在 Docker 中运行的 Django 服务,我将它部署到 AWS Elastic Beanstalk。

我想在部署时运行我的数据库迁移

如果我作为“Python 项目”部署到 EB,我的 .ebextensions 中可能包含以下内容:

$ cat .ebextensions/01run.config 
container_commands:
    01migrate:
        command: "python manage.py migrate --noinput"
        leader_only: true

但是,container_commands 用于 EC2 实例 - 在 Docker 容器内我有我的代码等。

我已经看过的东西

  • 我不能只将它添加到我的Dockerfile,因为应用迁移只是在附加的 RDS 实例(由环境提供)上操作 - 并不是真正的“构建 Docker 映像的一部分”

  • 我似乎没有什么有用的东西可以添加到Dockerrun.aws.json

到目前为止我已经确定的黑客选项

  • 我也许可以在 container_commands 中识别 Docker 映像名称,然后执行 docker run -ti $container-name python manage.py migrate 等,但不知道如何,感觉非常hacky

  • 我可以手动运行迁移

  • 我可以将CMD gunicorn $etc 替换为CMD $script,其中$script 应用迁移,然后启动gunicorn。

    • 这是迄今为止我发现的最不可怕的事情,也是我将要做的权宜之计。
    • 这意味着“每次我启动一个实例时都尝试应用迁移”,这并不让我感到舒服和快乐。

非常欢迎您提出想法!

【问题讨论】:

  • 这可能就是你要找的stackoverflow.com/a/29566028/1048839
  • 对不起,如果我来晚了,但是在这里放置一个脚本/opt/elasticbeanstalk/hooks/appdeploy/pre 将在部署之前执行脚本,/opt/elasticbeanstalk/hooks/appdeploy/post 将在部署之后执行它,如果那是你正在寻找的。

标签: python django amazon-web-services docker


【解决方案1】:

您可以像这样在 .ebextensions 中添加部署后脚本:

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

我只包括了领导者,以防您可能正在使用负载平衡环境,它不会同时在多台服务器上运行迁移。这也可以用于collectstatic 命令。

【讨论】:

  • 如果您在 Elastic Beanstalk 中使用单个容器 docker 设置,您可以像这样运行迁移命令:sudo docker exec $(sudo docker ps -q) ./manage.py migrate --noinput
  • 可以确认此方法适用于 Elastic Beanstalk 多容器 Docker (Amazon Linux/2.20.2)。
  • 请注意,对于最近的 AMI,应该使用不同的目录结构,基于新的钩子:docs.aws.amazon.com/elasticbeanstalk/latest/dg/…
【解决方案2】:

我认为在 Dockerfile 中使用 ENTRYPOINT 可能会解决您的问题。

您可以在容器映像中创建一个脚本(负责数据库迁移、启动网络服务器和其他健全性检查)并在 Dockerfile ENTRYPOINT 中调用该脚本。

ADD run_all /opt/bin/
ENTRYPOINT ["/opt/bin/run_all"]

这样脚本只会在您创建该图像的容器时执行。

或者使用 ENTRYPOINT

运行这两个命令(Python manage.py migrate && httpd start)

【讨论】:

  • 如果我理解正确,您是建议在容器构建时执行此操作(我不希望这样做),还是我的 $script 建议? (我不清楚使用ENTRYPOINT 而不是CMD 的优点,就像你说的......?)
  • 我的错,我没有阅读您问题中的“CMD $script”点。它本质上是一样的,所以答案不适用,因为你不想每次容器启动时都运行命令。
猜你喜欢
  • 2015-10-23
  • 2018-04-16
  • 2016-09-20
  • 2021-12-18
  • 2014-12-13
  • 2015-09-15
  • 1970-01-01
  • 2015-12-17
  • 2017-01-29
相关资源
最近更新 更多