Skip to content
smallPict

استخدم التخزين + CDN الخاص بك

اربط تخزين الكائنات وشبكة CDN الخاصين بك في خطتي API Velocity وMomentum: الإعداد لكل مزوّد، والحد الأدنى من الصلاحيات، وفحص الاتصال، وما يحدث عند تبديل الوضع.

متاح في: خطتي API Velocity وMomentum. غير متاح في Ignite (لا تتضمن CDN)، ولا في بيئة الاختبار للمطورين (ملفات بيئة الاختبار مؤقتة)، ولا في خطط WordPress (تستخدم شبكة smallPict CDN المُدارة).

باختصار: في وضع BYO يكتب smallPict صورك الأصلية والمحسّنة في حاويتك أنت، وتقدّمها شبكة CDN الخاصة بك أنت. يُربط التخزين وCDN معًا دائمًا: لا يمكنك إحضار أحدهما دون الآخر.


ما هو BYO

تتضمن خطتا Velocity وMomentum وضعين للتوصيل. تختار أحدهما من لوحة التحكم ← شبكة CDN والتخزين.

  • مُدار (الافتراضي): يحفظ smallPict صورك الأصلية في تخزينه المشفّر (وتُنقل إلى أرشيف طويل الأمد بعد 90 يومًا)، ويقدّم الصور المحسّنة من cdn.smallpict.app. لا حاجة لأي إعداد.
  • استخدم التخزين + CDN الخاص بك (BYO): تربط حاوية متوافقة مع S3 في حسابك وشبكة CDN في حسابك. تكتب كل مهمة جديدة الملف الأصلي والملف المحسّن في حاويتك، وتُرجع API عناوين URL على نطاق CDN الخاص بك.

توجد قاعدة الربط المزدوج لأن smallPict يجب أن يتمكن من تنفيذ نصفي التوصيل معًا: كتابة الملفات، وإزالة النسخ القديمة من ذاكرة التخزين المؤقت. فالحاوية بلا CDN تترك طلبات مسح ذاكرة التخزين المؤقت بلا وجهة، وشبكة CDN بلا حاوية لن يكون لديها ما تقدّمه.


المُدار مقابل BYO

مُدار (افتراضي)استخدم التخزين + CDN الخاص بك
الصور الأصليةتخزين smallPict المشفّرoriginals/<job_id>/<file> في حاويتك
الملفات المحسّنةتُقدَّم من cdn.smallpict.appoptimized/<job_id>.<ext> في حاويتك، وتُقدَّم من نطاق CDN الخاص بك
حصة التخزينVelocity ‏50 غيغابايت، Momentum ‏100 غيغابايتلا تُحتسب. تدفع لمزوّد التخزين الخاص بك.
سعة نقل CDNVelocity ‏30 غيغابايت/شهريًا، Momentum ‏200 غيغابايت/شهريًالا تُحتسب. تدفع لمزوّد CDN الخاص بك.
التحويلاتتُحتسب ضمن خطتكتُحتسب ضمن خطتك
نسخة يحتفظ بها smallPictنعم، ما دام حسابك نشطًالا شيء. فقط ملف الرفع المؤقت للمعالجة، ويُحذف خلال 24 ساعة.
مسح ذاكرة التخزين المؤقتتلقائيتلقائي، عبر API الخاصة بشبكة CDN لديك
أداء CDN ونطاقها وتكاليفهاsmallPictأنت. لا يتحمل smallPict مسؤولية أداء شبكة CDN الخاصة بك أو نطاقاتها أو فواتيرها.

المزوّدون المدعومون

التخزين (متاح الآن): Amazon S3 وCloudflare R2 وGoogle Cloud Storage (توافق S3) وAlibaba Cloud OSS وTencent Cloud COS وDigitalOcean Spaces وSumoPod Storage وMinIO، وأي خدمة أخرى متوافقة مع S3 عبر نقطة نهاية مخصّصة (مثل Hetzner أو Vultr أو Wasabi).

CDN (متاح الآن): Cloudflare وAmazon CloudFront.

مخطط له: Azure Blob Storage وشبكات CDN أخرى. يمكنك طلب وصول مبكر من صفحة مزوّدو الخدمات السحابية.


