HOWTO · Docker

將檔案從主機複製到 Docker 容器

本教程演示如何將檔案從主機複製到 Docker 容器。

本頁內容

若只需要把檔案一次性傳送到既有容器,請使用 docker cp,並指定本機來源與容器內目的地:

docker cp ./local-file CONTAINER:/existing-directory/

請將 CONTAINER 換成容器名稱或 ID。docker cp 可用於執行中或已停止的容器。相對的本機路徑會從執行命令的目錄解析;容器路徑以 / 為根,開頭的斜線可省略。完整語法和規則請見 Docker cp 參考文件

將檔案複製到既有容器

以下命令會把目前主機目錄中的 hello.txt 複製到 demo-app 容器的 /opt/。目的地目錄必須已存在:

docker cp ./hello.txt demo-app:/opt/

/opt/ 存在,容器中會有 /opt/hello.txt。結尾的斜線清楚表示目的地是既有目錄。目的地若是既有檔案,docker cp 會取代其內容;有風險時請先檢查。

可在執行中的容器內直接執行命令來驗證:

docker exec demo-app ls -l /opt/hello.txt

清單應顯示該檔案。docker exec 需要容器正在執行,但 docker cp 也可以對已停止的容器使用。

複製目錄或只複製其內容

docker cp 會遞迴複製目錄。來源的寫法決定要放入目錄本身,或只放入其中內容:

# Creates /opt/host-files/ in the container.
docker cp ./host-files demo-app:/opt/

# Copies the contents of host-files into the existing /opt/incoming/ directory.
docker cp ./host-files/. demo-app:/opt/incoming/

第二個命令要求 /opt/incoming/ 已存在。/. 後綴可避免多建立一層 host-files 目錄,只複製內容。Docker 不會建立缺失的父目錄;以 / 結尾的目的地必須是既有目錄。請參考 docker cp 目的地規則了解完整的檔案與目錄情況。

選擇 docker cp、Dockerfile COPY 或 bind mount

需求 使用方式 原因
立刻向一個既有容器加入檔案 docker cp 在該容器的檔案系統建立一次性副本。
每次建置映像都要包含檔案 Dockerfile COPY 將建置內容中的檔案加入映像。
開發時要讓主機目錄與容器共享 bind mount 在執行期共享路徑,而非建立另一份副本。

若要把應用程式檔案放進映像,請在 Dockerfile 中寫入:

COPY ./config.yaml /app/config.yaml

COPY 是建置期指令,不能修改已經存在的容器。來源路徑會相對於建置內容解析,通常不能使用該內容範圍以外的路徑。請見 Dockerfile COPY 參考文件

若要重複共享變更,建立容器時指定 bind mount:

docker run --mount type=bind,source=/absolute/host/path,target=/app/input,readonly IMAGE

bind mount 是共享儲存空間,不是複製。沒有 readonly 時,容器程序可修改或刪除它有權存取的主機檔案。若這正是實際需要,請參閱掛載主機目錄以即時共用檔案;Docker 也說明了 bind mount 的共用與權限取捨

也不要把 docker cp 當成映像設定:副本留在這個容器可寫入的檔案系統中,重新啟動同一個容器後仍會存在,但從映像新建的替代容器不會有該副本。

避免常見的 docker cp 失敗

複製前請檢查路徑。本機來源必須存在。把本機檔案複製到不存在且結尾沒有 / 的目的地時,Docker 可以在該確切路徑建立檔案,但不會建立父目錄。來源若為目錄,只要父目錄存在,Docker 可以建立最後一層目的地目錄;但不能把目錄複製到檔案上。

預設情況下,複製到容器的檔案屬於目的地使用者與群組,通常是 root:root。只有保留來源 UID 與 GID 適合容器使用者時,才使用 -a。本機符號連結預設會以連結本身複製;要複製其指向的目標,請使用 -L。目的地權限也可能使複製結果無法使用。

最後,docker cp 無法複製某些容器系統路徑,例如 /proc/sys/dev 下的資源、暫存檔案系統與使用者建立的掛載。這些情況需要容器特定的方法,請先閱讀文件列出的限制