SSD Nodes Learn Hosting plans →
راهنماها Matt Connorتوسط Matt Connor · به‌روزرسانی شده 2026-08-07

راه اندازی MinIO روی Ubuntu 24.04 برای فضای ذخیره‌سازی S3

با نصب MinIO روی یک سرور Ubuntu 24.04، فضای ذخیره‌سازی S3 شخصی بسازید. این راهنما شامل تنظیم systemd، پیکربندی mc و استفاده از آن به عنوان مقصد پشتیبان‌گیری restic است.

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, July 30, 2026.

مزایای استفاده از MinIO به عنوان فضای ذخیره‌سازی شیء (Object Storage) خودمیزبان

MinIO یک فضای ذخیره‌سازی شیء خودمیزبان است که از API سرویس Amazon S3 پشتیبانی می‌کند. کافی است restic یا هر SDK سازگار با S3 را به سمت سرور خود هدایت کنید و تنها یک تنظیم endpoint را تغییر دهید؛ در این صورت، کلاینت تفاوتی احساس نخواهد کرد. این راهنما یک گره (node) واحد را روی Ubuntu 24.04 پیاده‌سازی می‌کند: شامل یک باینری تأییدشده، یک کاربر سیستمی اختصاصی، یک unit فایل systemd که اعتبارنامه‌های root را خارج از فایل نگه می‌دارد، و یک bucket که restic برای پشتیبان‌گیری از آن استفاده می‌کند.

سرویس S3 (سرویس ذخیره‌سازی ساده) یک API مبتنی بر HTTP است و نه یک سیستم فایل. شما یک شیء را با یک کلید در یک bucket قرار می‌دهید (PUT) و آن را دریافت می‌کنید (GET)؛ در این مدل، نوشتن جزئی یا تغییر نام وجود ندارد. ابزارهای پشتیبان‌گیری این مدل را می‌پسندند، زیرا یک شیء یا به‌طور کامل منتقل شده است یا اصلاً منتقل نشده است.

یک گره، تنها یک نسخه از داده‌های شما را نگهداری می‌کند. این همان معامله‌ای است که انجام می‌دهید. شما در ازای هزینه یک VPS، یک endpoint با پروتکل S3 در اختیار دارید که کنترل آن با خودتان است، اما در عین حال تمام وظایفی که قبلاً ارائه‌دهنده ابری انجام می‌داد، از تعویض دیسک معیوب گرفته تا وصله‌کردن نرم‌افزار سرور، بر عهده شما خواهد بود. بخش انتهایی این راهنما به‌صراحت توضیح می‌دهد که این معامله چه زمانی منطقی و به‌صرفه است.

وضعیت نسخه Community از MinIO در ژوئیه 2026

پیش از آنکه بر اساس این راهنما اقدام به پیاده‌سازی کنید، این بخش را مطالعه کنید، زیرا اخیراً تغییراتی ایجاد شده است. در مه 2025، MinIO قابلیت‌های مدیریتی را از کنسول وب در نسخه Community حذف کرد. آنچه در مرورگر باقی مانده، صرفاً یک مرورگر آبجکت (object browser) است؛ بنابراین مدیریت باکت‌ها و کلیدهای دسترسی اکنون باید از طریق کلاینت خط فرمان mc انجام شود.

در اواخر سال 2025، MinIO انتشار باینری‌های پیش‌کامپایل‌شده برای نسخه Community را متوقف کرد. در فایل README این پروژه اکنون ذکر شده که نسخه Community تنها به صورت سورس‌کد توزیع می‌شود. URLهای قدیمی دانلود همچنان کار می‌کنند: تا ژوئیه 2026، این لینک‌ها نسخه سرور RELEASE.2025-09-07T16-13-09Z و نسخه کلاینت RELEASE.2025-08-13T08-35-41Z را ارائه می‌دهند و هیچ نسخه جدیدتری برای Community منتشر نشده است. بنابراین، باینری ذکر شده در ادامه، واقعی و قابل اجراست، اما در این نسخه ثابت مانده است. اصلاحات امنیتی منتشر شده پس از سپتامبر 2025 در این نسخه وجود ندارند.

