انتقل إلى المقال
Aniq-UI

Food Studioمتغيرات البيئة

متغيرات البيئة

ما يفعله كل إعداد في ملفات .env الخاصة بواجهة API والواجهتين الأماميتين، وأيها تحتاج إليه.

لحزمة الحزمة الكاملة

أين توجد الإعدادات

الملفيقرؤهيحتوي على أسرار
back-end/.envواجهة API، مع yarn dev وداخل Docker Composeنعم. لا تضفه إلى المستودع أبدًا.
storefront/.envموقع الطلبات، وقت البناءلا. كل القيم عامة.
admin-dashboard/.envلوحة تحكم الفريق، وقت البناءلا. كل القيم عامة.
.env بجوار docker-compose.ymlDocker Compose، للحزمة الكاملةلا

أنشئ ملف كل تطبيق من .env.example الموجود بجواره، والذي يشرح كل متغير: cp .env.example .env. تعمل الأمثلة كما هي للتشغيل المحلي.

أين توجد الإعدادات

ملف واحد، .env في مجلد الموقع، يُقرأ عند بناء الموقع. كل قيمة فيه عامة، لذلك لا يحتوي أي سر أبدًا: مفاتيح الدفع والذكاء الاصطناعي توجد في ملف .env الخاص بواجهة API. أنشئه من .env.example، الذي يشير إلى واجهة API على http://localhost:8000: cp .env.example .env.

أين توجد الإعدادات

ملف واحد، .env في مجلد لوحة التحكم، يُقرأ عند بناء لوحة التحكم. كل قيمة فيه عامة، لذلك لا يحتوي أي سر أبدًا: مفاتيح الذكاء الاصطناعي توجد في ملف .env الخاص بواجهة API. أنشئه من .env.example، الذي يشير إلى واجهة API على http://localhost:8000: cp .env.example .env.

أين توجد الإعدادات

ملف واحد، .env في مجلد واجهة API، تقرؤه واجهة API مع yarn dev، وتقرؤه الحاوية عندما تمرّره بـ --env-file .env. يحتوي على أسرار: لا ترفعه إلى المستودع أبدًا. أنشئه من .env.example، الذي يشرح كل متغير ويعمل كما هو للتشغيل المحلي: cp .env.example .env.

تضبط صورة Docker قيمها الافتراضية الخاصة، لذلك يعمل docker run من دون ملف: SQLite على /data/database.sqlite، والملفات المرفوعة في /data/uploads، وCORS_ORIGIN للواجهتين الأماميتين المحليتين، وPUBLIC_MEDIA_URL=http://localhost:8000/media وSEED_DEMO_DATA=false. غيّر أيًا منها باستخدام -e.

أساسيات واجهة API

تتحقق واجهة API من JWT_SECRET، ومن CORS_ORIGIN في الإنتاج، قبل أن تبدأ. إذا كان أحدهما ناقصًا أو غير صالح، تتوقف وتطبع سطرًا واحدًا يوضح ما يجب إصلاحه.

