Як скопіювати файли між контейнером та хостом?
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.
Швидкий приклад
# Витягти 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.
Синтаксис детально
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 існуючі директорії:
# Обидва існуючі директорії → копіювати вміст 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.txtGotcha: trailing /. важить. dir/ vs dir/. поводяться по-різному, та сама поведінка, що cp -r у shell.
Stream-форма (tar)
# 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-шар ефемерний
$ 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
# НЕПРАВИЛЬНО: не підтримується
$ 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:
$ 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) ... після копіювання, якщо треба.
Плутати напрямок
# НЕПРАВИЛЬНО: копіює З host У container, але двокрапка не на тому боці
$ docker cp container:./file ./file # помилка або сюрприз
# ПРАВИЛЬНО
$ docker cp container:/path/file ./file # container → host
$ docker cp ./file container:/path/file # host → containerForma з двокрапкою (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, відредагувати, повернути
$ 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
# 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
# Витягти усі логи як 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 шляхів.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.
Коментарі
Ще немає коментарів