وبلاگ نت‌آرامآموزش، تجربه و راهکارهای زیرساخت

خطای ۱۲۷ در کانتینر Docker؛ چرا دستور پیدا نمی‌شود و چطور رفعش کنیم؟

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

انتشار:
توسط تیم فنی نت‌آرام
۵ دقیقه زمان مطالعه
۰ دیدگاه
محتوای تخصصی، ساده و کاربردی
هماهنگ با هویت حرفه‌ای نت‌آرام
بازگشت به لیست مقالات
تصویر شاخص مقاله خطای ۱۲۷ در کانتینر Docker؛ چرا دستور پیدا نمی‌شود و چطور رفعش کنیم؟ در وبلاگ نت‌آرام
محتوای آموزشی وبلاگ نت‌آرام
کانتینر را راه می‌اندازید، اما چند ثانیه بعد متوقف می‌شود یا پیامی مانند command not found می‌بینید. کد خروج ۱۲۷ معمولاً می‌گوید فرمانی که باید اجرا شود پیدا نشده است. علت می‌تواند اشتباه تایپی، نبودن برنامه در تصویر، مسیر اشتباه یا حتی یک اسکریپت با مفسر ناموجود باشد. برای رفع مشکل لازم نیست همه کانتینرها یا داده‌های سرور را پاک کنید.
این راهنما برای Docker روی لینوکس است. فرمان‌ها را با SSH در ترمینال همان سروری اجرا کنید که کانتینر روی آن قرار دارد. دسترسی به Docker معمولی قدرت زیادی روی سرور می‌دهد؛ از حساب مجاز استفاده کنید. اگر دسترسی به socket داکر خطا دارد، ابتدا آن را جداگانه رفع کنید.

۱. کدام کانتینر و چه خطایی؟

در ترمینال اجرا کنید:
کد / دستورdocker ps -a
این فهرست، کانتینرهای متوقف را نیز نشان می‌دهد. نام کانتینر مشکل‌دار را از ستون NAMES بردارید. در دستورهای بعدی به جای myapp همان نام را بگذارید. اگر اصلاً کانتینری ساخته نشده و خطا بلافاصله هنگام اجرای docker run ظاهر می‌شود، متن کامل خطای همان فرمان را بخوانید؛ ممکن است Docker قبل از شروع برنامه از نبود دستور خبر داده باشد.
کد / دستورdocker logs --tail 100 myapp
این دستور ۱۰۰ خط آخر خروجی را نشان می‌دهد. دنبال نام فایل یا فرمان قبل از عبارت not found بگردید. اگر پیام، نام یک برنامه جانبی داخل اسکریپت را نشان می‌دهد، ممکن است خود اسکریپت شروع شده باشد ولی یکی از فرمان‌های داخل آن موجود نباشد. گزارش را پیش از فرستادن برای دیگران از رمزها و اطلاعات مشتری پاک کنید.
کد / دستورdocker inspect --format '{{.State.Status}} exit={{.State.ExitCode}} error={{.State.Error}}' myapp
خروجی exited exit=127 همراه با پیغام «پیدا نشد» سرنخ قوی است. کد خروج برنامه به‌تنهایی تشخیص قطعی نمی‌دهد؛ برنامه می‌تواند خودش ۱۲۷ برگرداند. اگر error به چیز دیگری مثل مجوز اشاره می‌کند، همان پیام را دنبال کنید.

۲. ببینید Docker قرار است چه چیزی را اجرا کند

برای دیدن نقطه شروع و آرگومان‌ها:
کد / دستورdocker inspect --format 'path={{.Path}} args={{json .Args}} image={{.Config.Image}}' myapp
نام تصویر و مسیر دستور را با فایل Dockerfile یا پیکربندی Compose پروژه مقایسه کنید. ممکن است تصویر تازه، نام برنامه را تغییر داده باشد یا در Compose بخش entrypoint و command تنظیم تصویر را عوض کرده باشد. اگر از Compose استفاده می‌کنید، در پوشه پروژه فرمان زیر پیکربندی نهایی را نشان می‌دهد:
کد / دستورdocker compose config
خروجی ممکن است مقادیر محیطی محرمانه داشته باشد؛ آن را عمومی منتشر نکنید. مسیر فایل، املای دستور و نوع فهرست یا رشته در پیکربندی را بررسی کنید. نام سرویس در Compose با نام کانتینر ممکن است یکسان نباشد.

