الخطوات
-
1
أضف .env إلى .gitignore فوراً
افعل هذا قبل إنشاء الملف. بمجرد commit ورفع الملف، يبقى في سجل git حتى بعد حذفه. إذا لم يكن
.envموجوداً بعد في.gitignore، أضفه الآن.bash# .gitignore .env .env.local .env.production .env.staging # لا تُدمج ملفات env الحقيقية أبداً — فقط .env.example -
2
ادمج .env.example مع قيم placeholder آمنة
.env.exampleهو العقد بين المطورين. يُوثّق كل متغير يحتاجه التطبيق، بقيم placeholder بدلاً من الأسرار الحقيقية. ينسخه أعضاء الفريق الجدد ويُكملون قيمهم الخاصة.bash# .env.example — مُدمج في git، لا قيم حقيقية NODE_ENV=development PORT=3000 DATABASE_URL=postgres://user:password@localhost:5432/myapp REDIS_URL=redis://localhost:6379 JWT_SECRET=replace-with-a-long-random-string STRIPE_SECRET_KEY=sk_test_replace_me # احصل عليه من لوحة AWS IAM AWS_ACCESS_KEY_ID=REPLACE_ME AWS_SECRET_ACCESS_KEY=REPLACE_ME -
3
تحميل .env أصلياً في Node 20.6+
أضاف Node.js 20.6 علامة
--env-file. لا حاجة لمكتبة — مرّر العلامة عند تشغيل العملية ويُعبئ Node تلقائياًprocess.envمن الملف.bash# تشغيل التطبيق node --env-file=.env server.js # أو في package.json scripts: # "start": "node --env-file=.env server.js" # "dev": "node --env-file=.env --watch server.js" // في الكود — process.env مُعبّأ بالفعل const port = process.env.PORT ?? 3000; const db = process.env.DATABASE_URL; -
4
استخدم dotenv مع Node 18 والإصدارات الأقدم
إذا كنت على إصدار Node أقدم أو تحتاج مزيداً من التحكم في ترتيب التحميل، فـ
dotenvهي المكتبة القياسية. استدعها في أول سطر في ملف الدخول — قبل أي imports أخرى تقرأprocess.env.javascriptnpm install dotenv // server.js — يجب أن يكون أول شيء require('dotenv').config(); // أو مع ES modules: // import 'dotenv/config'; const port = process.env.PORT ?? 3000; -
5
تحقق من متغيرات البيئة عند بدء التشغيل
أخفق بسرعة.
DATABASE_URLمفقود يجب أن يُوقف العملية فوراً عند بدء التشغيل برسالة واضحة — لا أن يُخفق بصمت في أول استدعاء لقاعدة البيانات بعد عشر دقائق من نشر إنتاجي. تحقق باستخدام zod للحصول على نتيجة محددة النوع، أو بفحص يدوي بسيط.javascript// الخيار أ: فحص يدوي (بدون مكتبات) const required = ['DATABASE_URL', 'JWT_SECRET', 'PORT']; for (const key of required) { if (!process.env[key]) { console.error(`متغير البيئة المطلوب مفقود: ${key}`); process.exit(1); } } // الخيار ب: zod (محدد النوع + قيم افتراضية) // npm install zod const { z } = require('zod'); const envSchema = z.object({ NODE_ENV: z.enum(['development', 'test', 'production']).default('development'), PORT: z.string().transform(Number).default('3000'), DATABASE_URL: z.string().url(), JWT_SECRET: z.string().min(32, 'JWT_SECRET يجب أن يكون 32 حرفاً على الأقل'), }); const env = envSchema.parse(process.env); // يرمي خطأ عند قيم غير صحيحة module.exports = env; -
6
استخدم ملفات خاصة بكل بيئة بحذر
لإعدادات مختلفة لكل بيئة، استخدم ملفات منفصلة. حمّل
.envالأساسي أولاً، ثم ملف البيئة المحدد لتجاوز القيم المحددة. ادمج فقط إصدارات.exampleدائماً — وليس الحقيقية أبداً.javascript# .env — قيم أساسية (في .gitignore) # .env.production — تجاوزات الإنتاج (في .gitignore) # .env.staging — تجاوزات الاختبار (في .gitignore) # .env.example — قالب placeholder آمن (مُدمج) // ترتيب التحميل مع dotenv (الأساسي أولاً، ثم تجاوز البيئة): require('dotenv').config({ path: '.env' }); require('dotenv').config({ path: `.env.${process.env.NODE_ENV}`, override: true, }); -
7
دوّر الأسرار عند مغادرة أحد أعضاء الفريق
عند مغادرة عضو في الفريق، افترض أن كل سر كان بإمكانه الوصول إليه قد تعرّض للخطر. دوّرها قبل اكتمال إجراءات المغادرة، وليس بعدها. يجب توثيق عملية التدوير والتدرب عليها — اكتشاف كيفية تدوير مفتاح Stripe الساعة الثانية صباحاً أثناء حادث ليس الوقت المناسب.
قائمة تدقيق عملية التدوير:
- أنشئ قيماً جديدة لكل سر في
.env.example - حدّث الأسرار في مدير الأسرار (AWS Secrets Manager أو 1Password Teams أو Doppler) — لا تشارك النص العادي عبر Slack أو البريد الإلكتروني أبداً
- انشر البيئة المحدّثة لكل بيئة بالترتيب: الاختبار ثم الإنتاج
- تحقق من سلامة التطبيق، ثم ألغِ الأسرار القديمة في الخدمة المصدرة
- أنشئ قيماً جديدة لكل سر في
نصائح ومحاذير
- لا تُسجّل <code>process.env</code> بالكامل — سيكشف هذا عن جميع أسرارك لمن يملك وصولاً إلى سجلاتك. سجّل المفاتيح الموجودة فقط، ليس قيمها.
- في الإنتاج، يُفضَّل استخدام مدير أسرار مخصص (AWS Secrets Manager أو HashiCorp Vault أو Doppler) بدلاً من ملفات <code>.env</code> على القرص. توفر مديرات الأسرار سجلات مراجعة وتدويراً وتحكماً في الوصول.
- علامة <code>--env-file</code> في Node 20.6+ لا تُلغي المتغيرات المضبوطة بالفعل في بيئة Shell. هذا سلوك صحيح — يتيح لأنظمة CI/CD حقن الأسرار الحقيقية دون أن تتجاوزها ملفات <code>.env</code> قديمة.
- اجعل الأسرار قصيرة العمر حيثما أمكن. API tokens ذات صلاحية محددة أكثر أماناً من بيانات الاعتماد الدائمة.
خاتمة
ثلاث قواعد تُغطي 90% من نظافة متغيرات البيئة: .env يذهب إلى .gitignore قبل أي شيء آخر، و.env.example هو ملف env الوحيد الذي يُدمج، وتتحقق من المتغيرات المطلوبة عند بدء التشغيل كي يُخفق النشر غير الصحيح بصوت عالٍ وفوراً. ابنِ هذه العادات منذ بداية كل مشروع.