مخازن دور زدن نت ملی
مخازن داخلی برای برنامه نویسان چیست و چه مشکلی رو حل میکنه؟ فرض کن پروژه پایتونت آمادهست و فقط میخوای چندتا کتابخونه نصب کنی، اما ترمینال مدام خطای اتصال میده. یا روی سرور لینوکسی دستور بهروزرسانی رو اجرا میکنی و دریافت فهرست بستهها متوقف میشه. اینجا ممکنه مشکل از کد تو نباشه؛ ابزار توسعه برای […]

مخازن داخلی برای برنامه نویسان چیست و چه مشکلی رو حل میکنه؟
فرض کن پروژه پایتونت آمادهست و فقط میخوای چندتا کتابخونه نصب کنی، اما ترمینال مدام خطای اتصال میده. یا روی سرور لینوکسی دستور بهروزرسانی رو اجرا میکنی و دریافت فهرست بستهها متوقف میشه. اینجا ممکنه مشکل از کد تو نباشه؛ ابزار توسعه برای دانلود به یک مخزن بیرونی وصل میشه که فعلاً در دسترس نیست. مخازن داخلی برای برنامه نویسان برای بخشی از همین وضعیت ساخته شدن: یک مسیر جایگزین برای دریافت پکیجها، وابستگیها و ایمیجهایی که سرویس ارائهدهنده پشتیبانی میکنه.

قبل از هر دستوری باید تفاوت سه مفهوم رو بفهمیم. مخزن بسته جاییه که نسخهها و فایلهای نرمافزار منتشر میشن؛ میرور داخلی نسخهای کپیشده، کششده یا واسطهای از اون منبعه؛ و نصب آفلاین یعنی تمام فایلهای موردنیاز رو از قبل داری و حین نصب هیچ شبکهای لازم نداری. پس استفاده از میرورهای ایرانی با نصب کاملاً آفلاین یکی نیست و هیچکدوم لزوماً راهی برای دسترسی آزاد به همه سایتهای خارجی نیستن.
توی این راهنما میخوام مخازن داخلی برای برنامه نویسان رو از حالت یک فهرست پراکنده آدرس خارج کنیم و به یک ابزار واقعی تبدیلشون کنیم. برای پایتون، اوبونتو، داکر، فلاتر، دارت و npm میبینیم چه چیزی تغییر میکنه، چطور عملکردش رو بسنجیم و اگر جواب نداد چطور برگردیم به وضعیت قبلی. این دستورها نمونههای قابل بررسیان، نه قول دسترسی دائمی؛ موجود بودن یک فایل روی میرور و وضعیت ارتباط شبکه در هر لحظه میتونه عوض بشه.
یک سؤال همون اول مهمه: آیا واقعاً با «اینترنت ملی» میتونی هر کاری انجام بدی؟ نه. مخازن داخلی برای برنامه نویسان فقط منابع موجود و قابل دسترس خودشون رو ارائه میدن. مثلاً اگه یک پکیج هنوز کش نشده باشه یا فرایند ساخت پروژه به سرویس احراز هویت، Git، فونت یا یک API بیرونی وصل بشه، تغییر مخزن بهتنهایی کافی نیست. بهتره بهجای وعده «دور زدن همه محدودیتها»، یاد بگیری مسیر وابستگیهای پروژه رو کنترل کنی.
| نیاز پروژه | منبع رایج | میرور یا تنظیم جایگزین | چه چیزی تضمین نمیشه؟ |
|---|---|---|---|
| نصب کتابخونه پایتون | PyPI | تغییر index در pip | وجود تمام نسخهها و فایلهای wheel |
| نصب بسته در اوبونتو | مخازن APT | میرور سازگار با نسخه توزیع | پوشش همه معماریها و شاخههای امنیتی |
| دریافت ایمیج داکر | Docker Hub | رجیستری جایگزین یا registry mirror | کش بودن تمام تگها و لایهها |
| پکیج فلاتر و دارت | pub.dev و منابع SDK | متغیرهای محیطی pub و Flutter | نصب کامل Android SDK و ابزارهای ساخت |
| نصب کتابخونه جاوااسکریپت | npm registry | تغییر موقت registry در npm | پوشش تمام بستههای باینری و postinstall |
قبل از عوضکردن مخزن، علت خطای دانلود رو پیدا کن
وقتی دانلود پکیج متوقف میشه، خیلی راحت میگیم «نت ملی شده» و دنبال میرور میگردیم؛ ولی خطای 404 با timeout فرق داره. اولی ممکنه یعنی مسیر یا نسخه اشتباهه؛ دومی یعنی اتصال در مهلت مشخص کامل نشده. خطای Could not resolve host هم از نام دامنه خبر میده و لزوماً ثابت نمیکنه خود مخزن از کار افتاده. استفاده عجولانه از مخازن داخلی برای برنامه نویسان بدون خواندن خطا، ممکنه فقط یک مشکل جدید روی مشکل قبلی اضافه کنه.
برای عیبیابی، سه چیز رو ثبت کن: متن کامل خطا، نام و نسخه ابزار و آدرسی که ابزار واقعاً باهاش ارتباط میگیره. مثلاً در پایتون خروجی python -m pip config debug میگه تنظیمات از کدوم فایل میآن؛ در اوبونتو فایلهای APT رو باید ببینی و در داکر میتونی با docker info تنظیمات Engine رو کنترل کنی. همین اطلاعات کمک میکنه بفهمی مشکل از DNS، گواهی TLS، مجوز، سهمیه سرویس یا نبودن فایل روی میروره.
یک قاعده برای تمام بخشهای این آموزش داریم: اول تنظیم موقت، بعد تست، بعد تنظیم دائمی. داخل پروژهای که باید پایدار بمونه، تغییر کلیِ آدرسها بدون نسخه پشتیبان کار درستی نیست. مزیت میرورهای داخلی اینه که گاهی مشکل دسترسی یا سرعت دانلود رو کم میکنن؛ نقطه ضعفشون هم اینه که یک وابستگی جدید به وضعیت یک سرویس ثالث میسازن. با این نگاه میتونیم مخازن داخلی برای برنامه نویسان رو واقعبینانه انتخاب کنیم.
میرور پایتون ایران؛ نصب پکیج با pip در اینترنت ملی
برای پایتون، نقطه اصلی کار pip و ایندکس PyPI هست. وقتی پکیجهایی مثل Django یا requests رو نصب میکنی، pip اول اطلاعات نسخهها و بعد فایلها و وابستگیهاشون رو از منبع تعریفشده دریافت میکنه. میرور پایتون ایران میتونه این درخواستها رو به مخزنی منتقل کنه که از داخل کشور قابل دسترسه؛ البته فقط برای نسخهها و فایلهایی که واقعاً ارائه میکنه. این یکی از کاربردیترین بخشهای مخازن داخلی برای برنامه نویسان موقع اختلال اینترنت به حساب میآد.
قبل از نصب، پیشنهاد میکنم از محیط مجازی استفاده کنی. این کار باعث میشه پکیجهای پروژه با بستههای سطح سیستم قاطی نشن. نمونه زیر برای لینوکس و مک نوشته شده و بهتره داخل پوشه یک پروژه آزمایشی اجرا بشه. اگر روی لینوکس ماژول venv نصب نیست، اول باید بسته مربوط به همون نسخه پایتون رو از منبع معتبر فراهم کنی.
python3 -m venv .venv
.venv/bin/python -m pip --version
در ویندوز هم میتونی با py -m venv .venv محیط بسازی و بهجای مسیر لینوکسی از .venv\Scripts\python.exe استفاده کنی. حالا برای یک نصب آزمایشی، آدرس رسمی معرفیشده در راهنمای PyPI رانفلر رو فقط برای همین دستور تنظیم میکنیم؛ برای نصب پکیج با اینترنت ملی لازم نیست از همون ابتدا تمام تنظیمات pip سیستم رو تغییر بدی.
.venv/bin/python -m pip install --index-url https://mirror-pypi.runflare.com/simple "Django>=5.2,<6"