همین واقعیت، رویکرد باقی این راهنما را تعیین می‌کند. به همین دلیل است که MinIO در اینجا روی 127.0.0.1 گوش می‌دهد و تنها از طریق پروکسی که شما کنترل می‌کنید به اینترنت دسترسی دارد. اگر ترجیح می‌دهید اصلاحات امنیتی را دنبال کنید، باید از سورس‌کد کامپایل کنید. فایل README سازنده، یک دستور واحد یعنی go install github.com/minio/minio@latest را ارائه می‌دهد که به زنجیره ابزار Go نیاز دارد و باینری را در مسیر ~/go/bin/minio می‌نویسد. آن باینری را در /usr/local/bin/minio نصب کنید؛ سایر مراحل این راهنما بدون تغییر باقی می‌مانند.

نصب باینری MinIO و تأیید دانلود

نسخهٔ مشخص‌شده (pinned release) و چک‌سام منتشرشدهٔ آن را دانلود کنید. پرچم -f باعث می‌شود curl در صورت بروز خطای HTTP، به‌جای ذخیره کردن صفحهٔ خطا با نام درخواستی شما، عملیات را متوقف کند؛ این همان اشتباهی است که باعث می‌شود کاربران به‌جای برنامه، یک صفحهٔ 404 را نصب کنند و سپس در عجب بمانند که چرا اجرا نمی‌شود.

cd /tmp
REL=RELEASE.2025-09-07T16-13-09Z
curl -fsSL "https://dl.min.io/server/minio/release/linux-amd64/archive/minio.$REL" -o minio
curl -fsSL "https://dl.min.io/server/minio/release/linux-amd64/archive/minio.$REL.sha256sum" -o minio.sha256sum

دو هش را با هم مقایسه کنید؛ فقط هش‌ها را مقایسه کنید.

published=$(awk '{print $1}' minio.sha256sum)
downloaded=$(sha256sum minio | awk '{print $1}')
[ "$published" = "$downloaded" ] && echo "checksum ok"

در اینجا از sha256sum -c minio.sha256sum استفاده نکنید. برچسبی که پس از هش در آن فایل نوشته شده است minio.RELEASE.2025-09-07T16-13-09Z است، اما ما فایل دانلودشده را با نام minio ذخیره کرده‌ایم، بنابراین -c به دنبال فایلی می‌گردد که وجود ندارد. این دستور پیام No such file or directory و سپس WARNING: 1 listed file could not be read را گزارش می‌دهد که ممکن است به اشتباه به معنای دانلود ناقص تلقی شود، در حالی که چنین نیست. برچسب فقط یک نام است، اما هش بخشی است که تضمین‌کنندهٔ صحت فایل است.

دقیق باشید که این بررسی چه چیزی را اثبات می‌کند. باینری و هش هر دو از یک منبع و از طریق یک اتصال واحد دریافت شده‌اند، بنابراین تطابق آن‌ها ثابت می‌کند که دانلود کامل انجام شده و در حین انتقال آسیب ندیده یا تغییر نیافته است. این موضوع اثبات نمی‌کند که فروشنده قابل اعتماد است؛ آن یک مسئلهٔ متفاوت است و هیچ دستور sha256sum آن را حل نمی‌کند.

sudo install -o root -g root -m 755 minio /usr/local/bin/minio
minio --version

دستور minio --version عبارت minio version RELEASE.2025-09-07T16-13-09Z و به دنبال آن چند خط مربوط به ساخت (build) را چاپ می‌کند. مشاهدهٔ Permission denied در اینجا به این معناست که مجوزهای فایل (mode) اشتباه است و command not found به این معناست که /usr/local/bin در PATH شما قرار ندارد.

ایجاد یک کاربر سیستمی و دایرکتوری داده

MinIO آپلودها را از شبکه می‌پذیرد، بنابراین نباید با دسترسی root اجرا شود. یک حساب کاربری بدون دایرکتوری home و بدون shell ورود برای آن در نظر بگیرید.

sudo groupadd -r minio-user
sudo useradd -M -r -g minio-user -s /usr/sbin/nologin minio-user
sudo mkdir -p /var/lib/minio/data
sudo chown -R minio-user:minio-user /var/lib/minio
sudo chmod 750 /var/lib/minio

دستور -r یک حساب سیستمی با UID کمتر از 1000 ایجاد می‌کند که آن را از محدودهٔ اختصاص‌یافته به کاربران انسانی خارج نگه می‌دارد. دستور -M از ایجاد دایرکتوری home صرف‌نظر می‌کند، زیرا حسابی که هرگز وارد سیستم نمی‌شود نیازی به آن ندارد. نتیجه را با id minio-user بررسی کنید؛ همچنین با دستور stat -c '%U %a' /var/lib/minio که باید خروجی minio-user 750 را نمایش دهد.

