php小編子墨發(fā)現(xiàn),有一些開(kāi)發(fā)者在使用Go語(yǔ)言編寫(xiě)docker容器時(shí)遇到了一個(gè)問(wèn)題,即無(wú)法為容器寫(xiě)入有效的掛載路徑。這個(gè)問(wèn)題可能導(dǎo)致在容器中進(jìn)行文件讀寫(xiě)操作時(shí)出現(xiàn)錯(cuò)誤或失敗。對(duì)于開(kāi)發(fā)者來(lái)說(shuō),這無(wú)疑是一個(gè)令人沮喪的困擾。接下來(lái),我們將探討這個(gè)問(wèn)題的原因以及可能的解決方案,幫助開(kāi)發(fā)者解決這個(gè)挑戰(zhàn)。
問(wèn)題內(nèi)容
我正在嘗試啟動(dòng)一個(gè)測(cè)試容器來(lái)測(cè)試我的數(shù)據(jù)庫(kù)。我正在使用測(cè)試容器。
這是我如何設(shè)置容器的一段代碼:
func createContainer(ctx context.Context) (testcontainers.Container, *pgxpool.Pool, string, error) { var env = map[string]string{ "POSTGRES_PASSWORD": DbPass, "POSTGRES_USER": DbUser, "POSTGRES_DB": DbName, } var port = "5432/tcp" // /Users/:/ path := `/c/Users/pizhlo21/Desktop/Folder/golang/TgBotReminder/internal/db/postgresql/migration:/usr/app` req := testcontainers.GenericContainerRequest{ ContainerRequest: testcontainers.ContainerRequest{ Image: "postgres:latest", ExposedPorts: []string{port}, Env: env, WaitingFor: wait.ForLog("database system is ready to accept connections"), VolumeMounts: map[string]string{"/docker-entrypoint-initdb.d": path}, SkipReaper: true, }, Started: true, } container, err := testcontainers.GenericContainer(ctx, req) if err != nil { return container, nil, "", fmt.Errorf("unable to start container: %v", err) } ...
登錄后復(fù)制
但我從 docker 收到錯(cuò)誤: failed to setup testunable to start container: failed to create container: error response from daemon: create /docker-entrypoint-initdb.d: "/docker-entrypoint-initdb.d" 包括本地卷名稱(chēng)的無(wú)效字符,僅允許“[a-za-z0-9][a-za-z0-9_.-]”。如果您打算傳遞主機(jī)目錄,請(qǐng)使用絕對(duì)路徑
。
有時(shí)此錯(cuò)誤如下所示:無(wú)法設(shè)置測(cè)試無(wú)法啟動(dòng)容器:無(wú)法創(chuàng)建容器:守護(hù)程序的錯(cuò)誤響應(yīng):“卷”類(lèi)型的安裝配置無(wú)效:安裝路徑無(wú)效:'“c” /desktop/folder/golang/tgbotreminder/internal/db/postgresql/migration/000001_init_schema.up"' 掛載路徑必須是絕對(duì)
我嘗試了許多不同的路徑,例如:
//c/用戶(hù)/...
c/用戶(hù)/...
/%cd%/桌面/...
$home/桌面/文件夾/...
但沒(méi)有任何幫助我。
如何正確執(zhí)行?
解決方法
tl;dr
替換
volumemounts: map[string]string{"/docker-entrypoint-initdb.d": path},
登錄后復(fù)制
與
bindmounts: map[string]string{"/docker-entrypoint-initdb.d": path},
登錄后復(fù)制
問(wèn)題 1
“/docker-entrypoint-initdb.d”包含本地卷名稱(chēng)的無(wú)效字符,僅允許“[a-za-z0-9][a-za-z0-9_.-]”。
重要的是要知道三種類(lèi)型的掛載:
卷存儲(chǔ)在由 docker 管理的主機(jī)文件系統(tǒng)的一部分中(linux 上為 /var/lib/docker/volumes/
)。非 docker 進(jìn)程不應(yīng)修改文件系統(tǒng)的這一部分。卷是在 docker 中保存數(shù)據(jù)的最佳方式。
綁定安裝可以存儲(chǔ)在主機(jī)系統(tǒng)上的任何地方。它們甚至可能是重要的系統(tǒng)文件或目錄。 docker 主機(jī)或 docker 容器上的非 docker 進(jìn)程可以隨時(shí)修改它們。
tmpfs
掛載僅存儲(chǔ)在主機(jī)系統(tǒng)的內(nèi)存中,并且永遠(yuǎn)不會(huì)寫(xiě)入主機(jī)系統(tǒng)的文件系統(tǒng)。
volumemounts
用于指定卷掛載。從 github.com/testcontainers/[email?protected]
的值volumemounts
中的條目存儲(chǔ)卷名稱(chēng),該條目?jī)H允許 [a-za-z0-9][a-za-z0-9_.-]
,這就是您看到錯(cuò)誤消息的原因。順便說(shuō)一句,要看到上面的錯(cuò)誤消息,您的代碼必須是這樣的(請(qǐng)注意 /docker-entrypoint-initdb.d
是值而不是鍵):
volumemounts: map[string]string{path: "/docker-entrypoint-initdb.d"},
登錄后復(fù)制
問(wèn)題 2
類(lèi)型“volume”的掛載配置無(wú)效:掛載路徑無(wú)效:“c/desktop/folder/golang/tgbotreminder/internal/db/postgresql/migration/000001_init_schema.up”掛載路徑必須是絕對(duì)的
要查看此錯(cuò)誤消息,您的代碼必須如下所示:
volumemounts: map[string]string{`"/c/desktop/folder/golang/tgbotreminder/internal/db/postgresql/migration/000001_init_schema.up"`: "/docker-entrypoint-initdb.d"},
登錄后復(fù)制
作為github.com/testcontainers/
, volumemounts
中條目的鍵存儲(chǔ)掛載路徑。由于掛載路徑包含雙引號(hào)("
),因此它是無(wú)效的。docker 守護(hù)進(jìn)程首先驗(yàn)證掛載路徑。這就是您看到錯(cuò)誤消息的原因。
考慮升級(jí) github.com/testcontainers/testcontainers-go
在版本v0.13.0中,containerrequest.bindmounts
和 containerrequest.volumemounts
替換為 containerrequest.mounts
。這是因?yàn)椤盎谟成涞臄?shù)據(jù)結(jié)構(gòu)在某種程度上令人困惑。此更改通過(guò)為所有組件引入專(zhuān)用類(lèi)型以獲得 ide 和編譯器的幫助來(lái)避免混亂”。 (請(qǐng)參閱 pr#386)。
升級(jí)到 github.com/testcontainers/[電子郵件受保護(hù)]
后,可以使用以下方式指定綁定安裝:
Mounts: testcontainers.Mounts( testcontainers.BindMount(path, "/docker-entrypoint-initdb.d"), ),
登錄后復(fù)制