如何在基于 Docker 镜像的 java:8-jdk-alpine 中使用 curl 并保持镜像干净?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/51192713/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to make curl available in Docker image based java:8-jdk-alpine and keep the image clean?
提问by user3356164
We are having java code that runs curl command to fetch the some result.
我们有运行 curl 命令的 java 代码来获取一些结果。
We have built a jar file and the jar file executes fine
我们已经构建了一个 jar 文件并且该 jar 文件执行正常
Now, when we try to dokerize the java program (using jar) and run the application in docker we get this error:
现在,当我们尝试对 java 程序(使用 jar)进行 dokerize 并在 docker 中运行应用程序时,我们会收到此错误:
errorjava.io.IOException: Cannot run program "curl": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at com.ps.api.common.CoreAPI_Spec.executeCoreAPI(CoreAPI_Spec.java:295)
at com.ps.api.common.CoreAPI_Spec.getAccessTokens(CoreAPI_Spec.java:319)
Dockerfile used :
使用的 Dockerfile :
FROM ubuntu:16.04
MAINTAINER niro;
# Install prerequisites
RUN apt-get update && apt-get install -y \
curl
FROM java:8-jdk-alpine
# Set the working directory to /app
WORKDIR /Users/******/Desktop/CoreAPI_Jar
# Copy the current directory contents into the container at /app
ADD *******_Automation-0.0.1-SNAPSHOT-jar-with-dependencies.jar ******_Automation-0.0.1-SNAPSHOT-jar-with-dependencies.jar
# Run app.py when the container launches
CMD ["java", "-jar", "******-0.0.1-SNAPSHOT-jar-with-dependencies.jar"]
回答by Markus
Your example dockerfile contains multiple FROM
statements. This is valid but as the documentation says each FROM
clears the state from previous instructions. And so the fresh installed curl is wiped after the second FROM
.
您的示例 dockerfile 包含多个FROM
语句。这是有效的,但正如文档所说,每个都FROM
从先前的说明中清除状态。因此,新安装的 curl 在第二个FROM
.
回答by David Maze
Most languages have readily available HTTP clients these days; you should almost never be calling out to curl
from a program in a language more sophisticated than a shell script. java.net.URLConnectionhas been a part of Java since Java 1.0 and (without knowing why you're trying to shell out for this) it's almost definitely the right tool here.
如今,大多数语言都有现成的 HTTP 客户端;您几乎永远不应该使用curl
比 shell 脚本更复杂的语言调用程序。 java.net.URLConnection自 Java 1.0 以来一直是 Java 的一部分,并且(不知道您为什么要为此付出代价)它几乎绝对是这里的正确工具。
Assuming you control the executeCoreAPI
method from your backtrace, you should change it to use the built-in Java HTTP client, and just delete all of the Dockerfile parts that try to install curl
.
假设您executeCoreAPI
从回溯中控制该方法,您应该将其更改为使用内置 Java HTTP 客户端,并删除所有尝试安装curl
.
回答by Imran
The Java base image you are using is Alpine Linux one and curl package also needs to be downloaded from there. Here is Dockerfile I have used for Production deployments.
您使用的 Java 基础映像是 Alpine Linux one,还需要从那里下载 curl 包。这是我用于生产部署的 Dockerfile。
FROM openjdk:8-jre-alpine
RUN apk add --update \
curl \
&& rm -rf /var/cache/apk/*
Update 05/2019
更新 05/2019
As of Alpine Linux 3.3 there exists a new --no-cache
option for apk
. It allows users to install packages with an index that is updated and used on-the-fly and not cached locally:
从 Alpine Linux 3.3 开始,存在一个新--no-cache
的apk
. 它允许用户安装带有索引的包,该索引是动态更新和使用的,而不是在本地缓存:
FROM openjdk:8-jre-alpine
RUN apk --no-cache add curl
This avoids the need to use --update
and remove /var/cache/apk/*
when done installing packages.
这避免了在安装完软件包后需要使用--update
和删除/var/cache/apk/*
。
Reference - https://github.com/gliderlabs/docker-alpine/blob/master/docs/usage.mdand Thank you @Daniel for the comment.
参考 - https://github.com/gliderlabs/docker-alpine/blob/master/docs/usage.md并感谢@Daniel 的评论。