为AWS Elastic Beanstalk部署定义特定的docker-compose文件

11
在运行eb create命令之前,我该如何告诉Elastic Beanstalk使用不同的docker-compose文件?
例如,我的项目目录:
HelloWorldDocker
├──.elasticbeanstalk
│  └──config.yml
├──app/
├──proxy/
└──docker-compose.prod.yml
└──docker-compose.yml

我的docker-compose.yml是我用于本地开发的文件。我的docker-compose.prod.yml是我想要用于生产环境的文件。在运行EB CLI的eb create命令之前,有没有一种方法可以定义这个配置呢?
显而易见的是:我意识到我可以将docker-compose.yml用于生产文件,将docker-compose.dev.yml用于本地开发,但是在本地运行docker-compose up命令会变得更加繁琐(例如:docker-compose -f docker-compose.dev.yml up --build...)。此外,我主要想知道是否可能实现这一点,因为我正在学习Elastic Beanstalk,以及如果我想要如何做到这一点。

编辑/更新:2021年6月11日

我尝试使用以下代码将docker-compose.prod.yml重命名为docker-compose.yml,并放置在.ebextensions/docker-settings.config中:

container_commands:
  rename_docker_compose:
    command: mv docker-compose.prod.yml docker-compose.yml

>eb deploy:

2021-06-11 16:44:45    ERROR   Instance deployment failed.
  For details, see 'eb-engine.log'.
2021-06-11 16:44:45    ERROR   Instance deployment: Both 
  'Dockerfile' and 'Dockerrun.aws.json' are missing in your
  source bundle. Include at least one of them. The deployment
  failed.

在{{eb-engine.log}}文件中,我看到:
2021/06/11 16:44:45.818876 [ERROR] An error occurred during 
  execution of command [app-deploy] - [Docker Specific Build
  Application]. Stop running the command. Error: Dockerfile and
  Dockerrun.aws.json are both missing, abort deployment

根据我的测试,这是由于AWS在执行后续的container_commands步骤之前需要调用/bin/sh -c docker-compose config

编辑/更新 #2

如果我使用commands而非container_commands

commands:
  rename_docker_compose:
    command: mv docker-compose.prod.yml docker-compose.yml
    cwd: /var/app/staging

看起来it成功地进行了替换:

2021-06-11 21:40:44,809 P1957 [INFO] Command find_docker_compose_file
2021-06-11 21:40:45,086 P1957 [INFO] -----------------------Command Output-----------------------
2021-06-11 21:40:45,086 P1957 [INFO]    ./var/app/staging/docker-compose.prod.yml
2021-06-11 21:40:45,086 P1957 [INFO] ------------------------------------------------------------
2021-06-11 21:40:45,086 P1957 [INFO] Completed successfully.

但我仍然遭遇到:
2021/06/11 21:40:45.192780 [ERROR] An error occurred during
  execution of command [app-deploy] - [Docker Specific Build 
  Application]. Stop running the command. Error: Dockerfile and 
  Dockerrun.aws.json are both missing, abort deployment 

编辑/更新:2021年6月12日

我使用的是Windows 10电脑。在本地运行eb deploy命令之前,我打开了使用MINGW64终端的Git Bash。我cdprebuild目录,该目录中包含build.sh文件。然后我运行了以下命令:

chmod +x build.sh

如果我执行ls -l,它会返回:
-rwxr-xr-x 1 Jarad 197121 58 Jun 12 12:31 build.sh*

我认为这意味着该文件是可执行的。

然后我提交到git。

接着我运行了eb deploy命令。

在eb-engine.log中,我看到了一个build.sh: permission denied错误。以下是相关部分的摘录。

...
2021/06/12 19:41:38.108528 [INFO] application/zip

