APT + DNF

نصب Docker، Kubernetes و Terraform روی سرور ایران: رفع خطای 403 و Timeout

علت خطای 403 و Timeout در apt و dnf روی سرورهای ایران، روش تشخیص لایه‌ی مشکل و نصب پایدار Docker، Kubernetes، Terraform و nginx از یک مخزن داخلی.

در سرورهای ایران، اجرای apt update یا dnf install برای مخزن‌های خارجی اغلب با خطای «403 Forbidden»، «Connection timed out» یا «Curl error» متوقف می‌شود. این راهنما علت‌های رایج این خطاها را توضیح می‌دهد، روشی برای تشخیص لایه‌ی مشکل (DNS، شبکه، HTTP یا ساعت سیستم) ارائه می‌کند و نشان می‌دهد چگونه Docker، Kubernetes، Terraform و nginx را از یک مخزن داخلی به‌صورت پایدار نصب و به‌روزرسانی کنید.

چرا نصب پکیج از ایران خطای 403 یا Timeout می‌دهد؟

چند دلیل جدا پشت یک نشانه‌ی ظاهراً یکسان است:

  • محدودیت بر اساس موقعیت IP: بعضی منابع دسترسی را برای بازه‌های IP مشخصی محدود می‌کنند. نتیجه معمولاً کد 403 است: سرور شما را می‌بیند ولی اجازه‌ی دانلود نمی‌دهد.
  • قطع یا کندی مسیر شبکه: اتصال اصلاً برقرار نمی‌شود یا وسط انتقال می‌پرد. نشانه‌اش Timeout، Connection reset یا Could not connect است.
  • مشکل DNS: نام مخزن resolve نمی‌شود یا به IP اشتباه می‌رسد.
  • گواهی یا ساعت سیستم: ساعت اشتباه سرور باعث رد شدن گواهی TLS می‌شود و شبیه یک خطای شبکه به نظر می‌رسد.

چون راه‌حل هرکدام فرق دارد، قبل از هر تغییری باید لایه‌ی مشکل را مشخص کنید.

گام اول: مشخص کنید مشکل از کدام لایه است

از خود سرور این چند دستور را بزنید؛ ترتیب مهم است، چون هر مرحله لایه‌ی بعدی را ممکن می‌کند:

# ۱) نام دامنه resolve می‌شود؟
getent hosts download.docker.com

# ۲) پورت 443 باز است؟
nc -zv download.docker.com 443

# ۳) پاسخ HTTP چیست؟ (کد وضعیت را ببینید)
curl -sI https://download.docker.com/linux/ubuntu/gpg | head -n 1

# ۴) ساعت سیستم درست است؟
timedatectl

اگر مرحله‌ی ۱ شکست بخورد مشکل DNS است؛ اگر ۲ شکست بخورد مسیر شبکه یا فایروال؛ و اگر به ۳ برسید و HTTP/2 403 ببینید یعنی اتصال برقرار است ولی خود مبدأ شما را نمی‌پذیرد. برای دو مورد اول می‌توانید از ابزارهای آنلاین هم کمک بگیرید، ولی توجه کنید آن‌ها از بیرون از سرور شما نگاه می‌کنند و ممکن است نتیجه‌ی متفاوتی ببینند.

DNSDNS Lookupرکوردهای دامنه‌ی مخزن را ببینید و مطمئن شوید به آدرس درست اشاره می‌کنند.HTTPHTTP Headers Viewerکد وضعیت و هدرهای پاسخ یک آدرس را از سمت یک سرور بیرونی ببینید.
note اگر خطا فقط روی یک مخزن (مثلاً Docker) است ولی بقیه‌ی مخزن‌ها کار می‌کنند، مشکل شبکه‌ی عمومی سرور نیست؛ منبع خاصی است که شما را رد می‌کند، و راه‌حل درست، عوض‌کردن منبع است نه دست‌کاری شبکه.

راه‌حل پایدار: مخزن داخل ایران

به‌جای مبارزه با هر خطا به‌صورت جداگانه، می‌توانید منبع بسته‌ها را عوض کنید. dacker.ir یک مخزن apt و dnf است که داخل ایران میزبانی می‌شود و بسته‌هایی را که از سرورهای ایران یا قابل‌دسترس نیستند یا 403 می‌دهند، در دسترس قرار می‌دهد. مزیت‌ها:

  • نصب و ارتقای عادی: بعد از افزودن مخزن، همان apt install و dnf install همیشگی کار می‌کند؛ ابزار جدیدی لازم نیست.
  • بسته‌های امضاشده: مخزن با یک کلید امضا شده و اثرانگشت آن منتشر شده است.
  • پوشش پرکاربردترین ابزارهای زیرساخت: Docker Engine، Kubernetes، Helm، Terraform، Packer، Vault، Ansible، nginx، PHP، Node.js، Python، .NET، PostgreSQL، MariaDB، MySQL، MongoDB، Redis/Valkey، Elastic Stack، Grafana، GitLab CE و GitLab Runner.
  • توزیع‌های رایج سرور: Ubuntu 22.04 و 24.04 و AlmaLinux، Rocky و RHEL نسخه‌ی ۸ و ۹ (CentOS 7 به‌صورت best-effort).
