<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>پست‌های انتشارات PaaSino</title>
        <link>https://virgool.io/paasino/feed</link>
        <description>paasino</description>
        <language>fa</language>
        <pubDate>2026-06-07 13:14:31</pubDate>
        <image>
            <url>https://files.virgool.io/upload/publication/mdgyhyyvinl0/0yiwvb.png</url>
            <title>PaaSino</title>
            <link>https://virgool.io/paasino</link>
        </image>

                    <item>
                <title>چرا کوبرنتیز این شکلی طراحی شده؟ - قسمت چهارم و آخر</title>
                <link>https://virgool.io/paasino/kubernetes-design-principles-4-h7ibnqpulzqr</link>
                <description>مقدمهاین مطلب قسمت چهارم و آخر از سری نوشته‌های اصول طراحی کوبرنتیز هست. در سه قسمت قبلی سه اصل رو گفتیم و در مورد هر کدوم توضیحاتی داده شد. الان می‌خوایم اصل چهارم رو بررسی کنیم که ایجاد abstraction از زیرساخت هست. کوبرنتیز با داشتن این ویژگی مثل یک سیستم عامل اون چیزی که در زیرساخت هست رو از اپلیکیشن پنهان می‌کنه و باعث میشه بتونیم به راحتی بین زیرساخت‌های مختلف جابجا بشیم. این مطالب از یک ارائه در kubecon 2018 گرفته شدن.اگه در حوزه‌ی زیرساخت هستید و با کوبرنتیز کار می‌کنید این نوشته می‌تونه به شما دید خوبی بده تا علاوه بر ساختار کوبرنتیز علتش رو هم بدونید و عمیق‌تر با کوبرنتیز آشنا بشید. تو این نوشته فرض شده شما با کوبرنتیز آشنایی ابتدایی دارید. اگر هم تجربه‌ی عملی داشته باشید که چه بهتر. معرفی volume و persistent volume در کوبرنتیزقبل از رسیدن به بحث اصلی در مورد ذخیره‌سازی داده در کوبرنتیز صحبت می‌کنم. چون بهمون در درک مطلب کمک می‌کنه. راهی که ما در کوبرنتیز برای ذخیره کردن داده داریم استفاده از volume هست؛ مثل داکر که مفهوم volume رو داره و میشه اون رو داخل کانتینر mount کرد. اما در کوبرنتیز بسیار بیشتر به بحث ذخیره‌سازی پرداخته شده و انواع و اقسام گزینه‌ها برای این کار فراهم هست. بیاید یک نمونه پاد که از volume استفاده می‌کنه رو ببینیم:به دو قسمت توجه کنید؛ اول به volumes که در spec پاد نوشته میشه و بعد به volumeMounts که در داخل تعریف هر کانتینر میاد. با استفاده از volume میشه نوع اون رو مشخص کرد و در volumeMounts در تعریف کانتینر میشه volumeهای تعریف شده رو mount کرد. برای دیدن انواع volumeها به این لینک مراجعه کنید. با دیدن انواع volumeها ممکنه این طور به نظر بیاد که برای هر زیرساختی لازمه که تعریف volumeها رو تغییر بدیم؛ اما یک نوع volume بسیار مهم در کوبرنتیز وجود داره که در ایجاد abstraction به ما کمک می‌کنه و اون persistent volume هست.برای آشنایی با persistent volume در کوبرنتیز بیاید یک پاد رو با این نوع volume ببینیم:دقت کنید فقط تعریف volume عوض شده و از PersistentVolumeClaim استفاده شده که یک آبجکت در کوبرنتیز هست و نقش اصلی رو در ایجاد abstraction بازی می‌کنه. برای این که PersistentVolumeClaim رو در تعریف volume بیاریم باید قبلش این شکلی یه آبجکت ازش بسازیم:اینجا حجم دیسک درخواستی ۲ گیگ هست. توجه کنید که این آبجکت فقط یک درخواست برای منابع ذخیره‌سازی هست و باید یک PersistentVolume هم باشه که به این آبجکت bind بشه. بعد از ساختن این آبجکت با این دستور:kubectl apply -f pvc.yamlدو حالت داریم. یا باید یک آبجکت PersistentVolume رو ادمین کلاستر برامون بسازه که مشخصات claim رو برآورده کنه یا باید StorageClass داشته باشیم که به شکل اتوماتیک برای claim یک PersistentVolume بسازه. به طور خلاصه میشه ارتباط پاد با PersistentVolume و PersistentVolumeClaim رو در این عکس نشون داد:ما یک پاد می‌سازیم و یک PVC که به یک PV وصل یا bind میشه. خود PV می‌تونه به شکل dynamic یا static ساخته بشه. راجع به اون تقسیم‌بندی user space و kernel space در عکس در قسمت بعد توضیح میدم.اصل چهارم: ایجاد abstraction از زیرساختیکی از کارهایی که کوبرنتیز سعی کرده برای ما انجام بده، کاری شبیه عملکرد سیستم عامل است؛ یعنی موقعی که کاربران مختلف کلاستر می‌خوان پاد تعریف کنن به زیرساختی که توش هستن توجهی نمی‌کنن. این وظیفه‌ی ادمین کلاستر هست که با توجه به زیرساخت موجود نیازهای کاربران رو برطرف کنه. مثل سیستم عامل که سخت افزار زیرین رو برای نرم افزارها abstract می‌کنه. در مورد کوبرنتیز میشه به PVC و PV اشاره کرد. ما (به عنوان کاربر معمولی کلاستر) موقعی که پاد رو تعریف می‌کنیم تنها اسم PVC رو میاریم و پاد رو با اون تعریف می‌کنیم؛ به همین دلیل این دو تا آبجکت رو در شکل قبلی در user space آوردم. موقع تعریف PVC هم مقدار و نوع storage درخواستی رو می‌نویسیم. از اینجا به بعد دیگه دست ادمین کلاستر هست که یا به شکل static (دستی) یا dynamic (اتوماتیک) برای ما PV رو ایجاد کنه. در شکل قبلی هم اگر نگاه کنید می‌بینید ساخت PV در kernel space گذاشته شده که نشون میده اگه کلاستر کوبرنتیز رو سیستم عامل در نظر بگیریم، ساخت PV رو کرنل (ادمین کلاستر) باید انجام بده. با این ویژگی کاربران به راحتی می‌تونن workloadهای خودشون رو بین زیرساخت‌های مختلف انتقال بدن و دغدغه‌ای برای این جابجایی نداشته باشن.جمع‌بندیدر این قسمت اصل چهارم طراحی کوبرنتیز رو معرفی کردیم. به کمک کوبرنتیز ما می‌تونیم workloadهای خودمون رو به زیرساخت‌های مختلف ببریم و این موضوع اصل چهارم است. در مورد PVC و PV هم صحبت کردیم که به ما امکان ایجاد این abstraction از زیرساخت رو میدن.امیدوارم این مطلب براتون مفید بوده باشه. همون طور که اول گفتم این آخرین اصل بود. کدوم یک از این چهار اصل براتون جالب‌تر بود؟ آیا به نظرتون ویژگی مهمی از کوبرنتیز هست که در این اصول آورده نشده؟ نظرات خودتون رو این پایین بنویسید. اگر هم سوالی هست خوشحال میشم مطرح کنید. قسمت قبلی</description>
                <category>PaaSino</category>
                <author>Ali Akbar Hemmati</author>
                <pubDate>Sat, 02 Apr 2022 15:08:55 +0430</pubDate>
            </item>
                    <item>
                <title>چرا کوبرنتیز این شکلی طراحی شده؟ - قسمت سوم</title>
                <link>https://virgool.io/paasino/kubernetes-design-principles-3-tlqbinzgjbqt</link>
                <description>مقدمهدر این سری نوشته‌ها قصد داریم ببینیم اصول طراحی کوبرنتیز چی هستن. در قسمت اول و دوم دو تا اصل رو بررسی کردیم و حالا وقتشه بریم سراغ سومی. در این قسمت ابتدا یکی از ویژگی‌های ایده‌آل یک نرم‌افزار رو معرفی می‌کنیم و بعد بحث می‌کنیم چجوری با کوبرنتیز میشه این ویژگی رو پیاده کرد. جا داره دوباره اشاره کنم این مطالب از یک ارائه در kubecon 2018 گرفته شدن. اگه در حوزه‌ی زیرساخت هستید و با کوبرنتیز کار می‌کنید این نوشته می‌تونه به شما دید خوبی بده تا علاوه بر ساختار کوبرنتیز علتش رو هم بدونید و عمیق‌تر با کوبرنتیز آشنا بشید. تو این نوشته فرض شده شما با کوبرنتیز آشنایی ابتدایی دارید. اگر هم تجربه‌ی عملی داشته باشید که چه بهتر.متدولوژی Twelve-Factor App در نوشتن نرم‌افزارقبل از رسیدن به اصل سوم بذارید یه کم مقدمه‌چینی کنم. احتمالا در مورد متدولوژی Twelve-Factor App یا ۱۲ فاکتور شنیدید. در این متدولوژی ۱۲ ویژگی ایده‌آل برای نرم‌افزار شمرده شده که با رعایت اون‌ها می‌تونیم فرایند بهتری برای توسعه‌ی نرم‌افزار داشته باشیم. یکی از  ویژگی‌های شمرده شده در این متدولوژی این هست که کانفیگ نرم‌افزار باید در محیطی که دیپلوی میشه باشه نه داخل کد به شکل هاردکد شده. منظور از کانفیگ هر چیزی هست که بین محیط‌های مختلف (مثل staging و production) عوض میشه؛ مثلا یک نرم‌افزار موقع اجرا می‌خواد بدونه برای اتصال به دیتابیس باید به چه آدرسی وصل بشه. برای دادن چنین چیزی نباید اون رو داخل کد قرار بدیم. بلکه باید از یک فایل یا متغیر محیطی بخونیم. در این لینک می‌تونید بیشتر در موردش بخونید.حالا که در مورد این ویژگی حرف زدیم، باید ببینیم آیا کوبرنتیز چنین امکانی به ما میده؟ و اگر جواب مثبته چطوری؟معرفی ConfigMap و Secretدو تا از آبجکت‌هایی که در کوبرنتیز میشه ساخت و داخل اون‌ها کانفیگ‌های نرم‌افزار رو قرار داد، ConfigMap و Secret هستن. یه نمونه از هر کدوم رو ببینیم. اولی یک ConfigMap هست:و دومی Secret:در ConfigMap تنظیمات غیرحساس رو می‌ذارن. مثلا اینجا اطلاعات اتصال به دیتابیس گذاشته شده‌ان و در نیم‌اسپیس staging هست. در مورد Secret باید توجه کنیم که اطلاعات فقط base64 میشن و عملا به شکل مستقیم در دسترس هستن. توی این مثال نام کاربر و رمز دیتابیس رو گذاشتم. میشه دسترسی به Secretها رو در کلاستر محدود کرد یا از روش‌های امن‌تری برای نگهداری Secret استفاده کرد که بحث ما اینجا نیست. هدف اینه که این دو تا آبجکت رو بشناسیم.خب حالا این‌ها رو در یه فایل می‌ذاریم و با زدن این دو دستور آبجکت‌ها رو می‌سازیم:kubectl apply -f secret.yaml
kubectl apply -f configmap.yaml چجوری در نرم‌افزار استفاده‌اش کنیم؟ یک راهی که به ذهن می‌رسه این هست که خود برنامه بیاد به API Server درخواست بده و این آبجکت‌ها رو بخونه. اما این کار اصلا خوب نیست چون نمی‌خوایم برنامه وابسته به زیرساختی که توش هست باشه؛ چون ممکنه من بخوام توی سیستم خودم برای تست با داکر اجراش کنم. اونجا دیگه API Serverی در کار نیست. علاوه بر این، برای این کار باید کد رو تغییر بدیم تا از API Server کانفیگ رو بخونه که باعث میشه هزینه‌ی زمانی بیشتری برای استفاده از کوبرنتیز بدیم. پس این کار رو نمی‌کنیم. اینجاست که به اصل سوم می‌رسیم؛ یعنی قابلیت جابجایی کاربر در محیط‌های مختلف.اصل سوم: قابلیت جابجایی در محیط‌های مختلفنمی‌دونم ترجمه‌ی خوبی هست یا نه ولی در ارائه این اصل رو&quot;meet the users where they are&quot;عنوان کرده. منظورش اینه که ما کافیه ویژگی گفته شده در متدولوژی ۱۲ فاکتور رو رعایت کنیم و کانفیگ رو از محیط (فایل یا متغیر محیطی) بگیریم. وقتی از روی کد ما ایمیج ساخته ميشه و در تعریف پاد میاریمش، همونجا می‌تونیم این فایل‌های کانفیگ یا متغیرهای محیطی رو تعیین کنیم. مثلا فرض کنید برنامه‌ای که نوشتم از مسیر/app/config/.envاطلاعات دیتابیس به غیر از نام کاربر و رمز رو می‌خونه. می‌تونم پادم رو این شکلی تعریف کنم و از ConfigMap ساخته شده در قسمت قبل استفاده کنم:اینجا قصد آموزش ندارم. فقط خلاصه بگم که یک volume تعریف کردم که از ConfigMap استفاده می‌کنه و در کانتینر مربوطه فایل رو در مسیر مناسب قرار دادم. به شکل مشابه میشه از Secret هم استفاده کرد.راه‌های دیگه‌ای برای دادن کانفیگ به پاد هست که بهش نمی‌پردازیم. هدفم این بود که ببینیم کوبرنتیز چنین قابلیت‌هایی داره.با توجه به این اصل کوبرنتیز من می‌تونم ایمیجی که ساختم و تعریف پاد متناظرش رو به راحتی بین کلاستر یا نیم‌اسپیس‌های مختلف جابجا کنم. تنها چیزی که بین محیط‌ها تغییر می‌کنه اون ConfigMap یا Secret هست که رفتار نرم‌افزار رو متناسب با محیط تغییر میده. مثلا در تعریفشون نیم‌اسپیس رو به جای staging می‌ذاریم production و مقادیر رو به شکل مناسب تغییر می‌دیم. این شکلی میشه ازشون در پادهای production استفاده کرد. علاوه بر این برنامه هیچ اطلاعی نخواهد داشت که روی کوبرنتیز هست یا نه.جمع‌بندیدر این مطلب ابتدا در مورد متدولوژی ۱۲ فاکتور صحبت کردیم  و یکی از ویژگی‌های مهمی که نرم‌افزارها باید داشته باشن (گرفتن کانفیگ از محیط) رو بررسی کردیم. در ادامه دیدیم چجوری میشه از قابلیت‌های کوبرنتیز استفاده کرد تا بشه نرم‌افزاری رو که این ویژگی رو داره در محیط‌های مختلف دیپلوی کنیم. به این شکل دیگه لازم نیست کد رو تغییر بدیم و میشه به راحتی کانفیگ نرم‌افزار رو در جای مناسب قرار داد. بدون این که نرم‌افزار بدونه در کوبرنتیز اجرا میشه.امیدوارم این مطلب براتون مفید بوده باشه. اگر سوال یا نظری دارید این پایین بنویسید.قسمت قبلیقسمت بعدی</description>
                <category>PaaSino</category>
                <author>Ali Akbar Hemmati</author>
                <pubDate>Sat, 19 Mar 2022 20:02:15 +0330</pubDate>
            </item>
                    <item>
                <title>چرا کوبرنتیز این شکلی طراحی شده؟ - قسمت دوم</title>
                <link>https://virgool.io/paasino/kubernetes-design-principles-2-fals1tgr93tn</link>
                <description>مقدمهدر قسمت قبل در مورد اصل اول طراحی کوبرنتیز گفتیم. چی بود؟ اینکه به جای imperative در کوبرنتیز از declarative API استفاده شده. توضیح هر کدوم هم دیدیم. حالا در ادامه‌ی بحث قبلی قراره اصل دوم رو ببینیم. این مطالب برگرفته از ارائه‌ی سعد علی از شرکت گوگل در kubecon سال ۲۰۱۸ هست. ایشون جزو توسعه‌دهندگان کوبرنتیز هست و تو این ارائه توضیح میده که اصول معماری کوبرنتیز چه چیزهایی هستن و دلیل هر کدوم چیه.اگه در حوزه‌ی زیرساخت هستید و با کوبرنتیز کار می‌کنید این نوشته می‌تونه به شما دید خوبی بده تا علاوه بر ساختار کوبرنتیز علتش رو هم بدونید و عمیق‌تر با کوبرنتیز آشنا بشید. تو این نوشته فرض شده شما با کوبرنتیز آشنایی ابتدایی دارید. اگر هم تجربه‌ی عملی داشته باشید که چه بهتر.سوالآخر قسمت قبل این سوال رو پرسیدم که «وقتی ما به کوبرنتیز (دقیق‌ترش رو بگم API server) گفتیم حالت دلخواهمون چیه چه شکلی ما رو به اون می‌رسونه» آیا API server خودش به نودها دستورات لازم رو میده؟ جوابش نه هست. برای این که ببینیم چجوری اصل دوم رو می‌بینیم.اصل دوم: هیچ API پنهانی بین اجزای کوبرنتیز نیستممکنه یه کم مبهم باشه عنوانش. قدم به قدم جلو میریم تا ببینیم چی میگه.معنی API پنهان چیه؟بیاید تعریف این پاد رو در نظر بگیریم:apiVersion: v1 