2021/06/12 19:41:38.108541 [INFO] app source bundle is zip file ...
2021/06/12 19:41:38.108547 [INFO] extracting /opt/elasticbeanstalk/deployment/app_source_bundle to /var/app/staging/
2021/06/12 19:41:38.108556 [INFO] Running command /bin/sh -c /usr/bin/unzip -q -o /opt/elasticbeanstalk/deployment/app_source_bundle -d /var/app/staging/
2021/06/12 19:41:38.149125 [INFO] finished extracting /opt/elasticbeanstalk/deployment/app_source_bundle to /var/app/staging/ successfully
2021/06/12 19:41:38.149142 [INFO] Executing instruction: RunAppDeployPreBuildHooks
2021/06/12 19:41:38.149190 [INFO] Executing platform hooks in .platform/hooks/prebuild/
2021/06/12 19:41:38.149249 [INFO] Following platform hooks will be executed in order: [build.sh]
2021/06/12 19:41:38.149255 [INFO] Running platform hook: .platform/hooks/prebuild/build.sh
2021/06/12 19:41:38.149457 [ERROR] An error occurred during execution of command [app-deploy] - [RunAppDeployPreBuildHooks]. Stop running the command. Error: Command .platform/hooks/prebuild/build.sh failed with error fork/exec .platform/hooks/prebuild/build.sh: permission denied 

2021/06/12 19:41:38.149464 [INFO] Executing cleanup logic
2021/06/12 19:41:38.149572 [INFO] CommandService Response: {"status":"FAILURE","api_version":"1.0","results":[{"status":"FAILURE","msg":"Engine execution has encountered an error.","returncode":1,"events":[{"msg":"Instance deployment failed. For details, see 'eb-engine.log'.","timestamp":1623526898,"severity":"ERROR"}]}]}

2021/06/12 19:41:38.149706 [INFO] Platform Engine finished execution on command: app-deploy
...

你知道为什么会出现权限被拒绝的错误吗?


这场疯狂让我得出的结论

Elastic Beanstalk的EB CLI命令eb deploy在Windows机器上不能正确压缩文件(即它创建的app_source_bundle)。

证明

我能够通过本地压缩并通过Elastic Beanstalk在线界面手动上传来重现Marcin的例子。当我这样做并检查源包时,它显示build.sh确实具有可执行权限(-rwxr-xr-x)。

[root@ip-172-31-11-170 deployment]# zipinfo app_source_bundle
Archive:  app_source_bundle
Zip file size: 993 bytes, number of entries: 5
drwxr-xr-x  3.0 unx        0 bx stor 21-Jun-13 03:08 .platform/
drwxr-xr-x  3.0 unx        0 bx stor 21-Jun-13 03:08 .platform/hooks/
drwxr-xr-x  3.0 unx        0 bx stor 21-Jun-13 03:08 .platform/hooks/prebuild/
-rwxr-xr-x  3.0 unx       58 tx defN 21-Jun-13 03:09 .platform/hooks/prebuild/build.sh
-rw-r--r--  3.0 unx       98 tx defN 21-Jun-13 03:08 docker-compose.prod.yml

当我使用EB CLI和完全相同的文件初始化并创建时,build.sh 没有可执行权限(-rw-rw-rw-)。
[ec2-user@ip-172-31-5-39 deployment]$ zipinfo app_source_bundle
Archive:  app_source_bundle
Zip file size: 1092 bytes, number of entries: 5
drwxrwxrwx  2.0 fat        0 b- stor 21-Jun-12 20:32 ./
-rw-rw-rw-  2.0 fat       98 b- defN 21-Jun-12 20:08 docker-compose.prod.yml
-rw-rw-rw-  2.0 fat      993 b- defN 21-Jun-12 20:15 myzip.zip
drwxrwxrwx  2.0 fat        0 b- stor 21-Jun-12 20:08 .platform/hooks/prebuild/
-rw-rw-rw-  2.0 fat       58 b- defN 21-Jun-12 20:09 .platform/hooks/prebuild/build.sh

因此,我认为这是AWS EB CLI部署命令的一个bug,涉及到它如何为Windows用户压缩文件。

“commands” 似乎正常工作,因为它必须在您当前的工作环境中运行。在解压缩您的 zip 文件之前,“commands” 就已经执行了。 - Marcin
另外,更新后需要澄清的是,只要提供正确的文件名,在EB中一切都可以正常工作?那么问题就在于如何将docker-compose.prod.yml重命名为docker-compose.yml? - Marcin
是的,我有一个工作项目。当我的项目根目录下有一个名为docker-compose.yml的文件时,它可以正常工作。当我将其重命名为docker-compose.prod.yml时,我希望能够在适当的时间配置Elastic Beanstalk将此文件重命名为docker-compose.yml - Jarad
我更新了答案,并附上了我对该问题的重现和解决方案。 - Marcin
2个回答