warn دستورهای زیر را همان‌طور که روی dacker.ir منتشر شده آورده‌ایم، ولی مخزن‌ها تغییر می‌کنند. قبل از اجرا، صفحه‌ی محصول و توزیع خودتان را روی سایت ببینید و اثرانگشت کلید را تطبیق دهید.

نصب Docker روی Ubuntu با apt

سه کار لازم است: دریافت کلید امضا، ثبت فایل مخزن، و نصب. نمونه‌ی زیر برای Ubuntu 24.04 است؛ در Ubuntu 22.04 به‌جای فایل .sources از فایل .list همان محصول استفاده می‌شود (آدرس دقیق در صفحه‌ی محصول آمده است).

# ۱) کلید امضای مخزن
sudo curl -fsSL https://repo.dacker.ir/dacker.gpg -o /usr/share/keyrings/dacker.gpg

# ۲) فایل مخزن Docker (Ubuntu 24.04)
sudo curl -fsSL https://repo.dacker.ir/apt/sources/dacker-docker.sources \
  -o /etc/apt/sources.list.d/dacker-docker.sources

# ۳) نصب
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

اگر ترجیح می‌دهید یک خط .list بنویسید، معادل آن این است:

echo "deb [arch=amd64 signed-by=/usr/share/keyrings/dacker.gpg] https://repo.dacker.ir/apt/docker noble main" \
  | sudo tee /etc/apt/sources.list.d/dacker-docker.list

نام بسته‌ها همان نام‌های مخزن رسمی هر محصول است. بعد از نصب، مطمئن شوید بسته واقعاً از مخزن داخلی می‌آید:

apt policy docker-ce
sudo docker run --rm hello-world

نصب روی AlmaLinux، Rocky و RHEL با dnf

در خانواده‌ی RHEL به‌جای کلید keyring، کلید هر فروشنده با rpm --import وارد می‌شود و فایل مخزن در /etc/yum.repos.d قرار می‌گیرد. نمونه برای Docker:

sudo rpm --import https://repo.dacker.ir/el/keys/docker.asc

sudo curl -fsSL https://repo.dacker.ir/el/repos/dacker-docker.repo \
  -o /etc/yum.repos.d/dacker-docker.repo

sudo dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker

برای هر محصول دیگر (مثلاً nginx یا Terraform) همین الگو را تکرار می‌کنید؛ فقط کلید و فایل مخزن همان محصول عوض می‌شود.

پیش از اعتماد، کلید را راستی‌آزمایی کنید

افزودن یک مخزن یعنی به منتشرکننده‌اش اجازه می‌دهید روی سرورتان کد نصب کند؛ پس این کار را با دقت انجام دهید. اثرانگشت منتشرشده برای کلید امضای dacker این است:

8F36 3F83 6263 F265 F686 BBB9 1363 921A A23C D7DB

روی سرور، اثرانگشت کلیدی را که دانلود کرده‌اید نشان دهید و با مقدار بالا (و صفحه‌ی کلید روی خود سایت) تطبیق دهید:

gpg --show-keys --with-fingerprint /usr/share/keyrings/dacker.gpg

اگر مقدارها یکی نبود، فایل را حذف کنید و نصب را ادامه ندهید.

وقتی docker pull هم 403 می‌دهد

مخزن بسته‌ها فقط خود Docker Engine را نصب می‌کند؛ ایمیج‌ها از یک رجیستری جدا دانلود می‌شوند و محدودیت آن‌ها جداست. راه‌حل معمول، تعریف یک آینه (registry mirror) در تنظیمات دیمن است:

{
  "registry-mirrors": ["https://<mirror-address>"]
}

بعد از ذخیره‌ی فایل /etc/docker/daemon.json سرویس را ری‌استارت کنید (sudo systemctl restart docker) و با docker info بخش Registry Mirrors را ببینید. آدرس آینه و جزئیات کار را در راهنمای مخصوص روی dacker.ir می‌بینید: رفع خطای 403 در docker pull. اگر می‌خواهید قبل از دانلود بدانید یک ایمیج چقدر حجم دارد و کدام لایه سنگین‌ترین است، از ابزار زیر استفاده کنید.

IMGDocker Image Size Calculatorحجم لایه‌های یک ایمیج را روی رجیستری ببینید و Dockerfile را بررسی کنید.YMLDocker Compose Validatorفایل docker-compose.yml را پیش از اجرا بررسی کنید.

نصب Kubernetes (kubeadm، kubelet و kubectl)

