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

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

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

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

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

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

الملفيقرؤهيحتوي على أسرار
back-end/.envواجهة API، مع yarn dev وداخل Docker Composeنعم. لا تضفه إلى المستودع أبدًا.
website/.envالموقع: قيم NEXT_PUBLIC_* عند البناء، وAPI_INTERNAL_URL على خادمهلا. كل قيمة عامة أو عنوان.
dashboard/.envلوحة التحكم، عند البناء، وPORT عندما يبدأ yarn dev أو yarn startلا. كل القيم عامة.
.env بجوار docker-compose.ymlفي Docker Compose فقط: المنافذ والعناوين التي يبني بها التطبيقات الثلاثةلا.

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

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

ملف واحد هو .env في مجلد الموقع، وكل قيمة فيه اختيارية. تُقرأ قيم NEXT_PUBLIC_* عند بناء الموقع وهي عامة، فلا تحمل سرًا أبدًا؛ أما API_INTERNAL_URL فيقرؤه خادم الموقع نفسه. من دون الملف يعمل الموقع على بياناته التجريبية المدمجة. لاستخدام واجهة API، أنشئه من .env.example الذي يشير إلى واحدة على http://localhost:8000: cp .env.example .env. مع Docker، مرّر قيم NEXT_PUBLIC_* بصيغة --build-arg وAPI_INTERNAL_URL باستخدام -e.

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

ملف واحد هو .env في مجلد لوحة التحكم، يُقرأ عند بناء لوحة التحكم، وتُقرأ PORT أيضًا عندما يبدأ yarn dev أو yarn start. كل قيمة فيه عامة، فلا يحمل سرًا أبدًا: مفاتيح المزوّدين والدفع موجودة في .env الخاص بواجهة API. من دون الملف تعمل لوحة التحكم على بياناتها التجريبية المدمجة. لاستخدام واجهة API، أنشئه من .env.example الذي يشير إلى واحدة على http://localhost:8000: cp .env.example .env. مع Docker، مرّر القيم نفسها بصيغة --build-arg.

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

ملف واحد هو .env في مجلد واجهة API، تقرؤه واجهة API مع yarn dev وyarn start:prod وyarn seed. يحوي أسرارًا: لا تضعه في Git أبدًا. أنشئه من .env.example الذي يشرح كل متغير ويعمل كما هو للتشغيل المحلي: cp .env.example .env.

تضبط صورة Docker قيمها الافتراضية بنفسها، فيعمل docker run من دون ملف: NODE_ENV=production، وSQLite عند /data/database.sqlite، والملفات المرفوعة في /data/uploads، وCORS_ORIGIN للواجهتين الأماميتين المحليتين، وFRONTEND_URL وDASHBOARD_URL على http://localhost:3031، وWEBSITE_URL=http://localhost:3030، وPUBLIC_API_URL=http://localhost:8000، وPUBLIC_MEDIA_URL=http://localhost:8000/media. تجاوز أيًّا منها باستخدام -e.

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

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

