نصب MinIO روی VPS اوبونتو برای ذخیرهسازی S3
MinIO را روی یک VPS با Ubuntu 24.04 اجرا کنید: نصب باینری تأییدشده، واحد systemd، کار با mc، ساخت presigned URL و استفاده بهعنوان مقصد پشتیبان restic.
MinIO چه امکاناتی در اختیار شما میگذارد؟
MinIO یک سامانه ذخیرهسازی شیءمحور با میزبانی شخصی است که از API مربوط به Amazon S3 استفاده میکند. restic یا هر SDK مربوط به S3 را به سرور خودتان متصل کنید، فقط یک تنظیم endpoint را تغییر دهید؛ در این حالت، کلاینت تفاوتی احساس نمیکند. این راهنما یک گره منفرد را روی Ubuntu 24.04 ایجاد میکند: یک باینری تأییدشده، یک کاربر اختصاصی سیستم، یک واحد systemd که اعتبارنامههای root را خارج از فایل واحد نگه میدارد، و یک bucket که restic نسخههای پشتیبان را در آن ذخیره میکند.
S3 (سرویس ذخیرهسازی ساده) یک API مبتنی بر HTTP است، نه یک فایلسیستم. با استفاده از PUT، یک object را تحت یک key در یک bucket قرار میدهید و با GET آن را دریافت میکنید. در این مدل، نوشتن جزئی و تغییر نام وجود ندارد. ابزارهای پشتیبانگیری این مدل را ترجیح میدهند، زیرا یک object یا بهطور کامل دریافت شده است یا اصلاً دریافت نشده است.
یک گره فقط یک نسخه از دادههای شما را نگه میدارد. این همان مصالحهای است که انجام میدهید. در ازای هزینه یک VPS، یک endpoint مربوط به S3 در اختیار دارید که خودتان کنترل میکنید. در عین حال، همه وظایفی را که ارائهدهنده cloud قبلاً انجام میداد نیز بر عهده میگیرید؛ از تعویض دیسک معیوب تا بهروزرسانی نرمافزار سرور. بخش پایانی راهنما بهصراحت توضیح میدهد که این مصالحه چه زمانی انتخاب مناسبی است.
وضعیت نسخه Community نرمافزار MinIO در ژوئیه 2026
پیش از استفاده از این راهنما، این بخش را بخوانید؛ زیرا وضعیت اخیراً تغییر کرده است. در مه 2025، MinIO قابلیتهای مدیریتی را از کنسول وب نسخه Community حذف کرد. آنچه در مرورگر باقی مانده است، یک مرورگر اشیا است. بنابراین، سطلها و کلیدهای دسترسی اکنون با کلاینت خط فرمان mc مدیریت میشوند.
بعدتر در سال 2025، MinIO انتشار باینریهای ازپیشکامپایلشده نسخه Community را متوقف کرد. فایل README پروژه اکنون میگوید که نسخه Community فقط بهصورت کد منبع توزیع میشود. URLهای قدیمی دانلود همچنان کار میکنند: تا ژوئیه 2026، این URLها ساخت سرور 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 و تأیید دانلود
نسخه مشخصشده و checksum منتشرشده آن را دانلود کنید. پرچم -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دو hash را با یکدیگر مقایسه کنید و فقط خود hashها را مقایسه کنید.
published=$(awk '{print $1}' minio.sha256sum)
downloaded=$(sha256sum minio | awk '{print $1}')
[ "$published" = "$downloaded" ] && echo "checksum ok"در اینجا از sha256sum -c minio.sha256sum استفاده نکنید. برچسبی که پس از hash در آن فایل نوشته شده minio.RELEASE.2025-09-07T16-13-09Z است و ما دانلود را با نام minio ذخیره کردهایم؛ بنابراین -c به دنبال فایلی میگردد که وجود ندارد. این دستور No such file or directory را گزارش میکند و سپس WARNING: 1 listed file could not be read را نشان میدهد؛ این وضعیت شبیه دانلود خراب است، اما دانلود خراب نیست. برچسب فقط یک نام است. بخش تضمینکننده، خود hash است.
دقیقاً مشخص کنید این بررسی چه چیزی را اثبات میکند. باینری و hash از یک فروشنده و از طریق یک اتصال یکسان دریافت شدهاند؛ بنابراین تطابق آنها کامل بودن دانلود و آسیبندیدن یا تغییرنکردن آن در مسیر انتقال را اثبات میکند. این بررسی قابلاعتمادبودن فروشنده را اثبات نمیکند. این موضوعی جداگانه است و هیچ دستور sha256sum آن را حل نمیکند.
sudo install -o root -g root -m 755 minio /usr/local/bin/minio
minio --versionminio --version، minio version RELEASE.2025-09-07T16-13-09Z را چاپ میکند و پس از آن چند خط مربوط به build را نشان میدهد. وجود Permission denied در اینجا یعنی mode نادرست است و command not found یعنی /usr/local/bin در PATH شما وجود ندارد.
ایجاد کاربر سیستمی و پوشه داده
MinIO بارگذاریها را از شبکه میپذیرد؛ بنابراین نباید با کاربر root اجرا شود. برای آن حسابی بدون پوشه خانگی و بدون پوسته ورود ایجاد کنید.
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 ایجاد پوشه خانگی را رد میکند، زیرا حسابی که هرگز وارد سیستم نمیشود، چیزی برای نگهداری در پوشه خانگی ندارد. نتیجه را با 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 قرار بگیرند، چون این فایل برای همه قابل خواندن است. ابتدا فایل را با mode مناسب ایجاد کنید و سپس دادهها را در آن بنویسید تا گذرواژه حتی برای یک لحظه نیز در فایلی قابلخواندن قرار نگیرد.
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/miniotee یک فایل موجود را truncate میکند، نه اینکه آن را دوباره ایجاد کند؛ بنابراین mode روی 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، اجرا میشود. این نخستین جفت اعتبارنامهای است که هر scanner امتحان میکند و سرویس در همان وضعیت کاملاً سالم به نظر میرسد. در مقابل، گذرواژه کوتاهتر از 8 نویسه رد میشود. MinIO هنگام راهاندازی با خطایی مبنی بر نامعتبر بودن اعتبارنامهها خارج میشود، زیرا access key دستکم به 3 نویسه و secret key دستکم به 8 نویسه نیاز دارد.
MINIO_VOLUMES مسیر داده است و MINIO_OPTS پرچمها را نگه میدارد. اتصال به 127.0.0.1 به این معناست که در این مرحله هیچ چیزی خارج از این VPS نمیتواند به S3 API دسترسی پیدا کند؛ این تنظیم پیشفرض مناسبی است. بعداً این دسترسی را بهصورت عمدی و از طریق proxy دارای certificate باز میکنید.
نوشتن واحد 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، - وجود ندارد و این تصمیمی عمدی است، نه خطای تایپی. با وجود خط تیره، systemd فایل مفقود را نادیده میگیرد و MinIO را همچنان اجرا میکند؛ بنابراین حذف فایل یا اشتباه تایپی در مسیر، بدون هیچ هشداری سروری را راهاندازی میکند که با minioadmin:minioadmin اجرا میشود. بدون خط تیره، مفقود بودن فایل باعث میشود واحد پیش از اجرای MinIO با شکست مواجه شود و journalctl -u minio مقدار Failed to load environment files: No such file or directory را نمایش دهد. واحدی که از اجرا شدن خودداری میکند، بسیار آسانتر شناسایی میشود تا سروری که بیسروصدا رمز عبور پیشفرض را میپذیرد.
$MINIO_VOLUMES و $MINIO_OPTS عمداً بدون علامت نقلقول هستند، زیرا systemd متغیرهای بدون نقلقول را بر اساس فاصلههای سفید به آرگومانهای جداگانه تقسیم میکند. به این ترتیب، چهار واژه موجود در MINIO_OPTS به چهار آرگومان برای minio server تبدیل میشوند. LimitNOFILE=65536 محدودیت file descriptor را افزایش میدهد، زیرا هر اتصال باز و هر فایل داده باز به یک descriptor نیاز دارد و مقدار پیشفرض 1024 در زمان بار زیاد تمام میشود.
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/liveis-active باید active را چاپ کند و endpoint سلامت باید با 200 پاسخ دهد. journalctl -u minio -n 20 --no-pager نشانی API را که سرور روی آن در حال گوش دادن است نمایش میدهد. اگر واحد مرتباً راهاندازی مجدد شود، systemd پس از مدتی متوقف میشود و Start request repeated too quickly را در log ثبت میکند. این پیام یعنی MinIO در هر تلاش خارج میشود؛ علت در خطوط بالاتر از آن پیام چاپ شده است، بنابراین log را به سمت بالا بخوانید.
برای جداسازی بیشتر، ProtectSystem=full و ProtectHome=true را به بخش [Service] اضافه کنید. هر دو به mount namespace از kernel میزبان نیاز دارند. در مجازیسازی مبتنی بر container که kernel میزبان را به اشتراک میگذارد، مانند OpenVZ یا LXC، این گزینهها ممکن است شکست بخورند و واحد در آن حالت status=226/NAMESPACE را گزارش میکند. این دو خط را حذف کنید تا واحد اجرا شود. خود واحد یک واحد معمولی است و خدمات و timerهای systemd در VPS سایر directiveها را پوشش میدهد.
نصب mc و اثبات رفتوبرگشت
کلاینت MinIO، mc است. آن را با apt install mc نصب نکنید. آن بسته مربوط به Midnight Commander، یعنی یک file manager نامرتبط با 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 ثبت کنید، سپس یک object را از طریق آن جابهجا کنید.
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.txtmc ls باید hello.txt را همراه با اندازه آن فهرست کند و mc cat باید hello object storage را چاپ کند. این رفتوبرگشت، اثبات واقعی عملکرد سرور است؛ زیرا همان درخواستهای امضاشده S3 را ایجاد میکند که همه clientهای دیگر نیز ایجاد خواهند کرد. اگر نظر دوم میخواهید، mc admin info local وضعیت سرور را چاپ میکند.
اکنون یک بررسی دیگر انجام دهید؛ زمانی که box هنوز خالی است.
mc alias set defaultcheck http://127.0.0.1:9000 minioadmin minioadminاین command باید شکست بخورد. اگر موفق شود، فایل environment هرگز به process نرسیده است و سرور شما با credentialهای پیشفرض اجرا میشود. پیش از آنکه هر چیز دیگری به machine دسترسی پیدا کند، این مشکل را برطرف کنید.
mc aliasها را در ~/.mc/config.json بهصورت متن ساده ذخیره میکند؛ بنابراین این credentialها در home directory کاربری قرار میگیرند که command را اجرا کرده است. اجرای mc با sudo، credentialهای root را در /root/.mc/config.json قرار میدهد. alias مربوط به root را روی یک حساب administrator نگه دارید و برای هر application یک key اختصاصی ایجاد کنید.
تحویل یک شیء با یک URL امضاشده
یک URL امضاشده، یک پیوند معمولی HTTPS است که یک امضا و زمان انقضا به آن پیوست شده است. هر فردی که این پیوند را داشته باشد، میتواند همان یک شیء را بدون حساب کاربری و بدون client دریافت کند.
mc share download --expire 12h local/backups/hello.txtخروجی شامل X-Amz-Signature و X-Amz-Expires در رشتهٔ پرسوجو است. دو نکته دربارهٔ آن برای بسیاری از افراد غیرمنتظره است. پیوند از endpoint موجود در alias استفادهشده ساخته میشود؛ بنابراین alias روی 127.0.0.1 پیوندی تولید میکند که فقط همین ماشین میتواند آن را باز کند. برای پیوندهایی که قصد ارسال آنها را دارید، یک alias دیگر روی hostname عمومی خود ایجاد کنید. همچنین دکمهای برای لغو وجود ندارد. امضا تا زمان انقضای آن معتبر میماند؛ بنابراین تنها کنترلی که در اختیار دارید، تعیین زمان انقضای کوتاه است. 7 روز، حداکثر زمانی است که قالب امضای S3 اجازه میدهد.
به restic کلید و bucket اختصاصی بدهید
اعتبارنامههای root میتوانند همه bucketها را بخوانند و حذف کنند؛ بنابراین job پشتیبانگیری نباید این اعتبارنامهها را در اختیار داشته باشد. یک bucket، یک policy محدودشده به همان bucket، و یک user ایجاد کنید که به هیچ منبع دیگری دسترسی نداشته باشد.
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-backupMinIO یک policy داخلی با نام readwrite دارد که در این حالت یک دستور کمتر لازم داشت، اما دسترسی کامل به همه bucketهای server میدهد. policy بالا عمداً نام bucket را دو بار میآورد: یک بار بهصورت arn:aws:s3:::restic تا فهرستکردن bucket امکانپذیر باشد، و بار دیگر بهصورت arn:aws:s3:::restic/* برای objectهای داخل آن. در S3، یک bucket و objectهای آن منابع جداگانه هستند؛ بنابراین policyای که فقط یکی از آنها را نام ببرد، به شکلی شکست میخورد که شبیه خرابی client به نظر میرسد.
پیش از اعتماد به این محدودیت، آن را آزمایش کنید.
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 را به bucket متصل کنید. 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 snapshotsrestic init یک گذرواژه برای repository درخواست میکند. این گذرواژه repository را رمزگذاری میکند؛ بنابراین MinIO فقط ciphertext را ذخیره میکند و گمکردن گذرواژه به معنای از دستدادن backup است. اجرای برنامهای که توسط یک timer از نوع systemd آغاز میشود، terminalی برای واردکردن گذرواژه ندارد؛ بنابراین RESTIC_PASSWORD_FILE را روی فایلی با mode 600 برای backupهای زمانبندیشده تنظیم کنید.
یک قاعده درباره محل استقرار، از هر یک از commandهای بالا مهمتر است. repository مربوط به restic روی همان VPS محل دادهای که از آن محافظت میکند، شما را فقط از یک rm نجات میدهد و از هیچ مشکل دیگری محافظت نمیکند. node مربوط به MinIO باید روی machine دیگری باشد؛ ترجیحاً در regionی دیگر. پشتیبانگیری restic روی VPS زمانبندی و نگهداری backupها را بر اساس این تنظیمات پوشش میدهد.
خاتمهدادن 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 MB است حذف میکند؛ در غیر این صورت، هر بارگذاری بزرگتر با 413 Request Entity Too Large رد میشود، پیش از آنکه درخواست اصلاً به MinIO برسد. proxy_request_buffering off بارگذاری را مستقیماً عبور میدهد، زیرا حالت پیشفرض ابتدا کل درخواست را در یک فایل موقت ذخیره میکند و در نتیجه، یک شیء بزرگ به دو برابر فضای دیسک نیاز دارد. proxy_set_header Host $http_host نکته ظریف پیکربندی است: امضای S3 شامل header مربوط به Host است؛ بنابراین، اگر proxy آن را بازنویسی کند، همه درخواستها با SignatureDoesNotMatch شکست میخورند، در حالی که access log ورود یک درخواست عادی را نشان میدهد.
نام عمومی سرویس را نیز به MinIO اعلام کنید تا لینکهایی که تولید میکند به proxy اشاره کنند، نه به localhost.
echo 'MINIO_SERVER_URL=https://s3.example.com' | sudo tee -a /etc/default/minio
sudo systemctl restart minioپیکربندی firewall کوچک باقی میماند. دسترسی SSH و HTTPS را مجاز کنید و برای پورتهای 9000 و 9001 هیچ ruleای تعریف نکنید، زیرا آدرسی که به 127.0.0.1 bind شده باشد، صرفنظر از تنظیم firewall، از ماشین دیگری قابل دسترسی نیست. مبانی firewall با ufw روی VPS شامل commandهای لازم است.
چه زمانی MinIO تکگرهی کافی است و چه زمانی S3 واقعی میخواهید
تکگره در اینجا یعنی یک drive بدون هیچ parity. مستندات خود MinIO این چیدمان را برای آزمایش و workloadهای کوچک بدون نیاز به availability مناسب میدانند. درون deployment هیچ نسخه دومی وجود ندارد؛ بنابراین durability هر object برابر با durability دیسک یک VPS است. قابلیتهایی که به backend توزیعشده و erasure-coded وابستهاند، از جمله bucket replication و object locking، به deploymentهای چندdriveای تعلق دارند. بنابراین در این setup به کسی policy نگهداری تغییرناپذیر وعده ندهید.
این چیدمان بهعنوان target برای restic روی یک VPS دوم در منطقهای دیگر مناسب است. برای endpoint مربوط به S3 در کارهای توسعه و artifactهای CI نیز مناسب است؛ در این موارد، از دست رفتن یک bucket فقط باعث میشود آن را دوباره بسازید. برای uploadهای کاربران در یک application کوچک نیز قابل قبول است، مشروط بر اینکه recovery plan داشته باشید و restore را واقعاً آزمایش کرده باشید.
وقتی یک قرارداد یا نهاد ناظر object lock یا durability چندمنطقهای میخواهد، managed S3 را انتخاب کنید. همچنین اگر نمیخواهید ساعت 03:00 به دلیل پر شدن یک دیسک مسئول رسیدگی باشید، managed S3 گزینه بهتری است. frozen بودن build نیز دلیل صادقانه دیگری است. تا July 2026، binary از پیش کامپایلشده جامعه کاربری مربوط به September 2025 است و هیچ fixی دریافت نمیکند. بنابراین اجرای آن یعنی پذیرفتن این وضعیت، یا build کردن از source و پیگیری مستقل تغییرات پروژه.
لازم است یک مرز مهم را بیان کنیم، چون این موضوع اغلب مطرح میشود. Object storage پایگاه داده نیست. هر write کل object را جایگزین میکند؛ بنابراین قرار دادن یک فایل زنده SQL در bucket مربوط به S3 کند و ناامن است. پایگاه داده را روی دیسک محلی نگه دارید و در عوض از آن در bucket پشتیبانگیری کنید: اجرای SQLite در محیط production روی یک 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 همچنان وارد سیستم میشود. فایل محیطی هرگز به فرایند نرسیده است. تأیید کنید که واحد شامل EnvironmentFile=/etc/default/minio است، sudo systemctl daemon-reload را اجرا کنید و سپس سرویس را دوباره راهاندازی کنید. MinIO اطلاعات کاربری root خود را فقط هنگام راهاندازی میخواند؛ بنابراین ویرایش آن فایل بدون راهاندازی مجدد هیچ تغییری ایجاد نمیکند.
Address already in use هنگام راهاندازی. فرایند دیگری پورت 9000 را در اختیار دارد. پیش از تغییر پورت MinIO، آن را با sudo ss -ltnp | grep :9000 پیدا کنید.
بارگذاری فایلهای بزرگتر از 1 MB از طریق proxy با خطا مواجه میشود. nginx پاسخ 413 Request Entity Too Large را برگردانده است و MinIO هرگز درخواست را دریافت نکرده است. client_max_body_size 0 را در بلوک server تنظیم کنید.
SignatureDoesNotMatch. یا کلید secret اشتباه است، یا چیزی بین client و MinIO سربرگ Host را بازنویسی کرده است؛ این سربرگ در امضا لحاظ میشود.
RequestTimeTooSkewed. ساعت client یا server اشتباه است. هر درخواست S3 دارای timestamp است و خارج از بازه 15 دقیقهای رد میشود. timedatectl را بررسی کنید و مطمئن شوید همگامسازی زمان فعال است.
Access Denied برای یک bucket که از وجود آن مطمئن هستید. این کلید به bucket دیگری محدود شده است. مواردی را که policy واقعاً مجاز میکند با mc admin policy info local restic-rw نمایش دهید و نام bucket را در خطوط resource مقایسه کنید.
FAQ
آیا MinIO تکگرهی برای پشتیبانگیری واقعی کافی است؟
برای استفاده بهعنوان مقصد restic که روی ماشینی جدا از دادههای تحت حفاظت اجرا میشود، کافی است. اما بهعنوان تنها نسخه کافی نیست. استقرار تکدرایوه هیچ افزونگیای ندارد؛ بنابراین نسخه دومی داخل MinIO وجود ندارد و اگر دیسک آن VPS دادهها را از دست بدهد، اشیا نیز از بین میروند. یک مقصد دوم را در محل دیگری نگه دارید و حداقل یکبار از هر دو مقصد بازیابی انجام دهید تا مطمئن شوید فرایند کار میکند.
چرا sha256sum -c روی فایل checksum مربوط به MinIO شکست میخورد؟
زیرا برچسب پس از hash داخل آن فایل، نام release یعنی minio.RELEASE.2025-09-07T16-13-09Z را مشخص میکند، درحالیکه فایل دانلودشده شما معمولاً minio نام دارد. sha256sum -c بهدنبال فایلی با نام نوشتهشده در فایل checksum میگردد، آن را پیدا نمیکند و No such file or directory و WARNING: 1 listed file could not be read را گزارش میدهد. دانلود سالم است. رشتههای hash را مستقیماً مقایسه کنید و برچسب را نادیده بگیرید؛ این برچسب هیچ معنای امنیتی ندارد.
کنسول وب مدیریت MinIO کجا رفت؟
MinIO در May 2025 قابلیتهای مدیریت را از کنسول نسخه community edition حذف کرد و فقط یک مرورگر اشیا را در رابط وب باقی گذاشت. اکنون bucketها و userها با client یعنی mc و با استفاده از commandهایی مانند mc admin user add و mc admin policy attach مدیریت میشوند. در نسخه community edition، این روش مسیر پشتیبانیشده است و workaround محسوب نمیشود؛ به همین دلیل این راهنما همه کارها را از خط فرمان انجام میدهد.
چگونه restic را به MinIO بهعنوان backend از نوع S3 متصل کنم؟
AWS_ACCESS_KEY_ID و AWS_SECRET_ACCESS_KEY را روی access key مربوط به MinIO و secret آن تنظیم کنید، سپس از repository string با قالب s3:https://s3.example.com/restic استفاده کنید؛ آخرین جزء مسیر، نام bucket است. ابتدا bucket را با mc mb ایجاد کنید، زیرا keyای که به یک bucket محدود شده است، مجوز ایجاد bucket ندارد. restic پیش از upload، همهچیز را با password اختصاصی repository رمزنگاری میکند؛ بنابراین MinIO ciphertext را ذخیره میکند و هرگز به فایلهای شما دسترسی ندارد.
آیا باید MinIO را پشت nginx اجرا کنم؟
هر زمان client روی همان ماشین نباشد، به TLS (امنیت لایه انتقال) نیاز دارید، زیرا credentialهای S3 و دادههای اشیا هر دو داخل request منتقل میشوند. استفاده از proxy روی port 443 همراه با certificate صادرشده توسط certbot سادهترین روش برای این کار است و تمدید certificate را از MinIO جدا نگه میدارد. MinIO همچنین میتواند خودش TLS را terminate کند، اگر --certs-dir را روی directoryای تنظیم کنید که public.crt و private.key را در خود دارد؛ اما در این حالت service account باید به private key تمدیدشده دسترسی خواندن داشته باشد، که برای رسیدن به همان نتیجه، کار بیشتری ایجاد میکند.