دایرکتوری داده باید برای آن کاربر قابل نوشتن باشد، نه فقط قابل خواندن. در اولین اجرا، MinIO یک دایرکتوری .minio.sys درون volume ایجاد می‌کند تا پیکربندی خود را در آن نگه دارد؛ بنابراین اگر مالکیت دایرکتوری متعلق به root باشد، MinIO هنگام شروع به کار با پیامی که به permission denied ختم می‌شود، متوقف خواهد شد. همین قاعده برای تمام سرویس‌هایی که به این شکل اجرا می‌کنید صدق می‌کند و کاربران سرویس با حداقل دسترسی در VPS این موضوع را به‌طور کامل بررسی می‌کند.

قرار دادن اعتبارنامه‌های root در یک فایل محیطی

اعتبارنامه‌های root دسترسی به تمام bucketها را ممکن می‌سازند، بنابراین نباید در فایل unit قرار بگیرند، زیرا آن فایل برای همه قابل خواندن است. ابتدا فایل را با مجوز دسترسی صحیح ایجاد کنید و سپس اطلاعات را در آن بنویسید تا رمز عبور حتی برای یک لحظه هم در فایلی که قابل خواندن است قرار نگیرد.

sudo install -o root -g root -m 600 /dev/null /etc/default/minio
printf 'MINIO_ROOT_USER=minio-root\nMINIO_ROOT_PASSWORD=%s\nMINIO_VOLUMES="/var/lib/minio/data"\nMINIO_OPTS="--address 127.0.0.1:9000 --console-address 127.0.0.1:9001"\n' "$(openssl rand -base64 24)" | sudo tee /etc/default/minio > /dev/null
sudo sed -n 's/^MINIO_ROOT_PASSWORD=//p' /etc/default/minio

دستور tee فایل موجود را به جای بازآفرینی، خالی (truncate) می‌کند، بنابراین مجوز دسترسی روی 600 و مالکیت آن روی root باقی می‌ماند. این کار عمدی است. systemd فایل EnvironmentFile را پیش از کاهش سطح دسترسی به User= با کاربر root می‌خواند؛ این یعنی حساب کاربری سرویس هرگز نیازی به خواندن اعتبارنامه‌های خود ندارد. پس از اجرای سرویس، آن را با sudo -u minio-user cat /etc/default/minio بررسی کنید. این دستور باید Permission denied را چاپ کند.

پیش از شروع کار با MinIO، دانستن دو رفتار آن ضروری است. اگر MINIO_ROOT_USER و MINIO_ROOT_PASSWORD در محیط آن تعریف نشده باشند، MinIO از شروع به کار امتناع نمی‌کند. این سرویس با اعتبارنامه‌های پیش‌فرض مستندشده یعنی minioadmin:minioadmin بالا می‌آید که اولین جفت‌نامی است که هر اسکنری امتحان می‌کند، و در حین انجام این کار کاملاً سالم به نظر می‌رسد. در مقابل، رمز عبور کمتر از 8 کاراکتر رد می‌شود: MinIO در زمان راه‌اندازی با خطایی مبنی بر نامعتبر بودن اعتبارنامه‌ها متوقف می‌شود، زیرا access key حداقل به 3 کاراکتر و secret key حداقل به 8 کاراکتر نیاز دارد.

MINIO_VOLUMES مسیر داده‌ها است و MINIO_OPTS شامل فلگ‌ها می‌باشد. اتصال به 127.0.0.1 به این معنی است که هنوز هیچ‌چیز خارج از این VPS نمی‌تواند به S3 API دسترسی داشته باشد، که این تنظیم پیش‌فرض درستی است. شما بعداً آن را به‌صورت آگاهانه و از طریق یک پروکسی که دارای گواهی است، باز خواهید کرد.

نوشتن unit فایل systemd

فایل /etc/systemd/system/minio.service را ایجاد کنید:

[Unit]
Description=MinIO object storage
Documentation=https://github.com/minio/minio
Wants=network-online.target
After=network-online.target

[Service]
User=minio-user
Group=minio-user
EnvironmentFile=/etc/default/minio
ExecStart=/usr/local/bin/minio server $MINIO_VOLUMES $MINIO_OPTS
Restart=always
RestartSec=5
LimitNOFILE=65536
NoNewPrivileges=true

[Install]
WantedBy=multi-user.target

