جستجو

Docker چیست و چرا در توسعه نرم‌افزار از آن استفاده می‌کنیم؟

29 مهر 1405

احتمالاً این جمله معروف را در تیم‌های توسعه نرم‌افزار شنیده‌اید:

«روی سیستم من که درست کار می‌کنه!»

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

نسخه PHP متفاوت است، کتابخانه‌ای نصب نشده، تنظیمات محیط با سیستم توسعه فرق دارد یا سرویس به پیش‌نیازهایی وابسته است که روی سرور وجود ندارند.

اگر بتوانیم برنامه را همراه با وابستگی‌های موردنیازش در یک محیط استاندارد بسته‌بندی کنیم، چه اتفاقی می‌افتد؟

اینجاست که Docker وارد می‌شود.

Docker چیست؟

داکر (Docker) یک پلتفرم متن‌باز برای ساخت، بسته‌بندی، توزیع و اجرای نرم‌افزار در محیط‌هایی به نام Container است.

Container یا کانتینر، محیطی نسبتاً ایزوله است که برنامه و وابستگی‌های موردنیاز آن را در خود اجرا می‌کند.

برای مثال، یک برنامه PHP ممکن است به موارد زیر نیاز داشته باشد:

  • نسخه مشخصی از PHP
  • افزونه‌های موردنیاز PHP
  • کتابخانه‌های سیستمی
  • فایل‌های برنامه
  • تنظیمات مربوط به اجرای برنامه

با Docker می‌توان این اجزا را در قالب یک Image آماده کرد و از آن برای اجرای کانتینرهای برنامه در محیط‌های مختلف استفاده کرد.

در نتیجه، به‌جای نصب و تنظیم دستی تمام پیش‌نیازها روی هر سرور، بخش مهمی از محیط اجرای نرم‌افزار به‌صورت یک بسته استاندارد مدیریت می‌شود.

البته Docker تمام تفاوت‌های محیطی را از بین نمی‌برد؛ تنظیمات خارجی، شبکه، معماری پردازنده و سیستم‌عامل میزبان همچنان اهمیت دارند.

Image و Container چه تفاوتی دارند؟

برای درک Docker ابتدا باید با دو مفهوم اصلی آن آشنا شویم.

Docker Image؛ بسته آماده نرم‌افزار

Image یک الگوی آماده و عمدتاً فقط‌خواندنی است که فایل‌ها، کتابخانه‌ها، وابستگی‌ها و تنظیمات لازم برای اجرای برنامه را در خود دارد.

برای مثال، یک Image می‌تواند شامل Nginx و فایل‌های لازم برای اجرای آن باشد.

Image به‌تنهایی یک برنامه در حال اجرا نیست.

Docker Container؛ نمونه اجرایی Image

وقتی از یک Image نمونه‌ای برای اجرا ایجاد می‌کنیم، یک Container ساخته می‌شود.

به زبان ساده:

Image نقشه و بسته آماده است؛ Container نمونه‌ای است که از روی آن ساخته و اجرا می‌شود.

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

این ویژگی کمک می‌کند یک نسخه مشخص از نرم‌افزار را بارها اجرا کنیم، بدون اینکه لازم باشد در هر نوبت تمام پیش‌نیازهای آن را دوباره نصب کنیم.

Docker چگونه کار می‌کند؟

در یک معماری ساده، سه بخش اصلی وجود دارد:

Docker Client: ابزاری که دستورات Docker را از طریق آن اجرا می‌کنیم؛ مانند docker run.

Docker Engine: موتور مدیریت کانتینرها که درخواست‌ها را دریافت می‌کند و عملیات ساخت، اجرا و مدیریت را انجام می‌دهد.

Docker Registry: مخزنی برای ذخیره و توزیع Imageها، مانند Docker Hub یا رجیستری خصوصی سازمان.

روند معمول به این صورت است:

  1. توسعه‌دهنده یک Image آماده می‌کند یا از یک Registry دریافت می‌کند.
  2. Docker Engine از روی Image یک Container می‌سازد.
  3. برنامه در محیط کانتینر اجرا می‌شود.
  4. همان Image می‌تواند برای ایجاد کانتینرهای دیگر استفاده شود.

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

Docker چه تفاوتی با ماشین مجازی دارد؟

در نگاه اول، Docker و ماشین مجازی (Virtual Machine) شبیه به هم هستند؛ چون هر دو امکان اجرای محیط‌های جداگانه را فراهم می‌کنند.

اما تفاوت مهمی در معماری آن‌ها وجود دارد.

در ماشین مجازی، هر VM معمولاً سیستم‌عامل مهمان و Kernel مخصوص خودش را دارد.

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

ویژگی ماشین مجازی کانتینر
سیستم‌عامل دارای سیستم‌عامل مهمان اشتراک Kernel میزبان
مصرف منابع معمولاً بیشتر معمولاً کمتر
زمان راه‌اندازی معمولاً طولانی‌تر معمولاً کوتاه‌تر
جداسازی مرز ایزوله‌سازی قوی‌تر در بسیاری از سناریوها وابسته به Kernel و تنظیمات امنیتی
کاربرد اجرای سیستم‌عامل‌های مستقل بسته‌بندی و اجرای برنامه‌ها

نکته مهم این است که Docker جایگزین تمام کاربردهای Virtualization نیست.

حتی می‌توان ابتدا روی VMware ESXi یک ماشین مجازی لینوکسی ایجاد کرد و سپس Docker را داخل آن اجرا کرد.

همچنین Docker Desktop برای اجرای کانتینرهای لینوکسی روی Windows و macOS از یک محیط لینوکسی مجازی استفاده می‌کند.