۳. فایل یا برنامه واقعاً در تصویر هست؟

اگر می‌دانید تصویر شما پوسته sh دارد، در یک محیط آزمایشی با همان تصویر می‌توانید بررسی کنید. در نمونه زیر my-image:tag را با نام تصویر خودتان عوض کنید:
کد / دستورdocker run --rm --entrypoint /bin/sh my-image:tag -c 'command -v my-command; ls -l /app/start.sh'
این فرمان یک کانتینر موقت می‌سازد، مسیر برنامه فرضی my-command و فایل نمونه /app/start.sh را می‌پرسد و پس از پایان کانتینر موقت را حذف می‌کند. نام‌ها و مسیرها را مطابق پروژه عوض کنید. اگر فایل نیست، مسیر COPY در Dockerfile و محتوای build context و فایل .dockerignore را بررسی کنید؛ ممکن است فایل اصلاً به تصویر کپی نشده باشد. تصویر را پس از اصلاح دوباره بسازید و ابتدا در محیط آزمایشی اجرا کنید.
برخی تصویرهای کوچک یا distroless اصلاً /bin/sh ندارند. شکست این دستور ثابت نمی‌کند برنامه اصلی خراب است. در آن حالت محتوای مرحله ساخت و مستندات همان تصویر را بررسی کنید یا برای عیب‌یابی از تصویر سازگار و ابزارهای مجاز پروژه استفاده کنید؛ پوسته را بی‌دلیل به تصویر حساس تولیدی اضافه نکنید.

۴. اسکریپت هست ولی باز «پیدا نشد» می‌گوید

خط اول اسکریپت، یعنی shebang، مفسر آن را مشخص می‌کند؛ مثلاً #!/bin/sh. اگر آن مسیر در تصویر موجود نباشد یا فایل با پایان خط ویندوزی CRLF ذخیره شده باشد، ممکن است پیام گیج‌کننده «فایل پیدا نشد» دریافت کنید. فایل منبع را با پایان خط LF ذخیره کنید و مفسری را انتخاب کنید که واقعاً در تصویر وجود دارد. تغییر محتوای فایل را در مخزن ثبت کنید و تصویر را دوباره بسازید. اگر خطا permission denied است، مجوز اجرای همان فایل را در مرحله ساخت اصلاح کنید؛ بازکردن مجوز همه فایل‌ها راه‌حل امنی نیست.
خطای exec format error معمولاً با خود ۱۲۷ فرق دارد و می‌تواند به ناسازگاری معماری فایل اجرایی و سرور مربوط باشد. معماری تصویر و ماشین و خروجی ساخت را طبق مستندات سازنده بررسی کنید؛ نصب یک فایل ناشناس از اینترنت می‌تواند مشکل امنیتی ایجاد کند.

۵. اصلاح را تأیید کنید

پس از اصلاح منبع و ساخت تصویر، ابتدا یک اجرای آزمایشی با همان تنظیمات و بدون دستکاری داده‌های اصلی انجام دهید. سپس در زمان مناسب، سرویس موردنظر را طبق روش انتشار پروژه جایگزین کنید. دوباره docker ps -a و docker logs --tail 100 myapp را ببینید: باید کانتینر در حالت مورد انتظار بماند و پیام قبلی تکرار نشود. اگر دوباره متوقف شد، نام فرمان تازه و کد خروج تازه را بررسی کنید؛ ممکن است بعد از رفع خطای اول، خطای دیگری آشکار شود.
برای پروژه‌هایی که به محیط مستقل نیاز دارند، مشخصات سرور مجازی ایران نت‌آرام را با نیاز برنامه و فضای پشتیبان مقایسه کنید. جزئیات کدهای خروج و نقطه شروع را در مستندات اجرای کانتینر Docker بخوانید.
اشتراک‌گذاری:
لینکدینتلگرامایکس

دیدگاه‌ها (۰)

دیدگاه‌های تاییدشده و پاسخ‌های تیم نت‌آرام