آیا تا به حال نیاز پیدا کرده‌اید که فایلی را به داخل کانتینر منتقل کنید یا فایلی را از کانتینر خارج کنید؟

دستور docker cp به شما امکان می‌دهد فایل‌های خود را بین میزبان و container کپی کنید تا بتوانید جزئیات پیکربندی را اضافه کنید، نسخه پشتیبان تهیه کنید و داده‌های موجود را بازیابی کنید.

 

 

این مطلب نیز ممکن است برای شما مفید باشد: آشنایی با مجوزهای فایل لینوکس

 

ساختار دستور

docker cp، مسیرهای منبع و مقصد را به عنوان دو آرگومان خود می‌پذیرد:

docker cp example.txt my-container:/example.txt

در اینجا فایل example.txt از دایرکتوری فعلی شما به /example.txt در کانتینر my-container کپی می‌شود. شما می‌توانید دو آرگومان را برای کپی کردن /example.txt در کانتینر به دایرکتوری فعلی خود معکوس کنید.

آرگمانی که به مسیر container اشاره می‌کند، باید با یک شناسه یا نام کانتینر و پس از آن یک دو نقطه (:) آغاز شود. شما می‌توانید شناسه یا نام یک container در حال اجرا را با دستور docker ps پیدا کنید.

 

هر دستور docker cp به یک مسیر سیستم فایل محلی و یک مسیر کانتینر نیاز دارد. بنابراین، شما نمی‌توانید مستقیماً بین دو container فایل منتقل کنید؛ در صورت نیاز به انجام این کار، از یک روش چند مرحله‌ای استفاده کنید؛ بدین صورت که ابتدا از container منبع در سیستم فایل خود، سپس از مسیر محلی جدید به container مقصد کپی کنید.

 

کپی کردن کل دایرکتوری‌ها

docker cp همچنین می‌تواند، دایرکتوری‌ها را به صورت بازگشتی کپی کند:

docker cp /home/demo/website apache-container:/var/www/html/.

Docker همه چیز را در/home/demo/website کپی کرده و به /var/www/html منتقل می‌نماید.

 

این مطلب نیز ممکن است برای شما مفید باشد: دریافت basename نام فایل یا نام دایرکتوری در bash

 

کپی کردن رفتار

هنگامی‌که شما در حال کپی کردن یک فایل هستید، اگر قبلاً وجود نداشته باشد، Docker یک فایل جدیدی را در مقصد ایجاد می‌کند. اما در صورتی که فایلی با آن نام موجود باشد، با محتوای جدید رونویسی می‌شوند. وقتی مقصد یک دایرکتوری باشد، فایل با استفاده از نام فایل منبع در آن کپی می‌شود؛ بجز زمانی که مقصد مشخص شده با  / خاتمه می‌یابد و یک دایرکتوری را نشان می‌دهد، اما مسیر از قبل وجود ندارد. در این سناریو خطایی رخ می‌دهد.

این فرایند برای کپی‌های دایرکتوری کمی پیچیده‌تر است. اگر مسیر مقصد از قبل وجود نداشته باشد، یک دایرکتوری جدید در مقصد با محتویات دایرکتوری اصلی ایجاد می‌شود. اما اگر وجود داشته باشد، بسته به اینکه آیا شما دنباله‌ای از عنصر /. را در مسیر وارد کرده‌اید، رفتار متفاوت متفاوت خواهد بود.

/. is present : دایرکتوری اصلی در دایرکتوری مقصد موجود کپی شده است.

/. is not present : محتوای دایرکتوری اصلی در مقصد کپی شده است.

این تمایز ظریف مشخص می‌کند که آیا یک زیرشاخه جدید در داخل مقصد ایجاد شود یا خیر.

 

محدودیت‌های فرمان

برخلاف نام آن، docker cp یک پیاده سازی کامل دستور cpدر shell نیست. بدین معنی که پرچم‌های cp پشتیبانی نمی‌شوند، به جز پرچم -a و -L:

-a : حالت آرشیو که اطلاعات کاربر و گروه را در فایل‌های کپی شده حفظ می‌کند.

-L :پیوندهای symlinks را در دایرکتوری منبع دنبال می‌کند تا محتویات پیوندها را کپی کند و نه خود پیوندها را.

برای موارد پیشرفته‌تر که کپی کردن انتخابی لازم است، باید از روش دیگری استفاده کنید.

 

استفاده از Bind Mounts برای کپی کردن فایل‌ها