المتغيروظيفته
NODE_ENVdevelopment محليًا، وتنشئ الجداول وتحدّثها عند البدء. وproduction على خادم حي، وهي لا تلمس الجداول أبدًا وترفض قيمة المثال لـ JWT_SECRET وقيمة CORS_ORIGIN الفارغة.
PORTمنفذ واجهة API، وهو 8000. تشير إليه الواجهتان الأماميتان.
DB_TYPEsqlite (القيمة الافتراضية عند عدم الضبط) أو mysql.
SQLITE_DATABASEمسار ملف SQLite، وهو ./database.sqlite، نسبةً إلى مجلد واجهة API.
JWT_SECRETيوقّع كل جلسة تسجيل دخول. مطلوب. قيمة المثال مقبولة خارج الإنتاج فقط.
JWT_EXPIRATIONمدة بقاء تسجيل الدخول، 7d عند عدم الضبط. نموذج الدخول في لوحة التحكم يتجاوزها: عند تحديد تذكّرني يدوم الدخول 30 يومًا، وبدونه 12 ساعة.
CORS_ORIGINعنوانا الموقع ولوحة التحكم، مفصولان بفاصلة. إذا لم يُضبط فلا يُسمح إلا بـ http://localhost:3030 وhttp://localhost:3031، وليس بكل الأصول أبدًا؛ مطلوب في الإنتاج.
FRONTEND_URLعنوان لوحة التحكم، وهو المصدر الوحيد الذي تقبله تحديثات الصلاحيات المباشرة، http://localhost:3031 عند عدم الضبط.
DASHBOARD_URLعنوان لوحة التحكم في الروابط التي تكتبها واجهة API: الدعوات وإعادة ضبط بيانات الدخول والصفحة التي يعود إليها دفع الخطة. http://localhost:3031 عند عدم الضبط.
WEBSITE_URLعنوان الموقع: تعيد Stripe وPayPal مشتري الترخيص إليه. http://localhost:3030 عند عدم الضبط.
PUBLIC_API_URLالعنوان العام لواجهة API نفسها، ويُستخدم في روابط تنزيل الفواتير الموقّعة.
RATE_LIMIT_LOGINعدد محاولات الدخول الفاشلة التي يستطيعها عنوان واحد خلال 15 دقيقة قبل أن يحصل على 429، والقيمة الافتراضية 10.
TRUST_PROXYعدد الوكلاء العكسيين أمام واجهة API (1 خلف Nginx أو Caddy أو موازن أحمال؛ 2 مع Cloudflare أمام ذلك الوكيل)، ليحسب حد تسجيل الدخول والحدود لكل عنوان في العرض التجريبي الزوار وليس الوكيل. يُقرأ العنوان من يمين X-Forwarded-For، فلا يستطيع العميل اختياره. اتركه فارغًا عندما يُوصل إلى واجهة API مباشرة.
ADMIN_EMAIL, ADMIN_PASSWORD, ADMIN_NAMEأول مسؤول منصة ينشئه الأمر yarn admin:create، للبدء من دون الحسابات التجريبية. يسأل الأمر عن البريد وبيانات الدخول إذا تُركا فارغين؛ والاسم Platform Admin عندما يكون فارغًا.
SEED_SAMPLE_DATAفي Docker فقط. true (الافتراضي) يملأ وحدة تخزين جديدة بالبيانات التجريبية وحسابات الدخول المنشورة. وfalse يبدؤها فارغة: الجداول، مع أول مسؤول منصة عندما تُضبط ADMIN_EMAIL وADMIN_PASSWORD. مع Docker Compose توضع في ملف .env بجوار docker-compose.yml، مع ADMIN_EMAIL وADMIN_PASSWORD؛ فيمرّر Compose هذه الثلاثة من هناك، أما في back-end/.env فتقرؤها أوامر yarn فقط.

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

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

كل ميزة اختيارية أدناه معطّلة ما دامت متغيراتها في .env.example فارغة.

المدفوعات

مساران يتعاملان مع المال. صفحة الفوترة في لوحة التحكم تغيّر خطة اشتراك مساحة العمل، ودفع الموقع يبيع التراخيص. كلاهما يأخذ بيانات البطاقة في صفحة Stripe أو PayPal نفسها فقط (ترقية الخطة تُحصَّل من البطاقة التي تحتفظ بها Stripe أصلًا)، فلا تُكتب أبدًا في موقعك، وكلاهما يعمل من دون أي حساب عبر صفحات دفع تجريبية مدمجة لا تحصّل مبلغًا من أحد. استخدم مفاتيح الاختبار أولًا: فهي لا تنقل أي مال.