kind: Pod
metadata:
  name: frontend
  labels:
    app: cache
    tier: frontend
spec:
   containers:
        - name: web-server
          image: nginx:1.21.1
فرض کنید ماشین مستر خودش با نودها صحبت می‌کرد و پاد رو برای ما بالا می‌آورد. برای این باید به نودها درخواست می‌داد و می‌گفت یه کانتینر از روی ایمیج nginx:1.21.1 بسازید. در کنارش باید مدام وضعیت کانتینر رو روی نودها بررسی می‌کرد و اگه تغییری لازم داشتن اعمال می‌کرد. این حالت رو توی عکس‌های زیر می‌بینید.برای این درخواست‌هایی که مستر به نودها میده، لازم هست یک API در نودها وجود داشته باشه تا کاملا توسط مستر کنترل بشن. این API از ما کاربران مخفیه و ازش استفاده نمی‌کنیم؛ به همین دلیل اسمش شد API پنهان. چیزی که اصل دوم میگه اینه که چنین APIی وجود نداره. نودها و بقیه‌ی اجزای کوبرنتیز دقیقا با همون APIی که ما (مثلا با kubectl) استفاده می‌کنیم با مستر صحبت می‌کنن و مستر مخفیانه با اون‌ها حرف نمی‌زنه. اگر مستر خودش می‌خواست تمام جزئیات رو مدیریت کنه بسیار سنگین می‌شد و مثل الان اجزاش قابل گسترش یا جایگزینی نبودن.پس چجوری پادها بالا میان؟درک جواب این سوال به ما کمک می‌کنه که تقریبا نحوه‌ی کار همه‌ی اجزای کوبرنتیز رو متوجه بشیم. بذارید مثال قبل رو ادامه بدیم. من به کوبرنتیز گفتم یه پاد درست کنه. وقتی دستور ساخت پاد به API server  داده میشه (هنوز روی نودها کانتینری ساخته نشده) باید تعیین بشه روی کدوم نود بالا بیاد. اینجا scheduler که خودش یه عضوی از مستر هست می‌بینه یه پاد هست که نود نداره:چجوری scheduler متوجه میشه؟ scheduler در هر لحظه API server رو watch می‌کنه که اگه پادی بدون نود ساخته شد، دست به کار بشه و با توجه به معیارهایی که داره یک نود رو برای هر پاد مشخص کنه. بعد از تعیین نود، آیا scheduler به اون نود میگه که پاد رو بسازه؟ نه. فقط به API server میگه پاد رو آپدیت کنه و  مقدار نود رو تعیین می‌کنه:تو این مثال مقدار رو  node 2 قرار داده. نودها هم هميشه دارن API server رو watch می‌کنن که اگه یه پاد به اون‌ها داده شد، ایجادش کنن. الان نود ۲ می‌بینه یک پاد بهش اختصاص داده شده و هنوز اون رو نساخته. پس یه کانتینر رو از روی ایمیج nginx:1.21.1 می‌سازه (اگه لازم باشه ایمیج پول میشه):از این به بعد حواس این نود هست که همیشه این پاد بالا باشه. اگر ما پاد رو از روی API server حذف کنیم، نود مطلع میشه و اون پاد رو حذف می‌کنه:توجه کنید که منظورم از نود تو همه‌ی موارد kubelet بود.این چه خوبی‌ای داره؟با این روش سیستم ما در مقابل اتفاقات غیرمنتظره خیلی مقاوم‌تر هست. فرض کنید یک نود مدتی از دسترس خارج بشه و بعد برگرده. وقتی برمی‌گرده دوباره API server رو نگاه می‌کنه و اگه لازم باشه پادی بسازه، می‌سازه یا اگه باید پادی حذف بشه، حذفش می‌کنه. یعنی تنها وضعیت فعلی مهمه و تغییراتی که تو بازه‌ی قطعی افتاده تاثیری روی نود نداره. هم‌چنین اگه مستر از دست بره خود نود‌ها وضعیت فعلی‌شون رو حفظ می‌کنن تا دوباره مستر بالا بیاد. یعنی با از دست رفتن مستر کلاستر نابود نمیشه. نکته‌ی دیگه اینه که مستر خیلی بزرگ و سنگین نمیشه و اجزای مختلف در یک ساختار توزیع‌شده دست به دست هم میدن تا به حالت مطلوب کاربر برسن.یکی از بزرگ‌ترین مزیت‌های این روش اینه که میشه کوبرنتیز رو گسترش داد. یعنی ممکنه من بخوام به جای scheduler کوبرنتیز یک scheduler مخصوص خودم بذارم. بدون تغییر در ساختار کوبرنتیز scheduler رو با برنامه‌ای که خودم نوشتم جایگزین می‌کنم. کافیه فقط بتونه با API server صحبت کنه و منطق خاص من رو برای scheduling پیاده کنه. هم‌چنین اگه یک کاری رو کوبرنتیز نمی‌کنه، من خودم می‌تونم به کوبرنتیز اضافه کنم. مفهوم CRD و اپراتور هم به این شکل در کوبرنتیز قرار گرفته. برای مثال اپراتورهایی که برای دیتابیس‌ها وجود دارن یا اپراتور پرومتئوس. از قدرتمند‌ترین ویژگی‌های کوبرنتیز همین گسترش‌پذیری‌اش هست.جمع‌بندیتو این قسمت در مورد اصل دوم در طراحی کوبرنتیز صحبت کردیم. به شکل خلاصه اگر بخوایم بگیم، در کوبرنتیز اجزا به طور مستقل API server رو watch می‌کنن و هر کدوم نقش خودشون رو برای رسیدن به وضعیت مطلوب ایفا می‌کنن. به این شکل دیگه لازم نیست در مستری چیزی باشه که به بقیه دستور بده چی کار کنن. این باعث میشه مستر سبک‌تر باشه، سیستم در مقابل اتفاقات مقاوم‌تر باشه و کوبرنتیز قابلیت گسترش داشته باشه.امیدوارم براتون مطلب مفیدی بوده باشه. اگر سوال یا نکته‌ای دارین این پایین بفرمایین.قسمت قبلیقسمت بعدی</description>
                <category>PaaSino</category>
                <author>Ali Akbar Hemmati</author>
                <pubDate>Fri, 03 Dec 2021 22:44:21 +0330</pubDate>
            </item>
                    <item>
                <title>داکر برای برنامه‌نویس‌ها: قسمت سیزدهم - آشنایی با اجزای فایل docker-compose.yaml</title>
                <link>https://virgool.io/paasino/docker-compose-file-h74vx0ch0czc</link>
                <description>مقدمهدر قسمت قبل با داکر کامپوز آشنا شدیم و یه سرویس کوچولو باهاش راه انداختیم. تو این قست کمی دقیق‌تر اجزای یه فایل docker-compose.yaml رو بررسی می‌کنیم و یه اپ‌ جنگو با دیتابیس پستگرس بالا میاریم. کد این قسمت رو در این ریپو در گیتهاب می‌تونید ببینید.برای همراهی با این مطلب لازمه که تجربه‌ی کار با داکر و کانتینرها رو داشته باشین و هم‌چنین آشنایی ابتدایی با داکر کامپوز داشته باشین. اگر این طور نیست خوبه که آموزش‌های قبلی رو ببینید.ساختار کلی فایل اولین چیزی که توی docker-compose.yaml می‌نویسیم ورژن است. ورژن‌های مختلف داکر کامپوز ویژگی‌های مختلفی را پشتیبانی می‌کنن. ما در اینجا جدیدترین نسخه رو نوشتیم:version: &amp;quot3.9&amp;quotبعد از اون services رو داریم که اصل کار ماست.version: &amp;quot3.9&amp;quot
services:داخل این بخش هر چی سرویس داریم رو می‌نویسیم. مثلا یک اپ بک اند داریم و یک دیتابیس. در نتیجه دو تا سرویس داخل services باید بنویسیم. version: &amp;quot3.9&amp;quot
services:
   web:

    db:
برای مشخص کردن هر سرویس اول یه اسم می‌نویسیم. تو مثال بالا یه سرویس به نام web داریم که همون اپ جنگو هست و یه سرویس db برای دیتابیس. حالا داخل هر سرویس قراره مشخصاتش رو بنویسیم و هر کدوم رو پر کنیم. نوشتن سرویس webمن به web یک ایمیج دادم با عبارت image. اسم و تگ ایمیج رو اینجا باید بنویسیم. بعدش تعدادی پورت با ports نوشتم. ترتیب عبارات در فایل yaml تفاوتی ایجاد نمی‌کنه. version: &amp;quot3.9&amp;quot
services:
  web:
    image: django-blog:1
    environment:
      - DB_NAME=postgres
      - DB_USER=postgres
      - DB_PASSWORD=postgres
      - DB_HOST=db
      - DB_PORT=5432 
    ports:
      - &amp;quot8000:8000&amp;quot
    depends_on:
      - dbدقت کنید که ports یک لیست می‌گیره و مثل وقتی هست که با docker run آپشن p- رو می‌زدیم؛ یعنی اول پورت روی سیستم میزبان و دوم پورت کانتینر. اگر بخوایم متغیر محیطی داشته باشیم اون رو با environment می‌نویسیم. تو این مثال مشخصات اتصال به دیتابیس رو دادم. همون طور که معلومه به شکل لیست داده میشه. تو هر مورد به ترتیب اسم متغیر، علامت = و مقدارش میاد. متغیرهای محیطی رو این شکلی هم میشه نوشت: environment:
    DB_NAME: postgres
    DB_USER: postgres
    DB_PASSWORD: postgres
    DB_HOST: db
    DB_PORT: 5432 اگر یه فایل از قبل دارید که این متغیرها از قبل توش نوشته شده می‌تونید با env_file بنویسید و بعد مسیر فایل رو بدید:env_file:
    - web-variables.envهمونطور که می‌بینید یک لیست هست و میشه چندتا فایل هم داد. اگه شما سورس کدی دارین و دارین توسعه‌اش میدین می‌تونین خودتون هر دفعه با دستور docker build بیلدش کنین و اسم ایمیج رو توی image بهش بدین. اما میشه بیلد رو به کمک داکر کامپوز انجام داد. یعنی یک قسمت به نام build به سرویس اضافه کنیم و به این شکل در میاد سرویس web:version: &amp;quot3.9&amp;quot 
services:
   web:
     build: ./
     environment:
       - DB_NAME=postgres
       - DB_USER=postgres
       - DB_PASSWORD=postgres
       - DB_HOST=db
       - DB_PORT=5432
     ports:
       - &amp;quot8000:8000&amp;quot
     depends_on:
       - dbجلوی build مسیر ساخت ایمیج رو میدیم. همونجور که موقع زدن docker build می‌دادیم. حالا هر وقت کدمون تغییری کنه میشه در روت پروژه دستور docker-compose build رو زد تا بیلد انجام بشه. دیگه image رو لازم نیست بنویسم. اگه بنویسم اسم و تگ ایمیجی که ساخته میشه رو می‌ذاره همون چیزی که من جلوی image نوشتم.یه نکته باقی مونده. اونم اینه که برنامه‌ی جنگوی من برای شروع نیاز داره که دیتابیس آماده باشه. برای این که وابستگی رو بیان کنیم توی سرویس web از depends_on استفاده می‌کنیم و یه لیست میدیم از سرویس‌هایی که این سرویس بهشون وابسته است. اینجا web فقط به db وابسته بود.نوشتن سرویس dbحالا سرویس دیگه‌مون که db هست رو می‌نویسیم:version: &amp;quot3.9&amp;quot 
services:
   web:
     image: django-blog:1
     environment:
       - DB_NAME=postgres
       - DB_USER=postgres
       - DB_PASSWORD=postgres
       - DB_HOST=db
       - DB_PORT=5432
     ports:
       - &amp;quot8000:8000&amp;quot
     depends_on:
       - db
  db:
    image: postgres
    volumes:
      - ./data/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgresایمیجش postgres هست چون می‌خوام از این دیتابیس استفاده کنم. در این سرویس می‌خوام اطلاعاتم باقی بمونه و با هر بار از خاموش و روشن کردن کانتینر از بین نره. به همین دلیل از volume استفاده کردیم. داخلش یه لیست قرار می‌گیره و مثل آپشن v- در docker run اول مسیر تو سیستم خودمون رو میدیم بعدش مسیر داخل کانتینر. اینجا می‌خوام اطلاعات دیتابیس که در مسیر var/lib/postgresql/data/ درون کانتینر هست رو توی پوشه‌ی data/db داخل پروژه‌ی خودم نگه دارم. بقیه‌ی چیزهایی که نوشتم رو قبلا دیدیم. اجرای سرویس‌هاالان دیگه آماده‌ایم. تو همون پوشه دستور docker-compose up رو می‌زنیم: به نظر میاد همه چی خوبه. حالا برای اطمینان از کارکردش با curl یک درخواست بهش می‌فرستم که یک user جدید بسازم:می‌بینید در جواب کد ۲۰۱ داده شده و همه چی خوب کار می‌کنه.جمع‌بندیما در این قسمت دیدیم چجوری یه فایل داکر کامپوز برای اپ جنگو با دیتابیس بنویسیم. با بعضی از تنظیماتی که میشد روی سرویس‌ها انجام داد هم آشنا شدیم. برای دیدن مرجع کامل داکر کامپوز به این لینک در سایت داکر مراجعه کنید.اميدوارم این مطلب براتون مفید بوده باشه. اگه سوال یا نظری دارین این پایین بگین.قسمت قبلی</description>
                <category>PaaSino</category>
                <author>Ali Akbar Hemmati</author>
                <pubDate>Fri, 05 Nov 2021 20:55:01 +0330</pubDate>
            </item>
                    <item>
                <title>داکر برای برنامه‌نویس‌ها: قسمت دوازدهم - معرفی داکر کامپوز</title>
                <link>https://virgool.io/paasino/docker-compose-intro-inlgmaj0kixv</link>
                <description>مقدمهبرنامه‌هایی که می‌نویسیم معمولا تنها نیستند و کنارشون باید سرویس‌های دیگه‌ای هم اجرا بشن. مثلا یک دیتابیس کنار برنامه اصلی باید باشه تا بتونه اطلاعات رو ذخیره کنه. هنگام نوشتن و تست برنامه‌ هم دوست داریم چنین شرایطی رو داشته باشیم. یعنی واقعا یک دیتابیس بالا بیاد و برنامه‌ی ما بتونه با اون کار کنه. داکر کامپوز (docker compose) ابزاری هست که به ما اجازه میده چند تا سرویس رو در داکر کنار هم بالا بیاریم و به هم متصل کنیم. در این مطلب قصدمون این هست که یک معرفی کوتاهی بر داکر کامپوز داشته باشیم، نصبش کنیم و یه سرویس ساده هم باهاش اجرا کنیم.برای درک بهتر این نوشته باید با داکر و کانتینرها کار کرده باشید و به یک سیستم لینوکسی دسترسی داشته باشید.آشنایی با داکر کامپوزهمون طور که در بخش قبلی گفته شد شما با داکر کامپوز می‌تونید چند سرویس کانتینری رو کنار هم اجرا کنید. کافیه در یک فایل yaml اطلاعات رو بنویسید و با دستور docker-compose up اون رو اجرا کنید. فرض کنید یه سرویس جنگو (یک فریم ورک بک اند به زبان پایتون) نوشتید و اون نیاز داره به یک دیتابیس MySQL وصل بشه. تو فایل yaml می‌تونید دو تا سرویس تعریف کنید که یکیش ایمیج mysql هست و دیگری ایمیجی که از روی کد شما ساخته میشه. در این فایل yaml اطلاعات ارتباط جنگو به mysql رو می‌دیم و وقتی جنگو بالا بیاد به یک دیتابیس MySQL وصل میشه. به این شکل در محیط development خودتون می‌تونید برنامه رو تست کنید.نصب داکر کامپوزحالا این ابزار باحال رو چجوری نصب کنیم؟ قبل از نصب لازمه داکر رو داشته باشید. برای نصب داکر می‌تونید به این پست قبلی مراجعه کنید. در این‌جا نصب داکر کامپوز در یک سیستم لینوکسی رو میگیم. برای داشتن داکر کامپوز فقط کافیه یک فایل باینری رو دانلود کنیم و قابلیت اجرایی بهش بدیم. به این لینک برید و آخرین نسخه‌ (یا هر نسخه‌ای که می‌خواید) رو دانلود کنید.من اونی که تو عکس دورش خط کشیدم رو دانلود کردم. حالا با دستور زیر بهش قابلیت اجرایی میدم: chmod +x docker-compose-Linux-x86_64 دستور chmod دسترسی‌های مختلف فایل رو تغییر میده. این‌جا فقط قابلیت اجرا شدن رو به فایل دادم. الان میشه اجراش کرد: این خروجی نشون میده تا اینجا درست اومدم. اما خوبه که فایل باینری رو تو PATH سیستم بذارم تا هر دفعه راحت اجراش کنم. اسمش هم عوض می‌کنم که راحت‌تر بنویسمش. برای این کار این دستور رو اجرا می‌کنم:  mv docker-compose-Linux-x86_64 /usr/local/bin/docker-composeدیگه به راحتی تو هر مسیری می‌تونم docker-compose رو اجرا کنم:اجرای سرویس سادهیک فایل با نام docker-compose.yaml ایجاد کنید و داخل اون این شکلی بنویسید:version: &amp;quot3.9&amp;quot