Docker volume، روش دیگری را برای انتقال فایل‌ها بین containerها و میزبان شما ارائه می‌دهد. اتصال mount یک دایرکتوری محلی در یک container به شما امکان می‌دهد، از طریق سیستم فایل میزبان خود به محتویات آن container دسترسی پیدا کرده و نیاز به استفاده از docker cp را از بین می‌برد.

docker run -v /example/host/directory:/container/path my-image:latest

محتویات مسیر/example/host/directory در سیستم فایل container در مسیر /container/path متصل است. شما می‌توانید با این فایل‌ها در خارج از Docker و با استفاده از ابزارهای آشنا مانند cp، rsync و مرورگر فایل‌های گرافیکی خود تعامل داشته باشید.

این تکنیک تنها زمانی مفید است که در حال کار با یک دایرکتوری کانتینر هستید اما زمانی که بخواهید از مکان‌های مختلف کپی کنید، به درستی کار نمی‌کند؛ زیرا باید هنگام ایجاد container، مسیرهایی را که پیش از آن زمان استفاده می‌کنید، بدانید.

همچنین باید نسبت به مجوزهای سیستم فایل احتیاط کنید؛ زیرا فایل‌های ایجاد شده در کانتینر معمولاً متعلق به root هستند. این می‌تواند سناریوهای ناخوشایندی را در میزبان ایجاد کند. بدین صورت که در آن شما ممکن است نتوانید فایل‌های داخل دایرکتوری را ویرایش یا حذف کنید. با این حال، در صورت لزوم می‌توانید از فرمان chown در میزبان و داخل کانتینر استفاده کنید تا مالکیت را بسته به محیط تغییر دهید.

 

این مطلب نیز ممکن است برای شما مفید باشد: برچسب زمان در فایل‌های لینوکس

 

در مورد COPY در Dockerfiles چطور؟

گاهی اوقات docker cp را می‌توان با دستور COPY در Dockerfiles اشتباه گرفت. تشخیص تفاوت موراد استفاده این دو ویژگی بسیار اهمیت دارد.

COPY برای جابجایی فایل‌ها بین میزبان شما و یک container در حال اجرا قابل استفاده نیست. بلکه این برای وارد کردن فایل‌ها به imageها در طول مراحل ساخت است:

COPY /home/me/my-website /var/www/html/.

در اینجا کد منبع وب سایت به عنوان بخشی از یک ساختار در یک image کپی می‌شود. این یک فرایند یکبار مصرف است. هر کانتینری که از image راه‌اندازی می‌شود، منبع وب سایت را به همان صورت زمان اجرای  docker buildشامل می‌شد.

docker cp به شما این امکان را می‌دهد که آن کد منبع را با یک کد جدیدتر در زمان اجرای یک container جایگزین کنید. دستورالعمل‌های COPY برای تبدیل فایل‌ها به بخشی از یک inmage ثابت هستند. در صورتی که دستورات cp با container زنده تعامل دارند.

 

چه موقع فایل‌ها را با Docker کپی کنیم؟

کپی کردن دستی فایل‌ها از میزبان شما در یک Docker Container یا برعکس، به ندرت پیش می‌آید. بدین معنی که imageها باید خودکفا باشند. بنابراین آن‌ها باید با هر چیزی که برای راه‌اندازی یک نمونه نیاز دارید، همراه باشند. پیکربندی معمولاً از طریق متغیرهای محیطی انجام می‌شود.

کانتینرهایی که نیاز به ذخیره مداوم داده‌ها دارند، باید از Docker volumeها استفاده کنند. volumeها محافظت از داده‌ها را تضمین می‌کند؛ بنابراین نیازی نیست قبل از جایگزینی یک نمونه، docker cp را به صورت دستی اجرا کنید. کافیست هنگام تهیه نسخه پشتیبان، volumeها را از میزبان خود کپی کنید؛ به جای اینکه فایل‌ها را از کانتینر خارج کنید.

docker cp در هنگام debug کردن container یا کار کردن در یک محیط توسعه بسیار مفید است. گاهی اوقات شما نیاز دارید که یک فایل پیکربندی موقت را به صورت دستی تزریق کنید یا یک لاگ ذخیره شده را بیرون بیاورید؛ در چنین شرایطی استفاده از docker cp سریع‌تر و راحت‌تر از بازسازی کل image در هر بار تغییر کد است.

همیشه به یاد داشته باشید که فایل‌های کپی شده در container تنها تا زمانی که آن container وجود دارد، باقی می‌مانند. راه‌اندازی یک container دیگر از همان image به شما یک container نو و خالی می‌دهد؛ بدون فایل‌هایی که با cp docker اضافه کرده‌اید.

 

 

 

منبع:

cloudsavvyit