[英]Use cp in entrypoint for docker run
有 Dockerfile
FROM openjdk:11.0.12-jre-slim
COPY target/app.jar /app.jar
COPY configs configs
ENTRYPOINT ["java","-jar","/app.jar"]
在文件夹 configs 中包含 java 应用程序的 json 配置。 构建 docker 命令是:
docker build --build-arg -f ~/IdeaProjects/app --no-cache -t app:latest
运行命令是:
docker run --entrypoint="cp configs var/opt/configs/ && java -jar app.jar" app:latest
让我们忽略通过 COPY 命令复制 Dockerfile 中的配置的能力。 不幸的是,这必须使用 --entrypoint 来完成。
执行 docker run 命令时出现错误:
docker:来自守护进程的错误响应:OCI 运行时创建失败:container_linux.go:370:导致启动容器进程:exec:“cp configs var/opt/configs/ && java -jar app.jar”:stat cp configs var/opt/ configs/ && java -jar app.jar:没有这样的文件或目录:未知。
你能解释为什么在这种情况下发生错误吗?
我会用一个入口点包装脚本来做到这一点。 Dockerfile 可以同时具有ENTRYPOINT
和CMD
; 如果这样做, CMD
将作为参数传递给ENTRYPOINT
。 这意味着您可以使ENTRYPOINT
成为执行首次设置的 shell 脚本,然后以exec "$@"
结尾以将其自身替换为CMD
。
#!/bin/sh
# docker-entrypoint.sh
# copy the configuration to the right place
cp configs var/opt/configs/
# run the main container command
exec "$@"
在 Dockerfile 中,确保COPY
脚本(它应该作为可执行文件签入源代码管理)并将其设置为ENTRYPOINT
。
...
COPY docker-entrypoint.sh .
ENTRYPOINT ["./docker-entrypoint.sh"] # must be JSON-array syntax
CMD ["java", "-jar", "/app.jar"] # what was previously ENTRYPOINT
当您运行容器时,替换CMD
很简单,因此您可以通过运行交互式 shell 代替java
应用程序来仔细检查这样做是否正确。
docker run -v "$PWD/alt-configs:/configs" --rm -it my-image sh
如果您确实需要在docker run
时覆盖这样的命令,您显示的命令使用&&
连续运行两个命令。 这需要运行一个 shell 才能被正确理解,在这种情况下,您需要手动提供一个/bin/sh -c
包装器。
我仍然会建议改变ENTRYPOINT
到CMD
在Dockerfile; 那么你可以运行一个相对简单的
docker run \
... \
-v "$PWD/alt-configs:/configs" \
my-image \
/bin/sh -c 'cp configs var/opt/configs && java -jar /app.jar'
如果您使用--entrypoint
,它只会从该命令中取出第一个单词,并且它是一个 Docker 选项,因此它需要位于图像名称之前。 我建议设计您的图像以避免需要这种笨拙的构造。
docker run \
... \
-v "$PWD/alt-configs:/configs" \
--entrypoint /bin/sh \
my-image \
-c 'cp configs var/opt/configs && java -jar /app.jar'
您提议的命令有问题,因为它试图将整个命令(包括嵌入的空格和 shell 运算符)作为一个单词传递,但这会导致操作系统级进程处理尝试查找带有空格和与符号的可执行文件文件名,因此出现“没有这样的文件或目录”错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.