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 下的資源、暫存檔案系統與使用者建立的掛載。這些情況需要容器特定的方法,請先閱讀文件列出的限制。