در ادامهی مسیرمون به سمت دواپس اینبار یه مقدار دقیق تر بررسی میکنیم که ایمیج های داکر به چه صورت ساخته میشن و به چه شکل میتونیم اپلیکیشنمون رو با استفاده از داکر بیلد کنیم.

خب یه مروری کنیم پستهای قبلی رو:
دواپس چیه و چرا لازمه؟ اینجا در مورد دواپس و ضرورت استفاده از آن صحبت کردم.
چطور اپلیکیشن مناسب کلاد آماده کنیم؟ و اینجا توضیح دادم که چطور میتونیم یه اپلیکیشن مناسب کلاد توسعه بدیم.
چه عمقی از لینوکس برای دواپس لازمه؟ و اینجا توضیح دادم که کدوم موارد لینوکس برای دواپس الزامی هست که اول سراغ اون موارد بریم.
خودکارش کن,مشکلاتت حل میشه در اینجا در مورد اتومیشن و اینکه انسیبل چیه و چه کمکی به ما میکنه صحبت کردم.
در مسیر دواپس اینبار اجزای اصلی انسیبل تو این پست اجزای انسیبل رو معرفی کردم و آنها را شرح دادم.
در مسیر دواپس به داکر رسیدیم (قسمت اول) تو این پست داکر رو شروع کردیم و اونو معرفی کردیم.
در مسیر دواپس اینبار: پشت داکر چه خبره؟ (قسمت دوم) توی این پست در مورد تکنولوژی هایی که داکر ازشون استفاده میکنه توضیح دادیم.
تست نوشتن و شروع مسیر CI/CD (قسمت اول) توی این پست انواع تست رو بررسی کردیم و با ابزارهای CI/CD آشنا شدیم و یه مقایسه بین گیتلب و جنکینز داشتیم.
در مسیر CI/CD گیت رو بررسی میکنیم (قسمت دوم) توی این پست قبل ورود به گیتلب نیاز بود که گیت و ورژن کنترل سیستم ها رو یه بررسی کنیم.
در مسیر CI/CD شناخت گیتلب (قسمت سوم) توی این پست اجزای گیتلب رو بررسی کردیم و با کامپوننتهای مختلفی که داره بیشتر آشنا شدیم.
در مسیر CI/CD پایپلاین و رانر گیتلب (قسمت چهارم) توی این پست پایپلاین و رانر گیتلب رو بررسی کردیم.
در مسیر CI/CD وریبل، گیتآپس و جمعبندی (قسمت پنجم) توی این پست وریبلهای گیتلب رو بررسی کردیم و یه معرفی کوتاه از گیتآپس و آتودواپس کردیم و در انتها یه مقدار تجربههای خودم رو در گیتلب باهاتون به اشتراک گذاشتم.
در مسیر Observability، الک (قسمت دوم) توی این پست استک قدرتمند ELK رو بررسی کردیم.
در مسیر Observability، جمع بندی استک الک (قسمت سوم) توی این پست بقیه کامپوننتهای استک الک رو بررسی کردیم و fluentd و fluentbit رو مقایسه کردیم و نهایتا یه معرفی هم روی opensearch داشتیم.
در مسیر Observability، استک پرومتئوس (قسمت چهارم) توی این پست یه معرفی اولیه داشتیم روی استک پرومتئوس.
در مسیر Observability، استک پرومتئوس (قسمت پنجم) توی این پست یه مقدار کامپوننت های استک پرومتئوس رو بیشتر بررسی کردیم.
در مسیر Observability، استک ویکتوریا (قسمت ششم) توی این پست استک ویکتوریا رو معرفی کردیم و سعی کردیم با پرومتئوس مقایسهاش کنیم.
در مسیر Observability، میمیر (قسمت هفتم) توی این پست در مورد ابزار میمیر از ابزارهای گرافانا توضیح دادیم و کاربردش رو بررسی کردیم.
در مسیر Observability، لوکی (قسمت هشتم) توی این پست در مورد ابزار گرافانا برای مدیریت لاگ یعنی لوکی توضیح دادیم و آخرشم یه معرفی کوتاه رو graylog داشتیم.
در مسیر Observability، تمپو (قسمت نهم) توی این پست در مورد تریسینگ توضیح دادیم و گرافانا تمپو رو بررسی کردیم و یه معرفی کوتاه روی Jaeger داشتیم
در مسیر Observability، گرافانا (قسمت دهم) توی این پست در مورد گرافانا و HA کردنش و همچنین یه سری از ابزارهاش مثل alloy , incident, on-call توضیح دادیم.
آغاز مسیر کوبر (قسمت اول) تو این قدم به معرفی ابزارهای ارکستریشن پرداختیم و مدارک کوبرنتیز رو بررسی کردیم.
کوبر سینگل ( قسمت دوم ) توی این قدم در مورد kubectl , kubeconfig توضیح دادیم و تعدادی ابزار رو معرفی کردیم که به کمک اونها میتونیم یک کوبرنتیز دمهدستی واسه تستهامون داشته باشیم.
کامپوننتهای کوبر ( قسمت سوم ) توی این پست کامپوننتهای مختلف کوبرنتیز رو بررسی کردیم و اجزای نودهای مستر و ورکر رو دونه دونه بررسی کردیم و توضیح دادیم.
پادها و مدیریت اونها در کوبرنتیز (قسمت چهارم) توی این پست در مورد پاد توی کوبرنتیز توضیح دادیم و موارد مربوط به اون رو بررسی کردیم.
ورکلودهای کوبر و مدیریت منابع کوبر (قسمت پنجم) توی این پست در مورد namespaceها توی کوبر توضیح دادیم و انواع ورکلود کوبر رو بررسی کردیم.
اگه لازم شد کوبر خودش گنده میشه! ( قسمت ششم ) توی این پست در مورد سه نوع ورکلود مرتبط با scaling به صورت خودکار در کوبرنتیز توضیح دادیم.
نتورک کوبر (قسمت هفتم) توی این قسمت انواع سرویس توی کوبرنتیز رو بررسی کردیم و در مورد مفاهیم اینگرس و نتورک پالیسی توضیح دادیم.
استورج کوبرنتیز (قسمت هشتم) توی این قسمت در مورد انواع استورج توی کوبرنتیز توضیح دادیم و مفاهیم PV و PVC و Storage Class رو بررسی کردیم.
پراب، ریکوئست و لیمیت (قسمت نهم) توی این قسمت موارد مربوط به محدود کردن منابع کانتینر توی کوبرنتیز رو بررسی کردیم و در مورد انواع probe ها توی کوبرنتیز توضیح دادیم.
پاد تو نود (قسمت دهم) توی این قسمت درمورد فرآیند انتقال پاد به نود مناسب مفاهیم پیشرفتهتری مثل affinity و anti-affinity و taint و toleration رو بررسی کردیم.
اولویت پاد و امنیت (قسمت یازدهم) توی این قسمت در مورد تعیین اولویت برای پادها و جنبههای مختلف امنیت در کوبرنتیز توضیح دادیم.
کنترل دسترسی به کوبر (قسمت دوازدهم) توی این قسمت در مورد مراحل دسترسی به api کوبرنتیز صحبت کردیم و بعدش مفاهیمی مثل سرویس اکانت رو توضیح دادیم.
دیزاین کلاستر (قسمت سیزدهم) توی این قسمت در مورد طراحی و دیزاین یک کلاستر و روشهای مختلفی که داره توضیح دادیم و همچنین تفاوت روشهای مختلف تقسیم منابع در کلاسترها را بررسی کردیم.
مالتی تننسی در کوبر (قسمت چهاردهم) توی این قسمت چالشهای مربوط به داشتن چند مستاجر بر روی کلاستر کوبرنتیز توضیح دادیم.
هلم (قسمت پانزدهم) توی این قسمت پکیج منیجر معروف کوبرنتیز یعنی Helm رو بررسی کردیم و در موردش ویژگیها و کاربردهاش توضیح دادیم.
سی آر دی و اُپراتور (قسمت شانزدهم) توی این قسمت در مورد اینکه چطوری یه ریسورس کاستوم شده به کلاستر اضافه کنیم توضیح دادیم و مفهوم اُپراتور رو توی کوبر بررسی کردیم.
نصب کلاستر با kubeadm (قسمت هفدهم) توی این قسمت قدم به قدم نحوه نصب یک کلاستر کوبرنتیز رو با استفاده از ابزار kubeadm توضیح دادیم.
نصب کلاستر با kubespray (قسمت هجدهم) توی این قسمت نحوه نصب کلاستر با یه پروژه خیلی خوب به نام کیوب اسپری که یه انسیبل خفن برای ستاپ کلاستر رائه میده رو توضیح دادیم.
نصب کلاستر با rancher (قسمت نوزدهم) توی این قسمت توضیح دادیم که چطور با استفاده از ابزار RKE یک کلاستر کوبرنتیز راهاندازی کنیم..
توصیه میکنم که حتما این پستها رو هم مطالعه کنید. بریم که ادامه بدیم.
قبل تر گفتم که آدما ایمیج هایی رو که بیلد کردن توی رجیستری میذارن و میتونن اونها رو جابهجا کنند، حالا سوال اینه که چجوری یه ایمیج رو میسازند؟ جوابش داکر فایله یعنی بهترین و دقیقترین راهش داکرفایله.
داکرفایل به فایلی گفته میشه که ما تمام مراحل آماده شدن ایمیجها شامل چه پکیجی نصب بشه یا اینکه چه فایلی کپی بشه رو اونجا نوشتیم.
به فایلی که مجموعه مراحل آماده شدن ایمیج مون شامل مواردی مثل اینکه چه فایل ها و دایرکتوری هایی در ایمیج باشن، چه کامند هایی اجرا بشن، چه متغیرهای محیطی تعریف بشن، چه پروسهای موقع بالا اومدن کانتینر اجرا بشه و … رو مشخص میکنیم، داکر فایل گفته میشه. یک فایل متنی که مرحله به مرحله تمام مواردی که نیاز است ایمیج آماده بشه رو داخل خودش داره.
یه قابلیت خوبی که داکر فایل بهمون میده Version Tracking هست و میتونیم ورژن های مختلف برای ایمیجمون داشته باشیم و توسعه اش بدیم یا اگه نیاز شد برگردیم به ورژن های قبلی و …
یادمون نرفته که ما همیشه دنبال این هستیم که بریم سمت اینکه همه چیز به صورت کد باشه و اینجا هم دنبال این هستیم که ساخت ایمیجهامون به صورت کد باشه که میشه.

