对于Java开发人员,按照以下解决方案会起作用:
如果您尝试使用像下面这样的Dockerfile运行容器
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["java", "$JAVA_OPTS", "-javaagent:/opt/newrelic/newrelic.jar", "-server", "-jar", "app.jar"]
以下是一个带有ENTRYPOINT shell脚本的示例:
#!/bin/bash
set -e
source /work-dir/env.sh
exec "$@"
它将正确构建图像,但在容器运行期间打印下面的错误:
Error: Could not find or load main class $JAVA_OPTS
Caused by: java.lang.ClassNotFoundException: $JAVA_OPTS
相反,Java可以通过命令行或通过环境变量_JAVA_OPTIONS读取命令行参数。这意味着我们可以通过_JAVA_OPTIONS传递所需的命令行参数,而无需更改Dockerfile,使其能够作为容器的父进程启动以便通过exec "$@"
进行有效的Docker信号处理。
以下是我的最终版本的Dockerfile
和docker-entrypoint.sh
文件:
...
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["java", "-server", "-jar", "app.jar"]
#!/bin/bash
set -e
source /work-dir/env.sh
export _JAVA_OPTIONS="-XX:+PrintFlagsFinal"
exec "$@"
当你构建完Docker镜像并试图运行它后,你将看到下面的日志,这意味着它已经成功运行:
Picked up _JAVA_OPTIONS: -XX:+PrintFlagsFinal
[Global flags]
int ActiveProcessorCount = -1 {product} {default}
$PROJECTNAME
的?何时进行定义? - Piotr WittchenCMD ["sh", "-c", "your command with ${any ENV} here"]
- vanduc1102