روش نگاشت محتوای یک سایت استاتیک در یک Container که وب سرور است
فرض کنید یک سایت استاتیک بوت استرپی را تهیه کردهاید و قصد دارید آنرا توسط وب سرور nginx، هاست کنید. برای اینکار، چندین گزینه پیش روی ما هستند:
گزینهی اول: دریافت image مربوط به nginx، سپس ایجاد یک container از آن و در آخر با استفاده از «روش به اشتراک گذاری فایل سیستم میزبان با کانتینرها» که در قسمت قبل بررسی کردیم، این وب سایت را آمادهی اجرا و دسترسی میکنیم.
گزینهی دوم: کپی کردن فایلهای وب سایت از سیستم میزبان، به درون فایل سیستم خود container.
گزینهی سوم: ایجاد یک image سفارشی که از ابتدا به همراه فایلهای وب سایت استاتیک ما است و در این حالت تنها کافی است این image را تبدیل به container اجرایی کنیم.
روش اول: به اشتراک گذاری فایل سیستم میزبان با کانتینر وب سرور جهت هاست آن
در قسمت قبل، یک فایل tar ایجاد شدهی در سیستم میزبان ویندوزی را با یک کانتینر لینوکسی به اشتراک گذاشتیم تا بتوانیم محتویات آنرا استخراج کنیم. در اینجا قصد داریم پوشهی وب سایت استاتیک خود را که در سیستم میزبان ویندوزی قرار دارد، با وب سرور nginx که توسط یک container در حال اجرا است، به اشتراک بگذاریم تا آنرا هاست کند.
فرض کنید وب سایت استاتیک ما در مسیر c:\users\vahid\mysite سیستم میزبان قرار دارد که داخل آن یک فایل index.html و تعدادی فایل css و js آمادهی برای هاست شدن، وجود دارند. برای هاست آن توسط nginx، از دستور زیر استفاده خواهیم کرد:
docker run --rm -it -p 8080:80 -v c:\users\vahid\mysite:/usr/share/nginx/html nginx
- سوئیچ rm سبب میشود تا پس از خاتمهی کار nginx، این container نیز حذف شود.
- از سوئیچ it استفاده شدهاست تا با فشردن ctrl+c، بتوانیم پروسهی container را خاتمه دهیم و پس از آن، برنامهی nginx دیگر در background در حال اجرا نباشد (اجرای آن در foreground).
- سپس پورت 8080 سیستم میزبان، به پورت 80 وب سرور nginx نگاشت شدهاست. چون containerها دارای network stack خاص خودشان هستند (که آنرا در قسمت سوم بررسی کردیم)، پورت 80 آنها با پورت 80 سیستم میزبان تداخل نمیکند و اگر برای مثال بر روی پورت 80 سیستم جاری، IIS در حال اجرا باشد، سبب عدم اجرا شدن وب سرور nginx به دلیل تداخل پورتها نمیشود.
- در ادامه روش volume mount را مشاهده میکنید که در قسمت قبل بررسی کردیم. مسیر c:\users\vahid\mysite سیستم میزبان، به مسیر ویژهی /usr/share/nginx/html داخل container نگاشت شدهاست. این مسیر، یک مسیر استاندارد بوده و در مستندات docker hub این وب سرور، ذکر شدهاست.
- در آخر هم نام image این وب سرور را ذکر کردهایم.
پس از اجرای این دستور، اگر nginx پیشتر دریافت نشده باشد، image آن دریافت شده، یک container بر اساس آن ساخته میشود و سپس با پارامترهایی که توضیح دادیم، اجرا خواهد شد. اکنون اگر در سیستم میزبان، مسیر http://localhost:8080 را در مرورگر باز کنید، وب سایت استاتیک خود را مشاهده خواهید کرد.
روش دوم: کپی کردن فایلهای وب سایت از سیستم میزبان، به درون فایل سیستم خود container
همانطور که در قسمت سوم نیز بررسی کردیم، فایل سیستم مربوط به هاست، به طور کامل از فایل سیستم container، جدا و ایزوله است و بدون volume mount، یک container نمیتواند به فایلهای میزبان خود دسترسی پیدا کند. بنابراین گزینهی دیگری که در اینجا وجود خواهد داشت، کپی کردن فایلهای میزبان و انتقال آنها به container میباشد؛ شبیه به کپی کردن فایلها از یک کامپیوتر موجود در شبکه به کامپیوتر دیگری در آن.
برای این منظور ابتدا nginx را در پسزمینه اجرا میکنیم:
docker run -d -p 8080:80 --name nginx nginx
پس از اجرای این دستور و بازگشت به command prompt، جهت اطمینان حاصل کردن از اجرای آن در پس زمینه، دستور docker ps را صادر میکنیم که لیست آن، حاوی گزارشی از containerهای در حال اجرا است.
اکنون توسط دستور ویژهی docker exec، میخواهیم درون یک container در حال اجرا، پروسهای را اجرا کنیم. یعنی با اینکه پروسهی nginx داخل این container در حال اجرا است، برای مثال میخواهیم یک shell را نیز داخل آن اجرا کنیم:
docker exec -it nginx bash
cd /usr/share/nginx/html
ls mv index.html index2.html exit
docker cp c:\users\vahid\mysite nginx:/usr/share/nginx/html
docker exec nginx ls /usr/share/nginx/html
روش سوم: ایجاد یک image سفارشی که از ابتدا به همراه فایلهای وب سایت استاتیک ما است
در روش دوم، موفق شدیم که فایلهای مدنظر خود را به درون container در حال اجرا کپی کنیم. اکنون میخواهیم یک snapshot را از آن تهیه کنیم؛ شبیه به کاری که با ماشینهای مجازی نیز انجام میشود و این روشی است که از آن برای ساخت یک image سفارشی استفاده میشود. برای این منظور از دستور docker commit استفاده میشود تا تصویری را از وضعیت یک container در حال اجرا، در آن لحظه تهیه کنیم:
docker commit nginx mysite:nginx
اکنون پس از اجرای این دستور، با استفاده از فرمان docker images میتوان مشاهده کرد که image جدید mysite، با tag ای معادل nginx، ایجاد شدهاست.
در ادامه برای اجرای این image جدید، میتوان از دستور زیر استفاده کرد:
docker run -d -p 8090:80 --name mysite mysite:nginx
اکنون اگر در سیستم میزبان، مسیر http://localhost:8090 را در مرورگر باز کنید، وب سایت استاتیک خود را مشاهده خواهید کرد و یا توسط دستور زیر میتوانید فایلهای موجود در پوشهی html وب سرور nginx این container جدید در حال اجرا را ملاحظه نمائید:
docker exec mysite ls /usr/share/nginx/html
نگاهی به لایههای یک Image در مقایسه با یک Container
زمانیکه خواستیم image جدید و سفارشی خاص خود را ایجاد کنیم، با image اصلی nginx شروع کردیم. اولین لایهی موجود در این image، سیستم عاملی است که میتواند آنرا اجرا کند. برفراز این لایه، لایهی خود nginx قرار گرفتهاست. اگر خواستید تاریخچهی ایجاد یک image را مشاهده کنید، از دستور docker history nginx استفاده نمائید. خروجی آن لیست دستوراتی را نمایش میدهد که برای ساخت این image مورد استفاده قرار گرفتهاند. البته دستور docker history nginx --no-trunc، اطلاعات بیشتری را با نمایش لیست کامل و خلاصه نشدهی دستورات، ارائه میدهد. این دستورات را در صفحهی docker hub هر image نیز میتوان مشاهده کرد. در قسمت full description هر image، در ابتدای توضیحات، قسمتی است به نام supported tags and respective dockerfile links. در اینجا هر tag نامبرده شده، در حقیقت لینکی است به یک فایل که دقیقا همین دستورات را لیست کردهاست. به این فایل، docker file گفته میشود که روش ساخت یک image را توضیح میدهد. هدف آن، خودکار سازی اجرای دستوراتی است که سبب ساخت یک image میشوند.
در ادامه اگر از این image، یک container را ایجاد کنیم، این container هر دو لایهی OS و Framework را به همراه خواهد داشت؛ به علاوهی لایهی دیگری به نام Container/Run که میتوان فایلهای آنرا خواند و یا در آن نوشت. بنابراین لایهای که فایلهای وب سایت استاتیک ما در آن کپی شدند، دقیقا همین لایهاست.
و زمانیکه از یک container تصویری تهیه میشود، تغییراتی را که به فایل سیستم آن ایجاد کردهایم، به صورت یک لایهی جدید بر روی لایههای قبلی آن image، ظاهر و ثبت میشود. برای اثبات این موضوع، میتوان از دستور docker diff nginx استفاده کرد. در اینجا nginx نام container ای است که میخواهیم تغییرات آنرا با image قبلی که بر پایهی آن ایجاد شدهاست، مشاهده کنیم.
تبدیل دستورات docker به یک docker file
تا اینجا یک چنین دستوراتی را برای اجرای کانتینر nginx، کپی فایلها به آن و سپس تهیهی یک تصویر از آن، اجرا کردیم:
docker run -d -p 8080:80 --name nginx nginx docker cp c:\users\vahid\mysite nginx:/usr/share/nginx/html docker commit nginx mysite:nginx
بجای سطر اول، تنها نام image ای را که میخواهیم کار را بر مبنای آن انجام دهیم، ذکر میکنیم:
FROM nginx
COPY mysite /usr/share/nginx/html
سپس برای اجرای این فایل، بجای دستور docker commit آخر، از دستور زیر استفاده میکنیم:
docker build -f Dockerfile -t mysite:nginx-df .
docker build -t mysite:nginx-df .
تگ این image را نیز متفاوت با قبلیها انتخاب کردهایم؛ nginx-df بجای مقدار قبلی.
در این حالت اگر دستور آخر را اجرا کنیم، دستور docker images گزارش اضافه شدن این image جدید را ارائه خواهد داد.
مرجع کامل ساخت Dockerfileها را در اینجا میتوانید مطالعه کنید.
ساخت یک image سفارشی برای هاست یک وب سایت استاتیک در IIS
تا اینجا از وب سرور لینوکسی nginx برای هاست وب سایت استاتیک خود استفاده کردیم. در ادامه میخواهیم از وب سرور IIS برای اینکار استفاده نمائیم. بنابراین ابتدا نیاز است یا از ویندوز سرور استفاده کنیم و یا میتوان با کلیک راست بر روی آیکن Docker در قسمت Tray Icons ویندوز، به Windows Containers سوئیچ کرد و سپس به صورت زیر عمل نمود.
اینبار محتوای Dockerfile ای که کنار پوشهی mysite قرار میگیرد، به صورت زیر خواهد بود:
FROM microsoft/iis:nanoserver COPY mysite c:/inetpub/wwwroot
در ادامه با استفاده از دستور زیر و اجرای فایل Dockerfile، این image جدید را با tag ای به نام iis ایجاد میکنیم:
docker build -t mysite:iis .
به اشتراک گذاری imageهای سفارشی در Docker Hub
برای به اشتراک گذاری imageهای سفارشی خود در Docker Hub، نیاز است tag آنها را توسط دستور docker tag مطابق فرمت ویژهی docker hub ویرایش کرد:
docker tag mysite:nginx-df my_user_name/some_name:new_tag_name
و در آخر برای انتشار آن میتوان از دستور docker push استفاده کرد:
docker push my_user_name/some_name:new_tag_name
پس از پایان کار اگر به سایت docker hub و مخازن خود مراجعه کنید، این image جدید قابل مشاهده خواهد بود.
Azure Container Instances a simple way to run a container in Azure, without having to manage any virtual machines.
Brady Gaster returns in this follow up to the previous episode on Worker services. This time Brady will show us how to deploy our worker service to Azure Container Instances
- [00:58] - Creating a new container instance
- [03:08] - Exploring the Docker tools in Visual Studio Code
- [04:30] - Reviewing the deployed container instance
- [05:50] - Exploring the tools for Kubernetes in Visual Studio Code
- [09:57] - Kubernetes Namespaces and Deployments
- [12:10] - .NET Architecture Guides
Docker Client برای Windows
Today, at Microsoft and Docker, Inc. we are making the Docker command line interface available on Windows starting with the Docker 1.6 release.
The Kubernetes project plans to deprecate Docker Engine support in the kubelet and support for dockershim will be removed in a future release, probably late next year.
داخل یک Image چیست؟
در قسمت قبل دریافتیم که یک Image، از کل User Space مورد نیاز جهت اجرای یک برنامه تشکیل میشود. در ادامه میخواهیم بررسی کنیم، این ادعا تا چه حد صحت دارد و یک Image، واقعا از چه اجزائی تشکیل میشود.
با استفاده از دستور docker images میتوان لیست imageهای دریافت شده را به همراه tagهای مرتبط با هر کدام، مشاهده کرد. سپس با استفاده از دستور docker save میتوان image ای خاص را export کرد؛ برای مثال:
docker save microsoft/iis:nanoserver -o iis.tar
البته ویندوز در حالت استاندارد آن، قابلیت کار با فایلهای tar را ندارد. هرچند میتوان از نرم افزارهای ثالثی مانند win-rar و یا 7zip برای انجام اینکار استفاده کرد، اما تمام Linux Containers، به همراه ابزار کمکی tar، برای استخراج محتوای این نوع فایلها نیز هستند. بنابراین نیاز است از حالت Windows Containers به Linux Containers سوئیچ کرد. برای اینکار فقط کافی بر روی آیکن Docker در قسمت Tray Icons ویندوز کلیک راست نمود و گزینهی Switch to Linux Containers را انتخاب کرد. اکنون اگر دستور docker images را صادر کنیم، تنها لیست imageهای لینوکسی از پیش دریافت شده را میتوان مشاهده کرد.
در ادامه، image یکی از سبکترین توزیعهای لینوکسی را به نام alpine، دریافت میکنیم که فقط 5 مگابایت حجم دارد؛ چون آنچنان فایلی در user space آن وجود ندارد. به همین جهت برای دریافت آن، دستور docker pull alpine را صادر میکنیم. اکنون اگر دستور docker images را صادر کنیم، این image جدید در لیست خروجی آن قابل مشاهدهاست.
سپس چون میخواهیم یک shell را در داخل این container اجرا کنیم (مانند اجرای کنسول PowerShell قسمت قبل)، نیاز است دستور docker run آنرا با سوئیچ it اجرا کنیم:
docker run -it alpine sh
اکنون میخواهیم به فایل iis.tar ای که export کردیم از اینجا دسترسی پیدا کنیم. این فایل نیز بر روی فایل سیستم ویندوز 10 تولید شدهاست. به همین جهت نیاز است بتوان به این فایل خارج از container جاری دسترسی پیدا کرد.
روش به اشتراک گذاری فایل سیستم میزبان با کانتینرها
برای اینکه از داخل یک container به فایلی در خارج از آن دسترسی پیدا کنیم، باید درایو آن فایل خارجی را اصطلاحا mount کرد؛ دقیقا مانند اتصال یک USB Stick به سیستم و اضافه شدن آن به صورت یک درایو جدید. در Docker، اینکار توسط مفهومی به نام Volumes انجام میشود. برای این منظور بر روی آیکن Docker در قسمت Tray Icons ویندوز کلیک راست کرده و گزینهی Settings را انتخاب کنید. البته این تصویر را در حالت کار با Linux Containers مشاهده میکنید:
در اینجا درایو C را انتخاب و Apply کنید و سپس نام کاربری و کلمهی عبور ویندوز خود را وارد نمائید، تا مجوز دسترسی به این درایو، به این Container داده شود.
سپس دستور زیر را اجرا کنید:
docker run --rm -v c:/Users:/data alpine ls /data
- عبارت c:/Users:/data به این معنا است که پوشهی C:\users ویندوز را به مسیر data/ داخل container لینوکسی نگاشت کن. به همین جهت بین این دو قسمت یک : وجود دارد و مسیرهای لینوکسی فاقد نام درایو خاصی هستند.
در این دستور میتوان پوشهای خاص مانند c:/Users/Vahid:/data و یا فایلی خاص را مانند c:/Users/Vahid/iis.tar:/data نیز نگاشت کرد. مزیت آن کاهش سطح دسترسی Container به فایلهای سیستم میزبان است.
- این دستور با اجرای دستور ls، محتوای پوشهی C:\users را لیست میکند.
کار با فایلهای سیستم میزبان از داخل یک Container
در ادامه دستور فوق را به صورت زیر اجرا میکنیم که در آن فایل iis.tar میزبان، در داخل container در مسیر data/ آن قابل دسترسی شدهاست و همچنین بجای ls، دستور sh صادر شدهاست تا به shell آن دسترسی پیدا کنیم. به همین جهت نیاز به سوئیچ it نیز وجود دارد:
docker run --rm -it -v c:/Users/vahid/iis.tar:/data alpine sh
tar -tf /data/iis.tar
در اینجا حداقل هفت پوشه را مشاهده میکنید که داخل هر کدام فایلی به نام layer.tar قرار دارد؛ لایههایی که این image را ایجاد میکنند.
پس از این، اگر دستور استخراج این فایلها را صادر کنیم (t برای نمایش لیست محتویات است و x برای استخراج آنها):
mkdir /data/extract tar -xf /data/iis.tar -C /data/extract
انتقال فایلها از Container به سیستم میزبان
البته نکتهی مهم اینجا است که این پوشهی /data/extract/ صرفا داخل دیسک مجازی این container ایجاد شدهاست و در سمت ویندوز قابل دسترسی و مشاهده نیست.
برای رفع این مشکل، اینبار دستور tar -xf را به صورت زیر اجرا میکنیم:
docker run --rm -it -v c:/Users/vahid/:/data alpine tar -xf /data/iis.tar -C /data/iis
در اینجا اگر دستور tar را بر روی این لایهها اجرا کنیم، در نهایت به یک چنین خروجیهایی خواهیم رسید:
که بسیار شبیه به درایو C یک سیستم ویندوزی است. بنابراین این لایه، همان OS Apps & Libs را به همراه دارد که در قسمت قبل با آن آشنا شدیم.
یک مثال دیگر: اجرای ffmpeg توسط docker
اگر خاطرتان باشد بحث docker را در قسمت اول با معرفی ffmpeg و سخت بودن اجرای آن آغاز کردیم. در ادامه میخواهیم image آنرا دریافت و سپس با تبدیل آن به یک container، کار تبدیل فرمتهای ویدیویی را انجام دهیم:
docker run --rm --volume ${pwd}:/output jrottenberg/ffmpeg -i http://site.com/file.mp4 /output/file.gif
- سوئیچ rm کار حذف container ایجاد شده را پس از اتمام کار آن انجام میدهد.
- سپس مسیرجاری (پوشهی جاری در سیستم میزبان که دستور فوق را اجرا میکند) به مسیر output/ کانتینر نگاشت شدهاست.
- در ادامه مخزن dockerhub ای که ffmpeg قرار است از آن دریافت و اجرا شود، مشخص شدهاست.
- در آخر پارامترهای کار با ffmpeg برای دریافت یک فایل mp4 آنلاین و تبدیل آن به یک فایل animated gif محلی، ذکر شدهاند. این فایل در مسیر output کانتینر ایجاد میشود که در نهایت با میزبان، به اشتراک گذاشته خواهد شد.
- خروجی نهایی تولید شده را در سیستم میزبان در همان پوشهای که دستور فوق را صادر کردهاید، مشاهده خواهید کرد.
مقدمهای بر داکر، قسمت سوم
Step 5/7 : RUN npm i ---> [Warning] The requested image's platform (linux/amd64) does not match the detected host platform (windows/amd64) and no specific platform was requested ---> Running in dc37481d5781 added 48 packages, and audited 49 packages in 6s found 0 vulnerabilities npm notice npm notice New minor version of npm available! 8.5.5 -> 8.7.0 npm notice Changelog: <https://github.com/npm/cli/releases/tag/v8.7.0> npm notice Run `npm install -g npm@8.7.0` to update! npm notice The command '/bin/sh -c npm i' returned a non-zero code: 4294967295: failed to shutdown container: container dc37481d5781615dbf01c129f2322f06fcac8851a8a4078a6273438a8427254a encountered an error during hcsshim::System::waitBackground: failure in a Windows system call: The virtual machine or container with the specified identifier is not running. (0xc0370110): subsequent terminate failed container dc37481d5781615dbf01c129f2322f06fcac8851a8a4078a6273438a8427254a encountered an error during hcsshim::System::waitBackground: failure in a Windows system call: The virtual machine or container with the specified identifier is not running. (0xc0370110)
آیندهی مبهم Docker
NET Core 3.0 Preview 6. منتشر شد
Today, we are announcing .NET Core 3.0 Preview 6. It includes updates for compiling assemblies for improved startup, optimizing applications for size with linker and EventPipe improvements. We’ve also released new Docker images for Alpine on ARM64.