مقدمه ای ملایم برای داکر

نوشتن نرم افزار سخت است …
برخی از قسمت ها سخت تر از سایر قسمت ها هستند – و برای من ، دشوارترین بخش در مورد توسعه ، تنظیم محیط برای هر نرم افزاری که با آن کار می کنم تنظیم شده است.
این که آیا آن را در حال نصب Manager Node Manager برای اطمینان از نسخه مناسب گره برای راه اندازی پروژه ای که از GitHub کشیده ام …
یا شروع یک پروژه جدید Ruby on Rails در یک دستگاه جدید …
برای من ، این چیزها همیشه سخت تر از نوشتن نرم افزار بوده است. و اگر تا به حال در مورد ایجاد محیط برای پروژه های خود به همان روش احساس کرده اید ، یادگیری Docker بهترین تصمیمی است که برای حرفه توسعه دهنده خود می گیرید.
اما داکر دقیقاً چه کاری انجام می دهد؟ در نگاه اول ، Docker فقط مانند ابزار دیگری برای یادگیری به نظر می رسد. اما هنگامی که شما می فهمید که Docker چه مشکلی را حل می کند – و نحوه استفاده از Docker برای حل این مشکلات – به عنوان یک توسعه دهنده احساس شکست ناپذیر می کنید.
مشکل بزرگ موی هر توسعه دهنده با آن روبرو است
هنگام نشان دادن نحوه استفاده از Docker ، من قصد دارم از Ruby on Code استفاده کنم. من 10 سال از روبی استفاده کرده ام و این اولین عشق من بود ، بنابراین این چیزی است که من در اینجا می خواهم از آن استفاده کنم. اما مفاهیم در همه زبانها کار می کنند.
بیایید بگوییم که من یک پروژه در روبی نوشته شده است که به نسخه روبی 3.1.0 نیاز دارد. اما سیستم من از Ruby 3.34 استفاده می کند – من می خواهم مشکلی داشته باشم.
مطمئناً ، من فقط می توانم از یک مدیر نسخه روبی برای نصب نسخه صحیح استفاده کنم. اما این بدان معناست که اگر می خواهم این پروژه را بر روی دستگاه دیگری اجرا کنم ، باید نسخه صحیح روبی را روی آن دستگاه نصب کنم. و ، این مثال ساده فقط به روبی نیاز دارد ، اما در مورد پروژه های بزرگتر که خیلی بیشتر از یک نسخه خاص از روبی نیاز دارند؟
بنابراین من یک برنامه کوچک سلام جهانی دارم که به نظر می رسد:
if RUBY_VERSION != '3.1.0'
abort("This app requires Ruby 3.1.0. Please use the correct Ruby version.")
end
puts "Hello world"
اگر سعی کنم این اسکریپت را اجرا کنم و نسخه روبی مورد نیاز را ندارم ، پیامی مانند این دریافت می کنم:
این برنامه به Ruby 3.1.0 نیاز دارد. لطفا از نسخه صحیح روبی استفاده کنید.
باز هم ، این یک مثال ساده است ، اما تصور کنید که تیمی از 20 توسعه دهنده و وابستگی های بسیار بیشتری داشته باشید – این به یک درد بزرگ در باسن تبدیل می شود.
آیا اگر بتوانید برخی از نرم افزارها را با افراد دیگر که فقط کار می کنند ، بهتر باشد – و برای سایر توسعه دهندگان بهتر نیست؟ این دقیقاً همان کاری است که داکر برای شما انجام می دهد.
داکر دقیقاً چه کاری انجام می دهد؟
به طور معمول وقتی کار خود را از یک توسعه دهنده دیگر شروع می کنید ، باید تمام وابستگی ها را برای خودتان پیدا کرده و نصب کنید. با Docker ، به جای ارسال مقداری کد به یک Dev دیگر و گفتن “در اینجا می روید ، بقیه را می فهمید” ، همه چیزهایی را که لازم دارند به صورت یک طرفه بسته بندی می کنید تا بتوانند بلافاصله درخواست شما را مالش دهند.
در مثال ساده ما ، نسخه Ruby 3.1.0 و کد را بسته بندی می کنیم و قبل از به اشتراک گذاشتن برنامه ، آن را در یک جعبه قرار می دهیم.
Docker چگونه کار می کند؟
دو اصطلاح بسیار مهم برای درک هنگام استفاده از Docker وجود دارد: تصاویر و ظروف.
وقتی تمام وابستگی ها و کد برنامه را بسته بندی می کنید ، یک تصویر ایجاد می کنید.
سپس ، شما یکی از این تصاویر را می گیرید و آن را درون یک ظرف اجرا می کنید.
یک ظرف فقط نمونه ای از یک تصویر است. شما حتی می توانید به آن فکر کنید که شبیه به کلاس ها و نمونه ها است.
شما یک کلاس (یک تصویر) ایجاد می کنید و سپس می توانید از آن کلاس به عنوان یک طرح استفاده کنید تا موارد زیادی را که می خواهید (کانتینر) داشته باشید.
واقعاً برای یک ثانیه در مورد آن فکر کنید … شما می توانید یک تصویر ایجاد کنید و آن را بر روی چندین سرور مستقر کنید بدون اینکه نیاز به نگرانی در مورد تنظیم هر سرور با نسخه صحیح روبی (و تنظیم تمام وابستگی های دیگر داشته باشید.
چگونه می توان تصاویر Docker خود را ساخت
بنابراین ، تصاویر بسیار عالی به نظر می رسند ، اما یک مسئله وجود دارد: از آنجا که تصاویر حاوی همه چیز یک برنامه برای اجرای آن هستند ، شما باید پرونده های بیشتری را ارسال کنید – که نیاز به ذخیره سازی بیشتر از ارسال کد برای یک پروژه دارد.
برای حل این مشکل ، ما از چیزی به نام Dockerfile استفاده می کنیم. به جای ارسال تصویری از برنامه خود به یک توسعه دهنده دیگر ، شما یک Dockerfile را برای آنها ارسال می کنید که دستورالعمل نحوه تنظیم محیط را دارد.
این در اصل مانند ارسال دستور العمل برای یک Dev دیگر است تا خود را به جای ارسال تصویر کامل ، خود را بسازید.
بیایید نگاهی بیندازیم که Dockerfile ما برای پروژه مثال ما به نظر می رسد:
FROM ruby:3.1.0
WORKDIR /app
COPY . .
CMD ["ruby", "app/script.rb"]
برای سازمان بهتر ، پرونده script.rb خود را در دایرکتوری به نام برنامه قرار دادم.
خارج از فهرست برنامه – در فهرست اصلی پروژه ما – ما این Dockerfile را داریم. به هر حال ، Dockerfile هیچ تمدیدی ندارد.
بنابراین در این پرونده چه خبر است؟
در بالا ، جایی است که جادو است:
FROM ruby:3.1.0
در اینجا ، ما می گوییم ، اولین کاری که قبل از اجرای این برنامه باید انجام دهید نصب Ruby 3.1.0 است.
بعد ، با:
WORKDIR /app
ما می گوییم که می خواهیم هنگام مراجعه به مسیرهای خود از فهرست برنامه به عنوان فهرست اصلی استفاده کنیم.
با:
COPY . .
ما می خواهیم همه چیز را از فهرست فعلی کپی کنیم – دایرکتوری برنامه ای که فقط تنظیم کرده ایم – و آن را در ریشه تصویر Docker خود کپی کنید.
سپس بالاخره ما داریم:
CMD ["ruby", "app/script".rb]
این به سادگی شروع برنامه ما است. اگر برنامه شما پیچیده تر است ، ممکن است به دستورات پیچیده تری نیاز داشته باشد.
اکنون که این پرونده را داریم ، در واقع برای ساخت تصویر باید از Docker استفاده کنیم.
می توانید دستورالعمل های گام به گام برای نصب Docker را در اینجا پیدا کنید.
در خط فرمان این دستور را اجرا می کنیم:
docker build . -t ruby-test
بیایید سریع آن را خراب کنیم …
Docker – به خط فرمان برای استفاده از Docker می گوید
ساخت – فرمان ما می خواهیم انجام دهیم. در این حالت ، ما می خواهیم تصویری از dockerfile خود بسازیم
بشر – در اینجا ، ما به Docker می گوییم که Dockerfile ما کجاست. اگر Dockerfile شما در فهرست فعلی نیست ، باید مسیر آنجا را تغییر دهید.
-t – این گزینه برای “برچسب” است که به این معنی است که می خواهیم تصویر خود را با یک نام برچسب گذاری کنیم. و سرانجام …
Ruby -Test – برچسب (نام) که به تصویر می دهیم.
پس از اجرای آن دستور ، ما یک دسته از مواد را در کنسول مانند SA مشاهده می کنیم:
اگر از نزدیک نگاه کنید ، این دستورالعمل های موجود در Dockerfile را دنبال می کند. و هنگامی که آن دستور را اجرا کردید ، ممکن است متوجه چیزی شوید …
هیچ چیز در فهرست پروژه شما تغییر نکرده است!
دلیل این امر این است که وقتی شما یک تصویر Docker می سازید ، تصویر در یک مکان خاص ذخیره می شود که در آن همه تصاویر Docker ذخیره می شوند.
سرانجام ، پس از ساخت تصویر ، می توانید یک ظرف جدید را با استفاده از Docker راه اندازی کنید. بعداً این را در یک آموزش دیگر پوشش خواهم داد تا این آموزش از طولانی بودن یک میلیون کلمه جلوگیری کند
اما یک ثانیه صبر کنید …
نکته اصلی Docker این است که هنگام به اشتراک گذاشتن کد خود ، اطمینان حاصل کنید که تمام وابستگی هایی را که پروژه برای اجرای آن نیاز دارد ، درج می کنید.
اما هنگامی که ما به جای یک تصویر یک dockerfile را به اشتراک می گذاریم ، Dockerfile باید بیرون برود و تمام وابستگی ها را بدست آورد. آیا این نوع شکست هدف نیست؟
قسمت آخر پازل DockerHub است.
Docker Hub میزبان یک تن از پرونده های مختلف است – از جمله Ruby: 3.1.0. هنگامی که Dockerfile خود را با استفاده از دستور ساخت اجرا می کنید ، Docker برای دریافت پرونده های مورد نیاز به DockerHub می رود.
این بدان معناست که هرکسی که این Dockerfile را اجرا می کند ، تمام وابستگی های لازم را از همان مکان دریافت می کند – اطمینان حاصل کنید که نه تنها تمام وابستگی هایی را که پروژه شما باید اجرا کند ، بلکه تمام نسخه های همه وابستگی ها از نسخه های دقیقاً یکسان استفاده می کنند دقیقاً همان مکان
و این آخرین قسمت است که همه چیز را با هم جمع می کند.
بیایید دوباره
ما یک dockerfile می نویسیم که شامل دستور العمل تمام وابستگی هایی است که برنامه ما نیاز دارد.
هنگامی که ما با استفاده از Dockerfile تصویری می سازیم – صرف نظر از اینکه دستگاه آن روشن است – ما از تمام نسخه های دقیق یکسان از همه وابستگی ها از همان منبع استفاده می کنیم.
ما می توانیم آن تصویر را بگیریم و آن را در چندین ظروف اجرا کنیم – اساساً از تصویر (کلاس) خود استفاده می کنیم و چندین ظروف (به عنوان مثال) ایجاد می کنیم.
این امر باعث می شود هر کجا که نرم افزار خود را اجرا کنیم ، همه چیز مورد نیاز خود را داریم.
تبریک می گویم ، شما (امیدوارم) بزرگترین مشکل در مهندسی نرم افزار را حل کرده اید.