بنابراین ماشین مجازی و Container می‌توانند در کنار هم استفاده شوند.

اولین کانتینر خود را اجرا کنیم

برای آشنایی عملی با Docker، یک وب‌سایت نمونه را داخل کانتینر اجرا می‌کنیم.

پیش‌نیاز: Docker Engine یا Docker Desktop نصب و در حال اجرا باشد. این مثال برای محیطی با قابلیت اجرای کانتینر لینوکسی است. همچنین باید Image موردنظر روی سیستم موجود باشد یا امکان دریافت آن از Registry وجود داشته باشد.

ابتدا ارتباط با Docker Engine را بررسی کنید:

docker info

حالا دستور زیر را اجرا کنید:

docker run -d \
  --name docker-intro-demo \
  --rm \
  -p 127.0.0.1:8080:80 \
  docker/welcome-to-docker

این دستور چه کاری انجام می‌دهد؟

  • docker run: یک کانتینر از روی Image ایجاد و اجرا می‌کند.
  • -d: کانتینر را در پس‌زمینه اجرا می‌کند.
  • --name: نام مشخصی به کانتینر اختصاص می‌دهد.
  • --rm: پس از توقف کانتینر، آن را خودکار حذف می‌کند.
  • -p: پورت 8080 سیستم میزبان را به پورت 80 کانتینر متصل می‌کند.
  • docker/welcome-to-docker: نام Image نمونه است.

برای مشاهده کانتینر در حال اجرا:

docker ps

سپس در مرورگر همان سیستم آدرس زیر را باز کنید:

http://localhost:8080

در صورت اجرای موفق، صفحه نمونه Docker نمایش داده می‌شود.

برای توقف کانتینر:

docker stop docker-intro-demo

تمام شد! شما یک وب‌سایت نمونه را بدون نصب مستقیم وب‌سرور آن روی سیستم میزبان اجرا کرده‌اید.

این مثال برای آموزش است و اجرای آن در محیط آزمایشگاهی پیشنهاد می‌شود. دستورات این مقاله بر اساس مستندات رسمی Docker نوشته شده‌اند و اجرای عملی آن‌ها در محیط پروژه ادعا نمی‌شود.

Docker در یک پروژه واقعی چه کاربردی دارد؟

فرض کنید یک سامانه سازمانی شامل سه بخش است:

  • Frontend با React
  • Backend با Laravel
  • Database با PostgreSQL

در روش سنتی، راه‌اندازی محیط توسعه ممکن است نیازمند نصب دستی نسخه‌های مشخصی از ابزارها و سرویس‌های مختلف باشد.

با Docker می‌توان هر بخش را در کانتینر جداگانه‌ای اجرا کرد.

در این حالت، توسعه‌دهنده می‌تواند با استفاده از Imageهای مشخص و تنظیمات استاندارد، محیطی نزدیک‌تر به سایر اعضای تیم ایجاد کند.

ابزاری به نام Docker Compose نیز امکان تعریف و مدیریت چند سرویس مرتبط را در یک فایل YAML فراهم می‌کند.

البته برای داده‌های پایدار پایگاه داده باید از سازوکارهای ذخیره‌سازی مناسب، مانند Volume، استفاده کرد. اطلاعات مهم نباید صرفاً به لایه قابل‌نوشتن کانتینر وابسته باشند.

این مباحث را در مقاله‌های بعدی با مثال‌های عملی بررسی خواهیم کرد.

آیا Docker تمام مشکلات استقرار را حل می‌کند؟

خیر. Docker یک ابزار قدرتمند است، اما استفاده از آن به‌تنهایی تضمین‌کننده امنیت، پایداری یا عملکرد صحیح نرم‌افزار نیست.

برای نمونه:

  • اگر برنامه باگ داشته باشد، همان باگ داخل Container نیز وجود خواهد داشت.
  • تنظیمات نادرست شبکه می‌توانند ارتباط سرویس‌ها را مختل کنند.
  • استفاده از Imageهای آسیب‌پذیر می‌تواند امنیت برنامه را به خطر بیندازد.
  • نگهداری اطلاعات مهم بدون ذخیره‌سازی پایدار می‌تواند باعث از دست رفتن داده شود.

بنابراین Docker استانداردسازی و مدیریت محیط اجرای برنامه را ساده‌تر می‌کند، اما جایگزین طراحی صحیح نرم‌افزار و مدیریت اصولی زیرساخت نیست.

جمع‌بندی

Docker یکی از ابزارهای مهم در توسعه و استقرار نرم‌افزار است که امکان بسته‌بندی برنامه و وابستگی‌های آن را در قالب Image فراهم می‌کند.

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

اگر تازه با Docker آشنا شده‌اید، اولین قدم این است که تفاوت Image و Container را درک کنید و اجرای یک کانتینر ساده را تجربه کنید.

در ادامه این مسیر آموزشی، به‌صورت عملی نحوه ساخت Docker Image با Dockerfile و مدیریت سرویس‌ها با Docker Compose را بررسی خواهیم کرد.

منابع رسمی

منابع اصلی که برای بررسی مفاهیم و دستورات مقاله استفاده شدند:

  1. Docker Docs — What is Docker? — معماری Docker، مفهوم Image و Container و کاربردهای آن.

  2. Docker Docs — What is a Container? — تعریف کانتینر، مقایسه با ماشین مجازی و اجرای اولین کانتینر.

  3. Docker Docs — What is an Image? — مفهوم Image، لایه‌ها و تفاوت آن با Container.

  4. Docker Docs — What is a Registry? — نحوه نگهداری و توزیع Imageها.

دیدگاه‌ خود را بنویسید

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