services:
    nginx:
        image: &amp;quotnginx&amp;quot    
        ports:     
             - &amp;quot8000:80&amp;quotاین فایل تنها یه کانتینر nginx بالا میاره که روی پورت ۸۰۰۰ در سیستم میزبان جواب میده. در همون پوشه‌ای که این فایل درش قرار داره دستور docker-compose up رو بزنید تا این خروجی رو ببینید: این نشون میده داکر کامپوز داره کارش رو به خوبی انجام میده. می‌تونید در مرورگر خودتون آدرس localhost:8000 برید و ببینید nginx داره جواب میده. خب اینم از این. در قسمت‌های بعدی ان شاء الله نوشتن این فایل رو یاد می‌گیریم.جمع بندیدر این مطلب با داکر کامپوز آشنا شدیم، نصبش کردیم و یک سرویس ساده رو باهاش اجرا کردیم. امیدوارم براتون مفید بوده باشه. اگر نظر یا سوالی دارین این پایین بفرمایین.قسمت قبلیقسمت بعدی</description>
                <category>PaaSino</category>
                <author>Ali Akbar Hemmati</author>
                <pubDate>Mon, 26 Apr 2021 23:49:57 +0430</pubDate>
            </item>
                    <item>
                <title>داکر برای برنامه‌نویس‌ها: قسمت یازدهم - best practices (ادامه)</title>
                <link>https://virgool.io/paasino/best-practices-2-ok7dfmsx1fk5</link>
                <description>مقدمهقسمت قبلی با تعدادی از best practiceهای دنیای کانتینرها و داکر آشنا شدیم. در این قسمت می‌خوایم به تعدادی دیگه‌ از این‌ نکات بپردازیم. این نوشته برای برنامه‌نویس‌ها و مهندسان DevOps مفید می‌تونه باشه.فرض بر این هست که شما سابقه برنامه‌نویسی دارید و با کانتینرها و داکر هم کار کردید.استفاده از dockerignore. وقتی در یک پوشه دستور docker build رو اجرا می‌کنیم کل محتوای پوشه به عنوان build context به حساب میان و اگر کل پوشه رو کپی کنیم همه‌شون میرن به ایمیج. بعضی از فایل‌ها یا پوشه‌ها ممکنه داخل ایمیج لازم نباشن. چجوری اینا رو حذف کنیم؟ مثل gitignore. داکر هم یه فایل dockerignore. داره که با اون می‌تونیم هر چیزی که نمی‌خوایم رو حذف کنیم. این شکلی بدون این که دست به ساختار پوشه بزنیم یه چیزایی رو کنار می‌ذاریم. مثلا ممکنه یک سری README.md نوشته باشید و نخواید تو ایمیج بذارید. این جاست که dockerignore. به دردتون می‌خوره. برای آشنایی با نحوه‌ی استفاده از الگوهای مختلف در این فایل می‌تونید این لینک رو ببینید.بیلد چند مرحله‌ایبعضی از برنامه‌ها هستن که برای بیلد شدن باید کامپایل بشن و برای این کامپایل شدن باید تعدادی ابزار وجود داشته باشه. این ابزارها برای اجرای نهایی برنامه لازم نیستن و باعث میشن حجم ایمیج زیاد بشه. این جور مواقع از بیلد چند مرحله‌ای استفاده می‌کنیم. به عنوان مثال زبان گو رو در نظر بگیرید. وقتی برنامه‌ای به این زبان کامپایل میشه یک فایل باینری به دست میاد که فقط باید دسترسی execute بهش بدیم تا بتونیم اجراش کنیم. چیز دیگه‌ای لازم نیست. یک داکرفایل به عنوان مثال آوردم:
FROM golang:1.7.3 AS builder
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html  
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine:latest  
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/alexellis/href-counter/app .
CMD [&amp;quot./app&amp;quot]این مثال تو این لینک آورده شده. دقت کنید دو تا FROM داریم. یعنی دو تا مرحله داریم و دو تا ایمیج قراره ساخته بشه. تو مرحله اول از ایمیج رسمی golang استفاده شده و برنامه رو بیلد کرده. خروجی بیلد به یک فایل به نام app میره. چیزی که احتمالا بهش توجه کردید AS builder در انتهای خط اوله. AS یکی از keywordهای داکرفایل هست و یک اسم به ایمیجی که ساخته میشه میده. این اسم رو گذاشتیم تا در مرحله دوم ازش استفاده کنیم.حالا بریم سراغ FROM دوم. می‌بینید که از alpine استفاده کرده که حجم خیلی کوچیکی داره. این همون چیزیه که این روش رو خیلی جذاب می‌کنه. تنها کافیه فایل باینری رو از ایمیج قبلی کپی کنیم. تو دستور COPY یک آپشن استفاده شده و اون from-- هست. با این آپشن اسم ایمیجی که ازش کپی می‌کنیم تعیین میشه. یعنی دیگه از سیستم خودمون کپی نمی‌کنیم. تو این مورد اسم ایمیج قبلی builder است. آخر سر هم app رو اجرا می‌کنیم. با این روش به جای استفاده از ایمیج golang که بیش از ۲۰۰ مگابایت حجم داره رسیدیم به alpine (با تنها چند مگابایت حجم) به علاوه فایل باینری.استفاده از non root userدستوراتی که توی داکرفایل برای RUN و ENTRYPOINT و CMD می‌نویسیم با کاربر root اجرا میشن. اما این از لحاظ امنیتی ممکنه خطرساز بشه؛ چون دسترسی بالایی داره. برای این که این اتفاق نیفته از USER استفاده می‌کنیم: FROM python:3.7
ENV PYTHONUNBUFFERED 1 
RUN mkdir /code 
WORKDIR /code 
COPY requirements.txt /code/ 
RUN pip install -r requirements.txt 
COPY . /code/ 
RUN useradd nonroot 
USER nonroot
ENTRYPOINT [&amp;quot/bin/bash&amp;quot, &amp;quotstart.sh&amp;quot]خط یکی مونده به آخر ازش استفاده کردم. جلوی USER نام کاربر رو می‌ذاریم. قبلش یادتون باشه باید کاربر تو سیستم ساخته بشه. خط قبلیش من useradd رو اجرا کردم. میشه بعد از نام دو نقطه بذاریم و گروهش رو هم مشخص کنیم. گروه هم باید قبلش ساخته بشه. هر چی دستور بعد از اون اجرا بشه رو این کاربر انجام میده. اگر توی شل کانتینر ساخته شده از این ایمیج هم بریم باز همون کاربر هستیم و نه root: تو تصویر بالا (به شل کانتینری که از داکرفایل قبلی ساخته شده رفتم) که به خروجی دستور id نشون میده نام کاربری من nonroot هست و گروهم هم nonroot. چرا گروه nonroot وجود داره؟ من که نساخته بودمش. به این فکر کنید و اگر جواب رو پیدا کردید تو نظرات بگید.جمع بندیدر این مطلب با یک سری دیگه از best practiceها برای برنامه‌نویس‌ها در دنیای کانتینرها و داکر آشنا شدیم. اگر نکات دیگه‌ای هم سراغ دارید معرفی کنید تا همه استفاده کنیم. اگر هم سوال یا نظری دارید این پایین بفرمایید.قسمت قبلیقسمت بعدی</description>
                <category>PaaSino</category>
                <author>Ali Akbar Hemmati</author>
                <pubDate>Sun, 21 Mar 2021 14:43:58 +0330</pubDate>
            </item>
                    <item>
                <title>داکر برای برنامه‌نویس‌ها: قسمت دهم - best practices</title>
                <link>https://virgool.io/paasino/best-practices-1-c5rrtqpiomzq</link>
                <description>مقدمهقسمت قبل یک برنامه جنگو رو داکرایز کردیم. اما برای یک برنامه‌نویس کافی نیست که فقط ایمیج بسازه. بلکه باید یک سری نکات رو رعایت کنه تا به استانداردهای لازم برسه. طی دوقسمت قراره به برخی از این نکات بپردازیم و دلیلش رو هم ببینیم. به این نکات میگن best practice. قطعا برای برنامه‌نویس‌ها این مطالب به درد می‌خورن. مهندسین دواپس هم این مطالب رو مفید خواهند یافت.برای ارتباط بهتر با این نوشته باید با کانتینرها، داکر و نحوه‌ی داکرایز کردن یک برنامه آشنایی داشته باشین. داشتن پیش‌زمینه در برنامه‌نویسی هم لازمه.ساختار ایمیج و چگونگی بیلد آنابتدا بیاید ساختار یک ایمیج رو بررسی کنیم. ایمیج‌ها یک سری لایه read only هستند و وقتی ما در داکرفایل برخی کارها رو می‌کنیم یک لایه جدید ساخته میشه. مثلا داکرفایل قسمت قبل رو ببینید: 
