[英]Executing java command on ENTRYPOINT of Dockerfile doesn't recognize given ARG values
我创建了一个 dockerfile 来在 DockerHub 上构建和上传一个图像,该图像将连接到数据库并创建一个表。 Dockerfile
FROM openjdk:11 as builder
EXPOSE 8080
WORKDIR application
ARG JAR_FILE=toDoAppWithLogin.jar
COPY $JAR_FILE application.jar
ARG SQL_PASSWORD
ARG SQL_USERNAME
ARG SQL_PORT
ARG SQL_SERVER
RUN java -Djarmode=layertools -jar application.jar extract
FROM openjdk:11
WORKDIR application
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/application/ ./
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher", "--my_sql.host=$SQL_SERVER", "--my_sql.port=$SQL_PORT", "--my_sql.username=$SQL_USERNAME", "--my_sql.password=$SQL_PASSWORD"]
我通过运行以下命令来构建映像(它已成功构建):
docker build -t nikspanos/cicd-pipeline:tag1 --build-arg SQL_USERNAME=user --build-arg SQL_PASSWORD=pass --build-arg SQL_PORT=0000 --build-arg SQL_SERVER=server .
然后我运行 docker 图像进行测试,然后再将其上传到 Docker 注册表
docker run nikspanos/cicd-pipeline:tag1
我得到的第一个错误:
java.sql.SQLNonTransientConnectionException: Cannot load connection class because of underlying exception: com.mysql.cj.exceptions.WrongArgumentException: Failed to parse the host:port pair '$SQL_SERVER:$SQL_PORT'.
我想我没有正确通过 arguments,所以它们无法被识别。 我已经搜索过它,许多其他答案包括 ENV 选项,但我只想使用 ARG。
对此事提出任何建议。
你在这里至少有 3 件事错了。
$var
语法扩展为变量的值,您需要像/bin/sh
一样的 shell 。 json/exec 语法明确绕过使用 shell 运行命令。结果如下所示:
FROM openjdk:11 as builder
EXPOSE 8080
WORKDIR application
ARG JAR_FILE=toDoAppWithLogin.jar
COPY $JAR_FILE application.jar
RUN java -Djarmode=layertools -jar application.jar extract
FROM openjdk:11
WORKDIR application
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/application/ ./
ARG SQL_PASSWORD
ARG SQL_USERNAME
ARG SQL_PORT
ARG SQL_SERVER
ENV SQL_PASSWORD=$SQL_PASSWORD
ENV SQL_USERNAME=$SQL_USERNAME
ENV SQL_PORT=$SQL_PORT
ENV SQL_SERVER=$SQL_SERVER
ENTRYPOINT java org.springframework.boot.loader.JarLauncher "--my_sql.host=$SQL_SERVER" "--my_sql.port=$SQL_PORT" "--my_sql.username=$SQL_USERNAME" "--my_sql.password=$SQL_PASSWORD"
我个人会切换到将入口点作为 shell 脚本运行,这样您就可以回到 json 语法。 这将允许在 CMD 值中传递其他 cli 选项。 那个脚本可能是
#!/bin/sh
exec java org.springframework.boot.loader.JarLauncher "--my_sql.host=$SQL_SERVER" "--my_sql.port=$SQL_PORT" "--my_sql.username=$SQL_USERNAME" "--my_sql.password=$SQL_PASSWORD" "$@"
exec 避免将/bin/sh
保留为 pid 1 的地方,这可能会干扰信号。
然后您会遇到下一个问题,您不应该将配置设置(如 db 主机名,尤其是密码)烘焙到映像中。 而是在您运行容器时成为运行时配置:
FROM openjdk:11 as builder
EXPOSE 8080
WORKDIR application
ARG JAR_FILE=toDoAppWithLogin.jar
COPY $JAR_FILE application.jar
RUN java -Djarmode=layertools -jar application.jar extract
FROM openjdk:11
WORKDIR application
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/application/ ./
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT [ "/entrypoint.sh" ]
然后你会在没有任何参数的情况下构建它并使用设置运行它:
docker build -t nikspanos/cicd-pipeline:tag1 .
docker run -e SQL_USERNAME=user -e SQL_PASSWORD=pass -e SQL_PORT=0000 -e SQL_SERVER=server nikspanos/cicd-pipeline:tag1
我还建议研究用于传递凭据的秘密解决方案,因为环境变量很容易暴露。 这些会将凭据作为文件挂载或使它们可从外部秘密服务器获得。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.