تجربه مهاجرت به Docker و سرور جدید

سلام تو این پست از تجربه مهاجرت به Docker و سرور جدید وبسایتم براتون میگم.

نزدیک به 6 سال میشه که وبسایتم روی زیرساختی بسیار محدود در حال ادامه حیات بود و به عبارتی بجای زندگی کردن فقط زنده بود، چرخه ی ناعادلانه ای که شاید خیلی از انسان ها به دلیل بی مهری مدیران و مسوولان دچارش هستند. سروری با 128مگابایت رم که بقیه مشخصات رو هم خودتون میتونید حدس بزنید و خوب این میزان منابع برای بالا نگه داشتن وبسایت تا اونجایی که میدیدید خوب بود و برای ارایه خدمات بهتر و استفاده از فناوری های روز جوابگو نبود، دقیقا مثل همون مسوولان عزیز که جوابگو نیازهای بروز ما نیستند. خلاصه که از من تلاش برای فشار بیشتر به سرور و از سرور صبوری پشت صبوری… تا اینکه دیدم فشار بیشتر در توان این بنده ی بخت برگشته نیست و از اونجایی که زمان هم یاری نمی کرد وقت ارتقاع و بروزرسانی و… رو هم نداشتم و به ناچار مدتی رها شد و هر از گاهی سر میزدم و پستی، آموزشی چیزی میذاشتم تا بالاخره به لطف ویروس کرونا و قرنطینه فرصتی شد تا دستی به سر و روی این بنده مخلص و گوش بفرمان بکشم…

سرویس هایی که استفاده می کردم:

1عدد توزیع Alpine Linux که بسیار سبک وزن و کاربردی هست.

1عدد وب سرور Apache و تعدادی ماژول + PHP

1عدد دیتابیس MySQL که بعد شد MariaDB

1عدد سیستم وردپرس(WordPress) قاتل منابع سیستم :mrgreen: :mrgreen:

1عدد DNS سرور جهت انجام امور لازم

همه اینها تنها با 128مگابایت رم 😯 در حال سرویس دهی بودن(ایمان بیارید).

بگذریم که این سرویسا رو چطور کانفیگ کردم که مثل یک خانواده 5نفره تو یک خونه یک خوابه به سختی زندگی میکنن، صداشونم در نمیاد و به عبارتی که گفتم فقط زنده هستن. 🙁 🙁

پردازنده سرور به اندازه ای ضعیف بود که توان انجام هیچ پردازش رمزنگاری رو نداشت و به همین دلیل HTTPS فعال نبود. محدودیت رم باعث شده بود که امکان آپلود فایل بالای 10مگابایت وجود نداشته باشه و در کل این محدودیتها باعث شده بود که درخواست های وب سرور یکی در میان Reject بشن و به دلیل بهینه نبودن دستورات SQL وردپرس(WordPress) بار زیادی به دیتابیس وارد بشه و برای Dump کردن بکاپ هم مشکلاتی داشته باشم… دقیقا مثل زندگی در ج. ا. میمونه. منظورم “جعبه ابزار” هست که انقد فضاش بسته و محدوده که هیچوقت هیچی سر جاش نیست و همیشه ی جای کارش میلنگه و زندگی هم داخلش سخته. 😥 😥

از همه مهم تر بروزرسانی وردپرس عموما با ورود به حساب ادمین و از بخش بروزرسانی خود وردپرس انجام میشه که این گزینه نیاز به تعامل با سیستم داره و معمولا من فراموش می کردم که در یک برنامه منظم دوره ای سر بزنم و آپدیت کنم! حالا آپدیت هم کردیم اگر مشکل داشت برای Rollback کردن باید بکاپ برگردونیم و خدا میدونه این بکاپ کی گرفته شده. 🙄

به عنوان ی مدیر سیستم وظیفه داشتم این مشکلات رو زودتر حل کنم! اما شما به دل نگیرید همیشه میگن “کوزه گر از کوزه شکسته آب میخوره!” و اما حل این مشکلات راه های زیادی داشت که من تصمیم گرفتم با استفاده از نگرش DevOps یک استک جدید برای وبسایت طراحی کنم. در یک جمله “استک با نگرش DevOps” همان و چالش های مهاجرت از مدل سنتی به کانتینرها و داکرایز کردن سیستم هم همان! میخوام بگم که بنظر کار ساده ای میاد ولی در عمل مهاجرت کردن خیلی سخته چه از شهر به شهر دیگه، چه از کشور به کشوری و چه از سیستم به کانتینری…

از این زندگی چی میخوام؟

خوب یک لیست از مواردی که نیاز داشتم رو درآوردم که علاوه بر سرویس هایی که گفتم شامل:

1- داشتن مجوز SSL برای امنیت خودم و بقیه.

2- راه اندازی WAF برای دفع حملات سایبری 😀

3- راه اندازی لایه بهینه کننده سرویس.

4- مهاجرت از DNS سنتی به DNSSEC+NSEC3 که تو ی پست دیگه مفصل در موردش میگم.