ملف .env الخاص بواجهة API
STRIPE_SECRET_KEY=sk_test_your_key
STRIPE_WEBHOOK_SECRET=whsec_your_secret
BILLING_PROVIDER=
BILLING_GRACE_DAYS=7
PAYPAL_CLIENT_ID=your-client-id
PAYPAL_CLIENT_SECRET=your-client-secret
PAYPAL_ENV=sandbox
المتغيروظيفته
STRIPE_SECRET_KEYStripe للمسارين. معها تفتح أول دفعة صفحة Stripe Checkout، وتُحصَّل ترقية الاشتراك الجاري من البطاقة المحفوظة، ويُجدول خفض الخطة على الاشتراك، وتفتح إدارة وسيلة الدفع بوابة عملاء Stripe، وتدفع البطاقة في صفحة الدفع بالترخيص على صفحة Stripe المستضافة. المفتاح الذي يبدأ بـ sk_test_ هو وضع الاختبار؛ ومع مفتاح sk_live_ تحصّل تغييرات الخطة من بطاقات حقيقية.
STRIPE_WEBHOOK_SECRETيتحقق من الـ webhook الواحد الذي يتشاركه المساران، https://<your-api>/api/billing/webhooks/stripe، مع الأحداث checkout.session.completed وcheckout.session.expired وinvoice.paid وinvoice.payment_failed وcustomer.subscription.deleted. يُطبَّق كل حدث مرة واحدة. عندما تُضبط STRIPE_SECRET_KEY ويبقى هذا فارغًا، يذكر سجل واجهة API ذلك عند البدء ويُرفض كل إرسال برمز 400 يسمّي المتغير، فلا تُسجَّل التجديدات ولا الدفعات الفاشلة ولا الإلغاءات.
BILLING_PROVIDERالفارغ يختار Stripe عندما يكون مفتاحها مضبوطًا، وإلا صفحة الدفع التجريبية. وsimulator يفرض صفحة الدفع التجريبية حتى مع وجود المفاتيح.
BILLING_GRACE_DAYSعدد الأيام التي يجوز فيها لمساحة عمل متأخرة في الدفع، أو انتهت تجربتها دون دفع، أن تبدأ مشاريع ودعوات ومفاتيح API جديدة، والقيمة الافتراضية 7. تبقى القراءة تعمل دائمًا، ولا يُحذف شيء بسبب دفعة فاشلة.
PAYPAL_CLIENT_ID, PAYPAL_CLIENT_SECRETتطبيق PayPal REST، لاستخدام PayPal في الدفع بالترخيص. يُحصَّل المبلغ عندما يعود المشتري.
PAYPAL_ENVsandbox (الافتراضي، من دون أموال حقيقية) أو live.

على جهازك لا تستطيع Stripe الوصول إلى الـ webhook، لذلك تطلب صفحات العودة الجلسة من Stripe بنفسها، ويكتمل الدفع التجريبي مع ذلك. لا تُعدّ الخطة أو الترخيص مدفوعين إلا بعد أن تتحقق منهما واجهة API لدى المزوّد، وليس من عنوان العودة وحده. لا يحصّل Northstack أي ضريبة بنفسه، لذلك أعدّ الضريبة لبلدك قبل قبول مدفوعات حقيقية.

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

تُرسَل الدعوات وإعادة ضبط بيانات الدخول وإيصالات التراخيص ورسائل الفوترة والملخص الأسبوعي عبر SMTP بعد ضبط SMTP_HOST، كلٌّ بلغة المستلم (ولغة مساحة العمل إن لم يختر لغة). إلى ذلك الحين تُكتب كل رسالة في سجل واجهة API بدلًا من ذلك، مع الروابط، ليتبعها من ثبّت محليًا (مع Docker: docker compose logs api).

ملف .env الخاص بواجهة API
SMTP_HOST=smtp.your-provider.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=your-smtp-user
SMTP_PASSWORD=your-smtp-secret
SMTP_FROM=Northstack <no-reply@your-domain.com>
CONTACT_INBOX=hello@your-domain.com

SMTP_SECURE=true لخادم يتكلم TLS من البايت الأول، وغالبًا على المنفذ 465. وCONTACT_INBOX هو العنوان الذي تُحوَّل إليه رسائل نموذج التواصل في الموقع؛ وإذا تُرك فارغًا بقيت الرسائل في قاعدة البيانات فقط.

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

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

ملف .env الخاص بواجهة API
DB_TYPE=mysql
DB_HOST=localhost
DB_PORT=3306
DB_USERNAME=root
DB_PASSWORD=your-database-secret
DB_DATABASE=northstack

ثم شغّل yarn seed، الذي ينشئ الجداول والبيانات التجريبية. لا تنشئ واجهة API العاملة الجداول وتحدّثها بنفسها إلا عندما يكون NODE_ENV=development، لذلك مع NODE_ENV=production شغّل yarn admin:create:prod مرة واحدة بعد yarn build للجداول وأول مسؤول منصة (yarn seed:prod للتثبيت التجريبي)، ثم yarn schema:prod بعد كل تحديث. تنشئ صورة Docker القاعدة بنفسها على SQLite فقط: على MySQL شغّل node dist/database/create-admin.js (أو node dist/database/seeder.js) بنفسك مرة واحدة في الحاوية.

الملفات المرفوعة والوسائط