بیلد کیت چیه؟ BuildKit
از ورژن ۱۸.۰۹ به بعد، داکر از بک اند BuildKit برای بیلد کردنش پشتیبانی میکنه که مزیت های زیادی رو نسبت به قبل به همراه میاره در ادامه یه لیستی از اونا رو براتون میذارم:
Detect and skip executing unused build stages
Parallelize building independent build stages
Incrementally transfer only the changed files in your build context between builds
Detect and skip transferring unused files in your build context
Use external Dockerfile implementations with many new features
Avoid side-effects with rest of the API (intermediate images and containers)
Prioritize your build cache for automatic pruning

سینتکس داکر فایل:
برای نوشتن داکر فایل، فایلی رو با نام Dockerfile و بدون پسوند ایجاد میکنیم و داخل اون دستورات داکر فایل رو مینویسیم. البته میتونه اسمش این نباشه ولی این اسم پیشفرضی هست که میشناسه و وقتی این اسم رو براش انتخاب میکنیم به راحتی میشناسه و سینتکس هایلایت بهمون میده. یک نکته اینکه سینتکس داکرفایل رو به صورت UpperCase همواره در ابتدای خط نوشته میشه. میتونه به صورت LowerCase هم باشه ولی نرمال اینه که به صورت UpperCase نوشته بشه.
در ادامه لیستی از گزینه هایی که تو داکر فایل استفاده میشه رو با یه توضیح مختصر ازشون براتون میارم و تو اینجا هم میتونید رفرنس کاملش رو داشته باشید.
معمولا ما Dockerfile رو کنار دایرکتوری و فایل های پروژه مون میذاریم و مثلا دستوراتی میزنیم که فایل هامون رو کپی کنیم توی ایمیج یا کارهای مشابه. حالا اگه فایلی با نام dockerignore. توی پروژه کنار داکر فایل باشه میتونیم داخلش لیستی از فایل ها و دایرکتوری هایی رو که میخوایم داخل داکرفایل نباشه رو مشخص کنیم. مفهومی شبیه gitignore. اگه باهاش آشنا باشید. قبلا این طوری بود که تمام فایلها و دایرکتوریهایی که کنار داکرفایل بود رو تو ایمیج لود میکرد که الان با این بیلدکیت جدیده دیگه این اتفاق نمیافته ولی هنوز این امکان وجود داره که خودمون یه سری فایل رو ignore کنیم تا داخل داکرفایلمون نباشه.
همونطور که بالاتر هم گفتم هر ایمیجی از یه بیس ایمیج شروع میشه. بنابراین هر داکر فایلی رو که باز میکنیم اولش یه FROM هست که اون بیس ایمیج رو مشخص کنه. حالا ممکنه ماجرای مرغ و تخم مرغ ابهامش تو ذهنتون ایجاد شه که خب اون بیس ایمیجمون که توی خط اول داکر فایلش نوشته FROM خودش از روی چه ایمیجی ساخته شده؟ پاسخ scratch هست که میتونید در موردش بیشتر بخونید. یعنی base imageها از From scratch ساخته میشوند.
یه جورایی تو این قسمت که نقش متا دیتا داره یه سری اطلاعات در مورد نویسنده داکر فایل رو مینویسن که این کار بهمون کمک میکنه که بتونیم نویسندهی آن رو مشخص کنیم تا بتونیم اگر لازم شد باهاش ارتباط بگیریم. دیگه دیپریکیت شده و ازش استفاده نمیشه و به جای آن از لیبل استفاده میشه تا مشخص کنیم که نویسندهی داکرفایل چه کسی بوده.
یکی از مهمترین سینتکسهای داکرفایل، با این دستور یک لایه جدید بالای ایمیج درست میشه و کامندی که زدیم توی اون لایه اجرا میشه و نتایج کامند توی اون ذخیره میشه. به صورت کلی هر اکشنی که تو ایمیج میخواهیم بزنیم رو با استفاده از RUN انجامش میدیم. دقت کنید RUN در زمان ساخت ایمیج اجرا میشه و هر RUN یک لایهی جدید تو ایمیج ایجاد میکنه.
تو کانتینرها چون خیلی سبک و کمحجم ساخته میشوند سرویسی نداریم شبیه systemd لینوکس که بیاد سرویسهای دیگه رو تو بکگراند ران کنه و بالا نگه داره. برای همین باید خودمون سرویسهایی که لازم داریم رو تو Forground بالا نگه داریم. CMD کارش اینه که باهاش ما سرویسهای خودمون رو تو Forground بالا نگه میداریم. دقت کنید که CMD در زمان تبدیل ایمیج به کانتینر اجرا میشه.
این گزینه علاوه بر اینکه کمک میکنه که نشون بدیم وقتی کانتینر بالا میاد چه پورتی رو لیسن میکنه و یه جورایی متادیتا هست بهمون کمک میکنه که زمانی که docker ps میزنیم تو قسمت پورتها، پورتی که داخل کانتینر قراره لیسن بشه رو نشون بده.
متغیرهای محیطی ایمیجمون رو اینجا تعریف میکنیم. متغیرهایی که بعدا در زمان کانتینر هم وجود داره و اگر داخل کانتینر env بزنیم میتونیم آنها رو ببینیم.
برای کپی کردن فایلها و دایرکتوریها از لوکال سرور ازش استفاده میکنیم. همانند RUN یک لایهی جدید ایجاد میکنه و روش Official کپی فایل داخل ایمیج هستش.
برای انتقال و کپی کردن فایل ها و دایرکتوری هامون به صورت لوکال یا ریموت فایل ازش استفاده میکنیم. ADD هم همانند COPY و RUN یک لایه ایجاد میکند. تنها تفاوتی که ADD برامون داره اول اینکه از ریموت مثل گیت میتونیم فایل داخل ایمیج قرار بدیم و دوم اینکه فایلهای Compress شده رو هم میتونه برامون در حین انتقال از Compress خارج کنه.
گاهی پیش میاد که راهاندازی پروسهی ما فقط با یه دستور نیست و نیاز داریم که براش یه اسکریپت اجرا کنیم. اینجا میتونیم از این سینتکس استفاده کنیم. در برخی از مواقع هم پیش میاد که همزمان با CMD ازش استفاده میشه. همانند CMD این سینتکس هم در زمان تبدیل ایمیج به کانتینر اجرا میشود. بیشتر برای پروسههایی که نیاز به bootstrapping دارند کاربرد دارد.
تو این سینتکس داریم مشخص میکنیم که دیتاهای حساس ما کجاها قرار دارند. علاوه بر اینکه داریم به فردی که داکرفایل رو میخونه میگیم که برای این مسیر باید در زمان کانتینر والیوم بسازی و یه جورایی نقش متادیتا رو بازی میکنه اگر فرد براش والیوم نساخت یه والیوم با نام رندم ایجاد میکنه که یک آیدی بهش میده و دیتا رو اونجا Persist میکنه. یعنی اگر براش والیوم ساخت و این مسیر رو آنجا مانت کرد که هیچ اگر نساخت خود داکر با توجه به داکرفایل براش میسازه.
هر کاربری که مشخص کنیم در ادامهی ایمیج و در زمان کانتینر با آن کاربر کار میکنه. این نکتهی مهمی است و جز Best Practiceهای داکرفایل هم هست که نباید ایمیج با کاربر Root باشه و اصطلاحا باید root less باشه.
دایرکتوری کاریمون رو مشخص میکنه. در ادامهی ایمیج و در زمان کانتینر تو این مسیر دستورات رو میزنه و ادامه میده. این دستور هم همانند RUN, COPY و ADD یک لایهی جدید برای ما ایجاد میکنه.
وریبل های زمان بیلدمون رو اینجا مشخص میکنیم. این خاصیت رو داره که به وریبل یه مقدار دیفالت رو بدیم و در زمان بیلد آن آرگومان رو به فراخور نیازمون تغییر بدیم. اگرم ندادیم که مقدار دیفالت رو برمیداره. نکتهای که داره تنها سینتکسی هست که قبل از FROM میتونه قرار بگیره.
دستور تریگری رو اینجا مشخص میکنیم که موقعیکه داکر فایل دیگهای از ایمیج ما به عنوان بیس ایمیج استفاده کرد براش اعمال شه. یعنی زمانی کاربرد داره که این ایمیج خودش به عنوان Base Image استفاده بشه.
اینجا سیگنال سیستم کالی رو که باید برای خروج به کانتینر فرستاده بشه رو مشخص میکنیم. یعنی وقتی که دستور kill برای کانتینر ارسال میشه اون چه طوری بمیره. واقعا خیلی مهم که کانتینر ما چطوری بمیره. مثلا اینکه وقتی kill براش ارسال شد در لحظه بمیره یا صبر کنه و تمام درخواستهایی که سمتش هست رو پاسخ بده و بعد بمیره یا اصلا reload بشه.
اینجا میتونیم متادیتاهایی که دوست داریم رو در قالب کلید و مقدار برای ایمیج و کانتینرمون اضافه کنیم. خوبه که لیبلهای مناسبی قرار بدیم تا کسی که با ایمیج کار میکنه بتونه از آنها استفاده کنه. مثلا یکیش اینکه نویسندهی داکرفایل چه کسی هست و اطلاعات ارتباط باهاش رو قرار بدیم.
اینجا میتونیم برای داکر مشخص کنیم که به چه شکلی چک کنه که کانتینری که از روی ایمیج ما بالا اومده هنوز داره کار میکنه یا اینکه کارش تموم شده و باید بمیره. یه جورایی داریم مشخص میکنه که وضیعت سالم و اوکی از نظر این کانتینر چی هست. دو تا مرحله داره مرحله اول starting و مرحلهی دوم Healthy یا Unhealthy هست.
اینجا هم میتونیم شل دیفالتی که برای کامند هامون وجود داره رو overwrite کنیم. به صورت پیشفرض معمولا shell رو از base image میگیره و اینجا ما میتونیم مشخص کنیم که دقیقا چی باشه. دقت کنید این موضوع هم همانند برخی دیگه از سینتکسها در ادامهی ایمیج و در زمان کانتینر اعمال میشه.
یه نمونه از داکرفایل یک app flask رو اینجا براتون میذارم:
# our base image
FROM alpine:3.5
# Install python and pip
RUN apk add --update py2-pip
# upgrade pip
RUN pip install --upgrade pip
# install Python modules needed by the Python app
COPY requirements.txt /usr/src/app/
RUN pip install --no-cache-dir -r /usr/src/app/requirements.txt
# copy files required for the app to run
COPY app.py /usr/src/app/
COPY templates/index.html /usr/src/app/templates/
# tell the port number the container should expose
EXPOSE 5000
# run the application
CMD ["python", "/usr/src/app/app.py"]

