Run application on server using Docker and Nginx
من درباره Docker و داکرایز کردن اپلیکیشنها محتواهای مختلفی دیده بودم و خب کلیت ماجرا رو میدونستم اما همیشه اون حجم از نکات پیچیده باعث میشد تو دل کار نرم و امتحانش نکنم اما این بار توی رهنماکالج، از صفر تا صد این کار رو انجام دادم و شاید بشه بگم به حد و اندازه یک دولوپر تجربه کردم که چطور از داکر استفاده کنم.
چون خودم همش دنبال این بودم که یک فلوی ساده و حتی با کامندهای مشخص که ترتیب انجام کارهام توش معلوم باشه پیدا کنم ولی پیداش نکردم(شاید خوب نگشتم ) پس حس کردم خوب باشه این تجربه رو به اشتراک بذارم که شاید به درد کسی بخوره که مثل من توی این مراحل همیشه ترسیده دست به سرور بزنه یا هی گیج شده و این کار بتونه کمی ذهنش رو شفاف کنه.
پس من به ترتیب میگم چه مراحلی رو پیش رفتم، اگر جاییم اشتباه رفتم یا بهتر بود قدمی رو اضافه کنم یا شکل دیگه ای میشد مراحل رو برم بهم بگید، خیلی خوشحال میشم:
- ما یک سرور خالی داریم که یک سیستم عامل لینوکسی داره .(سیستم من اینجا ubuntu بودش)
- داکر رو روی سیستم نصب میکنیم.(کامندهای دقیق رو توی فایل ضمیمه پست میکنم.)
- معمولا ما یک اپلیکیشن front-end داریم و یک اپلیکیشن backend داریم که به ازای هر کدوم از اینها نیازه یک داکر فایل داشته باشیم. داکر فایل شامل دقیقا همون کامندهاییه که خودمون توی ترمینال سیستممون برای اجرای اون اپلیکیشن روی سیستمون لوکال خودمون میزنیم. هر زمان قرار باشه داکر اپلیکیشن ما رو اجرا کنه و روی سرور بالا بیاره کامندهای توی این فایل رو اجرا میکنه.
- مرحله docker compose : توی این کیس ما یک دیتابیس mongo داشتیم، اپلیکیشنهای فرانت و بک رو داشتیم، یک rabbitMQ داشتیم ، nginx داشتیم و چون دامنه داشتیم و میخواستیم ssl داشته باشه نیاز به certbot داشتیم که ssl های رایگان بهمون میده . با اجرا شدن مجموعهی این اپلیکیشنها که بهم وابسته هم هستن، محصول ما اماده استفاده هستش پس باید اینجا یک docker compose داشته باشیم.توی این فایل دونه به دونه اپلیکیشنهایی که داریم رو کانفیگ میکنیم، این اپلیکیشنها بعد از اجرای فایل docker-compose هرکدوم به شکل یک container ساخته میشن واین containerها یک نتوورک درونی باهم خواهند داشت و و هرکدوم روی پورت مشخصی باید اجرا بشن. نکاتی که درباره این فایل به ذهنم میرسه چیاست:
- توی همین فایل مشخص میکنیم کدوم اپلیکیشنها بهم وابسته هستن مثلا اپلیکیشن تا دیتابیس کامل اجرا نشده باشه معمولا اجرا شدنش معنی ای نداره.
- Volumeهایی که توی این فایل مشخص میکنیم در واقع یک پوشه یا فضا رو از دیسک سرور به containerای که به ازای هر اپلیکیشن ساخته میشه assign میکنه تا فایلها،دیتاهایی که میخوایم ازش برامون بمونه رو توی اون بخش ذخیره بکنه و نگه داره.
- خب nginx نیاز به چی داره؟ افرین، باید configهای مورد نظرش رو بهش بدیم. توی این مورد ما برای اینکه کانفیگمون رو جایی داشته باشیم فایلش رو توی ریپازیتوری اپلیکیشن بکاند اضافه کردیم.
کنار پوشه اصلی اپلیکیشن همچین ادرسی میسازیم : config/nginx/default.conf و توی این فایل کانفیگ nginx رو قرار میدیم.(این فایل رو هم ضمیمه میکنم) حالا چه نکاتی درباره این فایل میتونم بگم؟ - اون upstreamهایی که اول فایل هستن درواقع اپلیکیشنهایی هستن که از طریق nginx قراره کنترلشون کنیم.و اسم سروری که به هر upstream داده میشه باید همنام container اون در فایل docker-compose باشه.
- اولین بلاک server که توی فایل هست دقیقا همیشه همونجوریه و وظیفه داره هرنوع درخواستی با هر دامنهای به سمت سرور ما میاد از http به https ریدایرکت کنه.
- دومین بلاک server رو جلوتر میگم که کجا استفاده میکنیم.
- سومین بلاک server مشخص میکنه به ازای هردرخواست https که به سرور میاد اگر از سمت دامنه موردنظر ما باشه باید اون درخواست رو به سمت کدوم اپلیکیشن (upstream) ارسالش کنیم. همچنین توی این بلاک یک سری هدرهای امنیتی هم میتونیم ست بکنیم.
- نکتهای که بهتره حواسمون باشه چیه؟ ما معمولا رمز و پسووردها رو به صورت hard code نباید مشخص کنیم پس نیاز به یک فایل env داریم که این متغیرها باید توشون تعریف شده باشه. این فایل .env رو کنار فایل docker-compose میذاریم تا موقع اجرا شدن بتونه مقادیر رو ازش بخونه.توی خود فایل هم برای خوندنشون لازمه بنویسیم {variable_name}$ (اگر اسم فایل .env نباشه باید توی فایل docker-compose بگیم برای خوندن مقادیر سراغ چه فایلی بره.)
- خب ما الان میشه گفت تقریبا همه فایلهای مورد نیازمون رو داریم. پس به هرشکلی که بلدین code sourceهای اپلیکیشنهای فرانت و بک رو، روی سرور میبریم. فایلهای کانفیگ nginx و docker-compose هم چون معمولا و همونطور که گفتیم توی source code اپلیکیشن بکاند هستن همراه اونا روی سرور میان :)
- حالا بعد اوردن فایلها روی سرور ما تقریبا همچین شمایی از فایلهامون داریم که کامندها بعدی روی توی خود روت اصلی سرور باید اجرا کنیم.
- Server:
├── backend-source-code/
├── src
├── config
├── docker-compose-file
├── docker-file
├── front-source-code/
├── src
├── docker-file
├── docker-compose-file
├── .env file
- ما اول نیازه certificateهای ssl رو بگیریم و باید از letsencrypt(certbot) استفاده کنیم که یا باید روی خود سرور بالا بیاد یا از طریق داکر نصبش کنیم. پس اول میریم توی فایل کانفیگ nginx و بلاک اول و سوم server که توی فایل هست رو کامنت میکنیم و فقط میذاریم بلاک دوم داخلش باشه.
- میریم جایی که فایل docker-compose هست، این کامند رو اجرا میکنیم docker compose -f [file_name] up —build
- بعد این دوتا کامند رو روی سرور اجرا میکنیم تا مرحله certificate ها کامل بشه.
- docker-compose -f [file_name] run --rm certbot certonly --webroot --webroot-path /var/www/certbot/ --dry-run -d [domain-name]
- docker-compose -f [file_name] run --rm certbot certonly --webroot --webroot-path /var/www/certbot/ -d [domain-name]
- بعد اگر از دیوارههای دفاعی تحریم و فیلتر رد شدین و این اوکی شد ، فایل کانفیگ nginx رو دقیقا برعکس میکنیم یعنی بلاک اول و سوم رو از کامنت درمیاریم و بلاک دوم رو دوباره کامنت میکنیم و nginx رو restart میکنیم.
- نکته ای که باید بدونیم اینه که این certificate ها هر سه ماه منقضی میشن و باید مجدد تمدیدشون کنیم.
- حالا در واقع این سیستم چجوری داره کار میکنه؟ ما روی سیستممون داکر رو نصب کردیم. یک سری container داریم که از طریق یک نتوورک درونی و مطابق با پورتی که روی اون اجرا شدن باهم ارتباط میگیرن و تنها containerای که پورتش به دنیای بیرون سرور ما باز هستش nginx هست که به پورت 443 و 80 سرور وصل هست و هر درخواستی به سرور بیاد رو براساس کانفیگی که براش مشخص کردیم رو بهش جواب میده.
اینا مراحلی بود که الزاما من رفتم تا بتونم این کار رو انجام بدم و قطعا بهترین یا تنها راه نیست دیگه و اگرم میشد بهترش کرد بهم بگین.
لینک فایل های مورد نیاز:
https://drive.google.com/drive/folders/1XT6VYiU1QDh6ZxpSqNanVPAsOvFcnVWK?usp=sharing