3
你不能在命令行级别完成这个操作,但是我猜你可以编写 container_commands 脚本来将你的 docker-compose.dev.yml 文件从 docker-compose.dev.yml 重命名为 docker-compose.yml

你可以使用 container_commands 键来执行影响应用程序源代码的命令。容器命令在应用程序和 Web 服务器设置以及应用程序版本归档被提取之后运行,但在部署应用程序版本之前运行。

更新于2021年6月12日: 我尝试使用简化设置来复制此问题,只使用了 docker-compose.prod.yml 和运行在 64 位 Amazon Linux 2 平台上的 Docker 3.4.1 EB。 docker-compose.prod.yml
version: "3"

services:
    client:
        image: nginx
        ports:
            - 80:80

我可以确认并重现使用container_commands时出现的问题。因此在我的测试中,解决方法是设置预构建部署钩子

因此我的部署zip文件的结构如下:

├── docker-compose.prod.yml
└── .platform
    └── hooks
        └── prebuild
            └── build.sh

where

build.sh

#!/bin/bash

mv docker-compose.prod.yml docker-compose.yml

在创建部署压缩包之前,我还将build.sh赋予了可执行权限。

app_source_bundle的权限(zipinfo -l)

Zip file size: 1008 bytes, number of entries: 5
drwxr-xr-x  3.0 unx        0 bx        0 stor 21-Jun-12 07:37 .platform/
drwxr-xr-x  3.0 unx        0 bx        0 stor 21-Jun-12 07:37 .platform/hooks/
drwxr-xr-x  3.0 unx        0 bx        0 stor 21-Jun-12 07:38 .platform/hooks/prebuild/
-rwxr-xr-x  3.0 unx       77 tx       64 defN 21-Jun-12 07:24 .platform/hooks/prebuild/build.sh
-rw-r--r--  3.0 unx       92 tx       68 defN 21-Jun-12 07:01 docker-compose.prod.ym

我遇到了“权限被拒绝”的错误。我已经在我的问题中更新了EDIT / UPDATE: June 12, 2021,其中包含了详细信息。你看出我做错了什么吗? - Jarad
@Jarad,在你压缩build.sh之前,你把它变成可执行文件了吗?chmod +x build.sh - Marcin
澄清一下:我没有在本地压缩,而是运行了“eb deploy”,它会将“app_source_bundle”发送到“/opt/elasticbeanstalk/deployment/”和一个S3存储桶。简短的回答是:是的,在运行“eb deploy”之前,我确实使build.sh可执行。我对build.sh进行了chmod + x操作。我甚至运行了“git update-index --chmod=+x<文件路径>”。当我SSH到实例并检查“build.sh”的文件权限时(zipinfo -l app_source_bundle),它显示为“-rw-rw-rw-”。我不知道这是否只是因为它在zip中,还是这些确实是权限。但为什么呢? - Jarad
@Jarad 我已经更新了我的权限问题。它们在app_source_bundle中是-rwxr-xr-x。看起来你的权限没有传播到zip文件中。在我的测试中,我没有使用git或eb cli。 - Marcin
1
感谢您的帮助,Marcin。我花了一整天的时间来解决这个问题。我的结论是,在Windows机器上,AWS EB CLI deploy命令在压缩文件时存在一个错误。我能够重现您的示例。但当我使用EB CLI时,相同的文件却无法工作! - Jarad
@Jarad 谢谢。Windows 可能是问题所在。我在测试中使用的是 Linux。 - Marcin

1
我能够通过以下方式绕过这个烦人的错误:
  1. 使用 git 和 AWS CodeCommit
  2. 运行 git add --chmod=+x .platform/hooks/prebuild/build.sh
这是因为这种方法规避了与 Windows 相关的问题:

当您将 CodeCommit 配置到 EB CLI 存储库中时,EB CLI 使用存储库的内容创建源代码包。当您运行 eb deploy 或 eb create 时,EB CLI 推送新提交并使用您分支的 HEAD 版本创建归档文件,然后将其部署到环境中的 EC2 实例。

来源:从 CodeCommit 存储库部署

尝试了几乎所有的方法,只有CodeCommit才能解决这个问题。 - NemyaNation

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接