如何在 Docker .NET Core Web 应用程序中持久保存数据?
How to persist data in a Docker .NET Core Web app?
我无法理解如何在 WebApi 应用程序中处理数据 运行 Docker。
在我的应用中,用户可以上传这样存储的文件:
~\App_Data\accounts\user123\files\<sha256>.bin
在没有配置任何卷的情况下,带有我的应用程序映像的 Docker 容器似乎工作正常并且写入文件没有任何问题。
现在我想进行配置,以便文件最终位于我可以明确指定的某个位置,而不是在默认的 docker 卷文件夹中。
我假设我需要创建一个卷映射?
我尝试创建一个文件夹并将其映射到“/App_Data”。它仍然像以前一样工作,但我仍然没有看到该文件夹中的任何文件。
这个文件夹的写入权限有问题吗?如果没有访问权限,是否会 Docker 回退并写入默认卷?
什么 user/group 应该有这个文件夹的写入权限?有 "docker" 用户吗?
我在 Synology NAS 上 运行 所以我只使用标准 Docker UI 和 "Add Folder" 按钮。
这是我试过的文件夹:
我建议你做一个卷的映射,在应用程序中做如下。检查这不是读取模式,因为您将看不到这些文件。
Volume:Since Transmission is a downloader, we need a way to access the file downloaded. Without mapping a physical shared folder on Synology NAS, all downloaded files will be stored in the containers and are difficult to retrieve.In Transmission’s Dockerfile page, we saw two volumes in Transmission: /config and /downloads. We will now perform the following to map these two volumes to the physical shared folders on Synology NAS:
Un-check the Read-Only option as we need to grant Transmission permission to write data into the physical drives.
现在可以使用了!
问题出在这一行:
var appDataPath = env.ContentRootPath + @"\App_Data";
当 Docker 中的 运行 时转换为 @"/app\App_Data"
。
首先,我使用的是 Windows 目录分隔符 '\'
,我认为它不适用于 Linux。另外我认为路径不能包含 "/app"
因为它是相对于这个文件夹的。当 运行 在 Windows 中的 Docker 之外时,我得到了一个效果更好的根路径:@"c:\wwwroot\app\App_Data"
无论如何,通过更改为它开始按预期工作:
var appDataPath = @"/App_Data";
更新
有后续问题。我希望路径在 Linux 上的 Docker 和正常的 Windows 托管中都能工作,但我不能只使用 /App_Data
作为路径,因为那会转化为 c:\App_Data
在 Windows 上。所以我尝试改用这条路径:./AppData
在 Windows 中运行良好,导致 c:\wwwroot\app\App_Data
。但不幸的是,这在 Docker 中仍然行不通。不明白为什么。 Maybee Docker 对路径匹配非常挑剔,只接受完全匹配,即 /App_Data
因为那是我在容器配置中映射到的路径。
不管怎样,这真是令人头疼,现在已经连续花了 6 个小时了。这就是我想出的在 Linux 和 Windows 上都有效的方法。看起来不太好,但它有效:
Path.Combine(Directory.GetCurrentDirectory().StartsWith("/") ? "/" : ".", "App_Data");
如果你能想出更好看的方法,请随时告诉我。
更新 2
好的,我想我现在明白了。我认为。当 运行 在 Docker 中时,每个路径都必须以 '/' 为根。不允许使用相对路径。我的应用程序文件被复制到容器路径“/app”,我已将我的数据映射到“/data”。当前目录设置为“/app”,但要访问数据,我显然必须指向“/data”而不是“/app/data”。我错误地认为所有路径都是相对于“/app”而不是“/”的。这样做的原因可能是因为在标准 Windows 托管中 运行 时我的应用程序文件夹中有我的数据文件(这在任何情况下都不是一个好主意)。然而,这让我觉得同样适用于我的 Docker 环境。
现在明白了这一点,就清楚多了。我必须使用'/data'而不是'./data'或'/app/data'甚至'data'(这也是相对的)等
在标准 Windows 主机中,相对路径可以,我仍然可以使用“./data”或任何其他将相对于 ContentRootPath/CurrentDir 解析的相对路径。但是,像“/data”这样的绝对根路径将不起作用,因为它将解析为 'c:\data'(相对于当前驱动器的根目录)。
我无法理解如何在 WebApi 应用程序中处理数据 运行 Docker。
在我的应用中,用户可以上传这样存储的文件:
~\App_Data\accounts\user123\files\<sha256>.bin
在没有配置任何卷的情况下,带有我的应用程序映像的 Docker 容器似乎工作正常并且写入文件没有任何问题。
现在我想进行配置,以便文件最终位于我可以明确指定的某个位置,而不是在默认的 docker 卷文件夹中。
我假设我需要创建一个卷映射?
我尝试创建一个文件夹并将其映射到“/App_Data”。它仍然像以前一样工作,但我仍然没有看到该文件夹中的任何文件。
这个文件夹的写入权限有问题吗?如果没有访问权限,是否会 Docker 回退并写入默认卷?
什么 user/group 应该有这个文件夹的写入权限?有 "docker" 用户吗?
我在 Synology NAS 上 运行 所以我只使用标准 Docker UI 和 "Add Folder" 按钮。
这是我试过的文件夹:
我建议你做一个卷的映射,在应用程序中做如下。检查这不是读取模式,因为您将看不到这些文件。
Volume:Since Transmission is a downloader, we need a way to access the file downloaded. Without mapping a physical shared folder on Synology NAS, all downloaded files will be stored in the containers and are difficult to retrieve.In Transmission’s Dockerfile page, we saw two volumes in Transmission: /config and /downloads. We will now perform the following to map these two volumes to the physical shared folders on Synology NAS: Un-check the Read-Only option as we need to grant Transmission permission to write data into the physical drives.
现在可以使用了!
问题出在这一行:
var appDataPath = env.ContentRootPath + @"\App_Data";
当 Docker 中的 运行 时转换为 @"/app\App_Data"
。
首先,我使用的是 Windows 目录分隔符 '\'
,我认为它不适用于 Linux。另外我认为路径不能包含 "/app"
因为它是相对于这个文件夹的。当 运行 在 Windows 中的 Docker 之外时,我得到了一个效果更好的根路径:@"c:\wwwroot\app\App_Data"
无论如何,通过更改为它开始按预期工作:
var appDataPath = @"/App_Data";
更新
有后续问题。我希望路径在 Linux 上的 Docker 和正常的 Windows 托管中都能工作,但我不能只使用 /App_Data
作为路径,因为那会转化为 c:\App_Data
在 Windows 上。所以我尝试改用这条路径:./AppData
在 Windows 中运行良好,导致 c:\wwwroot\app\App_Data
。但不幸的是,这在 Docker 中仍然行不通。不明白为什么。 Maybee Docker 对路径匹配非常挑剔,只接受完全匹配,即 /App_Data
因为那是我在容器配置中映射到的路径。
不管怎样,这真是令人头疼,现在已经连续花了 6 个小时了。这就是我想出的在 Linux 和 Windows 上都有效的方法。看起来不太好,但它有效:
Path.Combine(Directory.GetCurrentDirectory().StartsWith("/") ? "/" : ".", "App_Data");
如果你能想出更好看的方法,请随时告诉我。
更新 2
好的,我想我现在明白了。我认为。当 运行 在 Docker 中时,每个路径都必须以 '/' 为根。不允许使用相对路径。我的应用程序文件被复制到容器路径“/app”,我已将我的数据映射到“/data”。当前目录设置为“/app”,但要访问数据,我显然必须指向“/data”而不是“/app/data”。我错误地认为所有路径都是相对于“/app”而不是“/”的。这样做的原因可能是因为在标准 Windows 托管中 运行 时我的应用程序文件夹中有我的数据文件(这在任何情况下都不是一个好主意)。然而,这让我觉得同样适用于我的 Docker 环境。
现在明白了这一点,就清楚多了。我必须使用'/data'而不是'./data'或'/app/data'甚至'data'(这也是相对的)等
在标准 Windows 主机中,相对路径可以,我仍然可以使用“./data”或任何其他将相对于 ContentRootPath/CurrentDir 解析的相对路径。但是,像“/data”这样的绝对根路径将不起作用,因为它将解析为 'c:\data'(相对于当前驱动器的根目录)。