5- بروزرسانی خودکار همه چی با امکان Rollback خودکار در صورت وجود مشکل.

6- بکاپ گیری خودکار و البته ایمن کل سیستم.

و اما بحث شیرین پیاده سازی:

سرور جدید رو راه اندازی و مواردی که در کارگاه امنیت لینوکس با سعید بهتون گفتم رو درش پیاده سازی کردم. داکر(Docker) و داکر کامپوز(Docker Compose) رو هم نصب کردم و کوله بار مهاجرت رو بستم. پیاده سازی لایه ای سیستم یکم سخت و پیچیده هست و با مطرح کردنش گمراهتون نمی کنم، فقط در یک کلام تمام مواردی که بهتون میگم به صورت جدا از هم پیاده سازی شدن و با استفاده از سیستم لایه بندی سرویس، سرویس دهی میکنن که مزیت های ویژه ای داره.

داکر رو با “داکر با سعید” یاد بگیر.

گام اول: پیاده سازی کانتینر DNS سرور

برای اینکار یک توزیع جمع و جور مثل Alpine Linux میتونه مناسب باشه، منم همینو انتخاب کردم. برای اینکه بتونیم یک سرویس بروز با آخرین نسخه BIND داشته باشیم لازم بود که یک Pipeline ایجاد کنم که به ریپوزیتوری رسمی گوش کنه و هر زمان یک کامیت روی برنچ master زده شد، ایمیج با بسته جدید مجددا Build بشه و بره تو صف برای Deploy شدن. اگر نمیدونید پایپ لاین(Pipeline) چیه نگاهی به واژه نامه CI/CD بندازید یا صبر کنید بعدا در موردش خواهم گفت.

گام دوم: وب سرور لبه(Edge)

این وب سرور پل ارتباطی با دنیای بیرون از سرور و سرویس های پشتی سیستم هست و همچنین ارتباط امن TLS رو فراهم میکنه. مثل یک CDN ابری میمونه که درخواست ها رو میگیره و روی سرویس های مختلف توزیع میکنه. ابزارهای زیادی مثل HAProxy, Nginx, Apache و… میتونن اینکار رو انجام بدن. من Nginx رو انتخاب کردم و روال ساخت ایمیجش مثل مرحله قبل هست.

گام سوم: پیاده سازی WAF برای دفع حملات سایبری

یکی از WAF های آزاد که به خوبی کار میکنه Modsecurity هست و وقتی با CRS ترکیب بشه یک دیوار محکم رو برای وبسایت میسازه. برای پیاده سازی این گزینه از modsecurity-crs رسمی خود OWASP که روی Docker Hub موجوده استفاده کردم. شما هم همینو استفاده کنید.

گام چهارم: مهاجرت وردپرس به کانتینر (هفت خان رستم)

راه اندازی یک سیستم وردپرس صفر کیلومتر در کانتینر اصلا سخت نیست ولی الان یک وردپرس خارج از کانتینر دارم و علاوه بر اطلاعاتی که داشت، به آخرین نسخه وردپرس هم بروز نبود که این کارو یکم سخت میکنه. برای ادغام وردپرس موجود با وردپرس کانتینری، یک کانتینر موقت بالا آوردم، اطلاعات رو Merge کردم و بعد یک بکاپ از لایه Merge رو جدا کردم و به عنوان ورودی اولیه کامپوز در نظر گرفتم. این مرحله همچین هم ساده نیست ولی برای پیاده سازی استک بروزرسانی خودکار لازمه و حالا چرا هفت خان رستم؟ تو قسمت بعد میگم براتون… وردپرس همچین راحتم مهاجرت نمیکنه!

گام پنجم: مهاجرت دیتابیس به کانتینر

برای پیاده سازی این قسمت از ایمیج رسمی MySQL روی داکرهاب استفاده کردم و الان زمان معرفی Dump برای شروع اولیه دیتابیس هست و از اونجایی که سایت قدیمی HTTP بود و الان به HTTPS تغییر کرده لازم بود که تمامی لینک ها در دیتابیس بروز بشه و به https تغییر کنه که خود این موضوع پیچیدگی های خاص خودشو داشت و بالاخره انجام شد.

خوب مثل اینکه همه چی آماده شده…

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

ولی ی جای کار ایراد داره! با اینکه تمام لینک ها به https تغییر کرده ولی تعدادی از لینک ها هنوز http مونده و این مشکل تقریبا 24ساعت منو سرکار گذاشت و باعث شد چندین بار همه چیزو چک کنم و مشکلی هم پیدا نکنم تا در آخرین بررسی متوجه شدم که باید در وردپرس تغییراتی رو اعمال کنم. این داکیومنت بهتون کمک میکنه که مشکلات مربوط به مهاجرت به SSL رو حل کنید.

گام ششم: بروزرسانی خودکار