هیچ - پیش‌فرضی در EnvironmentFile وجود ندارد و این یک تصمیم آگاهانه است، نه یک اشتباه تایپی. با وجود خط تیره (dash)، systemd نبود فایل را نادیده می‌گیرد و MinIO را به هر حال اجرا می‌کند؛ بنابراین یک فایل حذف‌شده یا مسیر اشتباه، بی‌سروصدا باعث می‌شود سرور روی minioadmin:minioadmin اجرا شود. بدون خط تیره، نبود فایل باعث شکست unit پیش از اجرای MinIO می‌شود و journalctl -u minio وضعیت Failed to load environment files: No such file or directory را نشان می‌دهد. تشخیص unitای که از اجرا سر باز می‌زند، بسیار آسان‌تر از سروری است که بی‌سروصدا رمز عبور پیش‌فرض را می‌پذیرد.

متغیرهای $MINIO_VOLUMES و $MINIO_OPTS عمداً بدون کوتیشن (unquoted) رها شده‌اند، زیرا systemd متغیرهای بدون کوتیشن را بر اساس فضای خالی (whitespace) به آرگومان‌های جداگانه تقسیم می‌کند. به این ترتیب، چهار کلمه در MINIO_OPTS به چهار آرگومان برای minio server تبدیل می‌شوند. دستور LimitNOFILE=65536 محدودیت file descriptor را افزایش می‌دهد، زیرا هر اتصال باز و هر فایل دادهٔ باز، یک descriptor اشغال می‌کند و مقدار پیش‌فرض 1024 تحت بار کاری (load) به سرعت تمام می‌شود.

sudo systemctl daemon-reload
sudo systemctl enable --now minio
systemctl is-active minio
curl -fsS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:9000/minio/health/live

دستور is-active باید خروجی active را چاپ کند و endpoint سلامت باید پاسخ 200 را برگرداند. دستور journalctl -u minio -n 20 --no-pager آدرس API که سرور روی آن در حال گوش دادن است را نشان می‌دهد. اگر unit مدام در حال restart شدن باشد، systemd پس از مدتی تسلیم شده و پیام Start request repeated too quickly را لاگ می‌کند؛ این یعنی MinIO در هر تلاش با خطا مواجه شده و خارج می‌شود: دلیل آن در خطوط بالای آن پیام چاپ شده است، پس لاگ‌ها را به سمت بالا بخوانید.

برای ایزولاسیون بیشتر، ProtectSystem=full و ProtectHome=true را به بخش [Service] اضافه کنید. هر دو به mount namespace از هسته میزبان (host kernel) نیاز دارند. در مجازی‌سازی کانتینری که هسته میزبان را به اشتراک می‌گذارد، مانند OpenVZ یا LXC، ممکن است این دستورات با شکست مواجه شوند و unit وضعیت status=226/NAMESPACE را گزارش دهد. در این صورت، آن دو خط را حذف کنید تا سرویس اجرا شود. این unit یک فایل معمولی است و سرویس‌ها و تایمرهای systemd روی VPS سایر دستورالعمل‌ها را پوشش می‌دهد.

نصب mc و تایید یک چرخه کامل (Round Trip)

کلاینت MinIO همان mc است. آن را با استفاده از apt install mc نصب نکنید. آن بسته مربوط به Midnight Commander است، یک مدیر فایل که هیچ ارتباطی با MinIO ندارد.

cd /tmp
curl -fsSL https://dl.min.io/client/mc/release/linux-amd64/mc -o mc
curl -fsSL https://dl.min.io/client/mc/release/linux-amd64/mc.sha256sum -o mc.sha256sum
[ "$(awk '{print $1}' mc.sha256sum)" = "$(sha256sum mc | awk '{print $1}')" ] && echo "checksum ok"
sudo install -o root -g root -m 755 mc /usr/local/bin/mc

سرور را به عنوان یک alias ثبت کنید، سپس یک شیء را از طریق آن جابه‌جا کنید.

MINIO_PASS=$(sudo sed -n 's/^MINIO_ROOT_PASSWORD=//p' /etc/default/minio)
mc alias set local http://127.0.0.1:9000 minio-root "$MINIO_PASS"
mc mb local/backups
echo "hello object storage" > /tmp/hello.txt
mc cp /tmp/hello.txt local/backups/hello.txt
mc ls local/backups
mc cat local/backups/hello.txt

دستور mc ls باید hello.txt را به همراه اندازه آن لیست کند و mc cat باید hello object storage را چاپ کند. این چرخه کامل، اثبات واقعی عملکرد سرور است، زیرا همان درخواست‌های S3 امضاشده‌ای را ارسال می‌کند که هر کلاینت دیگری ارسال خواهد کرد. اگر به تایید مجدد نیاز دارید، mc admin info local وضعیت سرور را چاپ می‌کند.

اکنون یک بررسی دیگر انجام دهید، در حالی که مخزن هنوز خالی است.

mc alias set defaultcheck http://127.0.0.1:9000 minioadmin minioadmin

این دستور باید با شکست مواجه شود. اگر موفقیت‌آمیز باشد، یعنی فایل محیطی (environment file) هرگز به پردازش نرسیده است و سرور شما با اعتبارنامه‌های پیش‌فرض در حال اجراست. پیش از آنکه هر چیز دیگری با این ماشین در تماس باشد، این مشکل را برطرف کنید.

mc نام‌های مستعار (aliases) را به صورت متن ساده در ~/.mc/config.json ذخیره می‌کند، بنابراین آن اعتبارنامه‌ها در دایرکتوری home کاربری که دستور را اجرا کرده است باقی می‌مانند. اجرای mc با کاربر sudo، اعتبارنامه‌های root را در /root/.mc/config.json قرار می‌دهد. alias مربوط به root را فقط روی یک حساب کاربری مدیر نگه دارید و به هر برنامه، کلید اختصاصی خودش را بدهید.

ارائه یک آبجکت با استفاده از presigned URL

یک presigned URL در واقع یک لینک HTTPS معمولی است که یک امضا و زمان انقضا به آن پیوست شده است. هر کسی که این لینک را در اختیار داشته باشد، می‌تواند بدون نیاز به حساب کاربری یا کلاینت، آن آبجکت خاص را دریافت کند.

mc share download --expire 12h local/backups/hello.txt

خروجی این دستور شامل X-Amz-Signature و X-Amz-Expires در رشته پرس‌وجو (query string) است. دو نکته در مورد آن وجود دارد که ممکن است کاربران را غافلگیر کند. این لینک بر اساس endpoint موجود در alias استفاده‌شده ساخته می‌شود؛ بنابراین، یک alias روی 127.0.0.1 لینکی تولید می‌کند که فقط همان ماشین قادر به باز کردن آن است. برای لینک‌هایی که قصد ارسال آن‌ها را دارید، یک alias دوم روی hostname عمومی خود بسازید. همچنین، دکمه‌ای برای ابطال (revoke) وجود ندارد. امضا تا زمان انقضا معتبر باقی می‌ماند، بنابراین تنها ابزار کنترلی شما، تعیین یک زمان انقضای کوتاه است. 7 روز، حداکثر زمانی است که فرمت امضای S3 اجازه می‌دهد.

اختصاص یک کلید و باکت مجزا به restic

اعتبارنامه‌های root می‌توانند هر باکتی را بخوانند و حذف کنند، بنابراین یک job پشتیبان‌گیری نباید از آن‌ها استفاده کند. یک باکت، یک policy محدود به همان باکت و کاربری که دسترسی دیگری ندارد، ایجاد کنید.

mc mb local/restic
cat > /tmp/restic-rw.json <<'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:ListBucket", "s3:GetBucketLocation"],
      "Resource": ["arn:aws:s3:::restic"]
    },
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
      "Resource": ["arn:aws:s3:::restic/*"]
    }
  ]
}
EOF
RESTIC_KEY=$(openssl rand -base64 24)
mc admin policy create local restic-rw /tmp/restic-rw.json
mc admin user add local restic-backup "$RESTIC_KEY"
mc admin policy attach local restic-rw --user restic-backup

