WIUNIX ACADEMY
راهاندازی رجیستری خصوصی Docker با HTTPS و Nginx
رجیستری خصوصی ایمیج را با نسخهٔ پینشده، دسترسی محلی بکاند، احراز هویت bcrypt، آپلود جریانی و نگهداشت سازگار داده راهاندازی کنید.
محیطت را انتخاب کنآموزش متناسب با محیط تو
کجا اجرا میکنی؟
سیستمعامل و نسخه را انتخاب کن تا مراحل، دستورها و راهحلها برای همان محیط نمایش داده شوند.
آموزش متناسب با مقادیر تو
تنظیمات این آموزش
مقادیر نمونه را برای محیط خودت تنظیم کن؛ متن و دستورهای مرتبط با هم تغییر میکنند. رمز، کلید خصوصی و توکن وارد نکن. مقادیر فقط در همین زبانه نگهداری میشوند و به سرور یا لینک اشتراکگذاری فرستاده نمیشوند. پیش از اجرا، DNS، گواهیها و سیاست شبکهٔ واقعی را بررسی کن.
آیپی، دامنه یا پورت مثالها با محیط تو فرق دارد؟ دکمهٔ زیر را باز کن، مقادیر را تغییر بده و «اعمال در آموزش» را بزن؛ سپس دستورهای بهروزشده را کپی کن.
تنظیم مقادیر برای محیط من8 مقدار قابلتغییر
از اینجا شروع کن
در پایان چه چیزی خواهی داشت؟
ارسال و دریافت ایمیج خصوصی با HTTPS معتبر و حفظ داده و احراز هویت.
سیستمعاملها و نسخههای پوششدادهشده
مسیر سیستمعاملها مستند است؛ آزمون ایزوله و پذیرش عملیاتی اجرانشده جدا بیان شدهاند.
قبل از شروع
- VM تازه و Docker Engine روتدار نسخهٔ ۲۸ یا جدیدتر؛ محیط انتخابی مسیر مستند است.
- گواهی و کلید معتبر، DNS، دسترسی TCP443 و helper آمادهٔ کلاینت.
خروجی: رجیستری خصوصی با مرز دسترسی مشخص
هدف این راهنما داشتن مخزن خصوصی ایمیج برای یک تیم مورد اعتماد است: دامنهٔ registry.example.net با HTTPS پاسخ میدهد، بکاند فقط روی پورت محلی 5000 در دسترس است و دادهها زیر /srv/academy-registry باقی میمانند. اجرای اولیه حدود یک ساعت زمان میبرد؛ آمادهکردن گواهی و بکاپ را جدا حساب کنید.
این طراحی تکسرور است. کاربر ثبتشده مجوز گستردهٔ push و pull دارد؛ bcrypt جای سطح دسترسی به تفکیک مخزن، اسکن امنیتی یا امضای ایمیج را نمیگیرد. برای تیمهایی که نباید دادهٔ یکدیگر را ببینند، ابتدا سرویس صدور توکن و سیاست مجوزدهی طراحی کنید.
پیش از کپی، نمونهها را با محیط خود هماهنگ کنید
فرم تنظیمات را باز کنید، مقدارهای عمومی را تغییر دهید، «اعمال» را بزنید و بعد کپی کنید. تا وقتی تغییرات اعمال نشده یا نامعتبرند، کپی غیرفعال میماند. رمز، کلید خصوصی و secret را در این فرم ننویسید؛ جای آنها ویرایشگر محافظتشده است.
تنظیمات و پیشرفت نسخهٔ شخصی فقط برای همین تب، زبان، مقاله و محیط در sessionStorage میماند. پیشرفت با مقادیر پیشفرض در localStorage ذخیره میشود. «بازنشانی» نمونههای بازبینیشده را برمیگرداند؛ شخصیسازی متن، آزمون نصب یا تغییر واقعی DNS نیست.
نیازمندیهای سرور و کلاینت را از ابتدا مشخص کنید
سرور تازه و اختصاصی با sudo، فضای دیسک و inode کافی و Docker Engine روتدار نسخهٔ ۲۸ یا جدیدتر لازم است. نصب Docker باید طبق روش پشتیبانیشدهٔ همان سیستمعامل انجام شده باشد؛ بستههای Docker CE و توزیع را با هم ترکیب نکنید. با نسخهٔ قدیمی یا rootless این تمرین را ادامه ندهید.
دامنه باید با رکوردهای A و AAAA درست به همین سرور برسد و TCP443 برای کلاینتهای مجاز باز باشد. زنجیرهٔ معتبر گواهی، کلید متناظر و برنامهٔ تمدید را پیشاپیش آماده کنید. این مقاله حساب ACME نمیسازد. در شبکهٔ دارای CA خصوصی، ریشهٔ اعتماد باید روی سیستم و daemon تمام کلاینتها نصب شود؛ خطای اعتماد را با حالت insecure دور نزنید.
مسیر نمونهٔ کلاینت لینوکسی به helper نوع pass و کلید GPG آماده نیاز دارد. دستور ورود باید در نبود helper متوقف شود، نه اینکه رمز را به صورت base64 در JSON ذخیره کند. مسیر keychain سایر سیستمها در این آزمون اجرا نشده است.
قدم بعدی
تداخل نام، شناسه و پورت را بررسی کنید
روی VM رجیستری اجرا کنید. در خروجی SecurityOptions نباید rootless دیده شود. نام academy-registry، UID و GID عددی 23153 و دو پورت 443 و 5000 باید آزاد باشند. این شناسه را برای کانتینر در فهرست منابع خود رزرو کنید؛ حساب ورود لینوکسی ساخته نمیشود. اگر تداخلی هست، تنظیمات را عوض کنید، نه سرویس موجود را.
VM رجیستری
set -eu
sudo docker version --format '{{.Server.Version}}'
sudo docker info --format '{{.SecurityOptions}}'
sudo docker container inspect 'academy-registry' >/dev/null 2>&1 && exit 1
if getent passwd '23153' >/dev/null; then exit 1; fi
if getent group '23153' >/dev/null; then exit 1; fi
sudo python3 - <<'PY'
import socket, subprocess
v=subprocess.check_output(['docker','version','--format','{{.Server.Version}}'],text=True).strip()
assert int(v.split('.')[0]) >= 28, 'Docker Engine >=28 required'
for port in (443, 5000):
with socket.socket() as s:
s.bind(('0.0.0.0',port))
print('Engine version and port availability: OK')
PY
نسخهٔ مناسب و آزادبودن منابع تأیید میشود؛ در صورت تداخل ادامه ندهید.
قدم بعدی
ابزارهای لازم را از مخزن امضاشده نصب کنید
این دستور مخصوص محیط انتخابشده است و پیش از نصب نام انتشار را کنترل میکند. نصب Nginx ممکن است سرویس را روشن کند؛ به همین دلیل سرور باید اختصاصی و بدون سرویس قبلی باشد. نسخهٔ رجیستری از ایمیج پینشده میآید و به بستهٔ توزیع وابسته نیست.
VM رجیستری
set -eu
. /etc/os-release
test "$VERSION_CODENAME" = 'bookworm'
sudo apt-get update
apt-cache policy nginx apache2-utils python3
sudo apt-get install --no-install-recommends nginx apache2-utils python3 openssl ca-certificates curl nano
nginx -v
dpkg-query -W nginx apache2-utils python3 openssl
نام انتشار درست است و نسخهٔ ابزارهای نصبشده نمایش داده میشود.
قدم بعدی
مسیر اختصاصی و فایل ورودی رمز بسازید
مسیر /srv/academy-registry باید جدید و زیر یک پوشهٔ واقعی موجود در /srv باشد. کد، مسیرهای symlink و دادهٔ قبلی را رد میکند و مالکیت درختی از فایلهای موجود را تغییر نمیدهد. فقط data به شناسهٔ کانتینر تعلق میگیرد؛ auth و config همچنان در اختیار root هستند.
در ویرایشگر محافظتشده یک رمز تصادفی ۲۰ تا ۷۲ بایتی ASCII، بدون فاصله و فقط در یک خط وارد کنید. آن را از مدیر رمز مورد اعتماد بگیرید؛ رمز نباید در آرگومان فرمان، فرم مرورگر، اسکرینشات یا تاریخچهٔ شل قرار بگیرد. فایل را ذخیره کنید و ببندید.
VM رجیستری
sudo python3 - <<'PY'
import os
from pathlib import Path
p=Path('/srv/academy-registry')
assert p.is_absolute() and len(p.parts)>=3 and p.parts[1]=='srv'
for part in [p,*p.parents]:
assert not part.is_symlink(), 'Symlink path rejected'
assert p.parent.is_dir() and not p.exists(), 'Fresh dedicated path required'
os.mkdir(p,0o750)
os.chown(p,0,23153)
for name in ('data','auth','config','tls','recovery'):
d=p/name; os.mkdir(d,0o700)
if name=='data': os.chown(d,23153,23153)
elif name in ('auth','config'):
os.chown(d,0,23153); os.chmod(d,0o750)
f=p/'auth/password-input'
fd=os.open(f,os.O_WRONLY|os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW,0o600)
os.close(fd)
print('Dedicated directories reserved; protected password editor file is empty')
PY
sudo nano '/srv/academy-registry/auth/password-input'
پوشهها تازهاند و فایل ورودی رمز فقط با دسترسی 0600 در اختیار root است.