Dockerfile COPY 命令将文件复制为目录
Dockerfile COPY command copies file as a directory
请注意:这个问题提到Java和Java密钥库,但实际上没有使用 Java 进行操作,任何对 Docker 有足够了解并编写 Docker 文件的人都应该负责。
我有一个 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 keystore 但这超出了这个问题的范围,而且不是重点。重要的是你明白它是一个文件,而不是一个目录。 我将文件存储在我的本地计算机上。
我在该项目的根目录中也有以下 .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 进入 运行ning 容器时,我 do 在本地文件系统上看到 mykeystore.p12
,except...
这是一个目录!不是文件!
$ 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.
里面有很多奇怪的、意想不到的东西,比如我项目中其他目录的源文件!
显然,在我的 Dockerfile
中使用 ${KS_FILE}
或者 URI 值在我的 .env
文件中的存储方式有问题。无论如何,我必须改变什么:
- 我在
.env
文件中指定了 KS_FILE
环境变量的文件路径和名称;和
- 在我的
.env
和 Dockerfile
之间,文件路径 + 名称被作为 file 复制到 运行ning 容器中,例如当我从容器内部 ls -al
时,我将其视为一个文件?
这里有两个问题。
您只能从构建目录复制文件
您不能复制存在于构建目录之外的文件(例如 ../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 ()
环境变量扩展不能那样工作
Environment variables (declared with the ENV
statement) can also be
used in certain instructions as variables to be interpreted by the
Dockerfile
. Escapes are also handled for including variable-like
syntax into a statement literally.
由于您尚未在 Dockerfile
中声明任何 ENV
语句,
该环境扩展为一个空字符串,因此您将获得
效果:
COPY "" mykeystore.p12
这将简单地将构建目录的内容复制到
mykeystore.p12
.
docker build
没有使用 .env
文件。
This article 可能会有帮助。
请注意:这个问题提到Java和Java密钥库,但实际上没有使用 Java 进行操作,任何对 Docker 有足够了解并编写 Docker 文件的人都应该负责。
我有一个 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 keystore 但这超出了这个问题的范围,而且不是重点。重要的是你明白它是一个文件,而不是一个目录。 我将文件存储在我的本地计算机上。
我在该项目的根目录中也有以下 .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 进入 运行ning 容器时,我 do 在本地文件系统上看到 mykeystore.p12
,except...
这是一个目录!不是文件!
$ 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.
里面有很多奇怪的、意想不到的东西,比如我项目中其他目录的源文件!
显然,在我的 Dockerfile
中使用 ${KS_FILE}
或者 URI 值在我的 .env
文件中的存储方式有问题。无论如何,我必须改变什么:
- 我在
.env
文件中指定了KS_FILE
环境变量的文件路径和名称;和 - 在我的
.env
和Dockerfile
之间,文件路径 + 名称被作为 file 复制到 运行ning 容器中,例如当我从容器内部ls -al
时,我将其视为一个文件?
这里有两个问题。
您只能从构建目录复制文件
您不能复制存在于构建目录之外的文件(例如 ../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 ()
环境变量扩展不能那样工作
Environment variables (declared with the
ENV
statement) can also be used in certain instructions as variables to be interpreted by theDockerfile
. Escapes are also handled for including variable-like syntax into a statement literally.
由于您尚未在 Dockerfile
中声明任何 ENV
语句,
该环境扩展为一个空字符串,因此您将获得
效果:
COPY "" mykeystore.p12
这将简单地将构建目录的内容复制到
mykeystore.p12
.
docker build
没有使用 .env
文件。
This article 可能会有帮助。