如何在基于 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 23:59:47  来源:igfitidea点击:

How to make curl available in Docker image based java:8-jdk-alpine and keep the image clean?

javadockerdocker-java

提问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 FROMstatements. This is valid but as the documentation says each FROMclears 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 curlfrom 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 executeCoreAPImethod 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-cacheoption 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-cacheapk. 它允许用户安装带有索引的包,该索引是动态更新和使用的,而不是在本地缓存:

FROM openjdk:8-jre-alpine

RUN apk --no-cache add curl

This avoids the need to use --updateand 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 的评论。