محتوای آموزشی وبلاگ نتآرام
در فایل
.env یک مقدار گذاشتهاید، اما برنامه داخل کانتینر میگوید متغیر خالی است یا وجود ندارد. گاهی مقدار در ترمینال شما تنظیم شده، ولی کانتینر هنوز با تنظیم قبلی ساخته شده است. گاهی هم Docker Compose برای ساخت فایل تنظیمات به متغیر دسترسی دارد، ولی شما آن را به محیط برنامه داخل کانتینر ندادهاید.این دو مرحله را جدا میکنیم: اول Compose فایل پیکربندی را میخواند و جای متغیرها را پر میکند؛ بعد تنظیمهای سرویس مشخص میکنند چه چیزی به کانتینر میرسد. با یک مثال غیرمحرمانه مسیر را از ابتدا تا داخل کانتینر دنبال میکنیم.
این آموزش برای Docker Compose جدید با دستور
docker compose است. در نسخه قدیمی ممکن است دستور docker-compose یا بعضی گزینهها متفاوت باشند. web نام نمونه سرویس و APP_MESSAGE یک متغیر آزمایشی است؛ رمز یا کلید واقعی را در دستور، تصویر، تیکت یا خروجی عمومی قرار ندهید.۱. سرویس و محل پروژه را مشخص کنید
در سرور، به پوشه پروژه بروید و نسخه Compose را ببینید:
کد / دستورdocker compose version
سرویسهای پروژه و وضعیت آنها:
کد / دستورdocker compose ps
اگر از
کد / دستور-f، --project-directory یا --env-file استفاده میکنید، هنگام همه آزمایشها همان گزینهها را به کار ببرید. اجرای دستور در پوشهای دیگر ممکن است پروژه یا فایل دیگری را انتخاب کند. برای دیدن پوشه فعلی:pwd
پیش از بررسی متغیرهای حساس بدانید
docker compose config، docker compose config --environment، docker inspect و printenv میتوانند مقدار رمز و کلید را نمایش دهند. خروجی کامل آنها را در تیکت نفرستید. برای تمرین از مقدار غیرمحرمانه استفاده میکنیم.۲. مثال: مقدار در فایل .env است اما باید به سرویس هم داده شود
فرض کنید در پوشه پروژه فایلی به نام
کد / دستور.env دارید:APP_MESSAGE=hello
اگر میخواهید همین مقدار به کانتینر
کد / دستورweb برسد، بخشی از compose.yaml میتواند این باشد:services:
web:
image: myapp:example
environment:
APP_MESSAGE: ${APP_MESSAGE:?APP_MESSAGE is required}
این فقط بخشی از فایل نمونه است؛ image و سایر تنظیمات برنامه خود را جایگزین نکنید. Compose مقدار را در مرحله خواندن فایل جایگزین میکند و بخش
environment آن را به سرویس میدهد. عبارت :? در این مثال باعث میشود اگر متغیر تنظیم نشده یا خالی باشد، Compose خطا بدهد؛ با ? بدون دونقطه، خالی بودن و تنظیمنشدن رفتار متفاوتی دارند.اگر متغیری فقط در
.env باشد و هیچ تنظیمی آن را به محیط سرویس منتقل نکند، قرار گرفتنش در کنار فایل Compose بهتنهایی به معنی موجود بودن داخل کانتینر نیست.برای بررسی ساختار بدون چاپ تنظیمات:
کد / دستورdocker compose config --quiet
اگر متغیر اجباری غایب باشد، باید پیام خطا بگیرید. این آزمون صحت مقدار واقعی یا کارکرد برنامه را اثبات نمیکند. در نسخهای که گزینه
کد / دستور--environment دارد، میتوانید منابع مورد استفاده برای جایگذاری را ببینید:docker compose config --environment
این خروجی ممکن است همه مقدارهای محرمانه را نشان دهد. فقط در نشست خصوصی خود بخوانید و منتشر نکنید. در پروژه واقعی برای بررسی وجود نام، بدون چاپ عمدی مقدارها میتوانید نامها را جدا کنید:
کد / دستورdocker compose config --environment | cut -d= -f1
حتی در این حالت هشدارهای دیگر یا نام متغیرها ممکن است حساس باشند. اگر گزینه موجود نیست، نسخه Compose و مستند همان نسخه را بررسی کنید.
۳. اولویت shell و فایل env را بشناسید
اگر یک نام در چند جا مقدار داشته باشد، محیط shell اجرای Compose برای جایگذاری معمولاً بر فایل
.env اولویت دارد. مثال: اگر در فایل APP_MESSAGE=hello باشد ولی در ترمینال همان نام با مقدار خالی export شده باشد، ممکن است مقدار خالی shell استفاده شود و عبارت اجباری خطا بدهد.برای متغیر آزمایشی غیرمحرمانه در Linux:
کد / دستورprintf 'APP_MESSAGE=<%s>\n' "$APP_MESSAGE"
برای تشخیص تنظیمنشدن از خالی بودن:
کد / دستورif [ "${APP_MESSAGE+x}" = x ]; then echo 'set in shell'; else echo 'not set in shell'; fi
اگر فقط در همین نشست یک مقدار آزمایشی اشتباه export کردهاید، میتوانید آن را از محیط همان shell بردارید:
کد / دستورunset APP_MESSAGE
این دستور فایل
.env را ویرایش نمیکند و بر shellهای دیگر اثر ندارد. سپس docker compose config --quiet را تکرار کنید. متغیرهای واقعی سازمانی را بدون دانستن محل استفاده unset نکنید. در PowerShell دستورها و دامنه متغیر محیطی متفاوتاند.بدون
کد / دستور--env-file، Compose معمولاً فایل .env پروژه را برای جایگذاری میخواند. محل پروژه به گزینه --project-directory، فایل اول -f و سپس پوشه جاری وابسته است. اگر بهصراحت فایل دیگری میخواهید:docker compose --env-file ./config/app.env config --quiet
مسیر نمونه باید وجود داشته باشد و نسبت به پوشهای که فرمان را اجرا میکنید تفسیر میشود. در نسخههای جدید میتوان چند
--env-file داد و فایلهای بعدی بر موارد قبلی اثر میگذارند؛ محیط shell همچنان ممکن است اولویت بالاتری داشته باشد.۴. تفاوت --env-file و env_file سرویس
--env-file یک گزینه فرمان Compose برای تأمین مقادیر جایگذاری پیکربندی است. در مقابل، env_file: زیر یک سرویس، متغیرهای فایل را به محیط آن کانتینر میدهد. این دو نقش را یکی ندانید.مثلاً اگر فایل
کد / دستورweb.env شامل APP_MESSAGE=hello است:services:
web:
image: myapp:example
env_file:
- ./web.env
مسیر
env_file سرویس نسبت به محل فایل Compose تفسیر میشود. اگر همزمان در بخش environment همان نام را با مقدار خالی تعیین کنید، آن مقدار میتواند مقدار env_file را بازنویسی کند. بنابراین هر دو بخش را با هم بخوانید و تعریف تکراری اشتباه را فقط پس از شناخت منبع درست اصلاح کنید.فایل
web.env سرویس را با فایل جایگذاری پروژه اشتباه نگیرید؛ صرف تعریف آن زیر env_file تضمین نمیکند همان مقدار برای جایگذاری ${APP_MESSAGE} در کل فایل Compose استفاده شود. اگر هر دو نیاز را دارید، هر نقش را صریح و طبق مستندات تنظیم کنید.۵. آیا کانتینر هنوز تنظیم قدیمی دارد؟
تغییر فایل روی دیسک بهتنهایی محیط پردازشِ از قبل اجراشده را عوض نمیکند. بعد از اصلاح فایل و تأیید پیشنمایش، در زمان مجاز سرویس مربوط را دوباره با Compose اعمال کنید:
کد / دستورdocker compose up -d --no-deps web
این کار ممکن است کانتینر
web را بازسازی کند و قطع کوتاه ایجاد شود؛ مسیر داده، volume و روش برگشت را از قبل بررسی کنید. نام سرویس واقعی را جایگزین کنید و اگر پروژه چند فایل یا --env-file دارد، همان گزینههای استقرار را در این دستور هم وارد کنید.برای مثال غیرمحرمانه، پس از بالا آمدن سرویس:
کد / دستورdocker compose exec web printenv APP_MESSAGE
باید مقدار مورد انتظار مثل
hello نمایش داده شود. اگر image ابزار printenv یا shell ندارد، از روش تشخیصی خود برنامه استفاده کنید. برای رمز واقعی مقدار را چاپ نکنید؛ با امکان تشخیص وجود یا خالی نبودن مقدار، و بدون افشای آن، صحت را در محیط مجاز بسنجید. بعضی برنامهها تنظیم را از فایل یا secret میخوانند، نه از متغیر محیطی.۶. اگر هنوز مقدار خالی است
نام متغیر را از نظر حروف کوچک و بزرگ دقیق مقایسه کنید:
APP_MESSAGE با app_message یکی نیست. بررسی کنید برنامه همان نام را میخواند و مقدار در بخش سرویس درست قرار گرفته است. اگر چند فایل Compose با -f ترکیب میشوند، ممکن است فایل بعدی تنظیم سرویس را تغییر دهد.در فایلهای env، کوتیشن و علامت
$ هم مهماند. برای نمونه در فایل .env، مقدار تککوتیشنشده مانند VALUE='$OTHER' به شکل literal در نظر گرفته میشود؛ در مقدارهای بدون کوتیشن یا با کوتیشن دوتایی، قواعد جایگذاری Compose میتوانند اعمال شوند. اگر لازم است یک علامت دلار به فرمان داخل کانتینر برسد و Compose آن را جایگذاری نکند، در فایل Compose اغلب از $$ استفاده میشود؛ بعد رفتار فرمان را در محیط آزمایشی تأیید کنید.برای اسرار، از فایل یا secret با مجوز مناسب و راهکار مدیریت اسرار سازگار با برنامه استفاده کنید. حتی متغیر محیطی کانتینر هم ممکن است برای افرادی که به Docker دسترسی دارند قابل مشاهده باشد. قرار دادن رمز در repository عمومی یا چاپ آن برای عیبیابی امن نیست.
پس از اصلاح، علاوه بر مقدار آزمایشی، عملکرد واقعی برنامه را بررسی کنید؛ مثلاً اگر متغیر مربوط به اتصال دیتابیس است، از داخل برنامه اتصال مجاز و نتیجه را امتحان کنید. اگر سرویس بالا است اما وضعیت سلامت آن شکست میخورد، راهنمای unhealthy در Docker را هم ببینید.
این مراحل برای Docker روی سرور مجازی ایران و سرور اختصاصی ایران کاربرد دارند. تفاوت منابع و تقدم آنها در مستند جایگذاری متغیرهای Compose و مستند اولویت متغیرها توضیح داده شده است.
اشتراکگذاری:
لینکدینتلگرامایکس
مقاله قبلی
مقاله قبلی وجود ندارد.
مقاله بعدی
دیدگاهها (۰)
دیدگاههای تاییدشده و پاسخهای تیم نتآرام
