我正在尝试自动化在 Docker 容器内构建 React 应用程序的过程,然后使用 Dockerfile 中的 AWS CLI 将构建工件上传到 S3 存储桶。但是,我在尝试运行时遇到错误
docker-compose up
这是我的 Dockerfile:
FROM node:16 as builder
WORKDIR /app
COPY package*.json ./
# Install dependencies
RUN npm install
COPY . .
RUN npm run build
# Use AWS CLI version 2 image for uploading to S3
FROM amazon/aws-cli:2.4.9
# Copy the build artifacts from the builder stage to this new stage
COPY --from=builder /app/build /build
# The bucket name and (optional) path where you want to upload the build files
ENV BUCKET_NAME=product-build
# Run AWS CLI command to sync files to your S3 bucket
CMD ["sh", "-c", "aws s3 sync /build s3://${BUCKET_NAME} --delete"]
这是我的 docker-compose.yml:
version: '3.3'
services:
product-build:
build: ./
volumes:
- ./:/app
env_file:
- .env
stdin_open: true
我的 .env 文件包含:
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=
当我运行
docker-compose build
时,构建过程似乎已成功完成。但是,在运行 docker-compose up
时,容器无法启动并出现以下错误:
Container react-app-product-build-1 Recreate
Container react-app-product-build-1 Recreated
Attaching to react-app-product-build-1
react-app-product-build-1 |
react-app-product-build-1 | usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
react-app-product-build-1 | To see help text, you can run:
react-app-product-build-1 |
react-app-product-build-1 | aws help
react-app-product-build-1 | aws <command> help
react-app-product-build-1 | aws <command> <subcommand> help
react-app-product-build-1 |
react-app-product-build-1 | aws: error: argument command: Invalid choice, valid choices are: [list of valid AWS CLI commands]
react-app-product-build-1 exited with code 252
AWS CLI 似乎无法在 Docker 容器中正确识别该命令,尽管它应该可用。如何解决此问题并使用 Dockerfile 中的 AWS CLI 成功将构建工件上传到 S3?
预先感谢您提供的任何见解或解决方案!
来自 AWS 文档(我认为它比 Docker 文档更好地解释了这个特殊情况):
让我们从一个例子开始。这是一个 Dockerfile 片段,其中同时包含
和ENTRYPOINT
,均指定为数组:CMD
ENTRYPOINT ["/bin/chamber", "exec", "production", "--"] CMD ["/bin/service", "-d"]
将它们放在一起,容器的默认参数将是
。["/bin/chamber", "exec", "production", "--", "/bin/service", "-d"]
这正是这里发生的事情。
您正在使用的 docker 镜像是基于此 Dockerfile 构建的,它提供了
ENTRYPOINT
:
ENTRYPOINT ["/usr/local/bin/aws"]
然后你提供一个
CMD
:
CMD ["sh", "-c", "aws s3 sync /build s3://${BUCKET_NAME} --delete"]
这两个参数组合在一起,导致
/usr/local/bin/aws sh -c "aws s3 sync /build s3://${BUCKET_NAME} --delete"
,这不是有效的 AWS CLI 命令。
通常,您可以将参数传递给
aws
中的 CMD
,但由于您要替换环境变量,因此需要运行 shell。您可以通过放弃 CMD
并完全覆盖入口点来做到这一点:
ENTRYPOINT sh -c "aws s3 sync /build s3://${BUCKET_NAME} --delete"