تثبيت MinIO على خادم VPS بنظام Ubuntu 24.04
شغّل MinIO على VPS واحد بواجهة S3 تملكها: ابنِ المصدر الموثوق، أضف خدمة systemd، استخدم mc والروابط الموقعة، واجعل restic هدف النسخ الاحتياطي.
ما الذي يوفّره لك تخزين الكائنات ذاتي الاستضافة باستخدام MinIO
MinIO هو نظام تخزين كائنات ذاتي الاستضافة يتحدث عبر واجهة Amazon S3 API. وجّه restic أو S3 SDK إلى خادمك، وغيّر إعداد نقطة نهاية واحدة، وهذا يكفي لقراءة الكائنات وكتابتها وسردها وإنشاء الروابط الموقعة مسبقاً في الاستخدام اليومي. لكن التوافق لا يعني التطابق. فعلى سبيل المثال، لا يطبّق MinIO قوائم التحكم في الوصول (ACLs) الخاصة بكائنات Amazon، وقد صرّح المشرفون عليه بأنهم لا ينوون تطبيقها. لذلك يحتاج التطبيق الذي يعتمد على سلوك ACL إلى أكثر من تغيير نقطة النهاية. يبني هذا الدليل عقدة واحدة على Ubuntu 24.04: ملفاً ثنائياً مُجمّعاً من مصدر تم التحقق منه، ومستخدم نظام مخصصاً، ووحدة systemd تُبقي بيانات اعتماد root خارج ملف الوحدة، وbucket ينسخ restic النسخ الاحتياطية إليه.
S3 (خدمة التخزين البسيطة) هي واجهة HTTP وليست نظام ملفات. تضع كائناً في bucket تحت مفتاح، ثم تستعيده، ولا توجد في bucket قياسية كتابة جزئية أو إعادة تسمية. وتُعدّ directory buckets في Amazon S3 Express One Zone استثناءً، إذ توفر استدعاءات خاصة بها للإلحاق وإعادة التسمية، لكن ذلك يخص فئة تخزين واحدة، ولا يعتمد أي جزء من هذا الدليل عليه. تفضّل أدوات النسخ الاحتياطي النموذج القياسي، لأن الكائن إما أن يصل كاملاً أو لا يصل.
تحتفظ عقدة واحدة بنسخة واحدة من بياناتك. هذه هي المقايضة التي تجريها. تحصل على نقطة نهاية S3 تتحكم فيها مقابل تكلفة VPS، كما تتحمل كل المهام التي كان موفر السحابة ينفذها، بدءاً من استبدال القرص المتعطل ووصولاً إلى تصحيح برنامج الخادم. يوضح القسم القريب من النهاية صراحةً متى تكون هذه المقايضة مناسبة.
حالة إصدار MinIO المجتمعي في October 2026
اقرأ هذا الجزء قبل أن تبني عليه، لأن الوضع تغيّر مؤخراً. في May 2025 أزالت MinIO ميزات الإدارة من وحدة تحكم الويب في الإصدار المجتمعي. لم يتبقَّ في المتصفح سوى متصفح للكائنات، لذلك تُدار حاويات S3 ومفاتيح الوصول باستخدام عميل سطر الأوامر mc بدلاً من ذلك.
لاحقاً في 2025 توقفت MinIO عن نشر الملفات الثنائية المجتمعية المترجمة مسبقاً. يذكر ملف README للمشروع أن الإصدار المجتمعي يُوزَّع بصيغة الشفرة المصدرية فقط، ومنذ April 2026 أصبح المستودع minio/minio مؤرشفاً مع الإشعار THIS REPOSITORY IS NO LONGER MAINTAINED. كما توقف خادم التنزيل القديم عن توفير الملفات المجتمعية. وعند التحقق في 20 October 2026، أصبح كل مسار dl.min.io استخدمه هذا الدليل سابقاً للتنزيل، بما في ذلك الملف الثنائي للخادم والملف الثنائي للعميل وملفات checksums الخاصة بهما، يجيب بـ410 Gone، وهذا حذف متعمد وليس عطلاً. الملف الثنائي الوحيد mc الذي لا يزال على ذلك الخادم هو AIStor Client ضمن /aistor/mc/release/، وهو ينتمي إلى الخط التجاري. تسرد صفحة التنزيل على min.io الآن AIStor Server وAIStor Client وAIStor SDK وبعض إضافات AIStor، بالإضافة إلى فئة AIStor مجانية تصفها بأنها موجهة إلى المطورين والباحثين والمؤسسات الصغيرة التي تشغّل عمليات نشر مستقلة، ولا تتضمن أي إصدار مجتمعي.
لا تزال الشفرة المصدرية متاحة، وهي أحدث من آخر ملف ثنائي. الإصدار المجتمعي النهائي هو RELEASE.2025-10-15T17-29-55Z، وقد نُشر في 16 October 2025 باعتباره إصداراً أمنياً؛ إذ يعالج تصعيداً للامتيازات عبر تجاوز سياسة الجلسة في حسابات الخدمة وSTS، وتوصي ملاحظات الإصدار جميع المستخدمين بالترقية فوراً. كان آخر ملف ثنائي مترجم مسبقاً هو إصدار September 2025، ولذلك لم يتلقَّ هذا الإصلاح. يترجم هذا الدليل إصدار October، وبما أن المستودع مؤرشف، فهذا أيضاً آخر إصلاح سيحصل عليه الإصدار المجتمعي.
هذه الحقيقة الواحدة تحدد بقية هذا الدليل. ولهذا يستمع MinIO هنا على 127.0.0.1 ولا يصل إلى الإنترنت إلا عبر proxy تتحكم فيه.
تثبيت ملف MinIO الثنائي والتحقق من التنزيل
كُتب MinIO بلغة Go، ويبنيه README المرفق من المورّد باستخدام أمر go install واحد يتطلب Go 1.24 أو أحدث. ثبّت Go أولاً من الحزمة الرسمية بصيغة tarball. في 20 October 2026، كان الإصدار المستقر الحالي على go.dev/dl هو go1.27.3، وقد صدر في 19 October 2026 مع إصلاح أمني لحزمة crypto/x509. قيمة التجزئة أدناه هي القيمة المنشورة في الصفحة نفسها لأرشيف linux-amd64. إذا اخترت إصدار Go أحدث، فخذ قيمة التجزئة الخاصة به من الصفحة نفسها. يجعل الخيار -f الأمر curl يفشل عند حدوث خطأ HTTP بدلاً من حفظ صفحة الخطأ بالاسم الذي طلبته. يمنعك ذلك من فك حزمة صفحة 404 ثم التساؤل عن سبب عدم كونها أرشيفاً.
cd /tmp
GOVER=go1.27.3
curl -fsSL "https://go.dev/dl/$GOVER.linux-amd64.tar.gz" -o go.tar.gzقارن قيمتي التجزئة، وقارن القيمتين فقط.
published=65efbc80fdc1fa2cd2631cad5b481777a68e8725f34e89f50fc6ac714e379b40
downloaded=$(sha256sum go.tar.gz | awk '{print $1}')
[ "$published" = "$downloaded" ] && echo "checksum ok"كن واضحاً بشأن ما يثبته هذا الفحص. تطابق القيمتين يثبت أن التنزيل اكتمل ولم يتعرض للتلف أو التعديل أثناء النقل. لكنه لا يثبت أن المورّد جدير بالثقة. هذه مشكلة مختلفة، ولا يحلها أي أمر sha256sum.
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go.tar.gz
export PATH=$PATH:/usr/local/go/bin
go versionابنِ الآن الإصدار النهائي من إصدار المجتمع باستخدام حسابك العادي. يفحص go install كل وحدة ينزّلها، بما في ذلك مصدر MinIO نفسه، مقابل قاعدة بيانات Go العامة لقيم التجزئة في sum.golang.org. لذلك توقف وحدة تم العبث بها أو استبدالها عملية البناء بخطأ أمني بدلاً من إنتاج ملف ثنائي.
go install github.com/minio/minio@RELEASE.2025-10-15T17-29-55Z
sudo install -o root -g root -m 755 ~/go/bin/minio /usr/local/bin/minio
minio --version
go version -m /usr/local/bin/minio | head -n 3يطبع minio --version القيمة DEVELOPMENT.GOGET بدلاً من اسم الإصدار، لأن go install لا يطبّق خيارات البناء التي استخدمها المورّد لوضع معلومات الإصدار في ملفاته الثنائية. يقرأ go version -m معلومات الوحدة التي تضمنها Go في كل ملف ثنائي، ويعرض السطر mod github.com/minio/minio فيه commit الذي بنيته. تعني قيمة Permission denied هنا أن الوضع غير صحيح، وتعني command not found أن /usr/local/bin غير موجود في PATH. إذا كانت ذاكرة VPS غير كافية لعملية التجميع، فنفّذ الأمر go install نفسه على جهاز Linux آخر بالبنية نفسها، ثم انسخ الملف الثنائي إليه.
إنشاء مستخدم نظام ودليل بيانات
يستقبل 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 داخل وحدة التخزين للاحتفاظ بإعداده الخاص، لذلك يؤدي امتلاك root للدليل إلى خروج MinIO أثناء بدء التشغيل برسالة تنتهي بـ permission denied. تنطبق القاعدة نفسها على كل خدمة تشغّلها بهذه الطريقة، ويوضح مستخدمو خدمات أقل الصلاحيات على VPS هذه النقطة بالتفصيل.
ضع بيانات اعتماد root في ملف بيئة
تمنح بيانات اعتماد root صلاحية الوصول إلى كل bucket، لذلك لا مكان لها في ملف الوحدة، لأنه مقروء عالمياً. أنشئ الملف بالصلاحيات الصحيحة أولاً، ثم اكتب البيانات فيه ثانياً، حتى لا تبقى كلمة المرور في ملف مقروء ولو للحظة واحدة.
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 إلى اقتطاع ملف موجود بدلاً من إنشائه من جديد، لذلك تبقى الصلاحيات عند 600 ويبقى المالك هو root. هذا مقصود. يقرأ systemd ملف EnvironmentFile بصفته root قبل خفض الامتيازات إلى User=، ولذلك لا يحتاج حساب الخدمة إلى قراءة بيانات اعتماده بنفسه. بعد تشغيل الخدمة، أثبت ذلك باستخدام sudo -u minio-user cat /etc/default/minio. يجب أن يطبع هذا الأمر Permission denied.
هناك سلوكان في MinIO ينبغي معرفتهما قبل تشغيله. عند عدم وجود MINIO_ROOT_USER وMINIO_ROOT_PASSWORD في بيئته، لا يرفض MinIO التشغيل. بل يبدأ باستخدام بيانات الاعتماد الافتراضية الموثقة minioadmin:minioadmin، وهي أول زوج تجربه أي أداة فحص، ويبدو سليماً تماماً أثناء ذلك. أما كلمة المرور التي تقل عن 8 محارف فيُرفض استخدامها بدلاً من ذلك: يخرج MinIO عند بدء التشغيل مع رسالة خطأ تفيد بأن بيانات الاعتماد غير صالحة، لأن مفتاح الوصول يحتاج إلى 3 محارف على الأقل، ويحتاج المفتاح السري إلى 8 محارف على الأقل.
يمثل MINIO_VOLUMES مسار البيانات، بينما يحتوي MINIO_OPTS على الخيارات. ويعني الربط بـ127.0.0.1 أن أي جهة خارج هذا VPS لا تستطيع الوصول إلى S3 API بعد، وهذا هو الإعداد الافتراضي المناسب. تفتحه لاحقاً بشكل مقصود، عبر proxy يحمل شهادة.
إنشاء وحدة 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 حد واصفات الملفات، لأن كل اتصال مفتوح وكل ملف بيانات مفتوح يستهلك واصفاً واحداً، وينفد الحد الافتراضي البالغ 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/liveينبغي أن يطبع is-active القيمة active، وينبغي أن تستجيب نقطة الصحة بالقيمة 200. يعرض journalctl -u minio -n 20 --no-pager عنوان API الذي يستمع إليه الخادم. إذا استمرت الوحدة في إعادة التشغيل، يتوقف systemd عن المحاولة ويسجّل Start request repeated too quickly. وهذا يعني أن MinIO يخرج عند كل محاولة. يظهر السبب في الأسطر السابقة لهذه الرسالة، لذا اقرأ السجل إلى الأعلى.
لمزيد من العزل، أضف ProtectSystem=full وProtectHome=true إلى قسم [Service]. يحتاج كلاهما إلى مساحات أسماء للـmount من نواة المضيف. في المحاكاة الافتراضية المعتمدة على الحاويات والتي تشارك نواة المضيف، مثل OpenVZ أو LXC، قد يفشل هذان الخياران، وعندها تعرض الوحدة status=226/NAMESPACE. احذف هذين السطرين وستبدأ الوحدة. الوحدة نفسها وحدة عادية، ويغطي خدمات systemd والمؤقتات على VPS بقية التوجيهات.
ثبّت mc وأثبت نجاح رحلة ذهاب وإياب
عميل MinIO هو mc. لا تثبّته باستخدام apt install mc. تلك الحزمة هي Midnight Commander، وهو مدير ملفات لا علاقة له بـMinIO.
لا يزال dl.min.io يوفّر ملفاً ثنائياً باسم mc، لكنه ليس إصدار المجتمع. يجيب المسار القديم لإصدار المجتمع، https://dl.min.io/client/mc/release/linux-amd64/mc، بالاستجابة 410 Gone. ما يوفّره MinIO هناك الآن هو AIStor Client في https://dl.min.io/aistor/mc/release/linux-amd64/mc، وتشير إليه مرجعية AIStor CLI وتصفه بأنه يتضمن وظائف حصرية لنشرات AIStor Server المرخّصة. لا تذكر تلك المرجعية استخدامه مع خادم المجتمع، لذلك يلتزم هذا الدليل بعميل المجتمع. أُرشف مستودع minio/mc منذ July 2026، لذا ابنِ آخر إصدار منه، RELEASE.2025-08-13T08-35-41Z، باستخدام سلسلة أدوات Go نفسها. وتغطي قاعدة بيانات checksums هذا التنزيل أيضاً.
go install github.com/minio/mc@RELEASE.2025-08-13T08-35-41Z
sudo install -o root -g root -m 755 ~/go/bin/mc /usr/local/bin/mcسجّل الخادم كاسم مستعار، ثم انقل كائناً عبره.
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يجب أن يفشل هذا الأمر. إذا نجح، فهذا يعني أن ملف البيئة لم يصل إلى العملية، وأن الخادم يعمل ببيانات الاعتماد الافتراضية. أصلح ذلك قبل أن يتعامل أي شيء آخر مع الجهاز.
يخزّن mc الأسماء المستعارة في ~/.mc/config.json بنص واضح، لذلك تبقى بيانات الاعتماد في الدليل الرئيسي للمستخدم الذي نفّذ الأمر. يؤدي تشغيل mc باستخدام sudo إلى وضع بيانات اعتماد root في /root/.mc/config.json. احتفظ بالاسم المستعار الخاص بـroot في حساب مسؤول واحد، وامنح كل تطبيق مفتاحه الخاص.
إنشاء رابط presigned URL لكائن واحد
رابط presigned URL هو رابط HTTPS عادي مرفق بتوقيع ومدة صلاحية. يمكن لأي شخص يملك الرابط جلب ذلك الكائن الواحد من دون حساب ومن دون عميل.
mc share download --expire 12h local/backups/hello.txtيحتوي الناتج على X-Amz-Signature وX-Amz-Expires في سلسلة الاستعلام. هناك أمران يفاجئان المستخدمين. يُنشأ الرابط باستخدام نقطة النهاية الموجودة في الـalias الذي استخدمته، لذلك ينتج عن وجود alias على 127.0.0.1 رابط لا يمكن فتحه إلا من هذا الجهاز. أنشئ alias ثانياً على اسم المضيف العام للروابط التي تنوي إرسالها. ولا يوجد زر لإلغاء رابط محدد. يظل التوقيع صالحاً حتى تنتهي صلاحيته، أو حتى تُزال أو تُغيَّر الـkey التي وقّعته. وإذا كان الرابط موقّعاً ببيانات اعتماد root، فهذا يعني تدويرها. لذلك تكون مدة الصلاحية القصيرة هي وسيلة التحكم العملية. سبعة أيام هي الحد الأقصى الذي يسمح به تنسيق توقيع S3.
امنح restic مفتاحاً وbucket مستقلين
يمكن لبيانات اعتماد root قراءة كل bucket وحذفه، لذلك يجب ألا تحتفظ بها مهمة النسخ الاحتياطي. أنشئ bucket، وسياسة تقتصر على ذلك الـbucket، ومستخدماً لا يحصل على أي صلاحيات أخرى.
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 سياسة readwrite مضمّنة، وكانت ستختصر الأمر بخطوة واحدة، لكنها تمنح وصولاً كاملاً إلى كل bucket على الخادم. تذكر السياسة أعلاه اسم الـbucket مرتين عمداً: مرة بصيغة arn:aws:s3:::restic حتى يعمل سرد محتويات الـbucket، ومرة بصيغة arn:aws:s3:::restic/* للكائنات الموجودة داخله. في S3، يُعدّ الـbucket وكائناته موردين منفصلين، لذلك تفشل السياسة التي تذكر أحدهما فقط بطريقة تبدو كأن العميل معطّل.
اختبر حدود الصلاحيات قبل الاعتماد عليها.
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. السياسة التي لم تختبرها ليست سوى تخمين.
وجّه 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 snapshotsيطلب restic init كلمة مرور للمستودع. تشفّر كلمة المرور هذه المستودع، لذلك لا يخزّن MinIO سوى نص مشفّر، وفقدان كلمة المرور يعني فقدان النسخة الاحتياطية. لا يملك التشغيل الذي يبدأه مؤقت systemd طرفية لإدخال كلمة المرور، لذلك اضبط RESTIC_PASSWORD_FILE على ملف بصلاحيات mode 600 للنسخ الاحتياطية المجدولة.
هناك قاعدة لوضع المستودع أهم من أي أمر سبق. إن وضع مستودع restic على VPS نفسه الذي توجد عليه البيانات التي يحميها ينقذك من rm سيئ، ولا يحميك من أي شيء آخر. يجب أن تكون عقدة MinIO على جهاز مختلف، ويفضل أن تكون في منطقة مختلفة. يشرح النسخ الاحتياطية باستخدام restic على VPS جدولة النسخ والاحتفاظ بها استناداً إلى ذلك.
إنهاء TLS باستخدام nginx
يعمل MinIO على localhost، لذلك يمثّل nginx الواجهة العامة. أصدِر الشهادة أولاً كما هو موضح في شهادات Let's Encrypt باستخدام certbot وnginx، ثم استخدم كتلة الخادم التالية.
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 على ترويسة 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تبقى إعدادات جدار الحماية محدودة. اسمح بـSSH وHTTPS، ولا تضف أي قاعدة للمنفذين 9000 و9001، لأن العنوان المرتبط بـ127.0.0.1 لا يمكن الوصول إليه من جهاز آخر مهما كانت إعدادات جدار الحماية. تتضمن أساسيات جدار الحماية ufw على VPS الأوامر اللازمة.
متى يكفي MinIO على عقدة واحدة، ومتى تحتاج إلى S3 فعلي
تعني العقدة الواحدة هنا استخدام محرك واحد، لذلك لا توجد parity ولا نسخة ثانية داخل عملية النشر، وتساوي متانة كل كائن متانة قرص VPS واحد. توضّح وثائق MinIO نفسها، التي لم تعد متاحة إلا كمصدر في مستودع minio/docs منذ إزالة وثائق المجتمع المستضافة في أكتوبر 2025، أن عملية النشر المستقلة مخصصة للتطوير والتقييم المبكرين، وتذكر أن MinIO لا يوصي بها في بيئات الإنتاج. يمكنك تفعيل object locking لحاوية، لكنه على VPS واحد يمنع الحذف فقط عبر S3 API. يستطيع أي شخص يملك حساب root على الجهاز إزالة الملفات من القرص، لذلك لا تعد أي شخص بسياسة احتفاظ غير قابلة للتغيير في هذا الإعداد.
يناسب هذا الإعداد استخدامه كهدف لـrestic على VPS ثانٍ في منطقة أخرى، وكـS3 endpoint لأعمال التطوير وملفات CI، حيث لا يكلفك فقدان حاوية سوى إعادة البناء. كما يناسب تحميلات المستخدمين في تطبيق صغير، ما دمت تملك خطة استرداد واختبرت الاستعادة فعلياً.
اختر managed S3 عندما يطلب عقد أو جهة تنظيمية object lock أو متانة متعددة المناطق، أو عندما لا تريد أن تكون الشخص الذي تصله صفحة التنبيه عند الساعة 03:00 بسبب امتلاء القرص. كما أن تجمّد الشفرة سبب صريح آخر. اعتباراً من 20 أكتوبر 2026، تم أرشفة إصدار المجتمع ولم يعد قيد الصيانة، وآخر إصدار له، RELEASE.2025-10-15T17-29-55Z، هو الإصدار الذي يترجمه هذا الدليل. لن تُصلح أي مشكلات بعده، لذا يعني تشغيله قبول ذلك، أو الانتقال إلى خط MinIO التجاري AIStor أو إلى مخزن آخر مستضاف ذاتياً، وتُجري مقارنة بدائل MinIO المستضافة ذاتياً بين هذه الخيارات.
توجد حدود مهمة ينبغي توضيحها لأنها تتكرر كثيراً. تخزين الكائنات ليس قاعدة بيانات. في الحاوية القياسية يستبدل كل طلب كتابة الكائن بأكمله، وحتى استدعاء append الذي أضافته Amazon إلى S3 Express One Zone لا يضيف البيانات إلا إلى النهاية، لذلك يكون ملف SQL حي على حاوية S3 بطيئاً وغير آمن. أبقِ قاعدة البيانات على القرص المحلي، وأنشئ نسخة احتياطية منها داخل الحاوية بدلاً من ذلك: يشرح تشغيل 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 يسجّل الدخول. لم يصل ملف البيئة إلى العملية. تأكد من أن الوحدة تحتوي على EnvironmentFile=/etc/default/minio، وشغّل sudo systemctl daemon-reload، ثم أعد تشغيل الخدمة. يقرأ MinIO بيانات اعتماد root مرة واحدة عند بدء التشغيل، لذلك لا يؤدي تعديل ذلك الملف من دون إعادة التشغيل إلى أي تغيير.
Address already in use عند بدء التشغيل. توجد عملية أخرى تستخدم المنفذ 9000. اعثر عليها باستخدام sudo ss -ltnp | grep :9000 قبل تغيير منفذ MinIO.
تفشل عمليات الرفع التي تتجاوز 1 MB عبر الـproxy. أعاد nginx الاستجابة 413 Request Entity Too Large ولم ير MinIO الطلب مطلقاً. اضبط client_max_body_size 0 في كتلة الخادم.
SignatureDoesNotMatch. إما أن المفتاح السري غير صحيح، أو أن شيئاً ما بين العميل وMinIO أعاد كتابة ترويسة Host، وهي مشمولة في التوقيع.
RequestTimeTooSkewed. ساعة العميل أو الخادم غير صحيحة. يحمل كل طلب S3 موقّع طابعاً زمنياً، ويرفض MinIO، مثل Amazon S3، الطلب الموقّع عبر الترويسة إذا تجاوز الفرق بين طابعه الزمني وساعته الخاصة 15 دقيقة. أما الروابط المسبقة التوقيع فتُتحقَّق مدة صلاحيتها بدلاً من ذلك. افحص timedatectl وتأكد من أن مزامنة الوقت مفعّلة.
Access Denied في حاوية تعرف أنها موجودة. المفتاح مقيد بحاوية مختلفة. اطبع ما تسمح به السياسة فعلياً باستخدام mc admin policy info local restic-rw، وقارن اسم الحاوية في أسطر المورد.
FAQ
هل تكفي عقدة MinIO واحدة للنسخ الاحتياطية الفعلية؟
تكفي كوجهة لـrestic تعمل على جهاز منفصل عن البيانات التي تحميها. لكنها لا تكفي كنسخة وحيدة. لا يحتوي النشر على قرص واحد على أي تكافؤ، لذلك لا توجد نسخة ثانية داخل MinIO. وإذا فقد قرص VPS البيانات، فستضيع الكائنات. احتفظ بوجهة ثانية في مكان آخر، ونفّذ عملية استعادة من كلتا الوجهتين مرة واحدة على الأقل، حتى تتأكد من أن العملية تعمل.
لماذا يفشل sha256sum -c في ملف checksum الخاص بـMinIO؟
لن تصادف هذا الملف إلا في نسخة محفوظة في وقت سابق، لأن dl.min.io أعاد 410 Gone لكل ملف ثنائي وملف checksum من إصدار المجتمع عند التحقق في 20 October 2026. تسمّي التسمية بعد قيمة التجزئة داخل ذلك الملف الإصدار، مثل 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 ميزات الإدارة من وحدة تحكم إصدار المجتمع في May 2025، وأبقت متصفحاً للكائنات في واجهة الويب. تُدار الحاويات والمستخدمون الآن باستخدام عميل mc، عبر أوامر مثل mc admin user add وmc admin policy attach. هذا هو المسار المقصود في إصدار المجتمع، وليس حلاً مؤقتاً، ولذلك ينفّذ هذا الدليل كل شيء من سطر الأوامر.
كيف أوجّه restic إلى MinIO كواجهة خلفية لـS3؟
اضبط AWS_ACCESS_KEY_ID وAWS_SECRET_ACCESS_KEY على مفتاح وصول MinIO والسر المقابل له، ثم استخدم سلسلة مستودع بالصيغة s3:https://s3.example.com/restic، حيث يكون آخر عنصر في المسار هو اسم الحاوية. أنشئ الحاوية أولاً باستخدام mc mb، لأن المفتاح المقيّد بحاوية واحدة لا يملك صلاحية إنشاء الحاويات. يشفّر restic كل شيء باستخدام كلمة مرور المستودع الخاصة به قبل الرفع، لذلك يخزّن MinIO نصاً مشفراً ولا يطّلع على ملفاتك مطلقاً.
هل يجب أن أشغّل MinIO خلف nginx؟
تحتاج إلى TLS (أمان طبقة النقل) عندما لا يكون العميل على الجهاز نفسه، لأن كل كائن يعبر الشبكة بنص واضح من دونه، إلى جانب معرّف مفتاح الوصول وتوقيع الطلب. لا يغادر المفتاح السري العميل مطلقاً، لأن توقيع S3 يستخدمه محلياً فقط لحساب ذلك التوقيع. لكن يستطيع أي طرف على مسار الاتصال قراءة بياناتك وإعادة إرسال طلب ملتقط ما دام طابعه الزمني صالحاً. يُعدّ استخدام proxy على المنفذ 443 مع شهادة من certbot أبسط طريقة للحصول على TLS، كما أنه يفصل تجديد الشهادة عن MinIO. ويمكن لـMinIO أيضاً إنهاء TLS بنفسه إذا وجّهت --certs-dir إلى دليل يحتوي على public.crt وprivate.key، لكن حساب الخدمة سيحتاج إلى صلاحية قراءة المفتاح الخاص الذي جُدّد، وهذا يتطلب عملاً إضافياً للنتيجة نفسها.