کوبرنتیز برای هر نسخه‌ی minor (مثلاً v1.xx) مخزن و کلید جداگانه دارد؛ بنابراین اول تصمیم بگیرید کلاستر روی کدام نسخه باشد و بعد کلید و مخزن همان نسخه را اضافه کنید. صفحه‌ی محصول Kubernetes در dacker.ir نسخه‌ها و دستورهای هر توزیع را فهرست کرده است. بعد از افزودن مخزن:

sudo apt update
sudo apt install kubelet kubeadm kubectl

# جلوی ارتقای ناخواسته‌ی نسخه را بگیرید
sudo apt-mark hold kubelet kubeadm kubectl

قفل‌کردن نسخه مهم است: ارتقای کلاستر کوبرنتیز باید عمدی و مرحله‌ای (ابتدا control-plane، سپس workerها) انجام شود، نه به‌عنوان اثر جانبی یک apt upgrade معمولی. وقتی کلاستر بالا آمد، مانیفست‌های اپلیکیشن‌ها را می‌توانید با فرم بسازید:

K8SKubernetes YAML GeneratorDeployment، Service و Ingress آماده برای kubectl apply بسازید.

برای Terraform هم همین الگو برقرار است (کلید HashiCorp و فایل مخزن)، و dacker.ir یک راهنمای جداگانه برای استفاده از Terraform در ایران دارد که به آینه‌ی provider هم می‌پردازد.

توصیه‌های عملی برای نصب پایدار

  • نسخه را قفل کنید. برای Docker، Kubernetes و دیتابیس‌ها apt-mark hold (یا dnf versionlock) بگذارید و ارتقا را زمان‌بندی‌شده انجام دهید.
  • ابتدا روی staging. هر بار که منبع بسته یا نسخه عوض می‌شود، روی یک سرور آزمایشی امتحانش کنید.
  • یک مخزن، یک منبع حقیقت. اگر برای یک بسته چند مخزن فعال باشد، apt policy را بخوانید و مطمئن شوید نسخه از جایی می‌آید که انتظار دارید.
  • تنظیمات را در کد نگه دارید. افزودن کلید و مخزن را به‌صورت یک نقش Ansible یا بخشی از cloud-init/Packer ثبت کنید تا هر سرور جدید بدون دست‌کاری دستی ساخته شود.
  • ساعت سیستم را همگام نگه دارید (chrony یا systemd-timesyncd)؛ خطای گواهی ناشی از ساعت اشتباه شبیه مشکل شبکه به نظر می‌رسد و عیب‌یابی را به بیراهه می‌برد.

جمع‌بندی و گام بعدی

نصب پایدار روی سرور ایران از سه کار ساده تشکیل می‌شود: مشخص‌کردن لایه‌ی مشکل، استفاده از یک مخزن قابل‌اعتماد با کلید امضای راستی‌آزمایی‌شده، و قفل‌کردن نسخه‌ی بسته‌های حساس. بعد از نصب Docker، مرحله‌ی بعد نوشتن ایمیج و فایل Compose درست است؛ راهنماهای نوشتن Dockerfile بهینه و اشتباه‌های رایج docker-compose را ببینید. اگر هدف شما کلاستر است، مانیفست‌های Kubernetes نقطه‌ی شروع مناسبی است، و برای نظارت بر سرویس‌هایی که بالا آورده‌اید، راه‌اندازی Prometheus و Grafana را مطالعه کنید.

پرسش‌های متداول

آیا استفاده از مخزن داخلی امن است؟
بسته‌ها با کلید امضای مخزن امضا می‌شوند و apt و dnf پیش از نصب امضا را بررسی می‌کنند. اثرانگشت کلید روی خود dacker.ir منتشر شده است؛ پیش از اعتماد، آن را با خروجی gpg --show-keys مقایسه کنید.
بعد از نصب، به‌روزرسانی چطور انجام می‌شود؟
مثل هر مخزن دیگر: apt update && apt upgrade در اوبونتو یا dnf upgrade در خانواده‌ی RHEL. چون مخزن به‌صورت فایل در /etc/apt/sources.list.d یا /etc/yum.repos.d ثبت شده، نیازی به ابزار جداگانه نیست.
اگر خطای 403 هنگام docker pull بگیرم چه؟
این خطا به رجیستری ایمیج مربوط است، نه مخزن بسته‌های سیستم. راه‌حل معمول، تنظیم registry-mirrors در /etc/docker/daemon.json است؛ راهنمای مخصوص آن روی dacker.ir موجود است.
برای نسخه‌ی خاصی از Kubernetes چه کنم؟
کوبرنتیز برای هر نسخه‌ی minor مخزن و کلید جدا دارد. نسخه‌ی مورد نظر را در صفحه‌ی محصول انتخاب کنید و بعد از نصب، kubelet، kubeadm و kubectl را با apt-mark hold قفل کنید تا ارتقای ناخواسته رخ ندهد.