نکته مهم اینه که اجرای دستور بالا در شبکه تو تعیین میکنه دانلود موفق میشه یا نه. اگر پکیج خاصی روی این میرور پیدا نشد، پیام خطا رو بخون و نسخه پایتون و نام بسته رو با خود PyPI مقایسه کن؛ تغییر تصادفی ورژن همیشه راهحل نیست. همینجا میتونی میزان پوشش مخازن داخلی برای برنامه نویسان رو در عمل بسنجی: یک نسخه مشخص، یک محیط مجازی و خروجی قابل بررسی.
اگر روش موقت درست کار کرد، برای حساب کاربری خودت میتونی آدرس پیشفرض pip رو تغییر بدی. طبق مستندات رسمی pip config، کلید درست global.index-url هست. دستورات زیر رو با هم اشتباه نگیر: دو خط اول برای ثبت و مشاهده تنظیم هستن و خط سوم فقط وقتی باید اجرا بشه که قصد برگشت داری.
python3 -m pip config --user set global.index-url https://mirror-pypi.runflare.com/simple
python3 -m pip config --user get global.index-url
# Only when you want to revert:
python3 -m pip config --user unset global.index-url
برای میرور پایتون ایران معمولاً لازم نیست گزینه trusted-host رو اضافه کنی یا بررسی HTTPS رو غیرفعال کنی. با این کار بیدلیل بخشی از حفاظت اتصال رو کنار میذاری. همینطور --extra-index-url رو بدون بررسی استفاده نکن، چون جستوجو بین مخازن مختلف میتونه خطر انتخاب اشتباه بسته و وابستگی رو بالا ببره. اگر پروژه حساس داری، نسخه بستهها رو قفل کن و منشأ فایلها رو کنترل کن.
یادت باشه نصب پکیج پایتون با میرور، با نصب خود زبان پایتون روی یک سیستم بدون اینترنت فرق داره. آموزش اختصاصی نصب پایتون آفلاین در نابغهها به آمادهسازی نصبکننده و ابزارهای اولیه مربوطه. اینجا تمرکزمون روی دانلود وابستگی از مخازن داخلی برای برنامه نویسان باقی میمونه تا دو مقاله یک هدف جستوجویی رو دنبال نکنن.
مخازن لینوکس در ایران؛ تنظیم درست میرور اوبونتو
برای اوبونتو و توزیعهای مبتنی بر دبیان، دستورهای apt update و apt install سراغ مخازن تعریفشده در تنظیمات APT میرن. وقتی این منبع در دسترس نیست، یکی از گزینهها استفاده از مخزن داخلی اوبونتو هست. اما قبل از هر تغییری باید نسخه توزیع، فایل فعال تنظیمات و پوشش شاخههای امنیتی رو بشناسی. مخازن داخلی برای برنامه نویسان در لینوکس فقط وقتی کمک میکنن که دقیقاً با نسخه و معماری سیستم تو سازگار باشن.
از اوبونتو 24.04 به بعد، پیکربندی پیشفرض معمولاً داخل فایل /etc/apt/sources.list.d/ubuntu.sources با قالب deb822 قرار داره؛ بنابراین دستور قدیمی تغییر /etc/apt/sources.list ممکنه اصلاً روی منبع فعال اثر نذاره. اول بدون تغییر دادن فایلها، وضعیت سیستم رو ببین. حتی اگه نام فایل رو میدونی، بهتره مطمئن بشی فایل دیگری منبع تکراری یا متفاوت تعریف نکرده.
cat /etc/os-release
ls -l /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null
apt-cache policy
برای نمونه، مستندات مخازن لینوکس آروانکلاد یک مسیر جایگزین برای بستهها معرفی کرده. قبل از استفاده، بررسی کن نسخه اوبونتو، شاخههای main و universe و بهروزرسانی امنیتی موردنیاز واقعاً روی سرویس موجود باشن. عوض کردن کورکورانه تمام URLها به اسم «میرور اوبونتو ایران» ممکنه سیستم رو از وصلههای امنیتی ضروری دور کنه.
اگر از نسخه جدید اوبونتو با فایل ubuntu.sources استفاده میکنی، اول نسخه پشتیبان بگیر و بعد فایل رو در ویرایشگر باز کن. فقط مقدار URIs: مربوط به مخزنی رو تغییر بده که پوششش تأیید شده؛ مقدارهای Suites:، Components: و Signed-By: باید مطابق وضعیت واقعی سیستم حفظ بشن.
sudo cp -a /etc/apt/sources.list.d/ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources.bak
sudo nano /etc/apt/sources.list.d/ubuntu.sources
وقتی در حال بررسی مخازن داخلی برای برنامه نویسان هستی، لازم نیست حتماً تمام بخشهای APT رو یکجا جابهجا کنی. اگه فقط مخزن اصلی روی سرویس داخلی پشتیبانی میشه ولی درباره شاخه امنیتی مطمئن نیستی، بخش نامطمئن رو تغییر نده. برای نسخههای قدیمیتر هم فایل مورد استفاده ممکنه sources.list باشه؛ توی اون نسخهها هم اول نسخه پشتیبان بگیر و جایگزینی رو متناسب با قالب فایل انجام بده.
بعد از ذخیره فایل، این دو دستور رو اجرا کن تا هم خطای دریافت فهرستها رو ببینی و هم بررسی کنی بسته نمونه از کجا پیشنهاد میشه. رسیدن به پاسخ بدون خطا از مخزن داخلی اوبونتو یک نشانه مثبته، ولی بهتنهایی تضمین نمیکنه همه بستهها یا بهروزرسانیهای بعدی در دسترس بمونن.
sudo apt-get update
apt-cache policy htop
برای برگشت در اوبونتویی که فایل پشتیبان بالا رو ساخته، میتونی نسخه قبلی رو برگردونی. این مرحله رو فقط وقتی انجام بده که واقعاً پشتیبان موجوده و همون فایل فعال رو تغییر دادهای. اگر فایلهای APT ساختار متفاوتی دارن، دستورات بازیابی هم باید مطابق همون ساختار نوشته بشن.
sudo cp -a /etc/apt/sources.list.d/ubuntu.sources.bak /etc/apt/sources.list.d/ubuntu.sources
sudo apt-get update
در بحث امنیت مخازن لینوکس، یک نکته فنی رو دستکم نگیر: APT برای صحت فراداده مخزن از امضای دیجیتال استفاده میکنه، اما استفاده از HTTP رمزنگاریشده نیست. هیچوقت برای حل خطا گزینههای trusted=yes، خاموشکردن کنترل امضا یا پذیرش بیقیدوشرط بستهها رو فعال نکن. انتخاب مخازن داخلی برای برنامه نویسان باید با حفظ زنجیره اعتماد انجام بشه، نه حذفش.
میرور داکر ایران؛ دریافت ایمیج با رجیستری جایگزین
داکر برای دریافت ایمیج از یک رجیستری استفاده میکنه. گاهی خود Docker Hub در دسترس نیست و گاهی مسیر دریافت یک لایه خاص با خطا مواجه میشه. در این شرایط میتونی از میرور داکر ایران استفاده کنی؛ اما این روش با تغییر رجیستری برای تمام ایمیجها فرق داره. مخازن داخلی برای برنامه نویسان در بخش داکر ممکنه بعضی ایمیجهای عمومی رو نگه دارن و برای بعضی تگها یا رجیستریهای خصوصی پوشش نداشته باشن.
برای آزمایش، اول از یک ایمیج عمومی با نسخه مشخص استفاده کن. روش مستقیم یعنی نام میزبان رجیستری رو جلوی نام ایمیج بذاری؛ مثل نمونه آروان. این دستور فقط از سرویسی که معرفی شده درخواست میفرسته و هنوز ثابت نمیکنه دانلود در شبکه تو موفق خواهد بود. در صورت خطا، متن پیام و نام تگ رو کنترل کن.
docker pull docker.arvancloud.ir/nginx:stable
نکته ظریف این دستور اینه که ایمیج با نام کامل docker.arvancloud.ir/nginx:stable ذخیره میشه، نه الزاماً با نام ساده nginx. برای دیدن همون ایمیج بهتره docker image ls رو بدون فیلتر یا با مرجع کامل اجرا کنی. بنابراین چک عملی رجیستری جایگزین رو اینطور انجام بده:
docker image ls
docker image inspect docker.arvancloud.ir/nginx:stable --format "{{.Id}}"
روش دوم برای استفاده از مخازن داخلی برای برنامه نویسان در داکر، تنظیم registry-mirrors داخل Docker Engine هست؛ ولی این تنظیم معمولاً مخصوص آینه Docker Hub هست و تمام رجیستریها یا builderهای BuildKit رو پوشش نمیده. در لینوکس، فایل /etc/docker/daemon.json ممکنه تنظیمات مهم دیگهای داشته باشه. برای همین هیچ دستور آمادهای که فایل رو از صفر بازنویسی کنه پیشنهاد نمیکنم. اگر چنین تغییری لازمه، اول تنظیمات قبلی رو نگه دار و کلید جدید رو با JSON موجود ادغام کن.
sudo test -f /etc/docker/daemon.json && sudo cp -a /etc/docker/daemon.json /etc/docker/daemon.json.bak
sudo cat /etc/docker/daemon.json 2>/dev/null || true
مقدار زیر فقط یک نمونه JSON برای نمایش ساختار کلیده و نباید بدون بررسی مستندات و سرویس فعلی روی daemon اعمال بشه. طبق مستندات Docker Registry Mirror، آدرس باید مربوط به رجیستریای باشه که برای استفاده بهعنوان pull-through cache پشتیبانی شده. قبل از راهاندازی مجدد Docker هم JSON رو اعتبارسنجی کن و اثر وقفه احتمالی روی کانتینرهای فعال رو در نظر بگیر.
{
"registry-mirrors": ["https://YOUR-VERIFIED-MIRROR.example"]
}
برای بررسی نتیجه از docker info و در نسخههای سازگار dockerd --validate استفاده کن. یادت نره موتور Docker Desktop با Docker Engine روی یک سرور لینوکسی روش تنظیم متفاوتی داره. اگه روی سیستم تولیدی کار میکنی، هرگونه restart رو با در نظر گرفتن سرویسهای فعال انجام بده؛ مخازن داخلی برای برنامه نویسان قرار نیست به قیمت قطعشدن اپلیکیشن اصلی تنظیم بشن.

