شروع کار با Docker برای ویندوز با استفاده از سی شارپ

برای توسعه‌دهندگان، داکر عمدتا یک پلت‌فرم/مدیر است که گسترش برنامه را در محیط کانتینر (Container) به صورت خودکار انجام می‌دهد. هدف اصلی داکر ایجاد کانتینرهای قابل حمل و مستقل از هر برنامه‌ای (فرض کنید از برنامه node.js یا asp.net core یا سرویس‌های ویندوز از نوع برنامه‌های پایتون یا هر چیزی که فکرش را کنید) است.

شروع کار با Docker برای ویندوز با استفاده از سی شارپ

پیش‌نیازها

یک کامپیوتر در حال اجرا

ویژوال استودیو (ما از v15.5.2 استفاده می‌کنیم)

داکر برای ویندوز (لینک). Docker CE (stable) ویندوز را دانلود کنید. ورژن فعلی ما v17.12.0-ce-(win47 (15139 است.

در این مثال ما یک Docker image را توسط برنامه کنسول net core. ایجاد کرده و آن را روی دستگاه خود گسترش داده و اجرا می‌کنیم. همچنین از داکر برای ویندوز استفاده می‌کنیم، اما همین کار را می‌توان با استفاده از محیط لینوکس نیز انجام داد.

وقتی مراحل نصب‌تان انجام شد، می‌توانید دستور 'docker info' را از Power Shell یا Command prompt اجرا کنید تا ورژن داکر در حال اجرا روی دستگاه شما ( و تعدادی جزئیات مهم دیگر) را بررسی کند.

مطمئن شوید که در حال اجرای 'Windows Containers' هستید. روی آیکون Docker در نوار وظیفه کلیک راست کنید و چک کنید ببینید آیا گزینه 'Switch to Linux containers...' وجود دارد، اگر اینگونه بود به این معناست که شما در حال استفاده از ویندوز هستید.

بیایید یک برنامه net core console app. در ویژوال استودیو ایجاد کنیم که به طور دائمی کاراکترهای رندم را در خروجی کنسول چاپ می‌کند.

حالا ما یک برنامه کنسول net core. داریم که می‌توانیم بر روی دستگاه لوکال خود آن را ساخته و اجرا کنیم. F5 را فشار دهید، می‌توانید خروجی برنامه را ببینید. مرحله بعدی، انتشار این برنامه است. به سادگی دستور 'dotnet publish' را در PS/CMD (داخل پوشه پروژه) اجرا کنید و پکیج شما باید در کمترین زمان آماده شود. فقط مطمئن شوید که همه چیز خوب پیش می‌رود، می‌توانید PS/CMD prompt را درون فولدر publish قرار داده و 'dotnet DockerConsoleTestApp.dll' را اجرا کنید تا مطمئن شوید برنامه‌یتان به خوبی کار می‌کند.

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

حالا بیاید یک image برای کلاس برنامه خود با استفاده از داکر ایجاد کنیم تا بعدا بتوانیم آن را درون یک یا چند کانتینر قرار دهیم و تقریبا در هر جایی و بدون هیچ گونه وابستگی به محیط اجرا کنیم. اجازه دهید یک فایل docker را در سولوشن خود اضافه کنیم و محتوا را در آن قرار دهیم.

    FROM microsoft/dotnet:2.0.4-runtime-nanoserver-1709 AS base  
       
    WORKDIR /app  
    COPY /bin/Debug/netcoreapp2.0/publish/ .  
       
    ENTRYPOINT ["dotnet", "DockerConsoleTestApp.dll"]  

بیایید خطوط نوشته شده در فایل docker را بهتر درک کنیم. برای شروع نیاز به یک runtime برای اجرای برنامه net. داریم، درست است؟ بنابراین چگونه می‌توانیم ابتدا یک image ایجاد کنیم که دارای net runtime. باشد که بعدا بتوانیم کد خود را درون آن image گذاشته و آن را قابل اجرا سازیم. خوشبختانه لازم نیست خودتان آن را بسازید. مایکروسافت (و همه ارائه دهندگان تکنولوژی پیش از آن) این image را برای شما ایجاد کرده‌اند و شما فقط باید آن را از یک جای مناسب، برای مثالی که ما استفاده می‌کنیم از hub.docker.com، دانلود کنید. بنابراین اگر شما به این لینک بروید، مایکروسافت یک image را با net runtime. درون آن برای شما ایجاد کرده است. پس بیایید از آن استفاده کنیم.

    FROM microsoft/dotnet:2.0.4-runtime-nanoserver-1709 AS base 

خط بالا به داکر می‌گوید، یک image از docker hub به نام 'microsoft/dotnet' و با برچسب '2.0.4-runtime-nanoserver-1709'  بگیرد و یک کانتینر از آن ایجاد کند. همچنین آن را base نام‌گذاری می‌کند (در این مورد نام‌گذاری آن اجباری نیست). نحوه انتخاب برچسب مهم است، اما در حال حاضر اجازه دهید از آن بگذریم و بعدا یک مورد قابل استفاده برای net core 2.0. انتخاب کنیم.

WORKDIR /app

این خط به داکر می‌گوید یک کانتینر دیگر در بالای کانتینر قبلی در مرحله قبل ایجاد کند (فقط به خاطر داشته باشید اکثر مراحلی که در یک فایل docker می‌نویسید عملا کانتینرهای متفاوتی را بر اساس نیاز می‌سازند) و یک فولدر به نام 'app' در مسیر کانتینر جدید (در ویندوز 'C:\' drive) ایجاد می‌کند. اطمینان حاصل کنید 'app' دایرکتوری فعلی در کانتینر است. داکر ممکن است کانتینر قبلی را بسته به وابستگی های مختلف حذف کند یا نکند و کارایی را برای توسعه‌های بعدی افزایش دهد.

COPY /bin/Debug/netcoreapp2.0/publish/ . 

در حال حاضر، خط بالا به داکر می‌گوید تمام فایل‌ها را از فولدر publish در دایرکتوری در حال کار کانتینر فعلی، که هنوز 'C:\app' است، کپی کند. ما از مسیر نسبی استفاده می‌کنیم همان‌طور که فایل docker در همان پوشه همراه با فایل csproj برنامه کنسول قرار دارد.

ENTRYPOINT ["dotnet", "DockerConsoleTestApp.dll"] 

آخرین خط به داکر می‌گوید که دستور درون آخرین کانتینر ایجاد شده را اجرا کند. دستور 'dotnet DockerConsoleTestApp.dll' است، همان‌طور که آن را قبلا برای بررسی برنامه منتشر شده خود اجرا کردید.

خوب، حالا آماده‌ایم تا در عمل آن را ببینیم. بنابراین PS/CMD را درون پوشه برنامه خود (که در آن dockerfile  نیز موجود است)  باز کرده و 'docker build -t alphaimage' را اجرا کنید. این دستور به داکر می‌گوید تا دستورات فایل docker را یکی پس از دیگری اجرا کند (همان‌طور که قبلا توضیح داده شد) و یک image به نام 'alphaimage' بسازد (همه حروف آن باید با حرف کوچک باشد). می‌توانید به صورت اختیاری یک برچسب مثل 'docker build -t alphaimage:v1' اضافه کنید. اگر چیزی به عنوان برچسب ارائه نشد، برچسب 'latest' در نظر گرفته می شود. بنابراین در پایان اجرا خواهید دید که چگونه تمام مراحلی که در بالا شرح داده شد توسط موتور داکر اجرا شده و imageای را که می‌خواستید را می‌سازد. به خاطر داشته باشید اگر image دات نت پایه در ریجیستری لوکال شما وجود نداشته باشد، داکر ابتدا آن را از docker hub دانلود خواهد کرد. اما بعدا وقتی کد را تغییر داده و همان دستور را دوباره برای ساخت image جدید اجرا کنید، داکر به صورت هوشمندانه از تمام imageها/بخش‌ها می‌گذرد.

برای اطمینان از اینکه image را آماده کرده‌اید، 'docker images -a' را اجرا کرده و خروجی را بررسی کنید. چند image واسطه نیز خواهید یافت که برای ساخت image نهایی استفاده می‌شوند.

حالا شما imageای دارید که حاوی برنامه واقعا عالی است که ساخته‌اید. پس بیایید آن را درون یک کانتینر اجرا کرده و اعتبارسنجی کنیم. دستور 'docker run --name alphacontainer alphaimage:latest' را از PS/CMD و voila اجرا کنید، می‌توانید خروجی برنامه را ببینید. Ctrl+C را فشار دهید تا اجرا متوقف شود.

همراه با دستورات چه اتفاقی می‌افتد؟ ما از داکر خواستیم تا یک کانتینر به نام 'alphacontainer' از imageای به نام alphaimage' با برچسب 'latest' بسازد. حالا اگر فکر می‌کنید که image مسیر راه‌اندازی را می‌داند، بنابراین بعد از ایجاد کانتینر داکر به صورت اتوماتیک برنامه را آغاز می‌کند. برای سرگرمی اجازه دهید دستور را دوباره با نام کانتینر دیگری اجرا کنیم. بیایید بگوییم: ''docker run --name alphacontainer2 alphaimage:latest''. بنابراین حالا ما دو کانتینر در حال اجرای همان برنامه با استفاده از سیستم عامل دستگاه خود به عنوان پایه آن را داریم.

برای دریافت تمام جزئیات کانتینرهای در حال اجرا، 'docker ps -a' را اجرا کنید و باید موارد زیر را ببینید. می‌توانید کانتینرهایی که هنوز در حال اجرا هستند را ببینید (app). هنگامی که Ctrl+C را فشار می‌دهیم، فقط برای نمایش خروجی در پنجره PS متوقف می‌شود.

حالا تصور کنید که شما برنامه‌ای دارید که به Azure Service Bus گوش می‌دهد و دائما پیام‌ها را پردازش می‌کند. به راحتی می‌توانید کارایی برنامه را با داکر افزایش دهید.

اکنون همه چیز خوب است و می‌توانیم ببینیم که برنامه هنوز در حال اجراست. بیایید کمی درون کانتینر را بررسی کنیم. برای دریافت جزئیات آن می‌توانید 'docker inspect alphacontainer' را اجرا کنید و باید جزئیات مهمی مثل نقطه راه‌اندازی، شبکه و غیره را در اختیارتان قرار دهد. همچنین برای بررسی آنچه داخل کانتینر وجود دارد، مثل نحوه استفاده کانتینر از اجزای داخلی، می‌توانید از CMD درون کاننتنر استفاده کرده تا ساختار فولدر و موارد دیگری را بررسی کنید. این عمل می‌تواند به عنوان image دات نت ارائه‌شده مایکروسافت با خط فرمان نصب شده انجام شود. برای اجرای CMD داخل کانتینر، دستور 'docker exec -it alphacontainer cmd' را اجرا کنید. این دستور به داکر می‌گوید تا CMD درون کانتینر را اجرا کند (به خاطر داشته باشید هنوز برنامه ما داخل آن در حال اجراست).

حالا می‌توانید با کانتینر در حال اجرا بازی کنید، می‌توانید کانتینر را متوقف کنید، دوباره آن را شروع کنید (در حالت تعاملی یا نه با پارامتر –i) و وقتی انجام شد آن را حذف کنید. شما ممکن است بخواهید image را در صورتی که دیگر به آن نیاز ندارید هم حذف کنید.

# you must stop before removing a container  
docker stop alphacontainer2  
docker rm alphacontainer2  
docker stop alphacontainer  
docker start -i alphacontainer  
docker stop alphacontainer  
docker rm alphacontainer  
   
#you must remove all containers before removing an image  
docker rmi alphaimage 

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

static void Main(string[] args)  
        {  
            var i = 0;  
            while (i < 10)  
            {  
                Thread.Sleep(2000);  
                Console.WriteLine(GetLetter());  
                i++;  
            }  
        } 

حالا برای اجرای آن در حالت تعاملی بدون نام‌گذاری کانتینر، می‌توانیم دستور 'docker run -it alphaimage' را اجرا کنیم. داکر یک کانتینر با یک نام رندم ایجاد خواهد کرد و آن را همان‌گونه اجرا خواهد کرد. به یاد داشته باشید، حالا برنامه ما به صورت مداوم اجرا نمی‌شود، و بعد از یک زمان مشخص خارج می‌شود. بنابراین وقتی وضعیت کانتینری که به تازگی ایجاد شده است را بررسی کنید، خواهید دید که مورد قبلی خارج شده است (در صورتی که حلقه تکمیل شده باشد) نه مثل مثال قبلی که کانتینر همیشه در حال اجرا بود تا زمانی که آن را متوقف می‌کردیم. در واقع می‌توانید یک flag به نام –rm را همراه با دستور بالا اضافه کنید تا مطمئن شوید داکر کانتینری را که بعد از اجرای کامل ساخته است را حذف می‌کند، 'docker run -rm -it alphaimage'.