داکر (Docker) به شما کمک می کند تا به سرعت یک محیط توسعه را روی دستگاه خود راه اندازی کنید. تنها چند دقیقه طول می کشد تا کل فرآیند را طی کنید. اما بیایید فرض کنیم برای اجرای پروژه شما به حداقل 10 سرویس مختلف در حالت در حال اجرا نیاز دارد. برای مثال، فرض کنید پروژه شما به PHP، Node 23، MySQL، MongoDB، Go، RabbitMQ و غیره نیاز دارد.
در چنین شرایطی، شما باید همه آن ایمیج ها را به صورت جداگانه از داکر دانلود کنید و همه آنها را در کانتینرهای خود راه اندازی کنید. در برخی موارد، یک فرآیند ممکن است به اجرای دیگری بستگی داشته باشد. بنابراین، شما باید آنها را سفارش دهید. اگر این یک فرآیند یکباره باشد خوب است. اما، نه فقط یک بار، هر روز، هر بار که کار روی پروژه خود را شروع می کنید، باید همه این سرویس را شروع کنید. این یک روند خسته کننده است درست است؟
برای غلبه بر این موضوع، داکر مفهومی به نام Multi Containers (Docker Compose) را معرفی کرد. در این مقاله، ما اصول اولیه چیستی Compose و نحوه استفاده از آن را به اشتراک خواهیم گذاشت. بیایید شروع کنیم!
امنیت در داکر: آشنایی با 14 تا از بهترین روش ها
آشنایی با لاراول و داکر با لاراول Sail
Docker Compose چیست؟
Docker Compose ابزاری است که تعریف و مدیریت برنامههای Docker چند کانتینری را آسانتر میکند. اجرای سرویس های به هم پیوسته مانند frontend، backend API و پایگاه داده را با اجازه دادن به آنها برای راه اندازی و کنترل با هم ساده می کند.
با استفاده از یک فایل پیکربندی YAML (معمولا docker-compose.yml)، می توانید هر سرویس و وابستگی های آن را به عنوان کد توصیف کنید. این راهاندازی میتواند به مخزن منبع شما برای استقرار مداوم متعهد شود. پس از تعریف، همه سرویس ها را می توان با یک دستور docker-compose شروع کرد که هماهنگی محیط های توسعه یا تست را آسان تر می کند.
در مقایسه با راهاندازی دستی و لینک کردن کانتینرها، Compose سریعتر، آسانتر و تکرارپذیرتر است. کانتینرهای شما هر بار با پیکربندی یکسانی اجرا میشوند، هیچ خطری وجود ندارد که یک فلگ مهم اجرای docker را فراموش کنید.
Compose به طور خودکار یک شبکه Docker برای پروژه شما ایجاد می کند و اطمینان حاصل می کند که کانتینرهای شما می توانند با یکدیگر ارتباط برقرار کنند. همچنین Docker storage volumes شما را مدیریت میکند و پس از راهاندازی مجدد یا جایگزینی سرویس، بهطور خودکار آنها را دوباره وصل میکند.
چرا از Docker Compose استفاده کنیم؟
بیشتر برنامههای کاربردی دنیای واقعی چندین سرویس با dependency relationships دارند، به عنوان مثال، برنامه شما ممکن است در یک کانتینر اجرا شود، اما وابسته به یک سرور پایگاه داده است که در مجاورت یک کانتینر دیگر مستقر شده است. علاوه بر این، سرویسها معمولاً باید با حجمهای ذخیرهسازی، متغیرهای محیطی، اتصالات پورت و سایر تنظیمات پیکربندی شوند.
با استفاده از docker-compose up، میتوانید کل استک را با یک فرمان بچرخانید و از ثبات در محیطها اطمینان حاصل کنید. به عنوان مثال، یک برنامه وب با بک اند، دیتابیس و کش Redis را می توان بدون پیکربندی جداگانه برای هر کانتینر با هم راه اندازی کرد.
استفاده از Compose برای بالا آوردن استک، هر کانتینر را با استفاده از مقادیر پیکربندی که در فایل خود تنظیم کرده اید، شروع می کند. این ارگونومی توسعه را بهبود میبخشد، از استفاده مجدد استک در محیطهای مختلف پشتیبانی میکند و به جلوگیری از پیکربندی اشتباه تصادفی کمک میکند.
آیا Docker Compose هنوز کاربردی است؟
Docker Compose همچنان کاربردی است زیرا ابزاری ساده و مؤثر برای تعریف و اجرای برنامههای چند کانتینری در محیطهای محلی یا توسعه است. در حالی که ابزارهایی مانند Kubernetes ویژگیهای ارکستراسیون پیشرفتهتری را برای محیطهای تولید ارائه میدهند، Docker Compose یک ابزار ارزشمند برای توسعه محلی، آزمایش و استقرار سادهتر، بهویژه برای برنامهها یا تیمهای کوچکتر است.
تفاوت بین Docker و Docker Compose چیست؟
Docker پلتفرمی است که برای ساخت، اجرا و مدیریت کانتینرها استفاده می شود که برنامه ها را با وابستگی های آنها بسته بندی می کند. از سوی دیگر، Docker Compose ابزاری است که تعریف و مدیریت برنامه های کاربردی چند کانتینری را با استفاده از فایل docker-compose.yml ساده می کند.
در حالی که Docker کانتینرهای جداگانه را کنترل می کند، Docker Compose برای پیکربندی و اجرای چندین کانتینر به عنوان یک استک سرویس استفاده می شود. به عنوان مثال، یک برنامه وب با یک فرانت اند، بک اند و پایگاه داده را می توان با استفاده از Docker Compose راه اندازی کرد.
می توانید از Docker بدون Compose استفاده کنید. با این حال، استفاده از Compose هنگامی که در حال توسعه یک سیستم کانتینری هستید به شما این امکان را می دهد که برنامه خود را در هر محیطی با یک فرمان واحد مستقر کنید. در حالی که Docker CLI هر بار فقط با یک کانتینر تعامل دارد، Compose با پروژه شما ادغام می شود و از روابط بین کانتینرهای شما آگاه است.
مزایای Docker Compose
در زیر برخی از مزایای استفاده از Docker Compose آورده شده است:
- پیکربندی سریع و آسان با اسکریپت های YAML
استقرار Single host
افزایش بهره وری
امنیت با کانتینر های ایزوله
آموزش: استفاده از Docker Compose
بیایید ببینیم چگونه می توان از Compose در برنامه خود استفاده کرد. ما یک برنامه ساده Node.js ایجاد خواهیم کرد که نیاز به اتصال به سرور Redis دارد که در کانتینر دیگری اجرا می شود.
1. بررسی کنید که آیا Docker Compose نصب شده است یا خیر
از لحاظ کلی، Docker Compose به عنوان یک باینری مستقل به نام docker-compose، به طور جداگانه در Docker Engine توزیع شده است. از زمان راهاندازی Compose v2، این دستور اکنون در docker CLI به عنوان docker compose شده است Compose v1 دیگر پشتیبانی نمی شود.
اگر از نسخه مدرن Docker Desktop یا Docker Engine استفاده می کنید، باید قبلاً Docker Compose v2 را در دسترس داشته باشید. می توانید با اجرای دستور docker compose version بررسی کنید:
1$ docker compose version 2Docker Compose version v2.35.1
2. برنامه خود را ایجاد کنید
این آموزش را با کپی کردن کد زیر و ذخیره آن در app.js در پوشه ای شروع کنید:
1const express = require("express"); 2const {createClient: createRedisClient} = require("redis"); 3 4(async function () { 5 6 const app = express(); 7 8 const redisClient = createRedisClient({ 9 url: `redis://redis:6379` 10 }); 11 12 await redisClient.connect(); 13 14 app.get("/", async (request, response) => { 15 const counterValue = await redisClient.get("counter"); 16 const newCounterValue = ((parseInt(counterValue) || 0) + 1); 17 await redisClient.set("counter", newCounterValue); 18 response.send(`Page loads: ${newCounterValue}`); 19 }); 20 21 app.listen(80); 22 23})();
این کد از پکیج وب سرور Express برای ایجاد یک برنامه کاربردی ساده استفاده می کند. هر بار که از برنامه بازدید می کنید، بازدید شما را در Redis ثبت می کند، سپس تعداد کل صفحات بارگذاری شده را نمایش می دهد.
از npm برای نصب وابستگی های برنامه استفاده کنید:
1npm install express redis
سپس، محتوای Dockerfile زیر را در Dockerfile در ریشه پروژه خود کپی کنید:
1FROM node:23-alpine 2 3EXPOSE 80 4WORKDIR /app 5 6COPY package.json . 7COPY package-lock.json . 8RUN npm install 9 10COPY app.js . 11 12ENTRYPOINT ["node", "app.js"]
Compose بعداً این Dockerfile را میسازد تا ایمیج Docker را برای برنامه شما ایجاد کند.
3. یک فایل Docker Compose ایجاد کنید
اکنون، شما آماده هستید تا Compose را به پروژه خود اضافه کنید. این برنامه یک کاندید عالی برای Compose است زیرا برای اجرای موفقیت آمیز برنامه به دو کانتینر نیاز دارید:
- کانتینر 1 - برنامه سرور
Node.jsکه ایجاد کرده اید.
کانتینر 2 – یک نمونه Redis برای برنامه Node.js شما برای اتصال به آن.
ایجاد یک فایل docker-compose.yml اولین قدم در استفاده از Compose است. محتوای زیر را کپی کنید و آن را در docker-compose.yml خود ذخیره کنید، نگران نباشید، در زیر توضیح خواهیم داد:
1services: 2 app: 3 image: app:latest 4 build: 5 context: . 6 ports: 7 - ${APP_PORT:-80}:80 8 redis: 9 image: redis:7
بیایید به آنچه در اینجا می گذرد نگاهی بزنیم.
فیلد services سطح بالا، جایی است که شما کانتینرهای مورد نیاز برنامه خود را تعریف می کنید.
دو سرویس برای این برنامه مشخص شده است: app (برنامه Node.js شما) و redis (سرور Redis شما).
هر سرویس دارای یک فیلد image است که ایمیج داکری را که کانتینر اجرا می شود، تعریف می کند. در مورد سرویس app، این برنامه سفارشی: app:latest ایمیج است. از آنجایی که ممکن است هنوز وجود نداشته باشد، فیلد build طوری تنظیم شده است که به Compose بگوید می تواند ایمیج را با استفاده از دایرکتوری روت پروژه (.) به عنوان build context بسازد. سرویس redis ساده تر است، زیرا فقط باید به ایمیج رسمی Redis در Docker Hub اشاره کند.
سرویس app دارای یک فیلد پورت است که اتصالات پورت را برای اعمال به کانتینر، مشابه فلگ p- اجرای docker اعلام میکند. یک interpolated variable استفاده می شود. این به این معنی است که شماره پورت داده شده توسط متغیر محیطی APP_PORT شما با تنظیم شدن، همراه با پورت پیشفرض 80 ارائه میشود.
از این توضیحات، می توانید ببینید که فایل Compose شامل تمام تنظیمات مورد نیاز برای راه اندازی یک استقرار کاربردی برنامه است.
4. کانتینرخود را بالا بیاورید
اکنون می توانید از Compose برای بالا آوردن استک استفاده کنید!
برای شروع همه سرویسها در فایل docker-compose.yml خود، docker compose up را بنویسید. همانطور که هنگام فراخوانی docker run، باید آرگومان d- را اضافه کنید تا ترمینال خود را جدا کنید و سرویس ها را در پس زمینه اجرا کنید:
1$ docker compose up -d 2[+] Building 0.5s (11/11) FINISHED 3... 4[+] Running 3/3 5 ✔ Network node-redis_default Created 0.1s 6 ✔ Container node-redis-redis-1 Started 0.7s 7 ✔ Container node-redis-app-1 Started 0.6s
از آنجایی که ایمیج برنامه شما هنوز وجود ندارد، Compose ابتدا آن را از Dockerfile شما میسازد. سپس با ایجاد یک شبکه Docker و راه اندازی کانتینرهای شما، استک شما را اجرا می کند.
از localhost در مرورگر خود دیدن کنید تا برنامه خود را در حال اجرا ببینید.
در فایل app.js URL کلاینت Redis را روی redis:6379 قرار دادیم. نام میزبان redis با نام سرویس redis در docker-compose.yml مطابقت دارد.
Compose از نام سرویسهای شما برای اختصاص hostname کانتینر شما استفاده میکند. از آنجا که کانتینرها بخشی از همان شبکه Docker هستند، کانتینر برنامه شما می تواند هاست نیم redis را به نمونه Redis شما ارتباط برقرار کند.
جاوااسکریپت چگونه کار می کند؟ آشنایی با Event Loop و بررسی دقیق آن
5. دستورات Docker Compose را مدیریت کنید
اکنون که برنامه خود را راه اندازی کرده اید، می توانید از سایر دستورات Docker Compose برای مدیریت استک خود استفاده کنید:
docker compose ps
با اجرای دستور ps می توانید کانتینرهایی را که Compose ایجاد کرده است ببینید. خروجی تولید شده توسط docker ps:
1$ docker compose ps 2NAME IMAGE COMMAND SERVICE 3 CREATED STATUS PORTS 4node-redis-app-1 app:latest "node app.js" app 5 12 minutes ago Up 12 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp 6node-redis-redis-1 redis:7 "docker-entrypoint.s…" redis 7 12 minutes ago Up 12 minutes 6379/tcp
docker compose stop
این دستور تمام کانتینرهای Docker ایجاد شده توسط استک را متوقف می کند. از docker compose start استفاده کنید تا بعد از آن دوباره آنها را راه اندازی کنید.
docker compose restart
فرمان راهاندازی مجدد، کانتینرهای استک شما را مجدداً راهاندازی مجدد میکند.
docker compose down
از این دستور برای حذف اشیاء ایجاد شده توسط docker compose up استفاده کنید. این کانتینرها و شبکه های استک شما را از بین می برد.
ولوم ها حذف نمی شوند مگر اینکه فلگ v- یا volumes-- را تنظیم کنید. این در از دست رفتن تصادفی داده های پایدار جلوگیری می کند.
docker compose logs
خروجی کانتینرهای استک خود را با دستور logs مشاهده کنید. این خروجی استاندارد و جریان های خطا را از همه کانتینرهای استک جمع می کند. هر خط لاگ با نام کانتینری که آن را ایجاد کرده است برچسب گذاری می شود.
بیشتر بدانید: بهترین جایگزین ها Postman کدام است؟
docker compose build
می توانید با دستور build ایمیج خود را مجبور به بازسازی کنید. با این کار، ایمیج مربوط به سرویسهای موجود در فایل docker-compose.yml شما که فیلد build را در پیکربندی خود دارند، بازسازی میکند.
پس از آن، می توانید دستور docker compose up را برای راه اندازی مجدد استک خود با ایمیج بازسازی شده تکرار کنید.
docker compose push
پس از ساختن ایمیج خود، از push استفاده کنید تا همه آنها را به URL های رجیستری ریموت خود هدایت کنید. به طور مشابه، Docker compose pull ایمیج مورد نیاز استک شما را بدون شروع هیچ کانتینری بازیابی می کند.
6. از Compose Profiles استفاده کنید
گاهی اوقات، یک سرویس در استک شما ممکن است اختیاری باشد. به عنوان مثال، می توانید برنامه آزمایشی را برای پشتیبانی از موتورهای پایگاه داده جایگزین به جای Redis گسترش دهید. هنگامی که از موتور دیگری استفاده می شود، به کانتینر Redis نیاز ندارید.
با استفاده از ویژگی Compose's profiles می توانید این الزامات را برآورده کنید. تخصیص سرویسها به پروفایل ها به شما امکان میدهد هنگام اجرای دستورات Compose، آنها را به صورت دستی فعال کنید:
1services: 2 app: 3 image: app:latest 4 build: 5 context: . 6 ports: 7 - ${APP_PORT:-80}:80 8 redis: 9 image: redis:6 10 profiles: 11 - with-redis
این فایل docker-compose.yml سرویس redis را به profile ای به نام with-redis اختصاص می دهد. اکنون کانتینر Redis تنها زمانی در نظر گرفته می شود که فلگ profile with-redis-- را با دستورات نوشتن docker خود اضافه کنید:
1# Does not start Redis 2$ docker compose up -d 3 4# Will start Redis 5$ docker compose --profile with-redis up -d
دیتابیس NoSQL چیست؟ بررسی دقیق
10 تا از دیزاین پترن های میکروسرویس برای معماری بهتر
7. پروژه های Docker Compose را بشناسید
پروژه ها یک مفهوم مهم در Docker Compose v2 هستند. "project" شما فایل docker-compose.yml و منابعی است که ایجاد می کند.
Compose به طور پیش فرض از فایل docker-compose.yml پوشه روت پروژه شما استفاده می کند. فرض میکند که نام پروژه شما با نام دایرکتوری روت پروژه شما برابر است. این نام پیشوند اشیاء Docker را که Compose ایجاد میکند، مانند کانتینرها و شبکههای شما قرار میدهد. میتوانید با تنظیم فلگ Compose's --project-name یا با اضافه کردن یک فیلد name سطح بالا در فایل docker-compose.yml، نام پروژه را بازنویسی کنید:
1name: "demo-app" 2services: 3 ...
با تنظیم فلگ profile-directory-- می توانید دستورات Docker Compose را از خارج از دایرکتوری روت پروژه خود اجرا کنید:
1$ docker compose --profile-directory=/path/to/directory ps
فلگ directory به فایل docker-compose.yml یا دایرکتوری حاوی یکی را میپذیرد.
8. متغیرهای محیطی Docker Compose را تنظیم کنید
یکی از مزایای Docker Compose سهولت در تنظیم متغیرهای محیطی برای سرویس خود است.
بهجای تکرار دستی فلگ های docker run -e، میتوانید متغیرها را در فایل docker-compose.yml خود تعریف کنید، مقادیر پیشفرض را تنظیم کنید و بازنویسیهای ساده را تسهیل کنید:
1services: 2 app: 3 image: app:latest 4 build: 5 context: . 6 environment: 7 - DEV_MODE 8 - REDIS_ENABLED=1 9 - REDIS_HOST_URL=${REDIS_HOST:-redis} 10 ports: 11 - ${APP_PORT:-80}:80
این مثال چند روش مختلف برای تنظیم یک متغیر را نشان می دهد:
DEV_MODE - عدم ارائه یک مقدار به این معنی است که Compose آن را از متغیر محیطی مجموعه در shell شما می گیرد.
REDIS_ENABLED=1 - تنظیم یک مقدار خاص، استفاده از آن را تضمین می کند (مگر اینکه بعداً بازنویسی شود).
REDIS_HOST_URL=${REDIS_HOST:-redis} - این مثال درونیابی REDIS_HOST_URL را به مقدار متغیر shell REDIS_HOST شما اختصاص میدهد و به مقدار پیشفرض redis برمیگردد.
{APP_PORT:-80}$ - متغیرهای محیطی که در shell شما تنظیم شدهاند را میتوان در فیلدهای دلخواه در فایل docker-compose.yml درونیابی کرد، که امکان سفارشیسازی آسان پیکربندی استک شما را فراهم میکند.
علاوه بر این، میتوانید با ایجاد یک فایل محیطی، این مقادیر را نادیده بگیرید با env.، که به طور خودکار بارگیری میشود، یا فایل دیگری که به فلگ env-file-- ارسال میکنید:
1$ cat config.env 2DEV_MODE=1 3APP_PORT=8000 4 5$ docker compose --env-file=config.env up -d
9. سفارش راه اندازی سرویس را کنترل کنید
بسیاری از برنامهها به کامپوننت های خود نیاز دارند که منتظر باشند تا وابستگیها آماده شوند، مثلاً در برنامه تستی ما در بالا، اگر برنامه Node قبل از فعال شدن کانتینر Redis شروع به کار کند، از کار میافتد.
میتوانید ترتیب شروع سرویسها را با تنظیم فیلد dependent_on در فایل docker-compose.yml خود کنترل کنید:
1services: 2 app: 3 image: app:latest 4 build: 5 context: . 6 depends_on: 7 - redis 8 ports: 9 - ${APP_PORT:-80}:80 10 redis: 11 image: redis:7
اکنون Compose شروع به کار سرویس app را تا زمانی که کانتینر redis اجرا شود به تاخیر می اندازد. برای ایمنی بیشتر، میتوانید منتظر بمانید تا کانتینر بررسی سلامتی خود را با استفاده از depends_on انجام دهد:
1services: 2 app: 3 image: app:latest 4 build: 5 context: . 6 depends_on: 7 redis: 8 condition: service_healthy 9 ports: 10 - ${APP_PORT:-80}:80 11 redis: 12 image: redis:6
بیشتر بدانید: میکرو فرانت اند در Next.js بررسی با مثال
بیشتر بدانید: تست معماری در لاراول با Pest
نتیجه
در این مقاله از آنوفل، یاد گرفتید که چگونه Docker Compose به شما اجازه میدهد با استک های چند کانتینری Docker کار کنید. ما نحوه ایجاد یک فایل Compose را نشان دادیم. اکنون می توانید از Compose برای تعامل با کانتینرهای برنامه خود استفاده کنید، در حالی که از دستورات CLI اجرای docker compose از خطا اجتناب کنید.
یک docker compose up همه کانتینرهای استک شما را راه اندازی می کند و پیکربندی ثابت را در هر محیطی تضمین می کند.
