AWS CodePipeline 将 Spring Boot 应用程序部署到 Elastic BeansTalk
Posted
技术标签:
【中文标题】AWS CodePipeline 将 Spring Boot 应用程序部署到 Elastic BeansTalk【英文标题】:AWS CodePipeline deploy Spring Boot application to 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,它会完美运行。
请帮帮我。 我已准备好按需共享任何其他配置。
【问题讨论】:
【参考方案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/<name>.jar
。您可以通过从 s3 下载工件并自己解压缩来确认这一点(就像弹性 beanstalk 在 vm 中所做的那样)。
因此,当弹性 beanstalk 尝试部署它时,它会失败,因为它会查找*** <name>.jar
或 最多 somedir/<name>.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.jar
和build/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
如果它不同
【讨论】:
以上是关于AWS CodePipeline 将 Spring Boot 应用程序部署到 Elastic BeansTalk的主要内容,如果未能解决你的问题,请参考以下文章
AWS:帮助在 Codepipeline 中设置 CodeDeploy
AWS CloudFormation CodePipeline、ParameterOverrides、将列表传递给嵌套堆栈
通过 Cloudformation、CodeBuild 和 CodePipeline 将 python 包部署到 AWS Lambda
将 git merge 集成到 master 作为 AWS Codepipeline 中的最后一步