مالتی استیج داکر فایل:
یه مفهومی هست تحت عنوان Multi Stage توی داکر فایل که خیلی جالب و کاربردیه. تو حالت مالتی استیج ما میتونیم چند تا FROM یا بیس ایمیج توی داکر فایلمون داشته باشیم! معمولا استفاده از این قابلیت به این شکل هست که از استیج اول آرتیفکت یا خروجی رو به استیج های بعدی منتقل میکنیم. نهایتا ایمیج ما بعد از بیلد از جنس استیج نهایی داکر فایل خواهد بود. کجاها کاربرد داره؟ زمانی که ما میخواهیم یه پکیجی رو کامپایل کنیم نیاز داریم که کلی کامپایلر و اینا داشته باشیم در صورتی که بعد از کامپایل کردن دیگه به آنها نیاز نداریم. حالا چی میشه داستان؟ این طوری هست که تو استیجهای اول از یک base image استفاده میکنیم که تمام این کامپایلرها رو داشته باشه و بعد از اینکه پکیج خودمون رو کامپایل کردیم آن رو که نتیجه کارمون هست رو تو یه ایمیج خیلی سبکتر قرار میدیم که کلی برامون مزیت به همراه داره.

یه نمونه از داکرفایل مالتی استیج:
FROM golang:1.14
RUN git clone https://github.com/coredns/coredns.git /coredns
RUN cd /coredns && make
FROM scratch
COPY --from=0 /coredns/coredns /coredns
EXPOSE 53 53/udp
CMD ["/coredns"]
مزایای Multi Stage Build:
از مزایای Multi Stage میتویم به موارد زیر اشاره کنیم:
حجم کمتر ایمیج: چون پکیجهای غیر ضروری تو ایمیجمون نیست به مراتب حجم خیلی پایینتری خواهیم داشت که خیلی کارمون رو تو انتقال و نگهداری ایمیجها راحتتر میکنه.
امنیت بالاتر ایمیج: هر چقدر که پکیج کمتری داشته باشیم در نتیجه آسیبپذیری کمتری هم خواهیم داشت. معمولا اگر تعداد پکیجها بیشتر بشه به همون اندازه هم میتونه آسیبپذیری ما بیشتر بشه.
هزینهی پایینترمون: هم در زمان ساخت ایمیج، هم در زمان نگهداری آن، هم در زمان انتقال آن و هم در زمان تبدیل به کانتیر کردن باعث میشه که هزینهی ما کاهش پیدا کنه.
کارایی بالاتر: چون تعداد پکیجهای کمتری داره در نتیجه بهمون کمک میکنه که کارایی یا اصطلاحا Performance بالاتری رو تجربه کنیم.
سرعت بیشتر: با توجه به اینکه حجم پایینتری داریم سرعت دیپلویمنت بیشتری رو تو CI/CDها و یا به صورت منوآل میتونیم تجربه کنیم.