نمونه Dockerfile نابغهها؛ یک آزمایش قابل بازتولید
حالا بهجای اینکه یک Dockerfile با فایلها و اسکریپتهای ناموجود بذاریم، یک مثال کامل و کوچک میسازیم. هدف این تمرین اینه که بفهمی چطور هم ایمیج پایه از رجیستری جایگزین گرفته میشه و هم یک وابستگی پایتون از میرور نصب میشه. این مثال بهعنوان یک دمو برای بررسی مخازن داخلی برای برنامه نویسان نوشته شده و نباید بدون سختسازی امنیتی بهعنوان سرویس واقعی منتشر بشه.
داخل یک پوشه خالی سه فایل Dockerfile، requirements.txt و app.py بساز. برای کاهش تغییرات ناخواسته از تگ نسخه مشخص استفاده میکنیم و آدرس pip رو فقط داخل مرحله ساخت همین ایمیج قرار میدیم؛ بااینحال برای بازتولید دقیقتر، در پروژه واقعی بهتره نسخه یا digest تمام وابستگیها و خود ایمیج پایه ثابت باشه.
FROM docker.arvancloud.ir/python:3.12-slim-bookworm
WORKDIR /app
ENV PYTHONUNBUFFERED=1 \
PIP_INDEX_URL=https://mirror-pypi.runflare.com/simple
COPY requirements.txt .
RUN python -m pip install --no-cache-dir -r requirements.txt
COPY app.py .
EXPOSE 8000
CMD ["python", "app.py"]
فایل نیازمندیها یک وابستگی مشخص داره. اگر اون نسخه روی میرور موجود نبود، خطای ساخت رو باید در مرحله pip بررسی کنی؛ نبود یک نسخه روی سرویس داخلی بهتنهایی نشونه اشتباه بودن Dockerfile نیست.
requests==2.32.5
برای برنامه نمونه از کتابخونه استاندارد پایتون یک وبسرور کوچک میسازیم و نسخه پکیج requests نصبشده رو هم در پاسخ نشون میدیم. به این ترتیب آزمایش مخازن داخلی برای برنامه نویسان فقط به «build بدون پیام خطا» محدود نمیشه و میتونیم یک خروجی قابل اندازهگیری هم بررسی کنیم. این وبسرور ساده عمداً مکانیزم احراز هویت، TLS و محدودیت درخواست Production نداره.
import json
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
import requests
class DemoHandler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path not in ("/", "/health"):
self.send_error(404)
return
result = json.dumps({
"service": "nabegheha-mirror-demo",
"status": "ok",
"requests": requests.__version__,
}).encode("utf-8")
self.send_response(200)
self.send_header("Content-Type", "application/json; charset=utf-8")
self.send_header("Content-Length", str(len(result)))
self.end_headers()
self.wfile.write(result)
if __name__ == "__main__":
ThreadingHTTPServer(("0.0.0.0", 8000), DemoHandler).serve_forever()
برای اجرا، باید Docker روی سیستم تو فعال باشه، رجیستری پایه در دسترس باشه و میرور پایتون هم تمام وابستگیهای لازم رو ارائه کنه. اگر یکی از این شرطها برقرار نباشه، ساخت متوقف میشه. بنابراین نباید ادعا کنیم که صرفاً به خاطر استفاده از مخازن داخلی برای برنامه نویسان این پروژه «صددرصد آفلاین» ساخته میشه.
docker build --pull -t nabegheha-mirror-demo .
docker run --rm -p 127.0.0.1:8000:8000 nabegheha-mirror-demo
وقتی کانتینر اجرا شد، یک ترمینال دیگه باز کن. مسیر سلامت باید کد وضعیت 200 و خروجی JSON برگردونه، اما آدرس ناشناخته باید 404 بده. این روش کمک میکنه یک بخش از نتیجه رو مستقل از ظاهر ترمینال بررسی کنی؛ البته پاسخ درست برنامه لزوماً ثابت نمیکنه تمام لایههای بیلد فقط از میرور داخلی دریافت شدهان.
curl -i http://127.0.0.1:8000/health
curl -i http://127.0.0.1:8000/unknown
میرور فلاتر در رانفلر؛ تنظیم برای ویندوز، لینوکس و مک
فلاتر و دارت برای دریافت پکیجها و بخشی از فایلهای SDK به منابع شبکه وصل میشن. دو متغیر محیطی PUB_HOSTED_URL و FLUTTER_STORAGE_BASE_URL کمک میکنن این درخواستها رو به مسیر دیگری بفرستی. برای استفاده از مخازن داخلی برای برنامه نویسان در پروژه فلاتر باید بدونی متغیر اول روی مخزن پکیجهای pub و متغیر دوم روی محل دریافت فایلهای مرتبط با SDK اثر میذاره، نه تمام بخشهای Android Studio و Gradle.
طبق مستندات فعلی میرور فلاتر رانفلر دو نشانی زیر معرفی شدن. در بعضی آموزشهای قدیمی مسیرهایی با پسوند /pub یا /storage دیده میشه؛ اونها رو بدون تطبیق با مستندات جدید کپی نکن. اگه از میرور فلاتر ایران استفاده میکنی، اول در یک پروژه آزمایشی عملکردش رو بررسی کن.
روی ویندوز، سادهترین روش آزمایشی اجرای این دستورها در PowerShell هست. این دو متغیر فقط برای همون نشست و فرایندهای فرزندش معتبر میمونن و روی تمام سیستم اثر دائمی نمیذارن. باید دستور flutter pub get رو داخل پوشه پروژهای بزنی که فایل pubspec.yaml داره.
$env:PUB_HOSTED_URL="https://mirror-flutter.runflare.com"
$env:FLUTTER_STORAGE_BASE_URL="https://mirror-gcs.runflare.com"
flutter pub get
روی لینوکس و مک هم بهتره اول متغیرها رو در ترمینال فعلی تعریف کنی. این روش برای سنجش مخازن داخلی برای برنامه نویسان امنتر از ویرایش فوری فایلهای تنظیمات شله؛ چون اگر میرور مناسب نبود، با بستن نشست یا حذف متغیرها به وضعیت قبلی برمیگردی.
export PUB_HOSTED_URL="https://mirror-flutter.runflare.com"
export FLUTTER_STORAGE_BASE_URL="https://mirror-gcs.runflare.com"
flutter pub get