برای بروزرسانی خودکار کانتینرها به آخرین ورژن، ابزاری مثل watchtower به ما کمک میکنه که کانتینرها به طور خودکار بروز بشن. این ابزار با نگاه کردن به ریپوزیتوری، آخرین ایمیج موجود رو میگیره و کانتینرها رو با پارامترهایی که دارن دوباره میسازه و اجرا میکنه. نکته مهم اینه که اگر تغییراتی تو کانتینرها دادید بعد از بروزرسانی خودکار از بین میره! و خوب اگر یادتون باشه الان دوتا ایمیج هم خودمون ساختیم که تو Docker Hub وجود نداره و به ناچار به مرحله بعد میریم.

گام هفتم: راه اندازی ریپوزیتوری

برای راه اندازی ریپوزیتوری از ایمیج رسمی docker registry روی داکرهاب استفاده میکنیم. نکته بسیار مهم برای ارتباط watchtower و registry برای بروزرسانی خودکار کانتینرها اینه که برای هر ایمیج باید دو تا تگ(Tag) در نظر بگیریم و ایمیج رو با هر دو تگ Push کنیم. یکی با تگ latest که آخرین نسخه رو نشون میده و یکی تگ ورژن که برای هر نسخه باید منحصر به فرد باشه که ازشون برای Rollback کردن کانتینرها در صورت وجود مشکل استفاده می کنیم.

گام هشتم: بکاپ گیری خودکار و ایمن

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

تمام شد. کانتینری شدیم رفت. 😀

خلاصه که جونم براتون بگه مهاجرت ساده نیست!

شما هم از فرصت های کرونا استفاده کنید و هر چیزی که لازمه رو تغییر بدید. 😉

بنظرتون کامپوزفایل این پروژه چند خط شده و چقدر میتونه سخت باشه؟

راستی الان روی وبسایت جدید هستید و همه اون امکانتی که مد نظرم بود پیاده شده. 😉

برام کامنت کنید و سوالاتتون رو بپرسید و نظر بذارید.

موفق و پیروز باشید.

22

13 دیدگاه

  1. عالی بود البته برای من که مبتدیم هر قسمت رو باید یه جستجوهایی بکنم که ریز ماجرا رو بفهمم.

  2. مقاله بسیار عالی بود ولی ای کاش طنزش وجود نمیداشت و تکنیکالی بود.
    در کل عالی بود؛ خسته نباشید. ممنونم

  3. سلام.
    جالب بود ممنون از به اشتراک گذاری. اون قسمتش که گفتی pipeline باید درست میکردم با چی pipeline رو درست کردی؟ چون مثلا من خودم تجربه پیاده سازی مورد مشابه رو دارم jenkins رو وصل کردم به گیتلب خودمون و webhook رو روش فعال کردم اما اینجا اسمی از jenkins و … نیاوردی. میدونم خود گیتلب هم یه چیزایی داره که اصلا سراغ CI/CD گیتلب نرفتم این مورد رو بیشتر توضیح بده که چطور PIPELINE ات رو ساختی.
    عالی

    1. سلام خواهش میکنم.
      جنکینز یکی از ابزارهای بسیار مورد علاقه من هست و تو بحث پیاده سازی CI/CD واقعا کم نظیره ولی برای جایی مناسبه که ما یک پروژه برنامه نویسی و محصول داشته باشیم و برای بحث CI/CD پروژمون راه اندازی کنیم. با توجه به اینکه من فقط یک پایپ لاین لازم داشتم که به کامیت های پروژه گوش بده و از طرفی هم Jenkins منابع سیستم رو بیش از نیاز من مصرف میکنه از جنکینز استفاده نکردم و با یک اسکریپت ساده Bash کاری کردم که آخرین کامیت پروژه رو نگاه کنه و اگر تغییری کرده بود cloneش کنه و ایمیج جدید رو بسازه و pull کنه داخل رجیستریم. کل داستان به همین سادگی انجام میشه و برای این منظور کافیه.

  4. سلام
    کار زیبایی بوده ممنون از خوندنش لذت بردم
    من در داکر مبتدی هستم و همین طور برنامه نویس
    برای شروع دوتا کانتاینر با ایمیج های nginx و phpdockerio/php74-fpm درست کردم
    ارتباط روی پورت 9000 رو چطور برقرا کنم بین اینها توی nginx فایل کانفیگ رو تنظیم کردم روی 127.0.0.1:9000نمیبینه

    1. سلام خواهش میکنم.
      هر دو کانتینر رو عضو یک شبکه کنید. با عضو کردن هر دو در یک شبکه همدیگرو میبینن و با هاست نیم(اسم کانتینر) میتونن همدیگرو پیدا کنن. از این به بعد تو هر کانفیگی که دارید برای اشاره به اون یکی کانتینر کافیه اسمشو به کار ببرید.

  5. من خارج از موضوع کانتینر تجربه خوبی با ابزارfail2ban برای محافظت از وب سایت دارم البته بعد از سر کله زیاد واسه نوشتن regex ان.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *