在 docker 中找不到主机卷的路径
Can not find path to host volume in docker
我正在 spring 引导中开发一个应用程序,其中照片将上传到服务器,然后使用 url 从服务器读取。该应用程序位于 docker 和 tomcat 服务器上。据我了解,最好的方法是使用主机将照片存储在 docker 卷上。因此,我使用 docker-compose.yml 文件创建卷并提供主机路径。文件片段:
version: '3.8'
services:
my-app:
image: app
environment:
- _JAVA_OPTIONS=-Xmx512m -Xms256m
- SPRING_PROFILES_ACTIVE=prod,api-docs
.
.
.
ports:
- 8085:8085
networks:
default:
ipv4_address: 172.19.0.2
volumes:
- ./var/home/my-app:/var/lib/docker/containers/docker_my-app //"path to the host:path to the docker container"
根据我在 Docker 网站 there 上读到的内容,这就是您应该如何创建到将存储照片的主机的路径,即在左侧到主机的路径,右边是容器的路径。问题是没有创建或没有路径,但我找不到它。我还有一个每次检查路径是否存在时都会运行的方法:
@PostConstruct
public void init() {
if (!Files.exists(Paths.get("./var/home/my-app"))) {
try {
Files.createDirectory(root);
} catch (IOException e) {
throw new StorageException("Error initializing directory: " + e.getMessage());
}
}
这会抛出路径不存在。
所以,我有问题:
- 我是否创建了通往主机的良好路径?
- 或者主机的路径应该不同吗?
- 如果主机具有读写权限,我应该在 docker-compose.yml 文件中添加一些内容吗?
编辑
所以要说明我的问题。我想将文件保存在卷主机中,然后通过 URL 获取图像,例如localhost:8080/image/12/picture.png
我必须指定文件被删除的路径。方法 init() 检查路径是否存在,然后将路径分配给应保存文件的变量 root。
@PostConstruct
public void init() {
if (isProd) {
root = Paths.get("./var/home/my-app");
} else {
root = Paths.get("./uploads");
}
if (!Files.exists(root)) {
try {
Files.createDirectory(root);
} catch (IOException e) {
throw new StorageException("Error initializing directory: " + e.getMessage());
}
}
}
然后我这样保存文件:
Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING); //filePath: ./upluads/image/12/picture.png
filePath 应包含名称中带有 id 的每张照片的主机路径和唯一文件夹。
您当前正在将文件夹 /var/home/my-app
从主机安装到容器内的文件夹 /var/lib/docker/containers/docker_my-app
。
因为您的应用程序 运行 在您编写的方法的容器中
@PostConstruct
public void init() {
if (!Files.exists(Paths.get("./var/home/my-app"))) {
try {
Files.createDirectory(root);
} catch (IOException e) {
throw new StorageException("Error initializing directory: " + e.getMessage());
}
}
在容器文件系统中创建目录结构 /var/home/my-app
。
如果您的 Java 代码是为了将数据保存在文件夹 /var/home/my-app
下,您应该按以下方式创建卷:
volumes:
- /var/home/my-app:/var/home/my-app
假设您的 check-method 在您的 Spring 应用程序中,即在 my-app 容器中,您需要检查
/var/lib/docker/containers/docker_my-app
文件夹,而不是
./var/home/my-app
文件夹:
@PostConstruct
public void init() {
if (!Files.exists(Paths.get("/var/lib/docker/containers/docker_my-app"))) {
try {
Files.createDirectory(root);
} catch (IOException e) {
throw new StorageException("Error initializing directory: " + e.getMessage());
}
}
首次使用 volume-folder 时,应在主机上创建相应的文件夹(因为您使用 short-notation 作为卷定义)。
应创建的文件夹将位于 docker-compose.yml 文件旁边,名为 var/home/my-app
要能够根据提供的 url 创建子文件夹,例如 localhost:8080/image/12/picture.png
,您需要定义端点 /image/{id}/{image_name}
,其中 id
是路径变量,image_name
是一个路径变量。
同样,您用于上传文件的 POST 请求需要有 id
路径变量,您可以在代码中将其转换为文件夹名称,如果没有则创建它现在。
关于你的第三个问题:
If host will be with read write permissions should I add something in docker-compose.yml file?
这取决于你是否定义了一个用户来隔离你的容器。
看看这里:https://docs.docker.com/engine/security/userns-remap/
除非你做了这样的事情,否则容器内的进程是 运行 root 并且可以在你的主机上写入,无论是否缺少权限。
编辑以阐明由于 docker-compose.yml:
中的行而创建的文件夹
- ./var/home/my-app:/var/lib/docker/containers/docker_my-app //"path to the host:path to the docker container"
正如您对这一行的正确评论,
./var/home/my-app 是主机上的路径。
因为它以“.”开头它是一个相对路径,将从 docker-compose.yml 文件所在的当前位置开始。
第二部分:/var/lib/docker/containers/docker_my-app 是容器内的路径,映射到主机上的文件夹。
这是一个绝对路径,因为它以 '/' 开头。
您的应用程序放置在此文件夹 (/var/lib/docker/containers/docker_my-app) 中的任何内容都可以在您的主机(因此在您的 docker 容器之外)的另一个文件夹 (./var/home/my-app).
它们在您的硬盘驱动器上是相同的 space,一次是从容器内部访问,一次是从主机访问。
在 docker-container 中运行的应用程序中,您独占使用路径:/var/lib/docker/containers/docker_my-app.
在容器外部,因此在您的主机上,您只使用路径 ./var/home/my-app.
假设在您的主机上 docker-compose.yml 文件位于文件夹中:
/home/thortiede/docker/docker-compose.yml
然后你会在
下找到共享文件夹的内容
/home/thortiede/docker/var/home/my-app
如果您希望在 docker-container 中可以访问主机中的文件,您需要将它们放在该目录中。
然后,从 docker-container 中,您可以通过导航到 :
来访问这些文件
/var/lib/docker/containers/docker_my-app
我正在 spring 引导中开发一个应用程序,其中照片将上传到服务器,然后使用 url 从服务器读取。该应用程序位于 docker 和 tomcat 服务器上。据我了解,最好的方法是使用主机将照片存储在 docker 卷上。因此,我使用 docker-compose.yml 文件创建卷并提供主机路径。文件片段:
version: '3.8'
services:
my-app:
image: app
environment:
- _JAVA_OPTIONS=-Xmx512m -Xms256m
- SPRING_PROFILES_ACTIVE=prod,api-docs
.
.
.
ports:
- 8085:8085
networks:
default:
ipv4_address: 172.19.0.2
volumes:
- ./var/home/my-app:/var/lib/docker/containers/docker_my-app //"path to the host:path to the docker container"
根据我在 Docker 网站 there 上读到的内容,这就是您应该如何创建到将存储照片的主机的路径,即在左侧到主机的路径,右边是容器的路径。问题是没有创建或没有路径,但我找不到它。我还有一个每次检查路径是否存在时都会运行的方法:
@PostConstruct
public void init() {
if (!Files.exists(Paths.get("./var/home/my-app"))) {
try {
Files.createDirectory(root);
} catch (IOException e) {
throw new StorageException("Error initializing directory: " + e.getMessage());
}
}
这会抛出路径不存在。
所以,我有问题:
- 我是否创建了通往主机的良好路径?
- 或者主机的路径应该不同吗?
- 如果主机具有读写权限,我应该在 docker-compose.yml 文件中添加一些内容吗?
编辑
所以要说明我的问题。我想将文件保存在卷主机中,然后通过 URL 获取图像,例如localhost:8080/image/12/picture.png 我必须指定文件被删除的路径。方法 init() 检查路径是否存在,然后将路径分配给应保存文件的变量 root。
@PostConstruct
public void init() {
if (isProd) {
root = Paths.get("./var/home/my-app");
} else {
root = Paths.get("./uploads");
}
if (!Files.exists(root)) {
try {
Files.createDirectory(root);
} catch (IOException e) {
throw new StorageException("Error initializing directory: " + e.getMessage());
}
}
}
然后我这样保存文件:
Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING); //filePath: ./upluads/image/12/picture.png
filePath 应包含名称中带有 id 的每张照片的主机路径和唯一文件夹。
您当前正在将文件夹 /var/home/my-app
从主机安装到容器内的文件夹 /var/lib/docker/containers/docker_my-app
。
因为您的应用程序 运行 在您编写的方法的容器中
@PostConstruct
public void init() {
if (!Files.exists(Paths.get("./var/home/my-app"))) {
try {
Files.createDirectory(root);
} catch (IOException e) {
throw new StorageException("Error initializing directory: " + e.getMessage());
}
}
在容器文件系统中创建目录结构 /var/home/my-app
。
如果您的 Java 代码是为了将数据保存在文件夹 /var/home/my-app
下,您应该按以下方式创建卷:
volumes:
- /var/home/my-app:/var/home/my-app
假设您的 check-method 在您的 Spring 应用程序中,即在 my-app 容器中,您需要检查
/var/lib/docker/containers/docker_my-app
文件夹,而不是
./var/home/my-app
文件夹:
@PostConstruct
public void init() {
if (!Files.exists(Paths.get("/var/lib/docker/containers/docker_my-app"))) {
try {
Files.createDirectory(root);
} catch (IOException e) {
throw new StorageException("Error initializing directory: " + e.getMessage());
}
}
首次使用 volume-folder 时,应在主机上创建相应的文件夹(因为您使用 short-notation 作为卷定义)。 应创建的文件夹将位于 docker-compose.yml 文件旁边,名为 var/home/my-app
要能够根据提供的 url 创建子文件夹,例如 localhost:8080/image/12/picture.png
,您需要定义端点 /image/{id}/{image_name}
,其中 id
是路径变量,image_name
是一个路径变量。
同样,您用于上传文件的 POST 请求需要有 id
路径变量,您可以在代码中将其转换为文件夹名称,如果没有则创建它现在。
关于你的第三个问题:
If host will be with read write permissions should I add something in docker-compose.yml file?
这取决于你是否定义了一个用户来隔离你的容器。 看看这里:https://docs.docker.com/engine/security/userns-remap/ 除非你做了这样的事情,否则容器内的进程是 运行 root 并且可以在你的主机上写入,无论是否缺少权限。
编辑以阐明由于 docker-compose.yml:
中的行而创建的文件夹 - ./var/home/my-app:/var/lib/docker/containers/docker_my-app //"path to the host:path to the docker container"
正如您对这一行的正确评论, ./var/home/my-app 是主机上的路径。 因为它以“.”开头它是一个相对路径,将从 docker-compose.yml 文件所在的当前位置开始。
第二部分:/var/lib/docker/containers/docker_my-app 是容器内的路径,映射到主机上的文件夹。 这是一个绝对路径,因为它以 '/' 开头。
您的应用程序放置在此文件夹 (/var/lib/docker/containers/docker_my-app) 中的任何内容都可以在您的主机(因此在您的 docker 容器之外)的另一个文件夹 (./var/home/my-app). 它们在您的硬盘驱动器上是相同的 space,一次是从容器内部访问,一次是从主机访问。
在 docker-container 中运行的应用程序中,您独占使用路径:/var/lib/docker/containers/docker_my-app.
在容器外部,因此在您的主机上,您只使用路径 ./var/home/my-app.
假设在您的主机上 docker-compose.yml 文件位于文件夹中:
/home/thortiede/docker/docker-compose.yml
然后你会在
下找到共享文件夹的内容/home/thortiede/docker/var/home/my-app
如果您希望在 docker-container 中可以访问主机中的文件,您需要将它们放在该目录中。 然后,从 docker-container 中,您可以通过导航到 :
来访问这些文件/var/lib/docker/containers/docker_my-app