قبل أن تبدأ

  1. أنت مشترك في خطة API Velocity أو Momentum ومسجّل الدخول بصفتك مسؤولًا عن الحساب.
  2. لديك حاوية، وشبكة CDN تقدّم الملفات من تلك الحاوية عبر HTTPS.
  3. يمكن الوصول إلى نقطة نهاية التخزين من الإنترنت عبر HTTPS. تُرفض نقاط النهاية الخاصة والداخلية وتلك التي تعمل عبر HTTP العادي.
  4. أنشأت مفاتيح محدودة الصلاحيات لـ smallPict (راجع الحد الأدنى من الصلاحيات أدناه). لا تستخدم مفاتيح الجذر أو مفاتيح المسؤول الخاصة بحسابك.

بعد ذلك افتح لوحة التحكم ← شبكة CDN والتخزين، واختر استخدم التخزين + CDN الخاص بك، واملأ الجزأين، ثم اختر حفظ التخزين + CDN. يجري smallPict فحص الاتصال (الموضح أدناه)، ولا ينقلك إلى وضع BYO إلا إذا نجح.


أدلة الإعداد

أ. Amazon S3 + Amazon CloudFront

  1. أنشئ الحاوية في المنطقة التي تريدها، مثل my-images في ap-southeast-1. أبقِ خيار Block Public Access مفعّلًا.
  2. أنشئ توزيع CloudFront تكون الحاوية مصدره. استخدم Origin access control (OAC) حتى يتمكن CloudFront من قراءة الحاوية مع بقائها خاصة، وطبّق سياسة الحاوية التي يقترحها عليك CloudFront.
  3. اختياري: نطاقك الخاص. أضف إلى التوزيع اسم نطاق بديلًا (مثل images.example.com) وشهادة، ووجّه سجل DNS إلى التوزيع.
  4. أنشئ مستخدم IAM (أو دورًا) للتخزين بهذه السياسة:
JSON
{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Action": [        "s3:PutObject",        "s3:GetObject",        "s3:DeleteObject"      ],      "Resource": "arn:aws:s3:::my-images/*"    }  ]}
  1. أنشئ مستخدم IAM لـ CloudFront (يمكن أن يكون المستخدم نفسه) بهذه السياسة. الصلاحية cloudfront:GetDistribution اختيارية؛ وبوجودها يستطيع smallPict اكتشاف نطاق التوزيع عندما تترك نطاق CDN فارغًا.
JSON
{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Action": [        "cloudfront:CreateInvalidation",        "cloudfront:GetDistribution"      ],      "Resource": "arn:aws:cloudfront::123456789012:distribution/E2QWRUHAPOMQZL"    }  ]}
  1. في لوحة التحكم:
    • مزوّد التخزين Amazon S3، والحاوية my-images، والمنطقة ap-southeast-1، ونقطة النهاية فارغة (تُستخدم نقطة النهاية القياسية للمنطقة)، وAccess key ID والمفتاح السري الخاصان بالتخزين.
    • شبكة CDN Amazon CloudFront، وDistribution ID (مثل E2QWRUHAPOMQZL)، وAccess key ID والمفتاح السري الخاصان بـ CloudFront، ونطاق CDN اختياريًا (https://images.example.com). اترك النطاق فارغًا لاستخدام نطاق *.cloudfront.net الخاص بالتوزيع نفسه.

ب. Cloudflare R2 + Cloudflare

  1. أنشئ حاوية R2، مثل my-images.
  2. اربط نطاقًا مخصّصًا بالحاوية (R2 ← حاويتك ← Settings ← Custom Domains)، مثل images.example.com، على منطقة (Zone) في حساب Cloudflare نفسه. تمر الطلبات إلى هذا النطاق عبر ذاكرة التخزين المؤقت لـ Cloudflare. لا تستخدم عنوان التطوير r2.dev في بيئة الإنتاج.
  3. أنشئ رمز API لـ R2 (R2 ← Manage API tokens) بصلاحية Object Read & Write، مقصورًا على هذه الحاوية فقط. انسخ Access Key ID وSecret Access Key اللذين يظهران لك.
  4. أنشئ رمز API لـ Cloudflare (My Profile ← API Tokens) للمنطقة بصلاحية Zone → Cache Purge → Purge. صلاحية Zone → Zone → Read اختيارية.
  5. في لوحة التحكم:
    • مزوّد التخزين Cloudflare R2، والحاوية my-images، ونقطة النهاية https://<account_id>.r2.cloudflarestorage.com (تظهر في تفاصيل S3 API لحاويتك)، والمنطقة auto، وAccess Key ID وSecret Access Key الخاصان بـ R2.
    • شبكة CDN Cloudflare، وZone ID (صفحة Overview للنطاق، قسم API)، ورمز API، ونطاق CDN https://images.example.com.

ج. Google Cloud Storage + Cloudflare

يُربط Google Cloud Storage عبر واجهة XML API المتوافقة مع S3 باستخدام مفاتيح HMAC.

  1. أنشئ الحاوية، مثل my-images.
  2. أنشئ حساب خدمة وامنحه دور Storage Object User (roles/storage.objectUser) على هذه الحاوية فقط.
  3. أنشئ مفتاح HMAC لحساب الخدمة: Cloud Storage ← Settings ← Interoperability ← Create a key for a service account. انسخ معرّف الوصول والمفتاح السري.
  4. اجعل الملفات المحسّنة قابلة للقراءة من شبكة CDN. يجلب Cloudflare الملفات من Cloud Storage عبر HTTPS، لذا يجب أن تكون الكائنات ضمن optimized/ قابلة للقراءة للعامة. ومع الوصول الموحّد على مستوى الحاوية، فإن منح allUsers دور Storage Object Viewer يجعل الحاوية كلها قابلة للقراءة، بما فيها originals/. إذا كان يجب أن تبقى صورك الأصلية خاصة، فضع أمامها طبقة مصادقة (مثل Cloudflare Worker يوقّع الطلبات المرسلة إلى الحاوية).
  5. وجّه سجل DNS في Cloudflare مفعّلًا عليه الوكيل (proxied) إلى Cloud Storage، مثل images.example.com. إما أن تسمّي الحاوية باسم المضيف وتستخدم سجل CNAME عبر الوكيل يشير إلى c.storage.googleapis.com، أو تستخدم Origin Rule في Cloudflare ترسل الطلبات إلى storage.googleapis.com مع اسم الحاوية في بداية المسار.
  6. أنشئ رمز API لـ Cloudflare للمنطقة بصلاحية Zone → Cache Purge → Purge (صلاحية Zone → Zone → Read اختيارية).
  7. في لوحة التحكم: مزوّد التخزين Google Cloud Storage، والحاوية، ونقطة النهاية https://storage.googleapis.com، والمنطقة auto، ومعرّف الوصول والمفتاح السري لـ HMAC؛ وشبكة CDN Cloudflare، وZone ID، ورمز API، ونطاق CDN https://images.example.com.

د. MinIO أو أي تخزين متوافق مع S3 + Cloudflare

يغطي هذا القسم MinIO والخدمات المتوافقة مع S3 مثل Hetzner وWasabi وVultr وSumoPod وAlibaba Cloud OSS وTencent Cloud COS وDigitalOcean Spaces.

المزوّدما تختاره في لوحة التحكمنقطة النهايةملاحظات
MinIOMinIOخادمك، مثل https://minio.example.comطلبات path-style مفعّلة. يجب أن يكون الخادم قابلًا للوصول من الإنترنت عبر HTTPS.
Hetzner Object Storageمخصّص متوافق مع S3https://<location>.your-objectstorage.com
Wasabiمخصّص متوافق مع S3https://s3.<region>.wasabisys.com
Vultr Object Storageمخصّص متوافق مع S3https://<region>.vultrobjects.com
SumoPod StorageSumoPod Storageمن لوحة تحكم التخزين في SumoPodpath-style مفعّل افتراضيًا.
Alibaba Cloud OSSAlibaba Cloud OSShttps://oss-<region>.aliyuncs.comنمط virtual-hosted فقط.
Tencent Cloud COSTencent Cloud COShttps://cos.<region>.myqcloud.comيتضمن اسم الحاوية معرّف APPID الخاص بك، مثل my-images-1250000000.
DigitalOcean SpacesDigitalOcean Spaceshttps://<region>.digitaloceanspaces.com
  1. أنشئ الحاوية ومفتاحًا مقصورًا عليها بصلاحيات put وget وdelete على الكائنات (راجع الحد الأدنى من الصلاحيات أدناه).
  2. اجعل optimized/ قابلًا للقراءة من شبكة CDN، مثلًا بسياسة حاوية تسمح بـ s3:GetObject المجهول على optimized/* فقط. على MinIO:
JSON
{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Principal": {        "AWS": [          "*"        ]      },      "Action": [        "s3:GetObject"      ],      "Resource": [        "arn:aws:s3:::my-images/optimized/*"      ]    }  ]}
  1. ضع Cloudflare أمام الحاوية: سجل DNS عبر الوكيل لـ images.example.com يشير إلى المضيف العام للحاوية. إذا كان المزوّد يتطلب اسم المضيف الخاص به في الطلب، فأضف Origin Rule في Cloudflare تعيد كتابة ترويسة Host (وتضيف اسم الحاوية إلى المسار في مضيفات path-style).
  2. أنشئ رمز API لـ Cloudflare للمنطقة بصلاحية Zone → Cache Purge → Purge (صلاحية Zone → Zone → Read اختيارية).
  3. في لوحة التحكم: اختر المزوّد من الجدول، وأدخل الحاوية ونقطة النهاية والمنطقة (auto إذا لم يكن لدى المزوّد مناطق) والمفاتيح؛ وفعّل طلبات path-style حيث يشير الجدول إلى ذلك؛ ثم شبكة CDN Cloudflare، وZone ID، ورمز API، ونطاق CDN.

الحد الأدنى من الصلاحيات

امنح smallPict مفاتيح لا تستطيع إلا تنفيذ ما يحتاج إليه، على حاوية واحدة.

المزوّدالصلاحيات
Amazon S3s3:PutObject وs3:GetObject وs3:DeleteObject على arn:aws:s3:::<bucket>/*
Amazon CloudFrontcloudfront:CreateInvalidation على التوزيع؛ وcloudfront:GetDistribution اختيارية لاكتشاف النطاق
Cloudflare R2رمز API لـ R2 بصلاحية Object Read & Write، مقصور على الحاوية
Cloudflare (CDN)رمز API للمنطقة بصلاحية Zone → Cache Purge → Purge؛ وZone → Zone → Read اختيارية
Google Cloud Storageمفتاح HMAC لحساب خدمة لديه roles/storage.objectUser على الحاوية
Alibaba Cloud OSSمستخدم RAM لديه oss:PutObject وoss:GetObject وoss:DeleteObject على الحاوية
Tencent Cloud COSمستخدم فرعي في CAM لديه cos:PutObject وcos:GetObject وcos:DeleteObject على الحاوية (يتضمن اسم الحاوية معرّف APPID)
DigitalOcean Spacesمفتاح وصول Spaces مقصور على الحاوية بصلاحيات القراءة والكتابة والحذف
MinIO / مخصّص متوافق مع S3put وget وdelete على <bucket>/*؛ ويجب أن تكون نقطة النهاية HTTPS عامة

فحص الاتصال

في كل مرة تحفظ فيها (وعندما تختار إعادة الفحص)، يفحص smallPict الاتصال بالكامل قبل استخدامه:

  1. التخزين: يكتب ملف اختبار صغيرًا ضمن .smallpict-probe/ في حاويتك، ثم يقرؤه ويحذفه.
  2. Cloudflare: يرسل طلب مسح اختباريًا واحدًا لعنوان URL واحد إلى منطقتك.
  3. CloudFront: ينشئ طلب إبطال (invalidation) اختباريًا واحدًا لمسار /.smallpict-probe/.... ويُحتسب ضمن مسارات الإبطال في CloudFront لهذا الشهر.

إذا فشلت أي خطوة، فلن يُبدَّل شيء. تعرض لوحة التحكم السبب بجوار الحقل المعني، مثل اسم الحاوية أو رمز API. يقتصر فحص الاتصال على 5 محاولات في الدقيقة.


وصول شبكة CDN إلى الحاوية

  • optimized/ يجب أن يكون قابلًا للقراءة من شبكة CDN: إما بقراءة عامة على هذه البادئة، أو بوصول CDN إلى المصدر في حاوية خاصة (Origin access control في CloudFront، أو نطاق مخصّص في R2).
  • originals/ يمكن أن يبقى خاصًا. لا تحتاج إليه شبكة CDN أبدًا.
  • CORS مطلوب فقط إذا كانت المتصفحات تجلب الصور من مصدر مختلف عبر JavaScript (مثل fetch() أو canvas). وسوم <img> العادية لا تحتاج إليه. وإن احتجت إليه، فاسمح بـ GET وHEAD من مصدر موقعك.

بنية الكائنات وعناوين URL

العنصرالمفتاح في حاويتكURL
الأصليoriginals/<job_id>/<file>لا يُقدَّم
الملف المحسّنoptimized/<job_id>.<ext><cdn_domain>/optimized/<job_id>.<ext>

يمكن أن يتضمن نطاق CDN بادئة مسار، مثل https://example.com/images؛ ويصبح عنوان URL حينئذٍ https://example.com/images/optimized/<job_id>.<ext>.


ترويسات ذاكرة التخزين المؤقت

تُكتب الملفات المحسّنة مع Cache-Control: public, max-age=31536000, immutable. تحصل كل مهمة على مفتاح فريد، لذا يكون للنتيجة الجديدة دائمًا عنوان URL جديد، ونادرًا ما يلزم المسح. احرص على ألا تستبدل قواعد التخزين المؤقت في شبكة CDN هذه الترويسة بمدة أقصر.


مسح ذاكرة التخزين المؤقت

  • تُرسَل طلبات المسح التي تُجرى عبر API ‏(POST /v1/purge) إلى شبكة CDN الخاصة بك أنت، على دفعات.
  • على Cloudflare تُمسح الملفات حسب عنوان URL. ولا يمسح خيار «Purge all» إلا مضيف التوصيل وبادئة المسار الخاصين بك، لا منطقتك بالكامل.
  • على CloudFront تُمسح الملفات بطلبات الإبطال. وينشئ خيار «Purge all» طلب إبطال /*. وتفوتر AWS حسابك على مسارات الإبطال التي تتجاوز الحصة الشهرية المجانية في CloudFront.

تبديل الوضع

لا يؤدي تبديل الوضع إلى نقل الملفات الموجودة. تحتفظ الملفات التي سبق تقديمها بعناوين URL الحالية؛ ولا تستخدم الوضع الجديد إلا المهام الجديدة.

  • المُدار ← BYO: تذهب المهام الجديدة إلى حاويتك وتقدّمها شبكة CDN الخاصة بك. تبقى الملفات الموجودة بالفعل على cdn.smallpict.app في مكانها.
  • BYO ← المُدار: تعود المهام الجديدة إلى استخدام التخزين وCDN المُدارين. تبقى إعدادات BYO ومفاتيحك محفوظة لكن غير مستخدمة، فتستطيع العودة دون إدخالها مجددًا، إلى أن تختار قطع الاتصال.
  • قطع الاتصال: يحذف المفاتيح وإعدادات BYO المحفوظة ويعيدك إلى الوضع المُدار. لا تُمَس الملفات الموجودة في حاويتك.

عند حدوث خطأ

  • إذا تعذّر على smallPict الكتابة في حاويتك، فإنه يعيد المحاولة، ثم يُفشل المهمة مع سبب يمكنك قراءته في استجابة API.
  • تعرض لوحة التحكم آخر خطأ ووقت حدوثه، مع زر إعادة الفحص.
  • تتلقى رسالة بريد إلكتروني واحدة لكل حادثة، لا رسالة لكل مهمة فاشلة.
  • لا يلجأ smallPict أبدًا إلى التخزين المُدار كبديل. لا تُخزَّن ملفاتك أبدًا في مكان لم تختره.

الأمان

  • تُحفظ المفاتيح في مخزن أسرار مشفّر. لا تُعرض مرة أخرى أبدًا، ولا تُرجعها API أبدًا، ولا تُكتب في السجلات أبدًا.
  • لتدوير مفتاح، أدخل المفتاح الجديد واحفظ؛ يُجرى فحص الاتصال بالمفتاح الجديد. اترك حقل المفتاح فارغًا للاحتفاظ بالمفتاح المحفوظ.
  • يجب أن تستخدم نقاط نهاية التخزين وCDN بروتوكول HTTPS. تُرفض نقاط النهاية التي تشير إلى عناوين خاصة أو عناوين loopback أو link-local أو أي عناوين داخلية أخرى.
  • استخدم مفاتيح منفصلة ومحدودة الصلاحيات لـ smallPict، وألغِها من وحدة تحكم مزوّدك إذا توقفت عن استخدام BYO.