بست پرکتیسها داکرفایل:
خب دیگه الان میدونیم چطور داکرفایل بنویسیم و باهاش ایمیج آماده کنیم. در ادامه لیستی از برخی مواردی که توصیه میشه رعایتشون کنیم براتون میذارم:
تا جای ممکن از بیس ایمیج های سبک استفاده کنید مثلا debian-slim
حتما سعی کنیم که ایمیجهای ما Root-less باشند و با کاربر سطح پایینتری اجرا بشن.
حتما سعی کنیم از Multi Stage Build استفاده کنیم.
بهتره که Distroless باشیم و از From Scaratch استفاده کنیم.
از base imageهای Trusted استفاده کنیم.
حتما base imageهایی که استفاده میکنیم رو به صورت برنامهی مشخص و زمانبندی شده به روز کنیم و آنها رو آپدیت نگه داریم.
حتما تو داکرفایل خودمون پورتهایی که استفاده میشه رو Expose کنیم.
دیتاهای حساس همانند پسوردها و توکنها و … رو داخل داکرفایل قرار ندهیم.
سعی کنیم لایههای ایمیج رو بهینه ایجاد کنیم.
خوبه که ایمیجهای خودمون رو scan کنیم تا از بروز آسیبپذیری داخل آنها جلوگیری کنیم.
ابزارهایی که برای Tshoot ازشون استفاده میکنیم مثل vim و curl داخل ایمیجها قرار ندیدم تا بتونیم ایمیجهای سبکتری ایجاد کنیم.
در تمامی محیط های عملیاتی از یک ایمیج باید استفاده کنیم.
برای کم کردن حجم ایمیجها داکیومنت و man page پکیجهایی که نصب میکنیم رو غیرفعال کنید و پس از نصب کش و موارد دیگه رو پاک کنیم.
تا جای ممکن لایه های RUN رو کاهش بدید و سعی کنید step های نصب رو مثلا با هم ترکیب کنید. البته دقت کنیم که ترکیب کردن لایهها با هم زمانی کارایی بالایی بهمون میده که بتونیم بیشترین استفاده از cache رو داشته باشیم. یعنی تا جایی که میتونیم لایههایی که زیاد تغییر میکنند رو پایینتر قرار بدیم که بیشترین استفاده از cache رو داشته باشیم.
اگه از apt استفاده میکنید no-install-recommend-- بزنید تا از نصب پکیج های غیر ضروری جلوگیری کنید.
فایل های کش شده و مواردیکه در انتها نیازی بهشون نداریم رو پاک کنید مثلا rm -rf /var/lib/apt/lists/*
از ابزارهایی مثل dive یا DockerSlim برای آنالیز ایمیج هاتون استفاده کنید.
خب پس تا اینجا فهمیدیم که چطور میشه اپلیکیشن رو با داکر بیلد کرد و ایمیج برای سرویس مون بسازیم. در ادامه مسیر میریم سراغ داکر کامپوز.
مراقب خودتون باشید. 🌹🐳🌹
خوبه که داکرمی رو تو جاهای مختلف فالو کنید. پذیرای نظرات شما هستیم.
🫀 Follow DockerMe 🫀
🔔 Follow YouTube 🔔
📣 Follow Instagram 📣
🖇 Follow LinkedIn DockerMe🖇
🔎 Follow Linkedin Ahmad Rafiee 🔎
🕊 Follow Twitter 🕊