【问题标题】:AWS CodePipeline deploy Spring Boot application to Elastic BeansTalkAWS CodePipeline 将 Spring Boot 应用程序部署到 Elastic BeansTalk
【发布时间】:2020-07-05 12:15:10
【问题描述】:

我用 3 个步骤为 SpringBoot Java 应用程序构建了一个简单的 CodePipeline:

  • 来源:从 GitHub 获取源代码
  • 构建:jar 文件
  • 部署:到 AWS Elastic Beanstalk 实例

1 和 2 步骤成功通过,而 Deploy 步骤失败。我在 Elastic Beanstalk 日志中看到的唯一错误:

01_configure_application.sh] : Activity execution failed, because: Executing: /usr/bin/unzip -o -d /var/app/staging /opt/elasticbeanstalk/deploy/appsource/source_bundle
  FileMagic v0.7.1: compiled magic version [5.21] does not match with shared library magic version [5.37]
  Archive:  /opt/elasticbeanstalk/deploy/appsource/source_bundle
    inflating: /var/app/staging/microservices/my-service/target/my-service.jar  
  Unable to launch application as the source bundle does not contain either a file named application.jar or a Procfile.
  Unable to launch application as the source bundle does not contain either a file named application.jar or a Procfile. (ElasticBeanstalk::ExternalInvocationError)
caused by: Executing: /usr/bin/unzip -o -d /var/app/staging /opt/elasticbeanstalk/deploy/appsource/source_bundle
  FileMagic v0.7.1: compiled magic version [5.21] does not match with shared library magic version [5.37]
  Archive:  /opt/elasticbeanstalk/deploy/appsource/source_bundle
    inflating: /var/app/staging/microservices/my-service/target/my-service.jar  
  Unable to launch application as the source bundle does not contain either a file named application.jar or a Procfile.
  Unable to launch application as the source bundle does not contain either a file named application.jar or a Procfile. (Executor::NonZeroExitStatus)

我的构建规范:

build:
  commands:
      - mvn -P ci --settings settings.xml install -DskipTests
artifacts:
  files:
     - microservices/my-service/target/my-service.jar

如果我使用 AWS Web Interface 将这个 jar 直接部署到 AWS Elastic Beanstalk,它会完美运行。

请帮帮我。 我已准备好按需共享任何其他配置。

【问题讨论】:

    标签: amazon-web-services amazon-elastic-beanstalk aws-codepipeline


    【解决方案1】:

    虽然 Denys 的回答是正确的,但我认为它并不能清楚地解释问题。

    artifacts 指令下输出时,工件必须是顶级或最多一个深度目录

    例如使用gradle的spring项目默认是在执行bootJar任务后输出到<project root>/build/libs/<artifact name>.jar

    直觉上你会这样定义:

    version: 0.2
    
    phases:
      install:
        runtime-versions:
          java: corretto8
      build:
        commands:
          # bootJar task outputs to build/libs/<name>.jar
          - ./gradlew bootJar
    artifacts:
      files:
          - build/libs/<name>.jar
    

    此构建将成功并将压缩的工件上传到 S3。解压后你会得到:

    build/libs/&lt;name&gt;.jar。您可以通过从 s3 下载工件并自己解压缩来确认这一点(就像弹性 beanstalk 在 vm 中所做的那样)。

    因此,当弹性 beanstalk 尝试部署它时,它会失败,因为它会查找顶级 &lt;name&gt;.jar最多 somedir/&lt;name&gt;.jar,您会收到相当神秘的错误消息

    由于源包不包含名为 application.jar 或 Procfile 的文件,因此无法启动应用程序。

    它很神秘,因为它意味着必须将工件命名为 application.jar 或者必须添加 Procfile。这些都不是真的

    所以解决方案围绕着使该 jar 文件成为顶级文件。你可以:

    将构建工具中的输出工件定义为将其置于顶层(不理想)

    build 阶段添加第二个命令,将 jar 文件移到顶层,例如:

    version: 0.2
    
    phases:
      install:
        runtime-versions:
          java: corretto8
      build:
        commands:
          # bootJar task outputs to build/libs/<name>.jar
          - ./gradlew bootJar
          # move the jar (by wildcard, agnostic to its name) to top level app.jar
          - mv build/libs/*.jar app.jar
    artifacts:
      files:
          # publish the now top level app.jar as the artifact
          - app.jar
    

    最合适的解决方案是使用post_build 指令,该指令专为清理/重组步骤而设计,如下所示:

    version: 0.2
    
    phases:
      install:
        runtime-versions:
          java: corretto8
      build:
        commands:
          # bootJar task outputs to build/libs/<name>.jar
          - ./gradlew bootJar
      post_build:
        commands:
          # move the jar (by wildcard, agnostic to its name) to top level app.jar
          - mv build/libs/*.jar app.jar
    artifacts:
      files:
          # publish the now top level app.jar as the artifact
          - app.jar
    

    解压后你会得到app.jar 顶级和弹性豆茎很高兴!请注意app.jarbuild/libs 是任意的,设置它们对您和您的项目有意义。重要的是artifacts.files 是一个顶级jar 文件。弹性豆茎会处理剩下的事情

    如果您是 CP 新手或有一个简单的项目,则无需按照其他类似问题中的建议使用 config.yml 覆盖或添加 Procfile

    希望这对其他人有帮助。

    【讨论】:

    • 惊人的答案,对我帮助很大,谢谢!
    【解决方案2】:

    问题出在工件的子文件夹中,无法像在我的 Buildspec 中那样使用工件位置:

    artifacts:
      files:
         - microservices/my-service/target/my-service.jar
    

    唯一正确的方式是folder/myapp.jar,例如:

    artifacts:
      files:
         - target/my-service.jar
    

    所以你应该在你的 maven 配置中指定 outputDirectory 如果它不同

    【讨论】:

      猜你喜欢
      • 2015-09-07
      • 2015-01-25
      • 2014-05-03
      • 2017-09-28
      • 2020-11-09
      • 2021-02-11
      • 2018-12-07
      • 2022-06-11
      • 2019-03-08
      相关资源
      最近更新 更多