ساعت ۱۰ صبح است و یک فیکس کوچک مانده. پایپلاین را اجرا میکنی، میرسد به npm install و همانجا میماند: تایماوت. یکی از میرورهای npm از دسترس خارج شده و حالا همهٔ پروژههای Node روی همان میرور گیر کردهاند. راهحل قدیمی این بود که بروی سراغ Dockerfileها، آدرس رجیستری را در همهشان عوض کنی، کامیت کنی و امیدوار باشی میرور بعدی هم تا فردا زنده بماند.
این بار لازم نیست. در لکسویا میرور npm یک تنظیم پروژه است، نه یک خط داخل Dockerfile: از پنل عوضش میکنی، از بیلد بعدی اعمال میشود و به ریپازیتوری هم دست نمیزنی. این نوشته هم دقیقاً دربارهٔ همین است؛ اینکه میرور npm چیست، چرا وسط کار میمیرد و چطور در چند ثانیه بدون تغییر کد، رجیستری پروژه را عوض کنی.
در یک نگاه
- چه چیزی
- انتخاب میرور npm برای هر پروژه، جدا از بقیه
- کجا
- پنل لکسویا › پروژه › تنظیمات › «بیلد و دیپلوی» › «رجیستری npm»
- کی اعمال میشود
- از بیلد بعدی؛ برای اعمال فوری، «اجرای پایپلاین» را بزن
- چه چیزی عوض نمیشود
- کد پروژه و Dockerfile. مقدار فقط در زمان بیلد استفاده میشود و در محیط اجرای اپ نمینشیند
- محدودیت
- رجیستری باید عمومی باشد؛ میرور خصوصی با توکن فعلاً پشتیبانی نمیشود
میرور npm چیست و چرا لازم میشود؟
ابزار npm پکیجها را از یک مخزن مرکزی به اسم رجیستری npm میگیرد؛ رجیستری رسمی registry.npmjs.org است. میرور npm (یا آینهٔ npm) یک کپی یا پراکسی از همان رجیستری است که روی سروری نزدیکتر یا داخل کشور اجرا میشود. اولین درخواست یک پکیج را از رجیستری اصلی میگیرد، کش میکند و درخواستهای بعدی را از خودش جواب میدهد.
برای کاربر ایرانی، میرور فقط یک بهینهسازی سرعت نیست. وقتی مسیر دسترسی به رجیستری اصلی کند یا محدود میشود، npm install یا طولانی میشود یا با خطا میخورد. نتیجهاش را در بیلد میبینی: تایماوت، قطع وسط دانلود، یا پکیجی که نصفه دانلود شده و checksum نمیخورد.
ولی یک میرور هم موجودی نیست که همیشه زنده بماند. همینجاست که مسئله از «کدام میرور بهتر است» تبدیل میشود به «وقتی میرور خراب شد، چقدر سریع میتوانم عوضش کنم».
وقتی میرورها از کار میافتند
میرورها به چند دلیل معمول زمین میخورند: قطعی شبکهٔ همان دیتاسنتر، از کار افتادن کش، جواب ناقص برای یک پکیج خاص، یا خطای ۵۰۳ از سمت upstream. برای بیلد تو همهشان یک شکل دارند: یک مرحله کهنه میماند و یک خطای قرمز.
خطاهای رایجی که در این حالت میبینی:
- تایماوت اتصال (
ETIMEDOUTیاEAI_AGAIN): دسترسی به میرور برقرار نمیشود. - قطع وسط دانلود (
ECONNRESET): اتصال نمیماند و نصب نیمهکاره میشود. - خطای
۵۰۳از خود میرور، حتی وقتی سایتش بالا است. - نخواندن checksum (
EINTEGRITY): فایل دانلودشده با checksum پکیج نمیخواند، معمولاً چون پاسخ میرور ناقص بوده.
راهحلهای همیشگی دو دستهاند: یا یک میرور محلی راه بیندازی و پکیجها را کش کنی، یا آدرس رجیستری را عوض کنی. اولی برای محیط بدون اینترنت و تیمهایی که بیلد زیاد دارند منطقی است؛ راهنمایش را در راهاندازی npm mirror با Verdaccio نوشتهایم. دومی همان کاری است که موقع خرابی عجله داری، و تا قبل از این تنظیم، یعنی دست زدن به Dockerfile همهٔ پروژهها.
مشکل اصلی تغییر Dockerfile این نیست که سخت است؛ این است که همهٔ پروژهها را همزمان به یک میرور جدید گره میزند. اگر آن یکی هم بخوابد، دوباره باید همه را عوض کنی و دوباره کامیت کنی.
رجیستری npm در لکسویا: یک تنظیم برای هر پروژه
در لکسویا انتخاب رجیستری از Dockerfile جدا شده و به تنظیمات پروژه آمده. هر پروژه یک انتخاب دارد و همان انتخاب وقتی بیلد میشود بهصورت آرگومان بیلد NPM_REGISTRY به مرحلهٔ نصب پکیج داده میشود. یعنی Dockerfile دستنخورده میماند، ولی مقدارش هم داخل کد نیست که مجبور شوی برای عوض کردنش کامیت کنی.
دو حالت داری: یکی از گزینههای آماده را انتخاب کنی، یا آدرس رجیستری خودت را وارد کنی. گزینههای آماده بهصورت مرجع ذخیره میشوند، نه کپی آدرس. یعنی اگر بعداً آدرس یکی از میرورها عوض شود، همهٔ پروژههایی که آن گزینه را انتخاب کردهاند از بیلد بعدی با آدرس جدید کار میکنند. برای تو مهمترین نتیجهاش این است که انتخاب یک ارجاع است، نه یک رشتهٔ ثابت: آدرس میرور میتواند بدون کامیت تو عوض شود.
ترتیب تصمیمگیری هنگام بیلد این است:
| اولویت | منبع | کِی استفاده میشود |
|---|---|---|
| ۱ | گزینهٔ انتخابشدهٔ پروژه | وقتی از پنل یکی از میرورها را انتخاب کردهای |
| ۲ | رجیستری دلخواه | وقتی آدرس اختصاصی خودت را وارد کردهای |
| ۳ | متغیر محیطی NPM_REGISTRY | پروژههایی که از قبل این متغیر را داشتهاند؛ همچنان اولویت دارد |
| ۴ | پیشفرض پلتفرم | وقتی هیچ انتخابی ثبت نشده باشد (کلاستر ایران: میرور لکسویا) |
| ۵ | میرور لکسویا | آخرین سد؛ تا بیلد هیچوقت با رجیستری خالی اجرا نشود |
چطور رجیستری پروژه را عوض کنم؟
- وارد پنل شو و پروژه را باز کن.
- به تب تنظیمات و بعد بخش «بیلد و دیپلوی» برو.
- کارت «رجیستری npm» را پیدا کن. زیر «مکان بیلد» است و آدرس رجیستری فعلی را هم نشان میدهد.
- یکی از گزینهها را انتخاب کن، یا «رجیستری دلخواه» را بزن و آدرس خودت را وارد کن. برای برگشتن به پیشفرض، لینک «استفاده از پیشفرض پلتفرم» را بزن.
- ذخیره کن. بعد از ذخیره، برای اعمال فوری دکمهٔ «اجرای پایپلاین» را بزن؛ وگرنه از بیلد بعدی اعمال میشود.
هر پروژه انتخاب خودش را دارد؛ اگر پنج پروژهٔ Node داری، میتوانی فقط همان یکی که مشکل دارد را عوض کنی و بقیه را دست نزنی. این مهمترین تفاوتش با روش قبلی است.
کدام میرور npm را انتخاب کنم؟
گزینههای آماده در پنل اینها هستند: میرور لکسویا (پراکسی npm-group)، لیارا، رجیستری رسمی npm، و رانفلر. اینها فقط پیشنهادند؛ اگر میرور تیم خودت را داری، آدرسش را بهعنوان رجیستری دلخواه وارد کن.
| گزینه | مناسب برای | نکته |
|---|---|---|
| میرور لکسویا | پیشفرض کلاستر ایران | پراکسی داخلی روی repo.lexoya.com؛ در تست ما سریعترین بود |
| لیارا | وقتی میرور دیگری جواب نمیدهد | گزینهٔ جاافتاده و پایدار برای پروژههای ایرانی |
| npmjs.org | پیشفرض کلاستر آلمان و پکیجهای خاص | رسمی و کامل؛ از ایران معمولاً کندتر است |
| رانفلر | گزینهٔ جایگزین در قطعیها | در تست ما از شبکهٔ ما در دسترس نبود؛ اگر روی تو جواب داد نگهش دار |
برای اینکه حرفمان کلی و بیسند نباشد، موقع نوشتن این مطلب یک تست ساده گرفتیم: متادیتای یک پکیج پرکاربرد (express) را از چند رجیستری گرفتیم و زمان پاسخ را اندازه گرفتیم. چند میرور دیگر را هم برای مقایسه آوردهایم؛ هر کدام را میتوانی بهعنوان رجیستری دلخواه وارد کنی. این عددها را بهعنوان تضمین نخوان؛ شبکهٔ هر کس فرق دارد و وضعیت میرورها هم روزبهروز عوض میشود.
| رجیستری | زمان پاسخ (تست ما) |
|---|---|
میرور لکسویا (npm-group) | حدود ۱٫۸ ثانیه |
| npmmirror | حدود ۵ ثانیه |
| رجیستری رسمی npm | حدود ۵ ثانیه |
| لیارا | حدود ۹ ثانیه |
| رانفلر | در دسترس نبود |
اگر تازه شروع کردهای، پیشفرض را نگه دار. اگر بیلدت روی یک میرور گیر کرد، همان پروژه را روی گزینهٔ بعدی بگذار و دوباره بیلد کن؛ این دقیقاً همان کاری است که این تنظیم برایش ساخته شده.
رجیستری دلخواه: میرور تیم خودت
خیلی از تیمها یک Nexus یا Verdaccio داخلی دارند. کافی است آدرس عمومیاش را در حالت «رجیستری دلخواه» وارد کنی؛ چیزی شبیه این:
https://npm.example.com/repository/npm/آدرس باید http یا https باشد و فاصله یا کاراکتر عجیب نداشته باشد. سقف طولش هم ۲۰۰ کاراکتر است تا در دستور بیلد مشکلی پیش نیاید.
یک محدودیت را از همین اول بگوییم: رجیستری خصوصی که به توکن احراز هویت نیاز دارد، فعلاً از این مسیر پشتیبانی نمیشود. ما آدرس را نگه میداریم، نه رمز و توکن. اگر پکیجهای scoped خصوصی داری، آنها را با .npmrc و توکن خودت در پروژه تنظیم کن؛ روش تنظیم کلاینت را در راهاندازی npm در محیط Airgap نوشتهایم.
اگر پروژه Dockerfile اختصاصی دارد
تایپهای آمادهٔ لکسویا (Next.js، Nuxt، پروژههای React و Vue، Node و Express، Laravel و Supervisor) از قبل این آرگومان را میشناسند؛ کاری لازم نیست. اما اگر پروژه را با تایپ Docker و Dockerfile خودت ساختهای، Dockerfile باید مقدار را بگیرد. دو خط به فایل اضافه کن:
ARG NPM_REGISTRY=https://repo.lexoya.com/repository/npm-group/
RUN npm install --registry="${NPM_REGISTRY}"بعد از آن، انتخاب پنل روی بیلد اثر میگذارد. اگر این دو خط نباشند، تنظیم ذخیره میشود ولی به مرحلهٔ نصب نمیرسد.
کجا این تنظیم جواب نمیدهد؟
سه چیز را از قبل بدان تا وسط کار غافلگیر نشوی. اول، تغییر رجیستری از بیلد بعدی اعمال میشود؛ اگر عجله داری، «اجرای پایپلاین» را بزن. دوم، عوض کردن رجیستری کش لایهٔ نصب پکیج را باطل میکند؛ پس بیلد اول بعد از تغییر کمی طولانیتر است چون پکیجها دوباره دانلود میشوند.
سوم و مهمتر: این تنظیم جای یک میرور زنده را نمیگیرد. اگر میروری که انتخاب کردهای خودش از دسترس خارج شود، باز هم باید عوضش کنی. فرقش این است که دیگر کامیت و تغییر Dockerfile لازم نیست و فقط همان پروژهای که مشکل دارد عوض میشود. ضمناً این تنظیم فقط به بیلدهای npm مربوط است؛ پروژهٔ Go یا Python از آن استفاده نمیکند.
English quick facts: Lexoya projects can pick their npm registry per project (panel: Project → Settings → Build & CD → npm Registry). The value is passed to the build as the NPM_REGISTRY build arg, so the built-in framework images need no Dockerfile change. Resolution order: selected preset → custom URL → legacy NPM_REGISTRY env → platform default → Lexoya mirror fallback. Presets: Lexoya (npm-group), Liara, npmjs.org and Runflare; the Iran cluster defaults to the Lexoya mirror and the Germany cluster to npmjs.org. Changing it applies to the next deployment, or immediately when the pipeline is run. Custom registries must be public http(s) URLs; private registries that need an auth token are not supported.
میرور پروژهات را از پنل عوض کن
پنل › پروژه › تنظیمات › بیلد و دیپلوی › رجیستری npm
سؤالات متداول
میرور npm چیست؟
میرور npm یک کپی یا پراکسی از رجیستری رسمی npm است که روی سروری نزدیکتر اجرا میشود؛ پکیج را یکبار از رجیستری اصلی میگیرد و بار بعد از کش خودش پاسخ میدهد. در ایران برای سرعت بیشتر و دور زدن محدودیت دسترسی به registry.npmjs.org استفاده میشود.
چرا npm install وسط بیلد خطا میدهد؟
معمولاً چون میروری که استفاده میکنی جواب نمیدهد یا پاسخش ناقص است. نشانههای رایج: ETIMEDOUT، ECONNRESET، خطای ۵۰۳ یا EINTEGRITY. در لکسویا رجیستری هر پروژه از پنل عوض میشود و از بیلد بعدی اعمال میشود.
چطور رجیستری npm پروژه را در لکسویا عوض کنم؟
پنل › پروژه › تنظیمات › «بیلد و دیپلوی» › «رجیستری npm». یک گزینه انتخاب کن یا آدرس دلخواه بده و ذخیره کن. تغییر از بیلد بعدی اعمال میشود؛ برای اعمال فوری دکمهٔ «اجرای پایپلاین» را بزن.
برای عوض کردن رجیستری باید Dockerfile را تغییر بدهم؟
برای تایپهای آمادهٔ لکسویا نه؛ Next.js، Nuxt، پروژههای React و Vue، Node و Express، Laravel و Supervisor از قبل ARG NPM_REGISTRY را دارند. فقط اگر با تایپ Docker و Dockerfile خودت کار میکنی، باید ARG NPM_REGISTRY و npm install --registry="$NPM_REGISTRY" را در فایل داشته باشی.
بهترین میرور npm برای ایران کدام است؟
جواب ثابت ندارد و به شبکهٔ تو بستگی دارد. در تست ما میرور لکسویا (npm-group) سریعترین بود، بعد npmmirror و npmjs، و لیارا کندتر. مهمتر از انتخاب «بهترین»، این است که عوض کردنش یک تنظیم پروژه باشد، نه ویرایش Dockerfile. گزینههای آماده هم مرجعاند: اگر آدرس یکی از آنها از سمت پلتفرم عوض شود، پروژههای روی آن گزینه از بیلد بعدی آدرس جدید را میگیرند.
رجیستری خصوصی که توکن میخواهد پشتیبانی میشود؟
فعلاً نه. این تنظیم فقط آدرس http یا https را نگه میدارد و رمز و توکن ذخیره نمیکند. برای پکیجهای scoped خصوصی از فایل .npmrc و توکن خودت داخل پروژه استفاده کن.
منابع
- مستند رسمی npm دربارهٔ رجیستری، تعریف registry و نحوهٔ انتخاب آن.
- مستند فایل
.npmrc، برای تنظیم رجیستری در سطح پروژه یا سیستم. - پروژهٔ Verdaccio، میرور و رجیستری سبک برای کش کردن پکیجها.
- راهاندازی npm mirror در محیط Airgap، اگر میخواهی میرور خودت را داشته باشی.
مطالب مرتبط
- تنظیم npm برای استفاده از رجیستری داخلی برای وقتی که میخواهی کلاینت را دستی تنظیم کنی.
- راهاندازی npm mirror/cache برای تیمهایی که میخواهند پکیجها را یکبار بگیرند و داخل شبکه پخش کنند.
- راهنمای عملی دیپلوی برای اینکه کل مسیر از کامیت تا پروداکشن را ببینی.
- دیپلوی پروژهٔ Node.js و Express اگر پروژهات Node است و تازه میخواهی بالا بیاوریش.