0

请注意:这个问题提到了 Java 和 Java 密钥库,但实际上与 Java 无关,任何对 Docker 和编写 Dockerfiles 有足够了解的人都应该可以回答。


我有一个 Web 服务 ( myservice),它是一个 Docker 化的 JVM 应用程序。它Dockerfile看起来像这样:

FROM openjdk:8-jdk-alpine as myenv

COPY application.yml application.yml
COPY ${KS_FILE} mykeystore.p12
COPY build/libs/myservice.jar myservice.jar

EXPOSE 9200

ENTRYPOINT [ \
    "java", \
    "-Dspring.config=.", \
    "-Dkeystore.file=mykeystore.p12", \
    "-jar", \
    "myservice.jar" \
]

作为记录,mykeystore.p12是一个文件(不是目录!),它存储了 SSL 证书,该服务将返回给任何试图与其建立连接的客户端。具体来说,它是一个加密的Java 密钥库,但这超出了这个问题的范围,而且不重要。重要的是你明白它是一个文件,而不是一个目录。我将文件存储在本地计算机上。

.env我在这个项目的根目录中也有以下文件:

MYENV=local
KS_FILE=../apprunner/certs/mykeystore.p12

因此,../apprunner/certs/mykeystore.p12它是我的文件系统上所在位置的相对路径mykeystore.p12,我希望将该 URI 存储在.env文件中并用作Dockerfile.

我像这样构建图像:

docker build -t myorg/myservice .

我像这样运行该图像的容器:

docker run -d -p9200:9200 --name myservice --net myrunner_default --env-file .env myorg/myservice

当我 SSH 进入正在运行的容器时,我确实mykeystore.p12在本地文件系统上看到了,除了......

它是一个目录!不是文件!

$ docker exec -it 8391601f451b /bin/sh
/ # ls -al
total 62936
drwxr-xr-x    1 root     root          4096 Feb  1 21:24 .
drwxr-xr-x    1 root     root          4096 Feb  1 21:24 ..
-rwxr-xr-x    1 root     root             0 Feb  1 21:24 .dockerenv
-rw-r--r--    1 root     root          1510 Jan 29 16:27 application.yml
drwxr-xr-x    2 root     root          4096 May  9  2019 bin
drwxr-xr-x    7 root     root          4096 Jan 30 22:50 mykeystore.p12
-rw-r--r--    1 root     root      64371878 Jan 29 16:27 myservice.jar
drwxr-xr-x    5 root     root           340 Feb  1 21:24 dev
drwxr-xr-x    1 root     root          4096 Feb  1 21:24 etc
... etc.

它里面有很多奇怪的、意想不到的东西,比如我项目中其他目录的源文件!

显然,${KS_FILE}在 my 中使用 fromDockerfile或 URI 值如何存储在我的.env文件中都有问题。无论如何,我必须改变什么:

  1. KS_FILE我在我的文件中指定了环境变量的文件路径和名称.env;和
  2. 在 my.env和之间Dockerfile,该文件路径 + 名称作为文件复制到正在运行的容器中,这样当我ls -al从容器内部时,我将其视为文件?
4

1 回答 1

3

这里有两个问题。

您只能从构建目录中复制文件

您不能复制存在于构建目录之外的文件(例如../apprunner/certs/mykeystore.p12)。如果您尝试在 中引用此文件目录Dockerfile,如下所示:

FROM openjdk:8-jdk-alpine as myenv

COPY application.yml application.yml
COPY ../apprunner/certs/mykeystore.p12 mykeystore.p12

您将看到以下错误:

Step 3/6 : COPY ../apprunner/certs/mykeystore.p12 mykeystore.p12
COPY failed: forbidden path outside the build context: ../apprunner/certs/mykeystore.p12 ()

环境变量扩展不起作用

文档中

环境变量(与语句一起ENV声明)也可以在某些指令中用作要由 Dockerfile. 还处理转义以将类似变量的语法包含在字面上的语句中。

由于您尚未在 中声明任何ENV语句Dockerfile,因此该环境将扩展为空字符串,因此您实际上得到了:

COPY "" mykeystore.p12

这将简单地将构建目录的内容复制到 mykeystore.p12.

docker build不使用.env文件。

这篇文章可能会有所帮助。

于 2021-02-01T21:42:59.627 回答