Skip to main content

Як скопіювати файли між контейнером та хостом?

docker cp це найпростіший спосіб переміщати файли між container і host. Працює в обидва боки, з running і stopped container, обробляє директорії рекурсивно.

Теорія

TL;DR

  • Синтаксис: docker cp SRC DST. Одна сторона має формат CONTAINER:PATH.
  • Працює на running і stopped container.
  • Копіює рекурсивно для директорій. Зберігає ownership/permissions всередині container.
  • Для постійної host↔container синхронізації бери bind mount. Для бекапу volume бери tar через helper-container.
  • Не може копіювати між двома container напряму, pipe через host або shared volume.

Швидкий приклад

bash
# Витягти config з container для inspect $ docker cp nginx-c:/etc/nginx/nginx.conf ./nginx.conf # Закинути SQL-фікс у running db $ docker cp ./hotfix.sql db:/tmp/hotfix.sql $ docker exec db psql -U postgres -f /tmp/hotfix.sql # Витягти всю директорію з логами $ docker cp web:/var/log/nginx ./nginx-logs

Три напрямки, усі через ту саму docker cp.

Синтаксис детально

bash
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH docker cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH docker cp [OPTIONS] CONTAINER:SRC_PATH - # у stdout (як tar) docker cp [OPTIONS] - CONTAINER:DEST_PATH # зі stdin (tar)

Флаги:

  • -a / --archive = зберегти owner/group/mode файлу (дефолтна поведінка з останніх версій).
  • -L / --follow-link = слідувати symbolic-link у SRC.

Поведінка source/destination

Поведінка Docker залежить від того, чи SRC і DEST існуючі директорії:

bash
# Обидва існуючі директорії → копіювати вміст SRC у DEST docker cp /host/dir/. container:/dst/ # зверни увагу на trailing /. # SRC директорія, DEST не існує → SRC стає DEST docker cp /host/dir container:/newdst # /newdst тепер містить, що мало /host/dir # SRC файл, DEST існуюча директорія → файл йде всередину DEST docker cp /host/file.txt container:/dst/ # → /dst/file.txt # SRC файл, DEST новий шлях → файл перейменовано docker cp /host/file.txt container:/dst/renamed.txt

Gotcha: trailing /. важить. dir/ vs dir/. поводяться по-різному, та сама поведінка, що cp -r у shell.

Stream-форма (tar)

bash
# Stream tar /etc з container docker cp container:/etc - | tar tf - # список вмісту # Pipe довільного контенту у шлях всередині container tar cf - mydir | docker cp - container:/dest

Корисно для backup-pipeline і коли не можеш використати docker run --rm для mount.

Типові помилки

Забути, що cp у writable-шар ефемерний

bash
$ docker cp ./config.yml api:/etc/config.yml # Edit застосовано. Restart container → файл може лишитися (у writable-шарі). # Але docker rm → файл зник назавжди.

docker cp пише у writable-шар container. Лишається через docker stop/start того самого container. Зникає при docker rm. Для постійних змін редагуй image (Dockerfile) або бери volume / bind mount.

Спроба копіювати між двома container

bash
# НЕПРАВИЛЬНО: не підтримується $ docker cp source:/file target:/file Error: invalid arguments # Бери stream: $ docker cp source:/file - | docker cp - target:/file # Або shared volume.

Дивуватися owner файлу на host

Container часто крутиться під конкретним user (root, або app-specific). Файли, витягнуті через docker cp, тримають свій UID, що може бути незвичним на host:

bash
$ docker cp api:/var/log/access.log . $ ls -la access.log -rw-r--r-- 1 1000 1000 ... access.log # UID 1000 з container

Іноді UID 1000 збігається з твоїм user; іноді ні. Бери chown $(id -u):$(id -g) ... після копіювання, якщо треба.

Плутати напрямок

bash
# НЕПРАВИЛЬНО: копіює З host У container, але двокрапка не на тому боці $ docker cp container:./file ./file # помилка або сюрприз # ПРАВИЛЬНО $ docker cp container:/path/file ./file # container → host $ docker cp ./file container:/path/file # host → container

Forma з двокрапкою (container:path) це container-сторона; інша сторона це host.

Коли НЕ варто docker cp

  • Persistent дані (бази, аплоади): бери named volume. docker cp пише у writable-шар, що неправильне місце.
  • Live dev sync (edit-on-host, see-in-container): bind mount, не docker cp. Швидше, без copy-кроку.
  • Великі директорії повторно: розглянь rsync через docker exec для delta-only трансферу, або просто bind mount.
  • Між host: docker save | ssh ... | docker load для image; tar через ssh для raw-файлів.

Реальне застосування

  • Витягування логів з проблемного прод-container перед docker rm.
  • Інжект швидкого фіксу (SQL, config-сніпет) у running container як тимчасова заглушка. Постійний фікс іде у image.
  • Бекапи: docker cp зі stopped DB-container на host як snapshot. Або через tar через helper-container, docker run --rm -v vol:/data alpine tar cf - /data > backup.tar.
  • Debugging: копіювати core-dump або heap-dump з container для аналізу.

Питання для поглиблення

Q: Чи docker cp працює на stopped container?


A: Так. Filesystem container (image + writable-шар) існує, поки існує запис container. Можеш cp in/out без старту.

Q: Чи є permission-проблеми при копіюванні у running container?


A: Іноді. Permission директорії destination і owner шляху всередині container визначають, чи файл стане root або app-user. Бери флаг --chown, якщо потрібен конкретний UID/GID, але docker cp не має такого флагу як COPY --chown=. Обхід: docker exec ... chown після копіювання.

Q: Яка різниця між docker cp і docker exec ... cat ... > file?


A: docker cp розуміє рекурсію директорій, зберігає метадані і працює на stopped container. Трюк exec ... cat працює для одиничних файлів на running container лише. docker cp правильний примітив.

Q: Як копіювати з container у container на іншому host?


A: Pipe через мережу: docker cp src:/file - | ssh remote 'docker cp - dst:/file'. Або, якщо обидва host дістають той самий registry, збери image з файлом і pull на іншій стороні.

Q: (Senior) Коли docker cp неправильний примітив навіть для одноразових копій?


A: Усе, що ти повторюєш, має бути volume. Усе, що хочеш версіонувати (config-файли), має бути у Dockerfile або config-management volume. Усе велике і часто-мінливе належить у object-storage з container, що читає при старті. docker cp для ad-hoc, one-shot, debug-style копій.

Приклади

Витягти config, відредагувати, повернути

bash
$ docker cp web:/etc/nginx/nginx.conf ./nginx.conf $ vi ./nginx.conf $ docker cp ./nginx.conf web:/etc/nginx/nginx.conf $ docker exec web nginx -s reload

Швидкий one-off config-tweak. Правильний фікс це запекти config у новий image або змонтувати з host, але для emergency-tweak це працює.

Backup через tar через helper-container

bash
# Backup вмісту volume (container не має бути running) $ docker run --rm \ -v pgdata:/data \ -v $PWD:/backup \ alpine \ tar czf /backup/pgdata-$(date +%F).tar.gz -C /data .

Краще, ніж docker cp для volume, бо volume не частина writable-шару жодного container.

Stream директорії через tar-pipe

bash
# Витягти усі логи як tar-stream $ docker cp web:/var/log/nginx - > logs.tar $ tar xf logs.tar # Інверсно: push tar у container $ tar cf - some-dir | docker cp - container:/destination

Корисно, коли треба фільтрувати на льоту (tar-флаги) або коли destination не має shell-friendly шляхів.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Коментарі

Ще немає коментарів