اگر بعد از آزمایش نتیجه درست بود، برای استفاده دائمی میتونی متغیرها رو در تنظیمات کاربر ویندوز یا فایل مربوط به شل لینوکس ثبت کنی؛ Bash معمولاً ~/.bashrc و Zsh معمولاً ~/.zshrc رو استفاده میکنن. بعد از تغییر دائمی در ویندوز، ترمینال و ادیتور رو دوباره باز کن. برای برگشت در Bash یا Zsh دو متغیر رو حذف کن؛ در PowerShell هم مقدارهای نشست فعلی رو با دستورهای جداگانه پاک کن.
unset PUB_HOSTED_URL FLUTTER_STORAGE_BASE_URL
Remove-Item Env:PUB_HOSTED_URL -ErrorAction SilentlyContinue
Remove-Item Env:FLUTTER_STORAGE_BASE_URL -ErrorAction SilentlyContinue
مشکل بعضی پروژهها با همین دو تنظیم رفع نمیشه، چون Gradle، Android SDK یا وابستگیهای native مسیرهای جداگانه دارن. پس نباید ادعا کنیم تغییر میرور فلاتر ایران یعنی نصب کاملاً آفلاین فلاتر. برای آمادهسازی فایلهای SDK، کشها و اجرای پروژه بدون دسترسی شبکه، مقاله اختصاصی فلاتر با نت ملی رو بخون؛ اینجا موضوع اصلی راهاندازی و ارزیابی مخازن داخلی برای برنامه نویسان هست.
میرور دارت؛ تفاوت pub get و نصب آفلاین Dart SDK
دارت هم با ابزار pub پکیجهای پروژه رو مدیریت میکنه. وقتی دستور dart pub get رو اجرا میکنی، مخزن پیشفرض معمولاً pub.dev هست؛ متغیر PUB_HOSTED_URL میتونه این منبع رو تغییر بده. این یکی از کاربردهای مخازن داخلی برای برنامه نویسان در پروژههای Dart محسوب میشه، ولی نصب خود SDK یا فایلهای لازم برای بیلد مرحله جداگانهایه.
مثلاً در لینوکس یا مک میتونی مقدار متغیر رو برای همان نشست تنظیم کنی و بعد دستور دریافت وابستگیها رو اجرا کنی. اگر پروژه فایل pubspec.yaml نداره، طبیعیه که دستور موفق نشه. راهنمای رسمی متغیرهای محیطی Dart همین سازوکار رو توضیح میده.
export PUB_HOSTED_URL="https://mirror-flutter.runflare.com"
dart pub get
اگر واقعاً هیچ شبکهای نداری، موضوع «میرور دارت» رو با استفاده از کش محلی اشتباه نگیر. دستور dart pub get --offline فقط با بستههای موجود در کش کار میکنه و اگر نسخه لازم قبلاً دریافت نشده باشه ممکنه شکست بخوره. مقاله نصب دارت آفلاین با نت ملی مسیر آمادهسازی ابزار رو جدا توضیح میده؛ برای جلوگیری از همپوشانی سئو، توی این مقاله فقط نقش میرورها و وابستگیها رو پوشش میدیم.
سایر مخازن ایرانی؛ انتخاب میرور جایگزین و npm
هیچ دلیلی نداره تمام پروژهها رو به یک ارائهدهنده محدود کنی. بسته به نوع ابزار و وضعیت سرویس ممکنه رانفلر، آروانکلاد یا لیارا گزینههایی داشته باشن. برای انتخاب مخازن داخلی برای برنامه نویسان، اول صفحه رسمی همان سرویس رو ببین؛ آدرسها، سیاستهای مصرف و پوشش پکیج ممکنه تغییر کنن، حتی اگر یک مقاله قدیمی هنوز همون دستور رو نمایش بده.
برای نمونه رانفلر در صفحه پرسشهای متداول میرورها درباره سقف ۵۰۰ درخواست رایگان بهازای IP و نیاز به بسته بعد از اون توضیح داده. بنابراین حتی وقتی میرور در آزمایش کوتاه جواب میده، ممکنه استفاده مداوم در CI/CD با محدودیت سهمیه روبهرو بشه. این محدودیتها جزو معیارهای انتخاب میرورهای ایرانی هستن، نه جزئیات کماهمیت.
میرور npm ایران؛ تغییر رجیستری جاوااسکریپت بدون خاموشکردن SSL
اگر پروژه Node.js یا React داری، نصب پکیجها معمولاً با npm انجام میشه. برای آزمایش میرور npm ایران میتونی بهجای تغییر دائمی رجیستری، آدرس رو فقط در همان فرمان بدی. این روش برای مخازن داخلی برای برنامه نویسان منطقیتره، چون روی پروژههای دیگه و فایل تنظیمات کاربر اثر نمیذاره. آدرس نمونه از مستندات npm رانفلر گرفته شده.
npm install --registry=https://mirror-npm.runflare.com
برای تنظیم دائمی هم دستور npm config set registry وجود داره، اما بعد از آزمایش انجامش بده و برای برگشت از npm config delete registry استفاده کن. هرگز برای حل مشکل میرور بهطور پیشفرض strict-ssl رو غیرفعال نکن. حتی با وجود رجیستری داخلی ممکنه بعضی پکیجها در زمان نصب فایل باینری جداگانهای از سرور دیگری دانلود کنن؛ برای همین قطعبودن اینترنت بینالملل رو باید روی کل فرایند نصب آزمایش کنی.
npm config get registry
npm config set registry https://mirror-npm.runflare.com
# Revert only when needed:
npm config delete registry
برای انتخاب دقیقتر از بین مخازن داخلی برای برنامه نویسان به یک چکلیست نیاز داری: وضعیت فعلی سرویس، موجود بودن نسخه خاص، پشتیبانی از HTTPS، روش بررسی اصالت بسته، سیاست سهمیه، قابلیت پشتیبانی از کش و زمان بازگشت به منبع قبلی. جدول زیر یک راهنمای تصمیمه، نه رتبهبندی سرعت؛ بدون اندازهگیری روی شبکه واقعی نمیشه گفت کدوم ارائهدهنده همیشه سریعتره.
| معیار انتخاب | پرسشی که باید جوابش روشن باشه | روش بررسی |
|---|---|---|
| موجودی نسخه | آیا دقیقاً همین نسخه و معماری موجوده؟ | نصب آزمایشی با نسخه مشخص و خواندن خطا |
| دسترسی و سهمیه | آیا محدودیت نرخ، حجم یا IP وجود داره؟ | مستندات رسمی و پنل سرویس |
| امنیت | آیا ارتباط امن و اعتبارسنجی فعال میمونه؟ | TLS، امضا، هش و منشأ بسته |
| بازگشت | بعد از اختلال چطور به منبع قبلی برگردیم؟ | نسخه پشتیبان و تنظیم موقت |
| وابستگی زنجیره ساخت | آیا اسکریپتهای نصب فایل خارجی دیگری میگیرن؟ | لاگ کامل نصب یا build در محیط ایزوله |
رفع خطای میرورها؛ از DNS تا نبودن نسخه پکیج
تغییر آدرس مخزن معجزه نمیکنه. وقتی نصب هنوز خطا میده، بهجای امتحانکردن پشتسرهم چند دستور، متن پیام رو با نوع مشکل تطبیق بده. بررسی مخازن داخلی برای برنامه نویسان زمانی به نتیجه میرسه که بین خطای نام دامنه، قطع اتصال، محدودیت سهمیه و نبودن نسخه یک پکیج فرق بذاری.
| خطا یا نشانه | علت احتمالی | کار مناسب |
|---|---|---|
| Could not resolve host | نام دامنه از DNS پاسخ نگرفته | وضعیت DNS و نام میزبان رو بررسی کن |
| Connection timed out | ارتباط در زمان تعیینشده کامل نشده | دسترسی شبکه، فایروال و وضعیت سرور رو کنترل کن |
| 401 / 403 | مجوز، احراز هویت یا سهمیه | سیاست دسترسی و حساب سرویس رو بررسی کن |
| 404 / manifest unknown | آدرس، تگ یا نسخه پیدا نشده | نسخه و نام دقیق بسته یا ایمیج رو تطبیق بده |
| TLS / certificate error | گواهی معتبر نیست یا ساعت اشتباهه | اعتماد به CA و زمان سیستم رو اصلاح کن؛ TLS رو خاموش نکن |
| Hash / signature mismatch | اصالت یا یکپارچگی بسته تأیید نشده | نصب رو متوقف کن و منشأ فایل رو بررسی کن |
گاهی هم درخواست اصلی از میرور موفق میشه ولی مرحله بعدی خطا میده؛ مثلاً اسکریپت postinstall در npm، دانلود یک مدل، فهرست افزونهها یا دسترسی به سرویس احراز هویت خارجی. به همین دلیل برای استفاده جدی از مخازن داخلی برای برنامه نویسان باید «تمام زنجیره وابستگی» رو بشناسی. روی پروژههای مهم میتونی از کش داخلی کنترلشده، فایلهای wheel آماده، قفل نسخهها و رجیستری خصوصی استفاده کنی؛ البته اینها هم باید از قبل آزمایش بشن.
اگر لازم شد وضعیت یک سرویس HTTPS رو بهشکل اولیه بررسی کنی، ابزار curl میتونه فقط کد پاسخ HTTP یا خطای اتصال رو نشون بده. توجه کن درخواست HEAD ممکنه روی بعضی endpointها مجاز نباشه و نتیجه 405 الزاماً به معنی خرابی همه سرویس نیست. این بررسی ساده جای تست نصب واقعی پکیج رو نمیگیره.
curl -I --max-time 15 https://mirror-pypi.runflare.com/simple/
curl -I --max-time 15 https://mirror-flutter.runflare.com
پرسشهای متداول درباره میرور و اینترنت ملی
مخازن داخلی برای برنامه نویسان دقیقاً چه کاری میکنن؟
بسته به سرویس، نسخهای از پکیجها، فایلها یا ایمیجها رو در یک مسیر جایگزین ارائه میکنن. این کار ممکنه مشکل دسترسی به بعضی مخازن خارجی رو کم کنه، ولی دسترسی به همه منابع اینترنت رو تضمین نمیکنه.
بهترین میرورهای ایرانی برای پایتون و داکر کدومن؟
گزینه ثابتی برای همه پروژهها وجود نداره. اول بررسی کن نسخه موردنیاز روی سرویس هست، مدارک و سیاست مصرفش روشنه و کانال امن و روش بازگشت به مخزن قبلی داره؛ بعد در شبکه خودت آزمایش کن.
آیا با مخازن داخلی برای برنامه نویسان میشه کاملاً آفلاین کار کرد؟
خیر، خود میرور یک منبع شبکهایه. برای نصب کاملاً آفلاین باید SDK، بستهها، وابستگیها و ابزارهای ساخت از قبل آماده و در کش یا فضای محلی ذخیره شده باشن.
چرا pip بعد از تغییر میرور باز هم به اینترنت خارج وصل میشه؟
ممکنه یک وابستگی یا اسکریپت ساخت به منبع دیگری نیاز داشته باشه، متغیر محیطی تنظیمات pip رو تغییر داده باشه یا نسخه دلخواه روی میرور پیدا نشه. خروجی pip config debug و لاگ نصب رو بررسی کن.
چرا در اوبونتو 24.04 تغییر sources.list نتیجه نمیده؟
چون فایل فعال پیشفرض معمولاً ubuntu.sources در پوشه sources.list.d هست. اول فایلهای فعال رو شناسایی کن، نسخه پشتیبان بگیر و فقط منابع تأییدشده رو عوض کن.
آیا میرور داکر ایران برای تمام رجیستریها و تگها کار میکنه؟
نه. بعضی سرویسها فقط مجموعهای از ایمیجهای عمومی یا Docker Hub رو پشتیبانی میکنن. موجودی دقیق نسخه و رجیستری سازگار رو باید طبق مستندات و آزمایش واقعی بررسی کرد.
با تغییر PUB_HOSTED_URL فلاتر و دارت کاملاً آماده میشن؟
نه. این متغیر مقصد پیشفرض دریافت پکیجهای pub رو تغییر میده. Flutter SDK، Gradle، Android SDK و وابستگیهای native ممکنه تنظیمات و فایلهای جداگانه بخوان.
چطور تنظیمات میرور پایتون رو به حالت قبلی برگردونم؟
اگر با pip config –user set global.index-url مقدار ثبت کردی، با pip config –user unset global.index-url حذفش کن. اگر متغیر محیطی یا فایل دیگری مؤثر باشه باید اون رو جداگانه بررسی کنی.
آیا استفاده از مخازن داخلی برای برنامه نویسان از نظر امنیتی بیخطره؟
هیچ میرور ثالثی بهخودیخود امنیت رو تضمین نمیکنه. ارتباط HTTPS، امضای بستهها، نسخهها، هش فایل و اعتبار ارائهدهنده رو کنترل کن و برای رفع خطا، TLS یا اعتبارسنجی امضا رو خاموش نکن.
جمعبندی؛ برای هر ابزار یک مسیر جایگزینِ قابل بازگشت داشته باش
اگر فقط یک نکته رو از این راهنما نگه میداری، این باشه: مشکل دانلود رو تشخیص بده، بعد آدرس مخزن رو تغییر بده. مخازن داخلی برای برنامه نویسان میتونن برای نصب پکیج پایتون، بهروزرسانی اوبونتو، دانلود ایمیج داکر یا دریافت بعضی بستههای فلاتر و دارت مفید باشن؛ اما محدوده پشتیبانی، سهمیه، صحت بستهها و راه برگشت همیشه مهمتر از یک دستور ظاهراً جادویی هستن.
توی نابغهها هدفم اینه که وقتی با خطا روبهرو میشی، فقط دنبال یک کد برای کپیکردن نباشی و واقعاً بدونی چه اتفاقی افتاده. این راهنما درباره مخازن داخلی برای برنامه نویسان یک نقشه تصمیمگیریه: روش موقت رو آزمایش کن، وضعیت دانلود رو بررسی کن، بعد اگر لازم بود تنظیمات دائمی رو با نسخه پشتیبان انجام بده. برای نصب آفلاین خود زبانها هم مقالههای اختصاصی پایتون، دارت و فلاتر رو جدا نگه داشتیم تا هر صفحه دقیقاً به سؤال مخاطب خودش جواب بده.
منابع رسمی برای بررسی تنظیمات مخازن داخلی
چون مخازن داخلی برای برنامه نویسان ممکنه از نظر آدرس یا سیاست استفاده تغییر کنن، بهتره قبل از اجرای دستور روی سرور واقعی با مستندات رسمی تطبیق بدی: پیکربندی pip، میرور Docker Hub، راهنمای Flutter برای میرورها، متغیرهای Dart pub و فهرست میرورهای رانفلر. این منابع درباره سازوکار ابزارها و آدرسهای رسمی اطلاعات میدن، ولی موفقیت عملی روی شبکه تو رو تضمین نمیکنن.
اگه میخوای این موضوع رو جدیتر یاد بگیری، مسیر کاملش اینجاست.
دورهها موضوع رو از پایه تا اجرای واقعی، پروژه و نکتههایی که وسط کار بهشون میرسی جلو میبرن.
نظرها و تجربهها
سؤال، تجربه یا نکتهای درباره این مقاله داری؟ اینجا بنویس تا گفتوگو برای بقیه هم مفید بمونه.
ران فلیر برای پکیج های فلاتر عالیه، ولی گریدل رو چه کنیم؟ از همون روش افلاین مقالتون استفاده کنیم یا میرور هم هست که درست کنه، ران فلیر برای گریدل میرور داره و من هم ست کردم ولی خب نمیدونم چرا کار نمی کنه.
گریدل رو هم داره همین سایت
خدا وکیلی دمت گرم ، اوبونتومو آپدیت کردم دمت گرم خیلی عشقی
دم شما گرم آقای معلمی خیلی جواب بود! دست شما درد نکنه دوستان مخرن مایکت هم هست برای گردل (maven.myket.ir) علاوهبر کتابخانه ها، Gradle Wrapper و android sdk میتونید باهاش نصب کنید
سلام استاد در آینده اگر امکانش باشه ،میشه یاد بدین چطور سوپابیس رو بر روی هاست شخصی خودمون اجرا کنیم ؟چون اصلا منیع فارسی نیست که آموزش بده ،ممنون از زحماتتون❤️