المتغيروظيفته
NODE_ENVdevelopment محليًا، وهو ينشئ الجداول ويحدّثها عند بدء التشغيل. وproduction على خادم مباشر، وهو لا يلمس الجداول أبدًا.
PORTمنفذ واجهة API، وهو 8000. تشير إليه الواجهتان الأماميتان.
DB_TYPEsqlite (كما في .env.example) أو mysql.
SQLITE_DATABASEمسار ملف SQLite، وهو ./database.sqlite افتراضيًا.
JWT_SECRETيوقّع كل تسجيل دخول. مطلوب. قيمة المثال مقبولة خارج الإنتاج فقط.
JWT_EXPIRATIONمدة صلاحية تسجيل الدخول، وهي 7d افتراضيًا.
CORS_ORIGINعنوانا الموقع ولوحة التحكم، مفصولين بفاصلة. يجب أن يكون عنوان العودة من الدفع المستضاف على أحدهما. إذا لم يُضبط، فلا يُسمح إلا بـ http://localhost:3030 وhttp://localhost:3031؛ وهو مطلوب في الإنتاج.
FRONTEND_URLعنوان لوحة التحكم، الذي تتصل منه إشعاراتها المباشرة. مطلوب في الإنتاج لهذه الإشعارات.
STOREFRONT_URLعنوان الموقع، الذي يُرسَل إليه العميل من رابط الدفع ورابط إعادة تعيين كلمة المرور. قيمته الافتراضية أول عنوان في CORS_ORIGIN.
API_PUBLIC_URLالعنوان العام لواجهة API هذه، الذي يعيد إليه Stripe و PayPal المتصفح أولًا. قيمته الافتراضية http://localhost على PORT.
TRUST_PROXYاختياري. عدد الخوادم الوكيلة العكسية أمام واجهة API، حتى تحسب الحدود الخاصة بكل عنوان الزائرَ الحقيقي.
RATE_LIMIT_LOGINاختياري. عدد محاولات تسجيل الدخول الفاشلة المسموح بها لعنوان واحد على نموذج تسجيل دخول خلال 15 دقيقة قبل 429، وهو 10 افتراضيًا.
RATE_LIMIT_ORDERS, RATE_LIMIT_PAYMENT_SESSION, RATE_LIMIT_TRACKING, RATE_LIMIT_REGISTER, RATE_LIMIT_CONTACT, RATE_LIMIT_PASSWORD_RESETاختياري. الحدود الخاصة بكل عنوان على النماذج العامة؛ يذكر .env.example القيمة الافتراضية لكل حد ونافذته الزمنية.

ولّد JWT_SECRET خاصًا بك بالأمر:

الطرفية
node -e "console.log(require('crypto').randomBytes(48).toString('hex'))"

كل ميزة اختيارية أدناه تبقى متوقفة ما دامت أسطرها في .env.example معلّقة كتعليقات.

استخدم MySQL بدلًا من SQLite

أنشئ قاعدة بيانات فارغة، ثم اضبط المشغّل والاتصال في ملف .env الخاص بواجهة API:

ملف .env الخاص بواجهة API
DB_TYPE=mysql
DB_HOST=your-mysql-host
DB_PORT=3306
DB_USERNAME=your-mysql-username
DB_PASSWORD=your-mysql-password
DB_DATABASE=your-database-name

ثم شغّل yarn seed للمطعم التجريبي، أو yarn db:sync للجداول من دون بيانات. لا تنشئ واجهة API العاملة الجداول وتحدّثها بنفسها إلا مع NODE_ENV=development، لذلك مع NODE_ENV=production يُشغَّل أحد هذين الأمرين قبل التشغيل الأول (yarn seed:prod أو yarn db:sync:prod بعد yarn build).

موقع الطلبات ولوحة تحكم الفريق

كل قيمة NEXT_PUBLIC_* تُضمَّن في كود JavaScript الذي يحمّله المتصفح، ويستطيع أي شخص يفتح الصفحة قراءتها. لا تضع أي سر في هذه الملفات أبدًا، وأعد البناء بعد تغيير أي قيمة.