تقدّم واجهة API ملفات هوية الطقم بنفسها عند /media. أما ملفات المشاريع والصور المرفوعة من لوحة التحكم، بحد أقصى 10 MB للملف، فتُخزَّن على قرص واجهة API تحت MEDIA_UPLOAD_DIR وتُقدَّم عند /media/uploads/…، ما لم يُضبط bucket.

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

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

لإرسال الملفات المرفوعة إلى bucket في Cloudflare R2، اضبط المتغيرات الخمسة كلها. مع أقل من خمسة تبقى الملفات على القرص. يذكر سجل واجهة API التخزين الذي يستخدمه عند البدء: Media storage: R2 bucket متبوعة باسم الـ bucket، أو Media storage: local folder متبوعة بالمجلد.

ملف .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

الموقع ولوحة التحكم

كل قيمة NEXT_PUBLIC_* تُدمج في JavaScript الذي يحمّله المتصفح، ويستطيع أي شخص يفتح الصفحة قراءتها. لا تضع فيها سرًا أبدًا، وأعد البناء (أو أعد تشغيل yarn dev) بعد تغيير أي منها. مع Docker مرّرها بصيغة --build-arg.

NEXT_PUBLIC_API_BASE_URL يحدد من أين تأتي بيانات كل واجهة أمامية. إذا كان فارغًا، أو من دون .env أصلًا، يعمل التطبيق على بياناته التجريبية المدمجة ولا يستدعي أي واجهة API. وإذا ضُبط على عنوان واجهة API متضمنًا /api (http://localhost:8000/api في .env.example وفي صور Docker)، يستخدم تلك الواجهة، ويلجأ إلى البيانات التجريبية في المتصفح فقط ما دامت لا تجيب.

إعدادات الموقع

المتغيرالقيمة الافتراضيةوظيفته
NEXT_PUBLIC_SITE_URLhttp://localhost:3030العنوان العام لهذا الموقع: تُبنى منه الروابط الأساسية وبدائل اللغات وخريطة الموقع وبطاقات المشاركة. اضبطه على نطاقك قبل الإطلاق.
NEXT_PUBLIC_API_BASE_URLفارغ من دون .envواجهة API الخاصة بـ Northstack، متضمنة /api، لنموذج التواصل والدفع بالترخيص.
API_INTERNAL_URLفارغاختياري، يقرؤه خادم الموقع فقط وقت التشغيل، للدفع وإيصاله اللذين يُعرضان على الخادم. الفارغ يستخدم NEXT_PUBLIC_API_BASE_URL. في Docker اضبطه على عنوان واجهة API كما تصل إليه الحاوية (http://api:8000/api في Docker Compose).
NEXT_PUBLIC_DASHBOARD_URLhttp://localhost:3031لوحة التحكم. تفتحها جرّب العرض الحي واستكشف العرض الحي واطّلع على إدارة الأدوار وتسجيل الدخول في /error/401، وتسلّم /auth/signin و/auth/signup و/auth/forgot-password في الموقع الأمر إلى صفحاتها.
NEXT_PUBLIC_PURCHASE_URL_SINGLE, NEXT_PUBLIC_PURCHASE_URL_STUDIOفارغصفحة دفع متجر خارجي لكل ترخيص. الفارغ يُبقي صفحة الدفع الخاصة بالموقع عند /checkout.
NEXT_PUBLIC_SAMPLE_DATA_NOTICEفارغalways يعرض إشعار «بيانات تجريبية» في بناء الإنتاج ما دامت واجهة API المضبوطة أعلاه لا تجيب؛ ومع Docker: --build-arg NEXT_PUBLIC_SAMPLE_DATA_NOTICE=always. ويظهر دائمًا أثناء التطوير، وفي كل بناء يتم من دون واجهة API.
BUILD_STANDALONEفارغtrue يجعل yarn build ينتج خادمًا مستقلًا بذاته في .next/standalone، وهو ما يضبطه Dockerfile. اتركه فارغًا لـ yarn start.

منفذ الموقع هو 3030، مكتوب في سكربتات package.json. لمنفذ آخر شغّل yarn next dev -p 3040 (أو yarn next start -p 3040 بعد yarn build).

إعدادات لوحة التحكم

المتغيرالقيمة الافتراضيةوظيفته
PORT3031المنفذ الذي يستخدمه yarn dev وyarn start. يقرؤه scripts/next-with-port.mjs من .env ويسلّمه إلى Next.js.
NEXT_PUBLIC_API_BASE_URLفارغ من دون .envواجهة API الخاصة بـ Northstack، متضمنة /api. كل شاشة تتحدث إليها.
NEXT_PUBLIC_WEBSOCKET_BASE_URLعنوان واجهة API من دون /apiخادم واجهة API، لتحديثات الصلاحيات المباشرة.
NEXT_PUBLIC_BASE_URLhttp://localhost:3031العنوان العام للوحة التحكم هذه: يُبنى منه robots.txt وخريطة الموقع وعنوان مساحة العمل المعروض في الإعداد الأولي وعناوين البيانات الوصفية المطلقة.
NEXT_PUBLIC_WEBSITE_URLhttp://localhost:3030الموقع العام: رابط التوثيق في الشريط الجانبي، ورابطا الخصوصية والشروط في صفحة تسجيل الدخول.
BUILD_STANDALONEغير مضبوطtrue يجعل yarn build ينتج خادمًا مستقلًا بذاته، وهو ما يضبطه Dockerfile. اتركه غير مضبوط في غير ذلك.

لا يوضع هنا أي مفتاح مزوّد ذكاء اصطناعي أو دفع: قيمة NEXT_PUBLIC_* ظاهرة لكل من يفتح الصفحة. ويمكن استخدام مزوّد لا تملك واجهة API مفتاحه بمفتاح يضيفه القارئ في المساعد نفسه.

خيارات Docker Compose

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

المتغيرالقيمة الافتراضيةوظيفته
SITE_PORT3030منفذ الموقع على جهازك.
ADMIN_PORT3031منفذ لوحة التحكم على جهازك.
API_PORT8000منفذ واجهة API على جهازك.
SITE_URL, ADMIN_URL, API_URLالعناوين المحلية على هذه المنافذالعناوين التي يصل منها المتصفح إلى كل تطبيق. اضبطها الثلاثة معًا عند تقديم الحزمة على نطاقاتك الخاصة، مثل API_URL=https://api.your-domain.com.
PURCHASE_URL_SINGLE, PURCHASE_URL_STUDIOفارغصفحة دفع متجر خارجي لكل ترخيص، إن كنت تبيع عبر واحد؛ والفارغ يُبقي صفحة الدفع الخاصة بالموقع.
SEED_SAMPLE_DATAtrueتُقرأ عند أول تشغيل لوحدة تخزين جديدة فقط: true يملأ البيانات التجريبية، وfalse يبدؤها فارغة.
ADMIN_EMAIL, ADMIN_PASSWORDفارغمع SEED_SAMPLE_DATA=false، أول مسؤول منصة يُنشأ عند أول تشغيل؛ والفارغ ينشئ الجداول فقط.

غيّر المنفذ عندما يستخدمه برنامج آخر، مثل ADMIN_PORT=3041. تُبنى كلٌّ من CORS_ORIGIN وFRONTEND_URL وDASHBOARD_URL وWEBSITE_URL وPUBLIC_API_URL وPUBLIC_MEDIA_URL في واجهة API، وعناوين واجهة API والموقع ولوحة التحكم في الواجهتين الأماميتين، من المنافذ والعناوين الثلاثة، فتتبعها من تلقاء نفسها.

تقرأ حاوية واجهة API أيضًا ملف back-end/.env إن وُجد، فتُضبط المفاتيح الاختيارية (Stripe وPayPal والبريد وR2 والذكاء الاصطناعي وMCP) في مكان واحد لـ yarn dev ولـ Docker معًا. ويغلب docker-compose.yml في القيم التي تختلف داخل الحاوية: NODE_ENV=production والمنفذ ومسار قاعدة البيانات ومجلد الملفات المرفوعة والعناوين أعلاه. من دون JWT_SECRET خاص بك، أو مع قيمة المثال، تولّد واجهة API واحدًا وتحفظه في وحدة تخزين البيانات. وتعيش قاعدة البيانات والملفات المرفوعة في وحدة التخزين northstack-data.

مفاتيح المساعد الذكي

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

تفعيل مساعد مساحة العمل على الخادم: مفاتيح المزوّدين ومن يدفع ثمن كل رسالة.

خادم MCP

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

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

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

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

مفتاح العرض التجريبي العام، ولماذا يبقى مطفأً في المنتج الحقيقي.

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

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

حل المشكلات

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

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