FROM python:3.7 
ENV PYTHONUNBUFFERED 1 
RUN mkdir /code 
WORKDIR /code 
COPY requirements.txt /code/ 
RUN pip install -r requirements.txt 
COPY . /code/ 
ENTRYPOINT [&amp;quot/bin/bash&amp;quot, &amp;quotstart.sh&amp;quot]بعضی دستورها هستن که فایل سیستم رو تغییر میدن. مثلا وقتی COPY رو استفاده می‌کنم یه فایل از سیستم من می‌فرسته به ایمیج. در نتیجه فایل سیستم ایمیج تغییر می‌کنه. زمانی که چنین دستورهایی رو اجرا می‌کنیم داکر یک لایه جدید ایجاد می‌کنه. فایده‌‌ی این لایه لایه بودن چیه؟ در بخش بعد می‌بینیم.استفاده از قابلیت بیلد کش (build cache)طبق صحبتی که بخش قبل کردیم، با اجرای بعضی دستورها لایه‌هایی به ایمیج اضافه میشن. خوبی استفاده از لایه‌ها اینه که می‌تونیم از قابلیت کش استفاده کنیم. یعنی وقتی یک لایه قبلا ساخته شده و تغییری هم قرار نیست بکنه دوباره ساخته نمیشه و سریع میره مرحله بعد. دو تا از دستورهایی که فایل رو از سیستم میزبان به ایمیج منتقل می‌کنن COPY و ADD هستن. COPY رو قبلا دیدیم؛ فایل رو کپی می‌کنه. ADD هم همین کار رو انجام میده با این تفاوت که می‌تونیم علاوه بر مسیر داخل سیستم میزبان بهش یک url بدیم تا اون رو دانلود کنه و بذاره داخل ایمیج. وقتی این دو تا دستور می‌خواد اجرا شه داکر میاد روی لایه فعلی تغییرات رو ایجاد کنه. تمامی لایه‌هایی که تو سیستم هستن و از روی لایه فعلی ساخته شدن توسط داکر بررسی میشن. به این لایه‌ها میگیم لایه‌های فرزند برای لایه‌ی فعلی.  بررسی لایه‌های فرزند در داکر برای استفاده از cacheداخل این لایه‌های فرزند چی رو بررسی می‌کنه؟ فایل‌هایی که در ایمیج هست رو نگاه می‌کنه. اگه تمام فایل‌ها در یک لایه فرزند وجود داشته باشن و تغییری نکرده باشن از همون لایه استفاده می‌کنه و لایه‌ی جدید نمی‌سازه. مثلا به داکرفایلی که بالا گذاشتم دوباره نگاه کنید. به جایی که می‌خوام requirements.txt رو کپی کنم توجه کنید. دارم یه دونه فایل به ایمیج کپی می‌کنم. دستور قبلیش هم ببینید. داکر به همه لایه‌هایی که بعد از دستور قبلی وجود دارن نگاه می‌کنه و توی اون‌ها فایل‌ها رو با فایل‌های لایه فعلی مقایسه می‌کنه. البته در مورد requirements.txt محتوای فایلی که داره کپی میشه رو می‌بینه. اگه یکیشون دقیقا همین محتویات رو داشته باشه، از همون استفاده می‌کنه و لایه جدیدی نمی‌سازه. به این شکل سرعت بیلد بالاتر میره (داخل پرانتز بگم که این مقایسه رو با هش کردن انجام میده و نمیاد دونه دونه اطلاعات داخل فایل رو ببینه).یک دستور دیگه هم هست که برای کش کردن مهمه و در ارتباط با دو دستور بالا خیلی بهتر میشه. اون دستور RUN هستش. RUN موقع ساخت ایمیج دستوری رو داخلش اجرا می‌کنه. مثلا من در داکرفایل بالا pip install زدم. برای این دستور دیگه نمیاد تمام فایل‌های توی فایل سیستم رو بررسی کنه. بلکه فقط به دستوری که جلوش نوشته شده نگاه می‌کنه. مثل بند قبل میاد تمام فرزندان لایه قبلی رو نگاه می‌کنه و اگه بینشون لایه‌ای با همین دستور ساخته شده باشه از اون استفاده می‌کنه. حالا می‌تونیم ترکیب این با بند قبل رو داشته باشیم؛ تو داکرفایل وقتی کپی می‌کنم اغلب اوقات از کش استفاده میشه چون requirements.txt خیلی کم تغییر می‌کنه. در نتیجه RUN هم از کش استفاده می‌کنه چون لایه قبلیش تغییر نکرده و دستور جلوی RUN هم ثابته. اما اگر تمام سورس کد رو اول کپی می‌کردم (چون سورس کد دائما در حال تغییره) اون وقت برای COPY هر دفعه یک لایه جدید ساخته میشه و برای RUN هم دیگه کشی وجود نخواهد داشت چون لایه قبلیش جدیده. پس هر دفعه تمام اون پکیج‌های پایتون رو نصب می‌کنه که خیلی کار رو کند می‌کنه.ساخت ایمیج‌ برای همه جاوقتی یک ایمیج رو می‌سازیم باید دقت داشته باشیم که ممکنه به هر جایی بره و باید بیشترین انعطاف ممکن رو داشته باشه. منظورم اینه که نباید رفتار کدی که می‌نویسیم به شکل  hard code شده داخلش قرار گرفته باشه و باید با خوندن یک فایل یا متغیر محیطی رفتارش تعیین بشه. برای مثال فرض کنید من یک برنامه نوشتم که قراره به برنامه‌ی یک همکار دیگه از طریق شبکه متصل بشه و بهش درخواست HTTP بده.  این اصلا خوب نیست که آدرس، پورت و حتی HTTP یا HTTPS بودن این درخواست در برنامه‌ی من hard code بشه؛ چون در آینده شاید همه‌ی این‌ها تغییر کنه یا به محیط جدیدی بریم که نیازمند تغییر این مقادیر باشیم. در عوض مثلا این‌ها باید در یک متغیر محیطی گذاشته و متناسب با جایی که ایمیج در اون دیپلوی میشه تعیین بشن.ایمیج‌های statelessیکی از مهم‌ترین نکاتی که باید رعایت کنیم و از ویژگی‌های یک برنامه‌ی ۱۲ فاکتور این هست که ایمیج‌های ما داخل خودشون چیزی رو ذخیره نکنن. وظیفه‌ی نگهداری اطلاعات رو باید به ابزارهای خاصی که به این منظور نوشته شدن بسپاریم. به چنین سرویسی stateless میگیم چون هیچ state یا حالتی رو در خودش نگه نمی‌داره. مثلا برای نگهداری اطلاعات کاربران اون‌ها رو به دیتابیس MySQL بفرستیم که با ایمیج mysql اجرا شده. چنین ایمیجی وقتی اجرا بشه به راحتی می‌تونه scale بشه. اطلاعاتی ام که داخل ram یا فایل سیستم خود کانتینر قرار می‌گیرن برای cache استفاده میشن و نه برای ذخیره‌ی حالت سیستم.جمع بندیدر این مطلب تعدادی از best practiceها یا نکات مهم در نوشتن برنامه و داکرفایل رو مرور کردیم. این موارد به ما کمک می‌کنن نرم‌افزارمون به شکل مناسب بیلد و دیپلوی بشه. امیدوارم این مطلب براتون مفید بوده باشه. در صورتی که سوال یا نظری دارید این پایین بفرمایید.قسمت قبلیقسمت بعدی</description>
                <category>PaaSino</category>
                <author>Ali Akbar Hemmati</author>
                <pubDate>Fri, 19 Feb 2021 12:05:28 +0330</pubDate>
            </item>
                    <item>
                <title>داکر برای برنامه‌نویس‌ها: قسمت نهم - جنگو در داکرفایل</title>
                <link>https://virgool.io/paasino/django-dockerfile-ds5hqqfn8yel</link>
                <description>مقدمهقسمت قبلی یک داکرفایل ساده نوشتیم و از روش ایمیج درست کردیم. این دفعه قراره یک برنامه پایتون که با فریم‌ورک جنگو نوشته شده رو داکرایز و اجرا کنیم. این مطلب برای برنامه‌نویس‌هایی که می‌خوان برنامه‌هاشون رو در داکر اجرا کنن مفید خواهد بود.برای دنبال کردن مطالب این قسمت باید با داکر و اجرا کردن کانتینر در اون آشنا باشید. هم‌چنین خوبه که آشنایی ابتدایی با نوشتن داکرفایل و دستورات خط فرمان لینوکس داشته باشید.معرفی برنامهمن یک برنامه با جنگو نوشتم که می‌تونید اون رو تو این لینک گیتهاب ببینید و اگه خواستید کلون کنید. به برنچ simple-app برید. البته در زمان نوشتن این متن master با simple-app فرقی ندارن ولی در آینده تغییر می‌کنن. داکرفایلش رو هم همونجا می‌بینید که می‌خوایم در موردش صحبت کنیم. این برنامه وقتی اجرا بشه به درخواست‌های http ما جواب میده. چند تا جدول داره داخل دیتابیس که برای نویسنده و بلاگ هست. یک سری پارامتر هم داره که موقع اجرای برنامه از متغیرهای محیطی می‌خونه. از جمله اطلاعات ادمین. داخل فایل start.sh دستوراتی هست که برنامه رو اجرا می‌کنه و روی پورت ۸۰۰۰ گوش میده.نوشتن داکرفایلFROM python:3.7
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/
ENTRYPOINT [&amp;quot/bin/bash&amp;quot, &amp;quotstart.sh&amp;quot]اولش که قرار شد اسم ایمیج پایه رو بنویسیم. من از python:3.7 استفاده کردم. بعدش با ENV مقدار یک متغیر محیطی به نام PYTHONUNBUFFERED رو 1 گذاشتم که وقتی کانتینر اجرا شد لاگ‌ها رو بافر نکنه و تو خروجی استاندارد بنویسه. می‌تونستم موقع اجرا هم این متغیر رو بدم ولی چون می‌خوام تو همه‌ی کانتینرها باشه اینجا نوشتم. می‌خوام کدهای برنامه رو در مسیر code/ کپی کنم. اول این پوشه رو با RUN می‌سازم. با RUN یک دستور رو هنگام بیلد ایمیج داخل اون اجرا می‌کنیم. کلمه WORKDIR رو دیده بودیم. پوشه در مسیر code/ رو در نظر گرفتم تا از این به بعد اونجا باشیم.بعدش در دو مرحله فایل‌ها رو کپی می‌کنیم. دلیلش رو ان شاء الله قسمت بعد می‌بینیم. دستور COPY رو دیده بودیم قبلا. اول فایلی که requirement های برنامه رو داره منتقل می‌کنم و از روی اون با کمک RUN ماژول‌های لازم نصب میشه. دستوری که اجرا کردم pip هست و برای نصب پکیج‌های پایتون استفاده میشه. وقتی docker build رو اجرا کنم پکیج‌های لازم روی ایمیج نصب شده و هر جا که از روی اون کانتینری رو اجرا کنم این پکیج‌ها رو خواهم داشت. در بخش دوم سورس کد رو منتقل می‌کنم به پوشه اصلی. الان دیگه همه چیز رفته داخل ایمیج.آخرین کاری که انجام میدم اینه که اسکریپت start.sh رو اجرا کنم. با استفاده از ENTRYPOINT این کار رو تو بش انجام میدم. جلوش داخل یک آرایه دستور رو میدم. هر جا قرار باشه فاصله بذارم یا یه آپشن جدید از دستور رو بنویسم یه عنصر جدید به آرایه اضافه می‌کنم. ترتیب هم طبییعتا مهمه. حالا داکرفایل آماده است. بریم که بیلد و اجراش کنیم.بیلد ایمیج و اجرای کانتینربا دستور docker build داخل پوشه‌ای که داکرفایل هست بیلد رو شروع می‌کنم: با t- نام و تگ ایمیج رو میدم و بعد نقطه گذاشتم که یعنی پوشه اصلی همینجاست. دقت کنید فرایند بیلد مرحله به مرحله است و هر مرحله روی بعدی میاد. این نکته‌ی مهمی هست که ایشالا بعدا بهش می‌پردازیم. خب الان از روی ایمیج کانتینر می‌سازم (پورت رو یادتون نره): و با کمک curl بهش درخواست REST میدم (درخواست‌های نمونه رو در فایل curl.sh می‌تونید ببینید): هورااا...می‌بینم که کارم درست شده و کانتینر کار میکنه. با این درخواست یک کاربر جدید ثبت‌نام کردم و توکن گرفتم. دقت کنید مقدار متغیر PORT رو همون مقداری بذارید که موقع اجرای کانتینر پابلیش کردید.  جمع بندیدر این قسمت یک برنامه پایتون که با فریم‌ورک جنگو نوشته شده رو داکرایز کردیم، از روش ایمیج ساختیم و اجراش کردیم. در نهایت برای اطمینان از عملکردش یک درخواست دادیم و جواب گرفتیم. امیدوارم این نوشته براتون مفید بوده باشه. اگر نظر یا سوالی دارید این پایین بفرمایید.قسمت قبلیقسمت بعدی</description>
                <category>PaaSino</category>
                <author>Ali Akbar Hemmati</author>
                <pubDate>Sun, 31 Jan 2021 10:59:59 +0330</pubDate>
            </item>
                    <item>
                <title>داکر برای برنامه‌نویس‌ها: قسمت هشتم - بیلد کردن ایمیج با داکرفایل</title>
                <link>https://virgool.io/paasino/dockerfile-ivcreo31l1qd</link>
                <description>مقدمهبعد از این که با ایمیج‌های بقیه کار کردیم حالا می‌خوایم خودمون ایمیج بسازیم. وقتی برنامه‌ای رو می‌نویسیم اون رو تبدیل به یک ایمیج می‌کنیم تا ازش به شکل یه کانتینر استفاده کنیم. امروزم قصد داریم این رو یاد بگیریم. این مطلب برای یک برنامه‌نویس که می‌خواد برنامه‌اش رو داکرایز کنه خیلی مفید میتونه باشه. برای سیستم ادمین‌ها هم خوندنش ضرر نداره. برای این مطلب آشنایی با داکر و کانتینرها لازمه. هم‌چنین دونستن دستورات بش کمک میکنه. برای مطالعه در مورد داکر می‌تونید به قسمت‌های قبلی مراجعه کنید. برای بش در لینوکس هم به این دنباله می‌تونید برید. معرفی داکرفایلبرای این که بتونیم از روی ایمیج‌های دیگه ایمیج بسازیم باید یک فایل با نام Dockerfile بنویسیم. هیچ پسوندی نداره. حرف اولش هم بزرگه. این فایل رو داخل پوشه اصلی برنامه می‌ذاریم. اینجا یک فایل ساده‌ی بش دارم و می‌خوام به شکل کانتینری اجراش کنم. از عمد یک مثال ساده در نظر گرفتم تا فقط روی مفاهیم تمرکز کنیم. ان شاء الله قسمت‌های بعد فریم‌ورک‌ها و زبان‌های مختلف رو خواهیم دید. محتوای فایل بش این شکلیه:کار خاصی نمی‌کنه؛ هر ۲ ثانیه یه بار جمله‌ای رو چاپ می‌کنه. حالا تو همین پوشه داکرفایل رو درست می‌کنم. ویرایشگر من vscode هست و با ایجاد کردن داکر فایل لوگوی داکر رو نشون میده:احتمالا در ویرایشگرهای دیگه هم همین طوره.نوشتن داکرفایلخب دیگه وقتشه شروع به نوشتن کنیم. داخل داکرفایل یک سری کلمات خاص وجود دارن که با حروف بزرگ نوشته میشن. به تدریج باهاشون آشنا میشیم. اولین کاری که می‌کنیم اینه که بگیم از روی کدوم ایمیج می‌خوایم ایمیج جدید رو بسازیم و بهش ایمیج والد یا اصلی یا parent image میگیم. من از ubuntu استفاده کردم. برای این کار از FROM استفاده می‌کنم و جلوش اسم ایمیج رو می‌نویسم: FROM ubuntuاول داکرفایل همیشه FROM رو داریم تا مشخص بشه روی چه ایمیجی کار می‌کنیم. حالا فایل‌هایی که می‌خوایم رو به ایمیج اصلی منتقل می‌کنیم. اول مشخص می‌کنیم که تو کدوم پوشه از ایمیج هستیم.‌ این رو با WORKDIR نشون میدم: WORKDIR /rootبعدش فایل(های) مورد نظرم رو کپی می‌کنم: COPY ./script.sh ./دستور COPY دو تا آرگومان داره؛ اولیش فایل یا پوشه مبدا که در سیستم اصلی هست رو میگه و دومی پوشه مقصد که داخل ایمیج هست. تو آرگومان اول نقطه به معنای پوشه‌ای هست که داکرفایل توشه و تو آرگومان دوم نقطه پوشه‌ای هست که با WORKDIR تعیین گردیم.آخرین کاری که می‌کنم دادن دستوری برای اجرا هست. یعنی موقعی که یه کانتینر از روی این ایمیج اجرا شد چی کار کنه. در این مورد می‌خوام اسکریپت من اجرا بشه: ENTRYPOINT [ &amp;quot/bin/bash&amp;quot, &amp;quot./script.sh&amp;quot ]کلمه ENTRYPOINT رو نوشتم و بعدش دستوری که قراره اجرا شه. دقت کنید که دستور به شکل آرایه باید داده بشه و هر قسمت از دستور یک عنصری از آرایه هست. تمام اعضای لیست هم باید به شکل string باشن.بیلد کردن ایمیج و اجرای کانتینرحالا که یه داکرفایل ابتدایی نوشتم می‌خوام از روش ایمیج بسازم. به این کار build میگیم. با استفاده از دستور docker build در پوشه‌ای که داکرفایل دارم این کارو انجام میدم:جلوش t- گذاشتم تا اسم ایمیج جدید رو بدم. در ضمن بعد از : تگ مناسب هم گذاشتم. یک برنامه که می‌نویسیم اسم ایمیج یکسانی داره ولی با دادن نسخه‌های مختلف تگش تغییر می‌کنه. در آخر نقطه گذاشتم به این معنا که پوشه اصلی همینجاست.الان این ایمیج رو در لیست ایمیج‌ها می‌بینم:و بعد از ساخت کانتینر از روش: همون چیزی که می‌خواستم شد و خوشحالم :)جمع بندیدر این مطلب با داکرفایل و نحوه نوشتنش آشنا شدیم. بعدش ایمیج‌مون رو با docker build ساختیم و یه کانتینر درست کردیم. امیدوارم براتون مفید بوده باشه. اگر نظر یا سوالی دارید این پایین بفرمایید.قسمت قبلی</description>
                <category>PaaSino</category>
                <author>Ali Akbar Hemmati</author>
                <pubDate>Mon, 18 Jan 2021 21:51:29 +0330</pubDate>
            </item>
                    <item>
                <title>داکر برای برنامه‌نویس‌ها: قسمت هفتم - دستورات متفرقه ولی مفید!</title>
                <link>https://virgool.io/paasino/docker-miscellaneous-hoblkeojgupj</link>
                <description>مقدمه در این قسمت چند تا دستور رو می‌بینیم که تو هیچ دسته‌ی خاصی نذاشتمشون. این دستورها به بررسی کانتینر، رجیستری داکر و انتقال تصویر به یک ماشین دیگه مربوط میشن. آخرشم یه کار باحال انجام میدیم!دونستن این موارد میتونه به سیس‌ ادمین‌ها و برنامه‌نویس‌هایی که با داکر کار دارن کمک کنه.پیش نیاز این بحث نصب داشتن داکر روی سیستم هست و باید کار با کانتینرها در داکر رو تجربه کرده باشید. برای این موارد در صورت نیاز می‌تونید قسمت‌های قبلی رو ببینید.دیدن لاگ کانتینرمعمولا برنامه‌هایی که می‌نویسیم لاگ‌هایی تولید می‌کنن. اگر این لاگ‌ها در stdout یا stderr نوشته بشن میشه با دستور docker logs اون‌ها رو دید: بعد از logs آیدی کانتینر رو نوشتم. اگر لاگ برنامه‌ی داخل کانتینر تو یه فایل نوشته بشه باید خود فایل رو خوند. مثلا با docker exec که تو این قسمت دیدیم بریم تو کانتینر و فایل رو ببینم یا با docker cp که در قسمت قبل داشتیم اون رو به سیستم خودمون کپی کنیم.استفاده از inspectبا دستور docker inspect می‌تونیم هر اطلاعاتی که مربوط به کانتینر هست رو ببینیم: بعد از inspect آیدی کانتینر رو نوشتم. فرمت خروجی به شکل json هست. خیلی هم طولانیه. جابجایی تصویر داکرگاهی پیش میاد که یک تصویر رو توی یه سیستم پول کردید و می‌خواید تو یه سیستم دیگه هم اون رو داشته باشید. اگه نخواید دوباره حجم اینترنت مصرف کنید یا اصلا سیستم دوم به اینترنت دسترسی نداشته باشه می‌تونید از docker save استفاده کنید:جلوی save اسم تصویر میاد. به طور پیشفرض خروجی در stdout نوشته میشه. اما اینجا من redirect کردم به یه فایل. extension اون فایل رو tar. گذاشتم چون داکر خروجی رو به شکل آرشیو شده میده (البته می‌دونیم تو لینوکس extension مهم نیست و این کار برای خودمونه). با آپشن o- هم میشد این کارو کرد. کافیه اسم فایل رو جلوش بدید. خب حالا این فایل رو میشه به هر شکلی که دلمون میخواد بفرستیم به یه سیستم دیگه. مثلا با scp. من ادامه مراحل رو تو همون سیستم قبلی ادامه میدم ولی از اینجا به بعد باید تو سیستم مقصد اجرا شه. قبل از این کار تصویر رو حذف می‌کنم تا شبیه سیستم مقصد بشه:دیگه اون تصویر رو ندارم. اما با docker load اون فایل رو لود می‌کنم:با i- بهش گفتم از کدوم فایل بخونه. حالا دوباره تصویر رو دارم و این کار رو با load انجام دادم.لاگین کردن در داکر رجیستریاخیرا داکر یه محدودیتی در پول کردن تصاویر از رجیستری خودش گذاشته. برای من پیش اومده که اشتباها بهم میگه محدودیت رو رد کردم. احتمالا یکی دیگه با ip من این کارو کرده یا به هر دلیل داکر اشتباه کرده. برای نخوردن به این مشکل میشه یه حساب ساخت و در اون لاگین کرد تا ما رو با اسم بشناسه. وقتی لاگین کنیم دو برابر حالت قبل می‌تونیم پول کنیم. یه موقعی هم هست که رجیستری خصوصی داریم و برای استفاده ازش لازمه لاگین کنیم. برای لاگین از دستور (اگه گفتید؟!) login استفاده میشه (درست گفتید!): اگه به جایی غیر از داکرهاب لاگین می‌کنید آدرسش رو بعد از login بنویسید. از شما نام کاربری و رمز عبورتون رو می‌پرسه و اگر درست باشه می‌نویسه Login Succeeded. چون من قبلا این کارو کرده بودم دیگه از من چیزی نخواست. از این به بعد شما کاربر شناخته شده‌ای برای این رجیستری هستید. اگر در داکرهاب حسابی ندارید برای ساخت حساب به سایت داکر برید.یه کار باحال خب حالا که تا اینجا اومدین بذارین یه چیز باحال ببینیم. برای دیدن تمام کانتینرها از docker ps -a استفاده می‌کردیم. با q- میشه کاری کرد که فقط آیدی کانتینرها رو نشون بده:این به چه دردی می‌خوره؟ به این درد که همه کانتینرها رو با هم حذف کنیم:از back tick استفاده کردم و خروجی دستور قبلی رو گذاشتم جلوی docker rm. این طوری تک تک اون‌ها رو پاک می‌کنه. وقتی تعداد زیادی کانتینر دارید که در حال اجرا نیستن با این کار همه‌شون پاک میشن.به روز رسانی: یک نکته خوبی رو فرهاد در نظرات گفت و اون هم دستور prune هست. با prune میشه هر کانتینری که stop شده رو حذف کرد:اول از شما می‌پرسه مطمئن هستید؟ بعد شما y رو وارد می‌کنید و اونم حذف می‌کنه. با تشکر از فرهاد. جمع بندیدر این مطلب چند مبحث رو بررسی کردیم. اول لاگ کانتینر و اطلاعات اون رو دیدیم. بعد تصویر رو بین سیستم‌ها جابجا کردیم. بعد لاگین کردن رو تجربه کردیم. آخر سر هم همه کانتینرها رو با یه دستور پاک کردیم. امیدوارم براتون مفید بوده باشه. اگر نظر یا سوالی دارید این پایین بفرمایید.قسمت قبلیقسمت بعدی</description>
                <category>PaaSino</category>
                <author>Ali Akbar Hemmati</author>
                <pubDate>Sun, 27 Dec 2020 08:15:31 +0330</pubDate>
            </item>
                    <item>
                <title>داکر برای برنامه‌نویس‌ها: قسمت ششم - اشتراک و جابجایی فایل در کانتینر</title>
                <link>https://virgool.io/paasino/docker-mount-copy-ijmhcw9vtgg7</link>
                <description>مقدمهدر این قسمت می‌خوایم فایل‌ها رو به کانتینر انتقال بدیم یا از اون فایلی رو به فایل سیستم خودمون بیاریم. هم‌چنین فایل‌ها رو بین کانتینرها به اشتراک میذاریم. برنامه‌نویس‌ها و سیس ادمین‌هایی که با محیط‌های کانتینری کار دارن میتونن از این مطلب استفاده کنن. فرض بر این هست که شما نرم‌افزار داکر رو در سیستم خودتون نصب کردید و اجرای کانتینرها در داکر رو بلد هستید. هم چنین این که چطوری داخل یه کانتینر به شل دسترسی پیدا کنیم هم باید بدونید. می‌تونید قسمت‌های قبلی این دنباله رو ببینید. علاوه بر این باید با مفاهیم فایل سیستم لینوکس آشنایی داشته باشید.اشتراک فایل با کانتینروقتی بخوایم یک پوشه رو از سیستم خودمون داخل کانتینر داشته باشیم اون رو داخلش mount می‌کنیم.  بعد از این کار اون پوشه داخل کانتینر دقیقا همون پوشه سیستم ماست. با آپشن v- این کارو انجام میدیم: بعد از گذاشتن v-، اول مسیر پوشه در سیستم خودمون بعد دو نقطه و در آخر مسیر پوشه در کانتینر رو میدیم. من در این مثال پوشه‌ای که توش هستم رو به جایی که nginx ازش فایل‌ index.html رو می‌خونه mount کردم. در این پوشه این فایل موجود نیست. بیاید به این کانتینر درخواست بدیم: یه پیغام خطا میده و غیر اون چیزی بهمون نمیده. چون فایلی که می‌خواد نیستش. حالا index.html رو می‌سازم و داخلش یه چیزی می‌نویسم:این بار درخواستم رو جواب داد. چون فایلی که می‌خواست رو پیدا کرد. من می‌تونم همین پوشه رو با کانتینرهای دیگه هم به اشتراک بذارم (mount کنم). این بار از اوبونتو استفاده می‌کنم:این دفعه تو پوشه home برای کاربر root گذاشتم. دیدیم که فایلی که داشتیم دوباره اینجاست. هر تغییری توش بدم هم تو سیستم خودم و هم تو nginx اعمال میشه:کپی کردن فایل از/به کانتینرمواقعی پیش میاد که نمی‌خوایم فایلی رو با سیستم خودمون به اشتراک بذاریم و فقط می‌خوایم یه چیزی رو به کانتینر بفرستیم یا ازش بگیریم. در این مواقع از cp استفاده میشه: اگر بخوایم از کانتینر به سیستم انتقال بدیم اول آیدی کانتینر، بعد دو نقطه و مسیر مورد نظر داخل کانتینر رو می‌نویسیم. در آخر یه فاصله میذاریم و مسیر در سیستم خودمون رو می‌نویسیم. در صورتی که قصدمون انتقال به کانتینر باشه این رو برعکسش می‌کنیم؛ یعنی اول مسیر تو سیستم، یه فاصله، بعد آیدی کانتینر، دو نقطه و مسیر داخل کانتینر. تو تصویر بالا من new.html رو به root/ در کانتینر انتقال دادم. جمع بندیدر این قسمت دیدیم چطوری میشه فایل‌ها رو به داخل کانتینر فرستاد یا پوشه‌ها رو در کانتینر mount  کرد. امیدوارم براتون مفید بوده باشه. اگر سوال یا نظری دارید این پایین بفرمایید.قسمت قبلیقسمت بعدی</description>
                <category>PaaSino</category>
                <author>Ali Akbar Hemmati</author>
                <pubDate>Sat, 26 Dec 2020 08:54:03 +0330</pubDate>
            </item>
                    <item>
                <title>داکر برای برنامه‌نویس‌ها: قسمت پنجم - ارتباط با کانتینر</title>
                <link>https://virgool.io/paasino/docker-exec-publish-hh1xiqfcs03q</link>
                <description>مقدمهوقتی کانتینری رو اجرا می‌کنیم معمولا دلمون میخواد باهاش ارتباط برقرار کنیم. این ارتباط می‌تونه از طریق شبکه باشه یا این که داخل کانتینر یک شل بگیریم. در این قسمت این موارد رو بررسی می‌کنیم. مطالب این دفعه به درد برنامه‌نویس‌هایی که می‌خوان برنامه‌های داکرایز شده بنویسن می‌خوره. کسانی هم که قصد دارن ادمین سیستم بشن این مطلب رو مفید خواهند یافت.دیدن پورت کانتینر در پورت سیستمبیاید یک تصویر موجود در داکرهاب به نام nginx رو اجرا کنیم:این همون وب سرور معروف هست که در پورت ۸۰ به درخواست http ما گوش میده. اما در حال حاضر فقط لاگ‌هایی که میده رو می‌بینیم. برای ارتباط با این کانتینر ما نمی‌تونیم به ip اون درخواست بدیم چون دسترسی بهش نداریم. ما باید یک پورت اون رو expose کنیم. وقتی می‌خوایم یک کانتینر رو اجرا کنیم با آپشن p- بهش میگیم یک پورت از کانتینر رو در یه پورت سیستم publish کنه. جلوی این آپشن اول پورت سیستم و بعد پورت کانتینر رو میدیم:اینجا من پورت ۸۰ کانتینر رو می‌خواستم چون nginx روی اون جواب میده. پورت سیستم رو هر پورتی که آزاد باشه می‌تونم بذارم که من ۸۰۰۰ گذاشتم. حالا میشه تو مرورگر یا با curl به پورت ۸۰۰۰ سیستم و در نتیجه پورت ۸۰ کانتینر برسم:به این شکل ارتباط دنیای بیرون رو با کانتینر برقرار می‌کنم. جواب دریافت شده همون صفحه پیشفرض nginx هست.ارتباط از طریق شلممکنه یه موقعی بخوام برم داخل کانتینر و برای بررسی اون چند تا دستور اجرا کنم. در این موقع از exec استفاده می‌کنم. با exec میشه هر دستوری تو کانتینر اجرا کرد:تو این مثال گفتم در بش hello رو بنویسه.حالا با exec می‌خوایم بریم داخل کانتینر. بعد از اجرای کانتینر، نام یا id اون رو استفاده می‌کنم تا داخلش شل باز کنم: دو تا آپشن استفاده کردم: it- که به ما اجازه میده داخل کانتینر به شکل interactive کار کنیم. آخر هم مسیر بش رو دادم تا یه دونه شل اجرا بشه داخل کانتینر. خب الان داخلش هستم. میخوام فایل پیش فرض nginx رو تغییر بدم: حالا دوباره میرم خارج کانتینر curl می‌کنم: هورااا! تونستم از طریق دسترسی شل محتوای کانتینر رو تغییر بدم ^_^در کنار exec یه دستور دیگه هم هست که ممکنه با این اشتباه گرفته بشه. اونم attach هست. به exec هر دستوری بدید یه پروسه جدید شروع می‌کنه کنار پروسه اصلی. اما با attach ما به خود پروسه اصلی وصل میشیم. بیاید ببینیم. اول nginx رو با آپشن d- اجرا می‌کنم: این آپشن باعث میشه دیگه خروجی‌های کانتینر رو نبینم و در پس زمینه اجرا شه. در عوض فقط id کانتینر رو می‌نویسه. حالا با attach بهش وصل میشم:الان دوباره خروجی‌های nginx دیده میشه. البته خروجی‌های اولش رو دیگه نشون نمیده و فقط از اون لحظه که دستور رو اجرا کردم به بعد رو میاره.‌جمع بندی در این جلسه با روش‌هایی آشنا شدیم که میشه باهاشون با کانتینر ارتباط برقرار کرد. یک روش از طریق در معرض قرار دادن پورت هست و دیگری ssh کردن به اون. موقعی که یه برنامه نوشتیم و می‌خوایم داخل کانتینر اجراش کنیم این دو کار خیلی کمکمون می‌کنه.این قسمت هم تموم شد. امیدوارم استفاده کرده باشید. اگه صحبت یا نظری دارید این پایین بفرمایید.قسمت قبلیقسمت بعدی</description>
                <category>PaaSino</category>
                <author>Ali Akbar Hemmati</author>
                <pubDate>Fri, 18 Dec 2020 22:53:58 +0330</pubDate>
            </item>
                    <item>
                <title>داکر برای برنامه‌نویس‌ها: قسمت چهارم - حذف تصویر و کانتینر در داکر</title>
                <link>https://virgool.io/paasino/docker-delete-container-image-zhlocv90dvz7</link>
                <description>مقدمهکم کم داریم در زمینه داکر راه می‌افتیم. تو قسمت قبل چند تا دستور ابتدایی رو اجرا کردیم و با اونا با تصاویر و کانتینرها آشنا شدیم. در این قسمت به حذف تصویر و کانتینر و فرستادن سیگنال به کانتینر خواهیم پرداخت. این مطلب برای برنامه‌نویس‌هایی که می‌خوان برنامه‌هاشون در داکر اجرا بشه و هم‌چنین سیس ادمین‌ها مفید خواهد بود.برای درک مطالب و اجرای دستورات لازمه با داکر و دستورات اون برای اجرای کانتینر آشنایی داشته باشید و داکر روی سیستم شما نصب باشه. می‌تونید برای این منظور قسمت‌های قبل این دنباله رو ببینید. هم‌چنین با مفهوم سیگنال و فرستادن اون به پروسه‌ها در لینوکس آشنایی داشته باشید. حذف تصویرتو قسمت قبل pull کردن تصویر رو یاد گرفتیم. اگه بخوایم تصویری رو حذف کنیم از docker rmi استفاده میشه: کلمه rmi رو با rm و i یاد داشته باشید. rm برای remove و i برای image. با docker images لیست تصاویر توی سیستم رو می‌بینم. همون طور که می‌بینید بعد از این دستور دیگه اون تصویر روی سیستم من نیست و اگر بخوامش باید دوباره دانلود کنم. اگه یه کانتینر در حال اجرا از اون تصویر داشته باشم لازمه اول اون رو از بین ببرم تا بتونم تصویرش رو پاک کنم:این‌جا بهم گفته که یه کانتینر از این تصویر وجود داره. باید کانتینر اول حذف شه. برای این کار بخش بعدی رو بخونید.حذف کانتینر وقتی کانتینری رو اجرا می‌کنم ممکنه بخوام حذفش کنم. قبلا هم دیدیم که کانتینرها پروسه‌‌های در حال اجرا هستند. پس به اونا میشه سیگنال فرستاد. با دستور docker stop به پروسه‌ی اصلی کانتینر سیگنال SIGTERM میفرسته تا خودش رو جمع و جور کنه و از بین بره. اگرم زیاد طول بکشه بعد چند ثانیه SIGKILL میفرسته و در جا از بین می‌بردش: تو اینجا یه کانتینر در حال اجرا رو دیدید که stop شد و از کار افتاد. دیگه توی docker ps نمی‌بینمش چون در حال اجرا نیست. ولی اگر docker ps -a بزنم هستش. برای این که از اونجا هم پاک شه از docker rm استفاده میشه: دیگه توی docker ps -a نیست. برای این دستورات لازم نیست از id کانتینر به شکل کامل استفاده کنیم. تا هر جا که بشه تشخیص داد (قابل تمایز از بقیه باشه) بنویسیم خودش میفهمه: تو این دستور b هم می‌نوشتم می‌فهمید.اگر خواستیم با اسم کانتینر رو حذف کنیم (یا هر دستور دیگه‌ای روش اجرا کنیم) می‌تونیم از auto completion با زدن TAB استفاده کنیم. در کنار حذف کارهای دیگه‌ای هم میشه با کانتینر انجام داد. می‌تونیم با دستور docker pause سیگنال SIGSTOP رو به پروسه اصلی بفرستیم: در بخش status وضعیت این کانتینر رو می‌بینید که متوقف شده. میشه کانتینرها رو از این دو وضعیت در‌آورد. می‌تونم با docker unpause از وضعیت paused به حالت running در بیارمش. با docker start هم میشه یه کانتینر که stop شده رو اجرا کرد. برای مثال start رو ببینین:اینجا اول کانتینر در حال اجرا نبود ولی با start اجرا شد. در کل اگر خواستین سیگنالی به کانتینر بفرستین از docker kill استفاده کنید که مثل kill در لینوکس عمل می‌کنه. جمع بندیدر این قسمت دیدیم چطور میشه یک تصویر یا کانتینر رو از بین برد. هم‌چنین یاد گرفتیم میشه به پروسه‌های کانتینر سیگنال‌های مختلف رو فرستاد. امیدوارم استفاده کرده باشید. اگر سوال یا نظری دارید این پایین بفرمایید. قسمت قبلیقسمت بعدی</description>
                <category>PaaSino</category>
                <author>Ali Akbar Hemmati</author>
                <pubDate>Thu, 10 Dec 2020 18:13:36 +0330</pubDate>
            </item>
                    <item>
                <title>داکر برای برنامه‌نویس‌ها: قسمت سوم - دستورات ابتدایی در داکر</title>
                <link>https://virgool.io/paasino/docker-commands-pull-image-run-containers-xjahqv1ecsxi</link>
                <description>مقدمه رسیدیم به قسمت عملی ماجرا. در قسمت‌های قبل مفهوم کانتینر رو دونستیم و داکر رو نصب کردیم. حالا می‌خوایم در چند جلسه با کانتینرها و تصاویر کار کنیم تا تجربه عملی کسب کنیم. آشنایی و کار عملی با این مفاهیم هم به درد برنامه‌نویس‌ها می‌خوره و هم کسانی که می‌خوان سیس ادمین بشن. برای این قسمت باید داکر رو نصب کرده باشین و با مفهوم کانتینر، ایمیج و رجیستری داکر آشنایی داشته باشین.شناخت بیشتر تصویر (image)برای این که یه کانتینر بسازیم باید یه تصویر یا به انگلیسی image داشته باشیم. تصویر تمام اطلاعاتی که یه کانتینر لازم داره رو داخل خودش داره. مثلا فرض کنید شما یه برنامه به زبون پایتون نوشتید و می‌خواید به شکل کانتینر راه‌اندازی کنیدش. باید تمام فایل‌ها و تنظیمات لازم رو داخل یه تصویر قرار بدید و از روی تصویر کانتینر بسازید. خود ما می‌تونیم از اول یه تصویر رو بسازیم. اما خیلی بعیده که لازم باشه تصویری رو از اول خودمون بسازیم. ما از روی تصاویری که موجود هست تصویر جدید می‌سازیم یا همون‌ها رو استفاده می‌کنیم.تعداد زیادی تصویر آماده توسط شرکت‌های معتبر ساخته شده و در رجیستری داکر موجود هست.‌ ما می‌تونیم اون‌ها رو دانلود کنیم و بعد اجراشون کنیم یا از روشون تصویر جدید بسازیم. بیاید برای مثال یه تصویر خیلی ساده رو دانلود کنیم: با این دستور pull موتور داکر میره تو رجیستری و دنبال تصویری به نام hello-world می‌گرده و دانلودش می‌کنه. بعد از اتمام موفقیت‌آمیز این دستور، تصویر در سیستم ما وجود داره. با دستور docker images می‌تونم تصویرهایی که در سیستم هستن رو ببینم: در ستون اول اسم تصویر میاد. بعد تگ اون میاد. تگ خیلی مهمه برای تصویر. چون نسخه اون رو نشون میده. اگه موقع pull کردن هیچ تگی رو ندیم میره آخرین نسخه یا latest رو دانلود می‌کنه. برای این که نسخه بدیم به تصویر با دو نقطه معلومش می‌کنیم. مثلا ubuntu:20.04 نسخه 20.04 تصویر اوبونتو رو نشون میده. در ستون بعد یک id یکتا هست برای تصویر که می‌تونیم با اون هم صداش کنیم. بعد زمان ساخته شدن تصویر و در نهایت اندازه اون رو می‌بینیم. حالا می‌تونیم از روش کانتینر بسازیم: با دستور run از روی تصویری که جلوش نوشتیم کانتینر ساخته میشه. می‌تونستم همون اول run رو بنویسم. این دستور اگه ببینه تصویر وجود نداره، خودش اون رو pull می‌کنه. خروجیش رو ببینید. کانتینر اجرا شد و یک پیام نوشت و از بین رفت. وقتی پروسه‌ای که تو کانتینر در حال اجراست کارش تموم شه، کانتینر هم کارش تمومه.خب یه تصویر ساده رو اجرا کردیم و خروجیش رو دیدیم. تصاویر به درد بخور‌تری تو داکر رجیستری هست. مثلا تصویر ubuntu که وقتی اجرا شه گویا کانتینر ما داخل یه ماشین اوبونتو هست. تا دلتون بخواد تصاویر خوب و کاربردی در رجیستری داکر موجوده و تقریبا برای هر چیزی تصویر داریم. یه دسته از این تصاویر برای اجرای برنامه‌هایی که می‌نویسیم خیلی کاربردی هستن. مثلا تصویر python که توش پایتون هست و برای اجرای برنامه‌ی پایتون از اون استفاده میشه. از این دست تصاویر برای فریم‌ورک‌ها و زبان‌های مختلف ساخته شده و روی رجیستری داکر قرار دادن. با یه جستجو میشه برای هر برنامه‌ای تصویرش رو پیدا کرد.کار خوب دیگه‌ای که با تصویرها میکنن اینه که گاهی برای راحتی استفاده از یه ابزاری اون رو داخل تصویری میذارن و توی داکر رجیستری قرارش میدن. مثلا pyspark که برای big data کاربرد داره. چون نصب و تنظیم کردنش سخته گذاشتن تو یه تصویر که هر کی خواست دانلود کنه و برای کارهای علمی ازش بهره ببره. یا مثلا یه جا دیدم یه تصویر بود که مجموعه برنامه‌های مربوط به بیو الکتریک توش بود.پس در کل، با داشتن تصویر ما این امکان رو داریم یه برنامه یا مجموعه ابزار رو به شکل یکسان و سبک روی ماشین‌های مختلف داشته باشیم. فقط لازمه که داکر نصب شده باشه.کار با کانتینرها تو بخش قبل دیدیم که با دستور run میشه یه تصویر رو (در صورتی که روی سیستم‌مون نیست) pull کنیم و بعد کانتینری رو از روش بسازیم. حالا بیاید تصویر alpine رو اجرا کنیم:این تصویر یه لینوکس خیلی سبکه و کمک می‌کنه تصویری که از روش می‌سازیم هم خیلی سبک و کم حجم باشه. با دستور docker ps کانتینرهای در حال اجرا رو می‌بینیم: هیچ کانتینری در حال اجرا نیست. اون کانتینری که ساختیم خیلی سریع از بین رفت چون کاری ندادیم بهش. با اضافه کردن a- می‌تونیم تمام کانتینرها رو ببینیم؛ حتی اگه در حال اجرا نباشن: برای این که دستوری رو توی کانتینر اجرا کنیم این شکلی می‌نویسیم:جلوی اسم تصویر اون دستور رو نوشتم و بهش گفتم ۱۰۰ ثانیه فقط منتظر بمونه. حالا میرم تو یه شل دیگه تا docker ps رو اجرا کنم: این‌جا می‌بینم که کانتینر رو نشون میده. ستون اول یه id یکتا برای کانتینر هست. بعد تصویرش و بعد دستوری که زدیم. ستون بعدی زمانی که کانتینر ساخته شده رو میگه. ستون پنجم حالت کانتینر رو بیان می‌کنه که اینجا در حال اجراست. دقت کنید فاصله بین ساخت و در up شدن این کانتینر ۲ ثانیه بوده. این رو با یه ماشین مجازی مقایسه کنید! ستون ششم پورتی که از کانتینر expose کردیم رو میگه. فعلا این بحث رو انجام ندادیم ولی خیلی زود ایشالا بهش می‌رسیم. آخرین ستون هم یه اسم هست که خودش برای کانتیر انتخاب کرده. ما خودمون با name-- می‌تونیم این کار رو بکنیم.جمع بندیتو این جلسه با دستورهای ابتدایی داکر آشنا شدیم. دیدیم چطور تصویری pull میشه و می‌تونیم تصاویر موجود در سیستم رو ببینیم. هم‌چنین یاد گرفتیم چطوری از روی تصویر کانتینر بسازیم و کانتینرهای در حال اجرا تو سیستم رو ببینیم.قسمت قبلیقسمت بعدی</description>
                <category>PaaSino</category>
                <author>Ali Akbar Hemmati</author>
                <pubDate>Thu, 03 Dec 2020 18:21:02 +0330</pubDate>
            </item>
                    <item>
                <title>داکر برای برنامه‌نویس‌ها: قسمت دوم - نصب داکر</title>
                <link>https://virgool.io/paasino/docker-install-hbf9lglvpbey</link>
                <description>مقدمهامروز می‌خوایم راجع به نصب داکر صحبت کنیم. این مطلب برای هر کسی که می‌خواد با داکر کار کنه مفید خواهد بود. فرقی نداره کار dev می‌کنید یا کارای ops.  برای این نوشته لازمه که با تنظیمات شبکه‌ای در لینوکس آشنایی داشته باشید و با خط فرمان لینوکس کار کرده باشید.ممکنه برای نصب داکر به مشکل تحریم بخوریم. ممکن هم هست نخوریم. بگیر نگیر داره. برای نصب داکر از این لینک پیروی کنید.اینجا میخوام اجرای این روند نصب و رفع مشکل تحریم رو نشون بدم. اگر نکاتی هم باشه در حین کار میگم. فعلا راجع به سرور اوبونتو 18.04 صحبت می‌کنیم و ایشالا بعدا برای centos هم تکمیل میشه.مشکل تحریمبرای این که بتونیم داکر رو نصب کنیم ممکنه لازم نباشه این مرحله رو بریم. می‌تونید مراحل نصب رو طی کنید و ببینید مشکل تحریم هست یا نه. قبلا هم گفتم. بگیر نگیر داره. راهکاری که من دارم استفاده از شکن هست. این سایت دو تا ip به عنوان dns server ارائه داده که ما باید اون رو تنظیم کنیم. راهی که خیلیا استفاده میکنن اینه که اون ip ها رو داخل etc/resolv.conf/ بنویسن. این میتونه کار کنه ولی ممکنه لازم باشه مدام این کارو انجام بدین؛ چون این فایل تغییر می‌کنه. راه مطمئن چیه؟ این که بیایم تو تنظیمات interface شبکه‌مون این آدرس‌ها رو بذاریم. در اوبونتو 18 از netplan برای تنظیم interface شبکه استفاده میشه.با دسترسی روت داخل فایلی که توی etc/netplan/ هست این بخش رو می‌نویسم:    ....
     ethernets:
       ....
         enp01:
         ....
            nameservers:
                addresses: 
                    - 178.22.122.100
                    - 185.51.200.2دقت کنید که enp01 اسم اینترفیس شبکه هست و باید با دستور ifconfig یا هر دستوری که خودتون می‌دونید این اسم رو پیدا کنید و اینجا بذارید.حالا کافیه برای اینکه این تغییرات اعمال بشن دستور زیر رو بزنیم: $ sudo netplan applyبه این شکل شما می‌تونید مشکل تحریم رو در صورت وجود رفع کنید.نصب داکر چند تا راه در سایت داکر موجود هست ولی ما رایج‌ترین و راحت‌ترینش رو انجام میدیم.اول گفته که هر کدوم از نسخه‌های قبلی رو پاک کنیم: اگر هیچ کدومشون وجود نداشتن هم مشکلی نداره.بعد apt رو به‌ روز‌ رسانی کرده و تعدادی بسته نصب می‌کنیم:ممکنه چند دقیقه طول بکشه. بعد هم مراحل اضافه کردن مخزن داکر به apt رو طی می‌کنیم: با اضافه کردن مخزن جدید لازمه دوباره apt رو به روز رسانی کنیم و داکر رو نصب کنیم: این یکی ممکنه خیلی طول بکشه. درصد پیشرفت رو می‌نویسه. اگر نسخه خاصی از اون رو لازم دارید اول با دستور زیر ببینید چه نسخه‌هایی موجود هست:  یه لیست بلند بالا میاد براتون. بعد به این شکل نسخه‌ی دلخواه رو نصب کنید: ایشالا برای سیس‌ادمین‌هایی که لازم دارن روی تعداد زیادی ماشین داکر رو نصب کنن در مورد نصب اون با ansible هم یه مطلب می‌نویسم ولی در این دوره که برای برنامه‌نویس‌ها هست دونستن اون لازم نیست. حالا دستور زیر رو اجرا کنیم تا مطمئن شیم همه چی درسته:برای این که لازم نباشه مدام sudo بزنیم برای دستور docker می‌تونید این کار رو بکنید:به جای اوبونتو user خودتون رو بنویسید. با این کار user شما به گروه docker اضافه میشه و میتونه دستور رو خودش اجرا کنه و لازم نیست sudo کنه. ممکنه لازم باشه یه بار شل رو ببندید و باز کنید تا تغییرات تاثیر بذارن. جمع بندی در این قسمت دیدیم چطور میشه داکر رو نصب کرد تا در قسمت‌های بعدی از اون استفاده کنیم. هم‌چنین اگر به مشکل تحریم خوردید میتونید با استفاده از شکن حلش کنید. دقت کنید که برای مصرف تجاری شکن پولیه. این مطلب به اتمام رسید. امیدوارم استفاده کرده باشید. اگر نظر یا سوالی دارید این پایین بفرمایید. قسمت قبلیقسمت بعدی</description>
                <category>PaaSino</category>
                <author>Ali Akbar Hemmati</author>
                <pubDate>Thu, 26 Nov 2020 23:38:07 +0330</pubDate>
            </item>
                    <item>
                <title>داکر برای برنامه‌نویس‌ها: قسمت اول - آشنایی با مفاهیم</title>
                <link>https://virgool.io/paasino/docker-introduction-ilv558mnuisa</link>
                <description>مقدمهاز امروز در انتشارات PaaSino قصد داریم راجع به داکر صحبت کنیم و اون هم داکر برای برنامه‌نویس‌ها. تو این قسمت معرفی داکر و کانتینرها رو داریم و در قسمت‌های بعد به چگونگی استفاده از اون برای یه برنامه‌نویس می‌پردازیم. قطعا در کنار برنامه‌نویس‌ها کسایی که میخوان سیس ادمین بشن یا موقعیت شغلی مرتبط با زیرساخت و پلتفرم داشته باشن هم براشون مفید خواهد بود.در این دوره خوبه که آشنایی با مفاهیم کلی سیستم عامل داشته باشید. بعد باید با فایل سیستم و خط فرمان لینوکس کار کرده باشید و تو این زمینه راحت باشید. در کنار این باید با شبکه و مفاهیم اون هم آشنا باشید. هم‌چنین در قسمت‌های مختلف در زبان‌های مختلف کار می‌کنیم که دونستن اونا هم خوبه. سابقه برنامه‌نویسی رو که مشخصه باید همه داشته باشن و با مفاهیم اون راحت باشن.مفهوم کانتینر و تفاوت آن با ماشین مجازیاول ببینیم کانتینر چی هست. در کرنل لینوکس یک مفهومی وجود داره به نام  namespace. در خیلی از زبان‌های برنامه‌نویسی این مفهوم وجود داره. مثلا تو cpp شما یه namespace درست می‌کنید و کلاس‌هایی که تو اون تعریف میشه با کلاس‌های namespace دیگه تداخل ندارن و از هم جدا حساب میشن. تو کرنل لینوکس هم چنین مفهومی رو داریم. برنامه‌هایی که اجرا میشن به طور پیشفرض همه‌شون توی یه namespace هستن و همه هم دیگه رو می‌بینن. اما ما دوست داریم برنامه‌هامون مستقل از هم اجرا شن. پس میایم اونا رو تو namespaceهای جدا می‌ذاریم و بینشون isolation ایجاد می‌کنیم یا بهتر بگم ایزوله می‌کنیم.این جدا کردن namespace میتونه در چند زمینه انجام بشه. مثلا از نظر فایل سیستم یا شبکه. همه‌اش رو اینجا نمی‌گم ولی هر کدوم نوع خاصی از ایزوله بودن میده بهمون. اگه فایل سیستم جدا باشه کلا چیزی که تو فایل سیستم ماست رو داخل namespace جدید نمی‌بینیم و یه فایل سیستم جدید ساخته میشه. یا اگه شبکه باشه دیگه دو تا برنامه که تو namespaceهای مختلف هستن نمی‌تونن از طریق localhost هم دیگه رو ببینن. هر کدوم ip جدا می‌گیرن و انگار تو ماشین‌های مختلف اجرا شدن.پس namespace دید برنامه‌ها و پروسه‌های سیستم رو محدود میکنه و باعث میشه فکر کنن تو یه سیستم جدید هستن. در کنار اون یک عنصر دیگه هم می‌خوایم و اون برای محدود کردن منابع مورد استفاده برنامه‌هاست. برای این از مفهوم cgroup در کرنل استفاده می‌کنیم. با cgroup به کرنل می‌گیم که هر برنامه چقدر cpu و ram میتونه استفاده کنه. انگار اون برنامه تو یه سیستم با اون قدر cpu و ram نشسته.با این دو تا مفهوم فضایی ایزوله شده در کرنل به وجود میاد که توش برنامه‌ها بدون اطلاع از برنامه‌های دیگه اجرا میشن و به این فضا میگیم کانتینر. همونطور که گفتم این برنامه که تو کانتینر هست گویا تو یه ماشین جدید داره اجرا میشه و از این نظر به ماشین مجازی تشبیه میشه. ولی دقت کنید که تفاوت زیادی با ماشین مجازی داره؛ چون واسه ماشین مجازی یه سیستم عامل جدید روی سیستم عامل میزبان درست میشه ولی اینجا از همون سیستم عامل میزبان استفاده میشه و پروسه‌ها با کمک کرنل از دید هم ایزوله میشن.برای بهتر دیدن این تفاوت به این تصویر توجه کنین: همون توضیحاتی که بالا دادم رو میشه توش دید. پس کانتینر، کانتینر هست و ماشین مجازی، ماشین مجازی و با هم فرق دارن.مزایای استفاده از کانتینردیدیم کانتینر چیه. الان میخوایم ببینیم چرا این قدر محبوبه و سر و صداش پیچیده. یک برنامه‌نویس رو فرض کنید که تو سیستم خودش برنامه‌ای رو توسعه میده و تنظیماتی رو هم انجام داده و برنامه‌اش تو سیستم خودش به خوبی کار می‌کنه. وقتی این برنامه به سیستم جدیدی میره که در محیط production قرار داره و میخواد به کاربران خدمات بده به مشکل می‌خوره. چرا؟ چون همه تنظیماتی که تو سیستم برنامه‌نویس بود رو نداره. ممکنه اصلا این کد به یه برنامه‌نویس دیگه داده بشه و اون هم بخواد روش کار کنه. اون هم باید تنظیماتی که روی سیستم برنامه‌نویس اول بود رو داشته باشه. حالا فرض کنید تعداد زیادی برنامه‌نویس داشته باشیم که بخوان روی اون کد کار کنن. واقعا سخته هماهنگ شدن همه‌ی این‌ها. در دنیای کانتینرها مفهومی وجود داره به نام image یا تصویر. وقتی کانتینری می‌خوایم بسازیم از روی تصویر داده شده مشخصاتش رو می‌فهمیم. مثل این که چه فایل‌ها، برنامه‌ها و تنظیماتی داره؛ مثلا تصویر اوبونتو که با اجرا کردنش یک اوبونتو به شکل کانتینری رو سیستم‌ خواهیم داشت. تصویر مثل کلاس می‌مونه تو برنامه نویسی شیء گرا و کانتینر مثل شیء. تصویر ساختاری که کانتینر باید داشته باشه رو مشخص می‌کنه. حالا برنامه‌نویس ما کدش رو توی تصویر مناسب میذاره و تنظیمات لازم اون رو انجام میده و در اختیار بقیه میذاره. هر کس بخواد رو این پروژه کار کنه یا باهاش به کاربران خدمات بده کافیه یه کانتینر از رو این تصویر بسازه. این شکلی تمام کارها داخل تصویر اعمال میشن و این تصویر روی همه سیستم‌ها کانتینر یکسانی می‌سازه.مزیت دیگه اینه که خیلی سبک هستن کانتینرها و روی یه سرور میشه صدها کانتینر داشت در حالی که فقط تعداد کمی ماشین مجازی میشه ساخت. با توجه به این ویژگی دیگه لازم نیست تو یه ماشین مجازی چندین برنامه اجرا کنیم. میشه هر برنامه رو تو کانتینر جدا اجرا کرد. به این شکل از هم دیگه ایزوله میشن و خیلی راحت‌تر میشه به هر کدوم رسیدگی کرد.اگر مزیت دیگه‌ای سراغ دارید در قسمت نظرات بگید تا استفاده کنیم.داکر و کانتینرهاکانتینرها رو میتونیم خودمون با دستوراتی تو لینوکس اجرا کنیم. ولی این کار سخته و وقتی تعداد بالا باشه ممکنه خیلی خطاها پیش بیاد. موتور داکر یا Docker engine برنامه‌ای هست که این کارها رو برای ما انجام میده. بهش یک تصویر رو میدیم و اون کانتیر رو برای ما ایجاد می‌کنه. علاوه بر این داکر یک رجیستری داره که توش تعداد زیادی تصویر هست و می‌تونیم از اون‌ها کانتینر بسازیم یا تصاویر جدیدی رو از روی اون‌ها درست کنیم. ایشالا بعدا این کارها رو یاد خواهیم گرفت.در این دوره تمام کارهامون رو با داکر انجام میدیم. ابزارهای دیگه‌ای هم هستن برای ایجاد کانتینر ولی فعلا داکر از بقیه پر استفاده تر هست.جمع بندیدر این قسمت دیدیم کانتینرها برنامه‌های ایزوله شده به وسیله namespace و cgroup هستن و از دید اون‌ها انگار در سیستم‌ عامل جدید اجرا میشن. هم‌چنین با مفهوم تصویر یا image آشنا شدیم و دونستیم که تصاویر الگوهایی هستن که از روش کانتینر ساخته میشه. بعضی از مزایای استفاده از کانتینرها رو هم بررسی کردیم و در آخر با داکر آشنا شدیم.این مطلب به اتمام رسید. امیدوارم مفید بوده باشه براتون. صحبت یا نظری دارید این پایین بفرمایید. به امید دیدن شما در قسمت‌های بعدی.قسمت بعدی</description>
                <category>PaaSino</category>
                <author>Ali Akbar Hemmati</author>
                <pubDate>Sat, 21 Nov 2020 20:44:41 +0330</pubDate>
            </item>
                    <item>
                <title>لینوکسی بشیم: هارد لینک و سافت لینک؛ چی و چرا؟</title>
                <link>https://virgool.io/paasino/softlink-hardlink-linux-eefonfieltxj</link>
                <description>مقدمهدر این قسمت می خوایم ببینیم هارد لینک و سافت لینک چی هستن. این دو تا روش‌هایی هستن که می‌تونیم باهاشون به یک فایل ارجاع بدیم. مطلب این دفعه می‌تونه به درد هر کسی که در لینوکس کار می‌کنه بخوره. فرقی نداره برنامه‌نویس باشین یا سیس ادمین یا کاربر معمولی.برای این نوشته فرض میشه که شما با فایل سیستم لینوکس آشنایی دارید و می‌تونید با فایل‌ها در خط فرمان کار کنید. اگر این شرایط رو ندارید می‌تونید آموزش‌های قبلی رو ببینید.هارد و سافت لینک هر دو از روی یه فایل ساخته میشن. یعنی یک فایل اول باید باشه تا این دو تا از روش ایجاد بشن. حالا ببینیم چی هستن. هارد لینکوقتی هارد لینک از روی فایل ایجاد میشه ظاهرا یک فایل جدید در فایل سیستم به وجود میاد ولی در اصل این فایل جدید به همون محتوای قبلی روی دیسک اشاره داره و چیز جدیدی به وجود نیومده. یعنی برای سیستم عامل این دو تا یک چیز هستن. در سیستم عامل مفهومی به نام inode داریم که یه فایل با اون معنی پیدا میکنه و همه اطلاعاتش تو اونه. داخل inode یه عدد هست که بهش شماره inode می‌گیم و برای هر فایل در فایل‌ سیستم یکتاست. وقتی از روی فایل هارد لینک درست می‌کنیم شماره inode فایل جدید با قبلی یکیه. حرف زیاد زدم بیاید عملی ببینیم:با دستور ln که مخفف link هست هارد لینک ساخته میشه. جلوش اون فایلی که وجود داره و بعدش اسم فایل جدید رو میدم. بعدش می‌بینیم یه فایل با اسم داده شده به وجود میاد.  قبلا گفته بودم وقتی ls -l می‌گیریم ستون دوم یه عدده که تعداد هارد لینک‌های فایل رو نشون میده. اینجا اون عدد برای جفتشون ۲ شده. قبلش ۱ بود. اینم بگم که اینجا ترتیب مهم نیست و هر دو در سیستم عامل به یه چشم دیده میشن. حالا از کجا ببینم شماره inode این دو تا رو؟ از آپشن i در دستور ls کمک بگیریم:می‌بینید یه شماره بزرگ میاد که همون شماره inode هست. برای فایل اول و هارد لینکی که ساختیم این عدد یکی هست و نشان از این داره که این دو تا یکی‌ان. محتوای جفتشم ببینیم که مطمئن شیم:تغییرم بدم جفتش تغییر می‌کنه:حالا اگه فایل اول رو حذف کنم چی میشه؟ هیچی نمیشه:چون فایل دوم دقیقا به همون جای دیسک که فایل اول بود اشاره داره، ما هنوز به محتوای فایل دسترسی داریم.از لحاظ کاربردی زیاد ندیدم از هارد لینک استفاده کنن. یه نکته مثبتی داره و اونم اینه که بدون گرفتن حجم اضافه دو تا فایل به یه محتوا اشاره دارن. مثلا اگه فایلی تو یه مسیر دور و دراز بود و خواستین بهش دسترسی داشته باشین میتونین تو یه جای نزدیک ازش هارد لینک بسازین. اگه کاربردی از هارد لینک میشناسین در قسمت نظرات بگین تا استفاده کنیم.سافت لینکبحث دوم سافت لینک یا سمبولیک لینک هست. برای ساخت این هم مثل قبلی باید اول یه فایل باشه. با ساختن سافت لینک واقعا یه فایل جدید ساخته میشه. توی این فایل مسیر فایل اول قرار میگیره. تنها محتوای سافت لینک همینه‌. همون shortcut خودمون هست. بیاید یه دونه بسازیم:مثل قبلیه فقط آپشن s رو اضافه کردم. می‌بینیم که فایل جدید ساخته شده. همچنین تو ستون اول اون قسمت نوع فایل l نوشته. این یکی از انواع فایل هست که در لینوکس داریم. پس یادمون باشه l به معنی سافت لینکه. علاوه بر این فایل اصلی که بهش اشاره میکنه رو هم تو خروجی دستور می‌بینیم. ستون اندازه فایل رو هم دقت کنید. اندازه فایل سافت لینک از کجا میاد؟ اینو جوابشو قبل این گفتم یه جورایی. اگر با ستون‌هایی که در خروجی می‌بینیم آشنایی ندارید این قسمت رو بخونید.هر کاری با این سافت لینک کنیم سر اون فایل اصلیه میاد. بیاید یه نمونه نوشتن تو فایل رو ببینیم:تو سافت لینک نوشتم ولی تو فایل اصلی نوشته شد. اندازه سافت لینک هم تغییری نمی‌کنه. حالا اگه فایل اصلی حذف شه چی میشه:می‌بینید که دیگه سافت لینک بی‌خاصیت شده و کار نمی‌کنه. چون به چیزی اشاره داره که وجود نداره.سافت لینک خیلی کاربردی تره. وقتی می‌خوایم از دست ورژن‌های مختلف یه کتابخونه یا برنامه راحت شیم ازش استفاده می‌کنیم. مثلا من پایتون ۳ دارم ولی زیرنسخه‌های زیادی داره. زیرنسخه‌های ۳.۵ و ۳.۶ رو دارم و احتمالا بعدا ۳.۷ هم نصب کنم ولی نمیخوام تو برنامه‌ام درگیر این بشم که چه ورژنیه. فقط مهمه که پایتون ۳ باشه. پس در جایی که این زیرنسخه‌ها هستن یه سافت لینک به نام python3 درست می‌کنم و به جدیدترین نسخه پایتون اشاره‌اش میدم:اینجا تمام فایل‌های پوشه رو که python3 دارن لیست کردم تا ببینم چه فایلایی موجوده. می‌بینیم که python3 در اصل سافت لینکه به جدیدترین نسخه. اگه آپدیت کنم پایتون رو فقط این لینک عوض میشه و تو برنامه‌هایی که از پایتون ۳ استفاده کردم تغییری لازم نیست بدم. خیلی از کتابخونه‌ها هم هستن که اینطوری ان. با این کار دیگه تغییر نسخه‌ها تاثیری روی برنامه‌هام نداره. اگه کاربرد دیگه‌ای می‌شناسید در قسمت نظرات بگید.جمع بندیدر این قسمت با مفهوم سافت لینک و هارد لینم آشنا شدیم. هارد لینک دقیقا همون فایل قبلی هست و به همون جای قبلی در دیسک اشاره می‌کنه. سافت لینک ولی مسیر فایل اصلی رو در خودش داره و یه فایل جدید هست. این قسمت هم تموم شد. امیدوارم استفاده کرده باشید. اگر سوال یا نظری دارید این پایین بگید.قسمت قبلی</description>
                <category>PaaSino</category>
                <author>Ali Akbar Hemmati</author>
                <pubDate>Mon, 16 Nov 2020 13:14:00 +0330</pubDate>
            </item>
                    <item>
                <title>لینوکسی بشیم: استفاده از tar برای آرشیو و فشرده کردن فایل‌ها</title>
                <link>https://virgool.io/paasino/tar-archive-and-compression-g741axbqoqwn</link>
                <description>در دو قسمت قبل وارد مباحث مربوط به فایل شدیم. تو این قسمت قراره ببینیم چجوری چندتا فایل رو تبدیل به یه فایل کنیم یا اصطلاحا آرشیوش کنیم. بعد یاد می‌گیریم چجوری فشرده‌سازی هم روش انجام بدیم. طبیعتا برعکس این‌ کارها رو هم خواهیم دید. مطلب این دفعه برای برنامه‌نویس‌ها در محیط لینوکس می‌تونه مفید باشه. برای سیس ادمین‌ها ولی خیلی مهمه. چون برای backup گرفتن استفاده میشه. شاید به درد کاربران معمولی لینوکس هم بخوره. خیلی از فایل‌هایی که دانلود می‌کنیم به شکل آرشیو شده هستن و دونستن این که چجوری باهاشون کار کنیم مهمه. در این مطلب فرض بر این هست که شما با ساختار فایل سیستم لینوکس و برخی دستورهای ابتدایی اون آشنایی دارید. می‌تونید دو قسمت قبل رو برای این کار بخونید.اول ببینیم منظور از آرشیو چیه. وقتی چند تا فایل رو تبدیل کنیم به یه فایل میگیم آرشیوش کردیم. برای این کار داخل اون فایل محتویات تمام فایل‌هایی که آرشیو کردیم قرار می‌گیره. کنارش یه سری اطلاعات اضافی هم باید باشه که سر و ته هر فایل مشخص بشه. این رو در ادامه می‌بینیم.دستوری که معمولا باهاش آرشیو می‌کنیم tar هست. این دستور رو با تعدادی آپشن استفاده می‌کنیم. اولیش c هست به معنای create. یعنی می‌خوام یه فایل آرشیو درست کنم. بعد f می‌ذارم و منظورم فایلی هست که قراره خروجی توش قرار بگیره. f رو آخر میذارم تا بتونم جلوش اسم فایل خروجی رو بدم: آخر سر اسم فایل‌هایی که می‌خوام آرشیو بشن رو میذارم. آخر اسم فایل خروجی خوبه که tar. بذاریم تا بدونیم این یه آرشیوه. تو قسمت قبل گفتم که برای لینوکس مهم نیست extension فایل چی باشه و فقط برای این که خودمون یادمون بمونه این کار رو می‌کنیم. گاهی تو آپشن‌ها v میذارن که به معنی verbose هست و توضیحات بیشتری میده راجع به کاری که داره می‌کنه.حالا بیاید محتویات فایل‌هایی که بهش دادم و محتویات آرشیو رو مقایسه کنیم: اون آخر هر خط محتوای فایل‌ها هستن. اولش هم مسیر نسبی هر فایل نوشته شده. چجوری بازش کنیم؟ دوباره همون دستور tar رو داریم و این دفعه آپشن x رو به معنی extract میذاریم به جای c: تو این تصویر اون فایل آرشیو رو بردم یه پوشه جدید و بعد بازش کردم. دقت کنید دقیقا همون جور که بهش فایل‌ها رو دادم باز می‌کنه. تو دستور اول من مسیر نسبی فایل‌ها رو دادم. اگر مسیر مطلق بدیم (یعنی از / شروع کنیم به دادن مسیر) این دستور موقع آرشیو کردن اون / اولش رو برمی‌داره. چرا؟ چون موقع باز کردن دیگه نره تو اون جای اصلی بنویسه و تو پوشه‌ای که دستور اجرا میشه فایل‌ها باز بشن. بیاید یه مثال ببینیم:تو این دستور من همون فایل‌های قبلی رو دادم ولی با مسیر مطلق. یه پیام می‌نویسه که / اول رو حذف کرده. محتوای فایل آرشیو رو نگاه کنید:همه فایل‌ها مسیرشون بدون /  ذخیره شده و وقتی بازش کنیم دقیقا همون ساختار پوشه‌ای رو توی پوشه‌ فعلی ایجاد می‌کنه نه توی جای اصلیش:دقیقا از home شروع کرده و تا پایین رفته.خیلی از موقع‌ها میشه که نیاز داریم تعداد زیادی فایل رو آرشیو کنیم و خوبه که فشرده‌اش کنیم. برای فشرده‌سازی چندین ابزار در لینوکس وجود داره. در اینجا ما فقط یکیش رو بررسی می‌کنیم که با اضافه کردن آپشن z به دستور tar انجام میشه. با این کار فایل بعد از آرشیو شدن به کمک gzip فشرده میشه:من آخر فایل gz. گذاشتم که بدونم با gzip فشرده شده. می‌تونم با خود gzip این کار رو بکنم؛ یعنی اول با tar آرشیو کنم بعد با gzip فشرده‌اش کنم. وقتی با آپشن z فشرده کردیم باید با همین آپشن هم بازش کنیم تا فشرده‌سازیش برداشته بشه. دقت کنید الان که فشرده میشه دیگه فایل رو نمیشه به شکل متن دید. خودتون یه فایل بزرگ رو فشرده کنید و اندازه‌اش رو بررسی کنید. یادتونه با کدوم دستور و با چه آپشنی اندازه فایل رو به شکل human readable میشد دید؟ آپشن دیگه‌ای داریم که فایل‌های توی آرشیو رو نشون میده و اون t هست:اگرم‌ خواستید یک فایل داخل آرشیو رو به روز رسانی کنید یا فایل جدید اضافه کنید از r استفاده کنید: تو این قسمت دستور tar رو یاد گرفتیم تا باهاش فایل‌ها رو آرشیو کنیم. بحث این قسمت به اتمام رسید. امیدوارم براتون مفید بوده باشه. اگر سوال یا نظری دارید این پایین بفرمایید.قسمت قبلیقسمت بعدی</description>
                <category>PaaSino</category>
                <author>Ali Akbar Hemmati</author>
                <pubDate>Mon, 09 Nov 2020 10:56:48 +0330</pubDate>
            </item>
                    <item>
                <title>لینوکسی بشیم: مدیریت فایل‌ها و کار در فایل سیستم لینوکس - قسمت دوم</title>
                <link>https://virgool.io/paasino/manage-files-and-directories-n0qhmfzjpzzw</link>
                <description>در قسمت قبلی یه تعدادی از دستورات کار با فایل‌ها و پوشه‌ها رو دیدیم. این دفعه می‌خوایم یه تعداد دیگه‌شون رو ببینیم. مثل دفعه پیش این هم برای هر کسی که تو لینوکس کار میکنه مفیده؛ چه سیس ادمین باشه چه برنامه‌نویس و چه کاربر معمولی. در این نوشته فرض میشه شما با فایل سیستم و خط فرمان لینوکس آشنایی دارید. دستورات و توضیحات قسمت قبلی رو هم بخونید تا همه تو یه قایق باشیم.اولین دستور mv هست. با mv که مخفف move هست فایل یا پوشه از مبدا به مقصد جابه‌جا میشه. مثل cut and paste میمونه. مانند کپی مسیر مبدا و مقصد رو میگیره: توی تصویر بالا اول پوشه dir در پوشه بالایی وجود داره اما بعد از move فقط در paasino وجود داره. از mv برای تغییر نام یه فایل یا rename کردن میشه استفاده کرد:عین قبل اول اسم فایل اصلی و بعدش اسم جدید فایل.دستور بعدی ما rm هستش؛ مخفف remove. باهاش یک فایل حذف میشه:می‌تونیم برای حذف محتویات پوشه هم ازش استفاده کنیم. با آپشن r- این کار رو می‌کنیم: آپشن r خیلی جاها به معنی recursive هست. تو اینجا به شکل بازگشتی میره و فایل‌ها و پوشه‌ها رو پاک می‌کنه. تو عکس بالا اول محتویات داخل پوشه logs رو نشون دادم و بعد با آپشن r- حذفش کردم که همه چی توش حذف شد.برای حذف پوشه‌ی خالی از rmdir استفاده می‌کنیم:در این تصویر یه پوشه خالی به نام logs داشتم و با rmdir حذفش کردم.برای ساخت فایل و پوشه چی کار کنیم؟ اول فایل رو میگم. دستور touch برای ما یه فایل رو می‌سازه: یه کار دیگه هم برای ساخت فایل می‌کنن که استفاده از echo هست:یه جمله خالی رو میفرستم تو فایلی که وجود نداره و یه فایل خالی ساخته میشه. تو یکی از قسمت‌های قبل دیدیم که &lt; یه فایل رو اگه وجود نداشته باشه می‌سازه.برای پوشه دستور mkdir رو داریم: اگر خواستیم چند تا پوشه همزمان ساخته بشه اسم اونا رو با فاصله جلوش می‌ذاریم. یه موقعی هست می‌خوام پوشه‌ای بسازم که پوشه‌ی والدش وجود نداره. مثلا می‌خوام paasino/dir1/subdir1 رو بسازم ولی paasino/dir1 وجود نداره. یه راهش اینه که اول paasino/dir1 رو بسازم. راه دیگه اینه که از آپشن p- استفاده کنم:این آپشن اگر ببینه پوشه‌ای در مسیر داده شده وجود نداره می‌سازدش. این‌جا هم اول dir1 رو ساخت و بعد subdir1 رو. بدون این آپشن دستور بالا خطا می‌گرفت. مبحث بعدی این قسمت file globbing نام داره. این ویژگی در بش وجود داره. برای شل‌های دیگه به مستنداتشون مراجعه کنید. با این ویژگی میشه اسم فایل‌ها رو به شکل الگو نوشت. چیزی شبیه regex هست با قواعد خاص خودش. اگر بخوام بگم در جایی از اسم فایل یک حرف باشه و مهم نیس خود حرف چی باشه از ? استفاده می‌کنم:اینجا گفتم مهم نیست سه حرف اولش چیه. فقط بعد از اون سه حرف log. اومده باشه. اگر بخوام صفر یا بیشتر حرف رو بگم * میذارم:اینجا گفتم فقط آخرش log. باشه و مهم نیست قبلش چند تا حرف باشه. از { } برای دادن چند تا کلمه استفاده می‌کنم:تو تصویر گفتم سه تا پوشه بساز که اول اسم همه‌شون -dir هست و در ادامه one و two و three. دقت کنید این یه ویژگی بش هست و با هر دستوری میشه استفاده کرد.در نهایت بیاید دو تا دستور برای بررسی بیشتر فایل ببینیم. اولیش دستور file هست:اطلاعاتی در مورد فرمت محتوای فایل به ما میده. تو لینوکس این اطلاعات از extension آخر فایل به دست نمیاد و تغییر دادنش تاثیر خاصی از نظر سیستم عامل روی فرمت فایل نمی‌ذاره. مثلا اگه یه فایل آخرش pdf باشه دستور file به اون نگاه نمی‌کنه و به خود فایل نگاه میکنه. به این دلیل تو لینوکس extension فایل رو چیزی میذاریم که خودمون راحت‌تریم و معنی‌دارتر هست. تو مثال بالا میگه این یه فایل متنی ascii هست. دستور بعدی stat هست که اطلاعات دیگه‌ای بهمون در مورد فایل میده:این اطلاعات داخل یه چیزی به نام inode  ذخیره میشه که برای هر فایل در فایل سیستم وجود داره. می‌بینید که اطلاعاتی از جمله زمان تغییرات فایل و اندازه‌ی اون در دیسک ارائه میکنه.بحث ما در زمینه این دستورها تموم شد. سعی کنید تمرین کنید تا یادتون بمونه. امیدوارم براتون مفید بوده باشه. اگرم سوال یا نظری دارید این پایین بفرمایید.قسمت قبلیقسمت بعدی</description>
                <category>PaaSino</category>
                <author>Ali Akbar Hemmati</author>
                <pubDate>Thu, 05 Nov 2020 11:38:35 +0330</pubDate>
            </item>
                    <item>
                <title>لینوکسی بشیم: مدیریت فایل‌ها و کار در فایل سیستم لینوکس - قسمت اول</title>
                <link>https://virgool.io/paasino/manage-files-and-directories-cb5tdfor8iu7</link>
                <description>تو این قسمت دستورهایی رو یاد می‌گیریم که با محتوای فایل کاری ندارن. این دستورها برای بررسی و مدیریت پوشه‌ها و فایل‌ها به کار میرن. این مبحث مهمه تو لینوکس و به این دلیل هر کسی کارش قراره به لینوکس بیفته می‌تونه استفاده کنه. چه سیس ادمین باشه چه برنامه‌نویس و چه کاربر معمولی.تو این نوشته فرض میشه یه سیستم لینوکسی دارید که به خط فرمانش دسترسی دارید و هم‌چنین یه کمی هم در این زمینه آشنایی دارید.اول یه سری به فایل سیستم لینوکسی بزنیم. تو لینوکس همه مسیرها از روت یا / شروع میشه: دستور tree رو دیدید که به شکل درختی ساختار پوشه‌ها رو نشون میده. با L- بهش گفتم که داخل پوشه‌ها نره و فقط همون سطح اول رو نشون بده. بدون این آپشن خروجیش خیلی زیاد میشه. اگه خواستیم مسیر یه فایل یا پوشه رو بدیم اول / رو می‌ذاریم بعد دونه دونه پوشه‌ها رو می‌نویسیم و هر کدوم رو با / از بعدی جدا می‌کنیم تا به انتها برسیم. مثلا مسیر کامل پوشه paasino به شکل زیره: /home/aliakbar/paasinoمی‌تونیم مسیرها رو نسبی هم بگیم؛ مثلا وقتی من تو پوشه home/aliakbar/ هستم می‌تونم با نوشتن paasino خالی به اون پوشه اشاره کنم. برای نشون دادن پوشه فعلی میشه از نقطه هم استفاده کرد؛ مثلا بگم paasino/. به جای paasino خالی. می‌تونم به پوشه بالایی با دو نقطه اشاره کنم. مثلا اگه مسیر مطلق یه پوشه تو home/rio/ باشه و من تو home/aliakbar/ باشم میتونم با rio/.. بهش اشاره کنم. خب یه کم زیاد بحث تئوری شد. بریم سراغ دستورها تا دستور یاد بگیریم و این مفاهیم رو هم عملی ببینیم.برای تغییر پوشه فعلی از cd استفاده میشه که مخفف change directory هست. جلوش اسم پوشه‌ی مقصد رو می‌نویسیم که می‌تونه مطلق باشه یا نسبی:اینجا میشه دید که چجوری از اون مسیرها استفاده می‌کنیم. دستور pwd که استفاده شده مسیر مطلق پوشه فعلی رو بهمون میده. برای تغییر پوشه یک سری shortcutهایی موجوده. دو تا نقطه رو که دیدیم. نکات بعدی که میگم در مورد بش هست و در مورد شل‌های دیگه باید مستنداتش رو بخونید. اگر هیچی نزنیم جلوی cd ما رو به پوشه home می‌‌بره:پوشه home چیه؟ وقتی یه کاربر تو لینوکس می‌سازیم معمولا یه پوشه به نام اون کاربر توی home/ ساخته میشه. تو تصویر قبلی aliakbar پوشه home یه کاربر با همون نام هستش. اگر خط فاصله بذاریم جلوش، میره به جای قبلی که توش بودیم. در مسیر دادن میشه از تیلدا یا ~ استفاده کرد تا پوشه home رو نشون داد. تو عکسای بالا اونجایی که دستور میزنم وقتی تو home هستم با رنگ آبی نوشته ~ که منظورش همون home من هست. البته تیلدا رو برای دستورات دیگه هم میشه استفاده کرد و مختص cd نیست.با ls محتوای یه پوشه رو می‌بینیم:پوشه‌ها و فایل‌هایی که با نقطه شروع میشن با ls نشون داده نمیشن و بهشون فایل hidden میگن. با یه آپشن میشه اون‌ها رو دید: آپشن رو با خط فاصله مشخص می‌کنم. بعد خط فاصله هم حرف مربوط به اون آپشن رو می‌ذارم که اینجا a هست. خیلی جاها a آپشنی هست که همه چی رو نشون میده و مخفف all هست. اینجا هم یکی از اون جاهاست.اگه جلوی ls اسم یه پوشه رو بذارم محتوای اون رو نشون میده و اگر اسم فایل بذارم خود اون فایل رو نشون میده: با ls میشه اطلاعات بیشتری هم بدست آورد. این کارو با آپشن l انجام میدم:آپشن‌ها رو میشه ترکیبم کرد و مثلا بنویسیم al- تا هم اطلاعات زیادی بده و هم فایل‌های مخفی رو. بذارید ستون‌هایی که نمایش داده شده رو بررسی کنیم. ستون اول ده بخش داره و اولیش میگه این یه فایله یا پوشه. البته حالات دیگه هم داره که فعلا به اونا نمی‌پردازیم. اگه فایل باشه - میذاره و اگه پوشه باشه d. نه قسمت بعدی دسترسی‌های فایل یا پوشه رو میگن که الان باهاشون کاری نداریم و ایشالا بعدا می‌بینیم. ستون دوم برای یه پوشه نشون میده چند تا فایل یا پوشه داخلش هست. برای یه فایل نشون میده چند تا hard link به اون فایل هست. این مفهوم رو هم بعدا می‌بینیم. دو ستون بعدی مالک فایل و گروهی که فایل به اون تعلق داره رو میده. اینم امیدوارم بعدا ببینیم. بعدش حجم فایل هست. با اضافه کردن آپشن h این ستون human readable میشه و واحدهاش تر و تمیز میشن. سه تا ستون بعدی تاریخ آخرین تغییر فایل رو میدن. میشه با آپشن t بر اساس این زمان خروجی رو مرتب کرد. حالا که تا اینجا اومدیم بذارید یه سوالم بپرسم. اگه جلوی دستور ls اسم پوشه بذارم محتواش رو میده. اگه بخوام مشخصات خود پوشه رو (همونطوری که در مورد فایل نشون میده) نشون بده چه آپشنی استفاده کنم؟ قطعا فکر کردنی نیست و باید دنبالش بگردین.حالا دیگه بریم یه کم فایل‌ها رو جابه‌جا کنیم. دستور cp که مخفف copy هست فایلی رو از مبدا به مقصد کپی می‌کنه: دو تا آدرس می‌دیم بهش. اولی مبدا هست و دومی مقصد. جفتش میتونه مطلق یا نسبی باشه. واسه مقصد میتونیم فقط اسم پوشه رو بدیم که با این کار یه فایل به نام فایل اصلی توش ایجاد می‌کنه. اگرم اسم فایل بدیم اون فایل رو می‌سازه برامون. تو مثال بالا مسیر پوشه رو دادم.اگر فایلی با نام فایل اصلی تو مقصد باشه چی؟ cp هیچ کاری نمی‌کنه مگر اینکه ما آپشن i رو زده باشیم. در این حالت از ما می‌پرسه مطمئنی میخوای اون فایل مقصد رو overwrite کنی؟ ما هم میگیم بله یا خیر:تو این مثال با y گفتم بله. با آپشن R- یا r- کل محتوای پوشه کپی میشه:تو این حالت مقصد باید حتما پوشه باشه و نه فایل.این مطلب هم تموم شد. امیدوارم استفاده کرده باشین. در قسمت بعد ادامه مباحث این قسمت رو خواهیم دید. اگر سوال یا نظری دارید این پایین بفرمایید.قسمت قبلیقسمت بعدی</description>
                <category>PaaSino</category>
                <author>Ali Akbar Hemmati</author>
                <pubDate>Mon, 02 Nov 2020 10:53:56 +0330</pubDate>
            </item>
            </channel>
</rss>