المتغيرالتطبيقوظيفته
NEXT_PUBLIC_API_BASE_URLكلاهماعنوان واجهة API مع /api، وهو http://localhost:8000/api افتراضيًا.
NEXT_PUBLIC_MEDIA_HOSTNAMEكلاهمامضيف https لمخزن صورك، مثل pub-1234.r2.dev، أو لواجهة API عندما تقدّم الصور على نطاق عام. يغيّر Next.js حجم الصور القادمة منه؛ وأي صورة أخرى تُعرض كما هي. اسم المضيف فقط. اتركه فارغًا ما دامت واجهة API تعمل على localhost.
NEXT_PUBLIC_WEBSOCKET_BASE_URLلوحة التحكمعنوان واجهة API من دون /api، للطلبات والإشعارات المباشرة.
NEXT_PUBLIC_DASHBOARD_URLلوحة التحكمعنوان لوحة التحكم نفسها، للروابط الكاملة والتطبيق القابل للتثبيت.
NEXT_PUBLIC_STOREFRONT_URLلوحة التحكمالمكان الذي يقود إليه رابط «عرض المتجر» في شريط التنقل.
NEXT_PUBLIC_MAP_STYLE_LIGHT, NEXT_PUBLIC_MAP_STYLE_DARKالموقع (المظهر الفاتح فقط)، ولوحة التحكمأنماط اختيارية لمربعات الخريطة. القيمة الفارغة تستخدم أنماط OpenFreeMap العامة، التي لا تحتاج إلى مفتاح.
API_INTERNAL_URLالموقعاختياري، للخادم فقط، يُقرأ عند بدء الحاوية. المكان الذي يصل منه خادم الموقع نفسه إلى واجهة API عندما لا يعمل عنوان المتصفح من داخله، كما في Docker Compose (http://api:8000/api). اتركه غير مضبوط في غير ذلك.
BUILD_STANDALONEكلاهماالقيمة true تجعل yarn build يُخرج خادمًا مستقلًا بذاته، وهي القيمة التي تضبطها ملفات Dockerfile. اتركه غير مضبوط في غير ذلك.

وسوم التسويق في الموقع هي أيضًا قيم NEXT_PUBLIC_*.

خيارات Docker Compose

لا تحتاج إلى ضبط أي شيء للتشغيل المحلي. لتغيير شيء، ضعه في ملف .env بجوار docker-compose.yml وشغّل docker compose up --build مرة أخرى: تُضمِّن الواجهات الأمامية هذه القيم.

المتغيرالقيمة الافتراضيةوظيفته
SITE_PORT3030منفذ الموقع على جهازك.
ADMIN_PORT3031منفذ لوحة التحكم على جهازك.
API_PORT8000منفذ واجهة API على جهازك.
SITE_URL, ADMIN_URL, API_URLالعناوين المحلية على هذه المنافذالعنوان الذي يصل منه المتصفح إلى كل تطبيق. اضبط الثلاثة عند تشغيل التطبيقات على نطاقاتك الخاصة.
MEDIA_HOSTNAMEفارغالمضيف العام لمخزنك، مع متغيرات R2_* في back-end/.env.
SEED_DEMO_DATAtrueالقيمة false تبدأ بجداول فارغة ومن دون حسابات بدلًا من المطعم التجريبي. لا تهم إلا مع وحدة تخزين جديدة.
NEXT_PUBLIC_GTM_ID, NEXT_PUBLIC_GA4_MEASUREMENT_ID, NEXT_PUBLIC_META_PIXEL_ID, NEXT_PUBLIC_TIKTOK_PIXEL_ID, NEXT_PUBLIC_SNAPCHAT_PIXEL_ID, NEXT_PUBLIC_PINTEREST_TAG_IDفارغوسوم التسويق في الموقع، وكلها اختيارية.
NEXT_PUBLIC_ANALYTICS_CURRENCYUSDالعملة المرسلة مع كل قيمة متتبَّعة.

غيّر المنفذ عندما يستخدمه برنامج آخر بالفعل، مثل ADMIN_PORT=3041. تُبنى القيم CORS_ORIGIN وFRONTEND_URL وSTOREFRONT_URL وAPI_PUBLIC_URL وPUBLIC_MEDIA_URL في واجهة API، وعنوان واجهة API في الواجهات الأمامية، كلها من المنافذ والعناوين الثلاثة، لذلك تتبعها تلقائيًا.

تقرأ حاوية واجهة API الملف back-end/.env أيضًا إذا كان موجودًا، لذلك تُضبط مفاتيح المدفوعات والبريد والوسائط والذكاء الاصطناعي في مكان واحد لكل من yarn dev و Docker. ملف compose هو الذي يُعتمد للقيم التي تختلف داخل الحاوية: مسار قاعدة البيانات، ومجلد الملفات المرفوعة، والمنفذ، وNODE_ENV=production، والعناوين أعلاه. تعيش قاعدة البيانات والملفات المرفوعة في وحدة التخزين food-studio-data.

تخزين الوسائط

تقدّم واجهة API الصور التجريبية بنفسها، من public/media/food-studio، على /media/food-studio/…. الملفات المرفوعة من لوحة التحكم (صور الأطباق، وصور الملفات الشخصية، ونتائج استوديو الذكاء الاصطناعي) تُحفظ على قرص واجهة API تحت MEDIA_UPLOAD_DIR وتُقدَّم على /media/uploads/…، ما لم يُضبط مخزن.

ملف .env الخاص بواجهة API
PUBLIC_MEDIA_URL=http://localhost:8000/media
MEDIA_UPLOAD_DIR=./public/media/uploads

PUBLIC_MEDIA_URL هو العنوان الذي يُوصل منه إلى /media من المتصفح. تكتبه تعبئة البيانات داخل عنوان كل صورة، لذلك اضبطه قبل أول تعبئة على الخادم. على الخادم، وجّه MEDIA_UPLOAD_DIR إلى تخزين دائم؛ ومع Docker يكون داخل وحدة تخزين البيانات.

لإرسال الملفات المرفوعة إلى Cloudflare R2، أو أي مخزن متوافق مع S3، اضبط المتغيرات الخمسة كلها، وأعطِ الواجهتين الأماميتين المضيف العام للمخزن عبر NEXT_PUBLIC_MEDIA_HOSTNAME (ومع Docker Compose، MEDIA_HOSTNAME). اضبط الخمسة كلها أو لا شيء منها.

ملف .env الخاص بواجهة API
R2_ACCESS_KEY_ID=your-r2-access-key-id
R2_SECRET_ACCESS_KEY=your-r2-secret-access-key
R2_ENDPOINT=https://your-account-id.r2.cloudflarestorage.com
R2_BUCKET_NAME=your-bucket-name
R2_PUBLIC_URL=https://your-public-url.r2.dev

المدفوعات

ترسل صفحة إتمام الطلب العميل إلى صفحة Stripe أو PayPal نفسها. اضبط STRIPE_SECRET_KEY وSTRIPE_WEBHOOK_SECRET، أو PAYPAL_CLIENT_ID وPAYPAL_CLIENT_SECRET وPAYPAL_WEBHOOK_ID (مع PAYPAL_ENV، وقيمته الافتراضية sandbox). من دون أي مزوّد، توفّر صفحة إتمام الطلب دفعًا تجريبيًا مدمجًا يجعل الطلب مدفوعًا من دون تحويل أي مال.

ملف .env الخاص بواجهة API
STRIPE_SECRET_KEY=sk_test_your-stripe-secret-key
STRIPE_WEBHOOK_SECRET=whsec_your-webhook-secret

البريد الإلكتروني

تُرسل روابط إعادة تعيين كلمة المرور عبر Resend. تحتاج إلى القيمتين معًا: مفتاح بصلاحية الإرسال، وعنوان مرسِل (From) على نطاق موثَّق في Resend. من دونهما يستجيب «نسيت كلمة المرور» كالمعتاد، ولا تُرسل أي رسالة، ويذكر السجل أن البريد غير مضبوط.

ملف .env الخاص بواجهة API
RESEND_API_KEY=re_your-sending-access-key
MAIL_FROM=Food Studio <noreply@your-domain.com>
MAIL_MAX_PER_ADDRESS_PER_DAY=5

يفتح الرابط صفحة إعادة التعيين في الموقع على STOREFRONT_URL، بلغة العميل، ويعمل مرة واحدة خلال ساعة. يستقبل العنوان الواحد MAIL_MAX_PER_ADDRESS_PER_DAY رسالة في اليوم كحد أقصى، و5 افتراضيًا.

ميزات الذكاء الاصطناعي

مُضمَّن مع مشترياتك. سجّل الدخول لقراءته، أو افتحه في ملف التنزيل.

تشغيل ميزات الذكاء الاصطناعي: مفاتيح المزوّدين، والنماذج التي تستخدمها كل ميزة، ونموذج إزالة الخلفية.

خادم MCP

مُضمَّن مع مشترياتك. سجّل الدخول لقراءته، أو افتحه في ملف التنزيل.

السماح لوكلاء البرمجة وعملاء MCP الآخرين باستخدام أدوات المساعد: المفتاح ونقطة النهاية.

وضع العرض التجريبي

مُضمَّن مع مشترياتك. سجّل الدخول لقراءته، أو افتحه في ملف التنزيل.

تشغيل نسخة تجريبية عامة: مفاتيح الوضع التجريبي، والحسابات الخاصة بكل زائر، وما يمكن للزوار تغييره.

الإطلاق

قبل النشر على أي مكان عام:

  1. في ملف .env الخاص بواجهة API، اضبط NODE_ENV=production وJWT_SECRET طويلًا وعشوائيًا خاصًا بك.
  2. اضبط CORS_ORIGIN على عنوانَي الموقع ولوحة التحكم، وFRONTEND_URL على عنوان لوحة التحكم، وSTOREFRONT_URL على عنوان الموقع، وAPI_PUBLIC_URL على عنوان واجهة API، وPUBLIC_MEDIA_URL على عنوان واجهة API متبوعًا بـ /media.
  3. على قاعدة بيانات جديدة، شغّل yarn build، ثم yarn seed:prod مرة واحدة (أو yarn db:sync:prod لجداول فارغة)، ثم yarn start:prod. لا توجد عمليات ترحيل (migrations): أداة تعبئة البيانات هي أداة إنشاء المخطط.
  4. احفظ الملفات المرفوعة على تخزين دائم: مخزن، أو MEDIA_UPLOAD_DIR على قرص يبقى بعد النشر.
  5. وجّه فحص السلامة لدى الاستضافة إلى /api/health، واضبط TRUST_PROXY عندما يقف خادم وكيل عكسي أمام واجهة API.
  6. ابنِ كل واجهة أمامية مع NEXT_PUBLIC_API_BASE_URL يشير إلى واجهة API المنشورة؛ ولوحة التحكم أيضًا مع NEXT_PUBLIC_WEBSOCKET_BASE_URL وNEXT_PUBLIC_DASHBOARD_URL وNEXT_PUBLIC_STOREFRONT_URL.
  7. في الموقع، اضبط domain.url في src/config/brand.config.ts، وأعد كتابة سياسة الخصوصية والشروط في messages/legal لتناسب نشاطك.
  8. في لوحة التحكم، اضبط مطابخك وساعات عملها ورموز التوصيل البريدية، ورسومك ورموز الخصم، وحوّل ساعة الخدمة إلى «الساعة الحقيقية»: تبدأها تعبئة البيانات على الساعة التجريبية، التي تُبقي كل المطابخ مفتوحة.
  9. غيّر كلمات المرور التجريبية، أو احذف الحسابات، وحوّل المدفوعات إلى المفاتيح الحقيقية (live).

لا يصلح لمطعم فيه طلبات حقيقية

يبني yarn railway:setup، ويجلب نموذج إزالة الخلفية، ويحذف كل الجداول ويعبّئ البيانات، في كل مرة يُشغَّل فيها، ويحذف yarn drop:prod كل الجداول. يناسبان بيئة جديدة، ولا يصلحان أبدًا كأمر بناء لمطعم يعمل فعليًا.

توقفت عند خطوة؟

ابحث عن الحل قبل أن تبدأ من جديد.

حل المشكلات

تفضيلات ملفات تعريف الارتباط

نستخدم ملفات تعريف الارتباط لتعزيز تجربة التصفح الخاصة بك وتحليل حركة المرور على الموقع وتخصيص المحتوى. بالنقر على "قبول الكل"، فإنك توافق على استخدامنا لملفات تعريف الارتباط للتحليلات والإعلانات المخصصة.