MinIO دارای یک policy داخلی به نام readwrite است که اگرچه استفاده از آن یک دستور کوتاه‌تر است، اما دسترسی کامل به تمام باکت‌های سرور را اعطا می‌کند. policy بالا به عمد نام باکت را دو بار ذکر کرده است: یک بار به عنوان arn:aws:s3:::restic تا امکان لیست کردن باکت فراهم شود و یک بار به عنوان arn:aws:s3:::restic/* برای اشیاء داخل آن. در S3، باکت و اشیاء درون آن منابعی مجزا هستند؛ بنابراین policy که فقط یکی از آن‌ها را نام ببرد، با خطایی مواجه می‌شود که شبیه به خرابی کلاینت به نظر می‌رسد.

پیش از اعتماد به محدودیت، آن را تست کنید.

mc alias set resticuser http://127.0.0.1:9000 restic-backup "$RESTIC_KEY"
mc ls resticuser/restic
mc ls resticuser/backups

دستور اول ls موفقیت‌آمیز است و دومی با خطای Access Denied شکست می‌خورد. policy که تست نشده باشد، صرفاً یک حدس است.

اکنون restic را به سمت باکت هدایت کنید. restic اعتبارنامه‌های S3 را از متغیرهای محیطی استاندارد AWS می‌خواند، بنابراین هیچ فایل اعتبارنامهٔ اختصاصی برای restic در کار نیست.

sudo apt install -y restic
export AWS_ACCESS_KEY_ID=restic-backup
export AWS_SECRET_ACCESS_KEY="$RESTIC_KEY"
restic -r s3:http://127.0.0.1:9000/restic init
restic -r s3:http://127.0.0.1:9000/restic backup /etc
restic -r s3:http://127.0.0.1:9000/restic snapshots

دستور restic init رمز عبور مخزن را درخواست می‌کند. این رمز عبور مخزن را رمزنگاری می‌کند، بنابراین MinIO همیشه فقط متن رمزنگاری‌شده (ciphertext) را ذخیره می‌کند و گم کردن رمز عبور به معنای از دست رفتن پشتیبان است. اجرای یک job توسط systemd timer ترمینالی برای تایپ کردن ندارد، بنابراین برای پشتیبان‌گیری‌های زمان‌بندی‌شده، RESTIC_PASSWORD_FILE را روی فایلی با دسترسی 600 تنظیم کنید.

یک قاعدهٔ مکان‌یابی از هر دستور دیگری مهم‌تر است. مخزن restic روی همان VPS که داده‌ها را محافظت می‌کند، فقط شما را در برابر یک rm بد محافظت می‌کند و نه هیچ چیز دیگر. گره MinIO باید ماشینی متفاوت و در حالت ایده‌آل در منطقه‌ای (region) دیگر باشد. پشتیبان‌گیری‌های restic روی VPS علاوه بر این موضوع، زمان‌بندی و نگهداری (retention) را نیز پوشش می‌دهد.

خاتمه TLS با nginx

سرویس MinIO روی localhost قرار دارد، بنابراین nginx رابط عمومی سرور است. ابتدا گواهی را طبق توضیحات دریافت گواهی‌های Let's Encrypt با certbot و nginx صادر کنید و سپس از این server block استفاده نمایید.

server {
    listen 443 ssl;
    server_name s3.example.com;

    ignore_invalid_headers off;
    client_max_body_size 0;
    proxy_buffering off;
    proxy_request_buffering off;

    location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 300;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        chunked_transfer_encoding off;
        proxy_pass http://127.0.0.1:9000;
    }
}

چندین مورد از این خطوط نقش حیاتی دارند. دستور client_max_body_size 0 محدودیت پیش‌فرض 1 مگابایتی بدنه درخواست را حذف می‌کند؛ در غیر این صورت، هر آپلود بزرگ‌تر با خطای 413 Request Entity Too Large رد می‌شود، پیش از آنکه MinIO اصلاً درخواست را دریافت کند. دستور proxy_request_buffering off آپلود را مستقیماً جریان می‌دهد (stream)، زیرا در حالت پیش‌فرض، کل درخواست ابتدا در یک فایل موقت ذخیره می‌شود و برای یک شیء بزرگ، نیاز به فضای دیسک دوبرابر ایجاد می‌گردد. دستور proxy_set_header Host $http_host نکته ظریفی دارد: امضای S3 هدر Host را پوشش می‌دهد، بنابراین پروکسی که آن را بازنویسی کند، باعث می‌شود هر درخواست با خطای SignatureDoesNotMatch شکست بخورد، در حالی که لاگ دسترسی، ورود یک درخواست عادی را نشان می‌دهد.

نام عمومی MinIO را نیز به آن اعلام کنید تا لینک‌هایی که تولید می‌کند به جای localhost، به سمت پروکسی اشاره کنند.

echo 'MINIO_SERVER_URL=https://s3.example.com' | sudo tee -a /etc/default/minio
sudo systemctl restart minio

فایروال باید محدود باقی بماند. دسترسی SSH و HTTPS را مجاز کنید و پورت‌های 9000 و 9001 را بدون هیچ قانونی رها کنید، زیرا آدرسی که به 127.0.0.1 متصل است، فارغ از تنظیمات فایروال، از ماشین‌های دیگر غیرقابل دسترس است. اصول فایروال ufw در VPS دستورات مربوطه را در بر دارد.

چه زمانی MinIO تک‌گره کافی است و چه زمانی به S3 واقعی نیاز دارید

منظور از تک‌گره در اینجا، یک درایو بدون parity است. مستندات خود MinIO این چیدمان را برای تست و بارهای کاری کوچک که نیازی به دسترس‌پذیری ندارند، مناسب می‌داند. هیچ نسخهٔ دومی در این استقرار وجود ندارد، بنابراین دوام هر آبجکت برابر با دوام یک دیسک VPS است. قابلیت‌هایی که فرض را بر backend توزیع‌شده با erasure-coding می‌گذارند، از جمله bucket replication و object locking، مربوط به استقرار‌های چنددرایوی هستند؛ بنابراین در این چیدمان به کسی وعدهٔ سیاست نگهداری تغییرناپذیر (immutable retention policy) ندهید.

این چیدمان برای استفاده به عنوان مقصد restic در یک VPS دوم در منطقه‌ای دیگر، و به عنوان یک endpoint S3 برای کارهای توسعه و artifactهای CI که از دست دادن یک bucket فقط هزینهٔ بازسازی مجدد دارد، مناسب است. همچنین برای آپلود کاربران در یک اپلیکیشن کوچک معقول است، به شرطی که شما مالک طرح بازیابی باشید و واقعاً یک restore را تست کرده باشید.

زمانی که یک قرارداد یا نهاد نظارتی، object lock یا دوام چندمنطقه‌ای (multi-region durability) را درخواست می‌کند، یا زمانی که ترجیح می‌دهید ساعت 03:00 به دلیل پر شدن دیسک با شما تماس نگیرند، از S3 مدیریت‌شده استفاده کنید. دلیل صادقانهٔ دیگر، build منجمد است. تا جولای 2026، باینری پیش‌کامپایل‌شدهٔ community مربوط به سپتامبر 2025 است و هیچ اصلاحیه‌ای دریافت نمی‌کند؛ بنابراین اجرای آن به معنای پذیرش این وضعیت، یا کامپایل از سورس و به‌روز نگه داشتن پروژه توسط خودتان است.

یک مرز ارزش بیان کردن دارد چون زیاد پیش می‌آید. آبجکت استوریج دیتابیس نیست. هر عملیات نوشتن، کل یک آبجکت را جایگزین می‌کند، بنابراین یک فایل SQL زنده روی یک bucket S3 کند و ناامن است. دیتابیس را روی دیسک محلی نگه دارید و به جای آن، از آن در bucket نسخهٔ پشتیبان تهیه کنید: اجرای SQLite در محیط عملیاتی روی یک VPS این تفکیک را شرح می‌دهد.

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

واحد بلافاصله پس از systemctl enable --now با شکست مواجه می‌شود. journalctl -u minio -n 30 --no-pager را بخوانید. Failed to load environment files: No such file or directory به این معنی است که /etc/default/minio وجود ندارد یا مسیر آن در فایل واحد اشتباه نوشته شده است. پیامی که به permission denied ختم می‌شود به این معناست که دایرکتوری داده توسط حساب کاربری سرویس قابل نوشتن نیست؛ بنابراین بررسی کنید که stat -c '%U' /var/lib/minio/data خروجی minio-user را نمایش دهد.

minioadmin:minioadmin همچنان وارد سیستم می‌شود. فایل محیطی (environment file) هرگز به پردازش نرسیده است. تأیید کنید که واحد شامل EnvironmentFile=/etc/default/minio باشد، دستور sudo systemctl daemon-reload را اجرا کنید و سپس سرویس را ری‌استارت نمایید. MinIO اعتبارنامه‌های ریشه (root credentials) خود را فقط یک‌بار در زمان شروع می‌خواند، بنابراین ویرایش آن فایل بدون ری‌استارت کردن، تغییری ایجاد نمی‌کند.

Address already in use در زمان شروع. پردازش دیگری پورت 9000 را اشغال کرده است. پیش از آنکه پورت MinIO را تغییر دهید، با استفاده از sudo ss -ltnp | grep :9000 آن پردازش را پیدا کنید.

آپلودهای بالای 1 مگابایت از طریق پروکسی با شکست مواجه می‌شوند. nginx پاسخ 413 Request Entity Too Large را برگردانده و MinIO هرگز درخواست را دریافت نکرده است. مقدار client_max_body_size 0 را در بلوک سرور تنظیم کنید.

SignatureDoesNotMatch. یا کلید مخفی (secret key) اشتباه است، یا چیزی بین کلاینت و MinIO هدر Host را که امضا آن را پوشش می‌دهد، بازنویسی کرده است.

RequestTimeTooSkewed. ساعت کلاینت یا سرور تنظیم نیست. هر درخواست S3 دارای یک برچسب زمانی است و اگر خارج از بازه 15 دقیقه‌ای باشد، رد می‌شود. timedatectl را بررسی کنید و مطمئن شوید که همگام‌سازی زمان فعال است.

Access Denied روی باکتی که می‌دانید وجود دارد. کلید به باکت دیگری محدود شده است. با استفاده از mc admin policy info local restic-rw سیاستی که در حال حاضر مجاز است را چاپ کنید و نام باکت را در خطوط منبع (resource lines) مقایسه نمایید.

FAQ

آیا MinIO تک‌نود برای پشتیبان‌گیری واقعی مناسب است؟

این سرویس به‌عنوان مقصد restic که روی ماشینی جدا از داده‌های تحت حفاظت اجرا می‌شود، مناسب است. اما به‌عنوان تنها نسخهٔ پشتیبان شما کافی نیست. استقرار روی یک دیسک واحد فاقد parity است، بنابراین هیچ نسخهٔ دومی در MinIO وجود ندارد و اگر دیسک آن VPS دچار خرابی شود، آبجکت‌ها از دست می‌روند. یک مقصد دوم در جای دیگری داشته باشید و حداقل یک‌بار از هر دو مقصد بازیابی (restore) انجام دهید تا از صحت فرایند مطمئن شوید.

چرا sha256sum -c روی فایل checksum مربوط به MinIO با خطا مواجه می‌شود؟

زیرا برچسب بعد از هش در داخل آن فایل، نام نسخه یعنی minio.RELEASE.2025-09-07T16-13-09Z را ذکر می‌کند، در حالی که فایلی که دانلود کرده‌اید معمولاً minio نام دارد. sha256sum -c به دنبال فایلی با نام نوشته‌شده در داخل فایل checksum می‌گردد، آن را پیدا نمی‌کند و خطای No such file or directory و WARNING: 1 listed file could not be read را گزارش می‌دهد. فایل دانلودشده سالم است. رشته‌های هش را مستقیماً با هم مقایسه کنید و از برچسب صرف‌نظر کنید، چرا که آن برچسب هیچ معنای امنیتی ندارد.

کنسول مدیریتی تحت وب MinIO کجا رفته است؟

MinIO در مه 2025 قابلیت‌های مدیریتی را از نسخهٔ community کنسول حذف کرد و تنها یک مرورگر آبجکت در رابط وب باقی گذاشت. باکت‌ها و کاربران اکنون با کلاینت mc و با استفاده از دستوراتی مانند mc admin user add و mc admin policy attach مدیریت می‌شوند. این مسیرِ پشتیبانی‌شده در نسخهٔ community است و نه یک راهکار موقت؛ به همین دلیل است که این راهنما تمام کارها را از طریق خط فرمان انجام می‌دهد.

چگونه restic را برای استفاده از MinIO به‌عنوان S3 backend تنظیم کنم؟

متغیرهای AWS_ACCESS_KEY_ID و AWS_SECRET_ACCESS_KEY را روی یک access key و secret مربوط به MinIO تنظیم کنید، سپس از یک رشته مخزن (repository string) به فرم s3:https://s3.example.com/restic استفاده کنید که در آن آخرین بخش مسیر، نام باکت است. ابتدا باکت را با mc mb ایجاد کنید، زیرا کلیدی که دسترسی آن به یک باکت محدود شده، اجازهٔ ایجاد باکت جدید را ندارد. restic پیش از آپلود، همه چیز را با رمز عبور مخزن خود رمزنگاری می‌کند، بنابراین MinIO داده‌های رمزنگاری‌شده (ciphertext) را ذخیره می‌کند و هرگز فایل‌های شما را نمی‌بیند.

آیا حتماً باید MinIO را پشت nginx اجرا کنم؟

هر زمان که کلاینت روی همان ماشین نباشد، شما به TLS (امنیت لایه انتقال) نیاز دارید، زیرا اعتبارنامه‌های S3 و داده‌های آبجکت هر دو در داخل درخواست جابه‌جا می‌شوند. یک پروکسی روی پورت 443 با گواهی certbot ساده‌ترین راه برای دستیابی به این هدف است و تمدید گواهی را از MinIO دور نگه می‌دارد. MinIO همچنین می‌تواند خودش TLS را مدیریت کند اگر --certs-dir را به دایرکتوری حاوی public.crt و private.key اشاره دهید، اما در این صورت حساب کاربری سرویس نیاز به دسترسی خواندن به کلید خصوصی تمدیدشده دارد که برای رسیدن به همان نتیجه، کار اضافه‌ای است.

#minio#s3#object-storage#self-hosted#vps