使用单独的Dockerrun.aws.json文件与Travis CI进行单独的分支部署

时间:2018-12-15 21:04:36

标签: travis-ci amazon-elastic-beanstalk

因此,我正在尝试设置一个简单的Multicontainer Elastic Beanstalk应用程序,该应用程序将通过Travis CI自动部署。

此外,我在Elastic Beanstalk上设置了两个环境,一个生产环境和一个暂存环境,并且将.travis.yml文件设置部署到master上的生产环境和stage分支上的暂存中,就像这样:

sudo: required
services:
  - docker
before_install: docker build -t web:ci -f web/Dockerfile.dev web
script: docker run web:ci npm run test -- --coverage
before_deploy:
  - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_ID" --password-stdin
  - bash .build/image_maker.sh
  - bash .build/environment_initializer.sh
deployments:
  elasticbeanstalkdeploy: &elastic_beanstalk_deploy
    skip_cleanup: true
    provider: elasticbeanstalk
    app: "MySuperCoolApp"
    region: "us-east-2"
    bucket_name: "elasticbeanstalk-us-east-2-012345678910"
    bucket_path: "MySuperCoolApp"
    access_key_id: $ELASTIC_BEANSTALK_ACCESS_KEY
    secret_access_key:
      secure: $ELASTIC_BEANSTALK_SECRET_KEY
deploy:
  - <<: *elastic_beanstalk_deploy
    env: "MySuperCoolApp-ProductionEnv"
    on:
      branch: master
  - <<: *elastic_beanstalk_deploy
    env: "MySuperCoolApp-StagingEnv"
    on:
      branch: stage

您会注意到在构建的“ before_deploy”阶段,我将bash称为两个单独的文件。

第一个是image_maker.sh,它负责构建EB应用程序所需的所有图像并将其推送到Docker集线器。

我不会向您显示image_maker.sh文件中的任何代码,因为我确定它可以正常工作且与问题无关,但是您应该知道它根据当前推送到的分支来标记图像。

当被推送到母版时,每个图像都将被标记有production.latest(例如:image_name:production.latest),当被推送到舞台分支时,每个图像将被标记有staging.latest(例如:image_name) :staging.latest。)

要知道这一点很重要,因为它解释了为什么我要尝试下一步(这是我一直在努力的原因)。

基本上,我有两个Dockerrun.aws.json文件,每个文件都存储在生产或暂存子目录下的.build目录中(因此,我在'.build / production / Dockerrun.aws.json'中有一个文件,而另一个在.build / production / Dockerrun.aws.json中。 '.build / staging / Dockerrun.aws.json。')

这是基本的文件结构:

root
  .travis.yml
  .build
    image_maker.sh
    environment_initializer.sh
    production
      - Dockerrun.aws.json
    staging 
      - Dockerrun.aws.json

每个Dockerrun.aws.json文件之间唯一的区别是它们在容器定义中使用了哪个图像标签,登台Dockerrun文件将查找带有staging.latest标签的图像,而生产Dockerrun文件将查找具有标签的图像。 production.latest

似乎很容易。

显而易见的下一步是根据推送到哪个分支将Dockerrun文件移动到根目录,以便当Elastic Beanstalk收到代码时,它知道该怎么做。

这是'before_deploy'命令中第二个bash脚本的唯一目的:.build / environment_initializer.sh。

代码如下:

#!/bin/bash

if [[ "$TRAVIS_PULL_REQUEST" = false ]]; then

  if [ "$TRAVIS_BRANCH" = 'master' ]; then
    echo Moving production Dockerrun.aws.json to root
    mv ./.build/production/Dockerrun.aws.json ./
  fi

  if [ "$TRAVIS_BRANCH" = 'stage' ]; then
    echo Moving staging Dockerrun.aws.json to root
    mv ./.build/staging/Dockerrun.aws.json ./
  fi

fi

理想情况下,我希望它能完全实现我想要的功能并无缝地工作。问题是,无论我如何尝试,我在Elastic Beanstalk日志上总是会遇到相同的错误:

No ecs task definition (or empty definition file) found in environment

这基本上意味着传递给Elastic Beanstalk的代码没有在.build / environment_initializer.sh中进行的更改,这很烂,因为根据我的理解,在deploy命令中使用skip_cleanup可以停止Travis撤消对代码所做的更改。

接下来的尝试让我感到迷茫,到目前为止,我已经对上面的代码进行了约一千种不同的细微调整,包括:

  1. 在environment_initializer.sh文件的末尾添加“ git stash -all”。
  2. 'mv ./.build/production/Dockerrun.aws.json ./'约有一百种版本
  3. 使用cp代替mv。

但是无论我做什么,似乎都没有任何效果。所以现在,我把它留在您手中。任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

原来的问题是Travis如何将代码传递给deploy命令。 显然,Travis使用git将构建阶段的结果传递到部署阶段。通常,Travis将通过运行'git stash --all'清除在构建过程中所做的所有代码更改。

在.travis.yml部署部分中设置skip_cleanup:true 阻止Travis撤消所有更改(通过跳过git stash命令),因为代码仍在通过git传递,因此所有默认情况下,未暂存的文件不会传递给部署。

考虑到这一点,解决方案很简单:

添加“ git add”。将文件移至根目录后,如下所示:

if [[ "$TRAVIS_PULL_REQUEST" = false ]]; then

  if [ "$TRAVIS_BRANCH" = 'master' ]; then
    echo Moving production Dockerrun.aws.json to root
    mv ./.build/production/Dockerrun.aws.json ./
    git add .
  fi

  if [ "$TRAVIS_BRANCH" = 'stage' ]; then
    echo Moving staging Dockerrun.aws.json to root
    mv ./.build/staging/Dockerrun.aws.json ./
    git add .
  fi

fi