البرمجة مبتدئ 6 دقيقة

كيفية إدارة متغيرات البيئة بأمان في Node.js

متغيرات البيئة هي الطريقة التي تُبقي بها الأسرار خارج الكود المصدري. كلمة مرور قاعدة بيانات مُدمجة في مستودع عام تنكشف لحظة رفعها، وإزالتها من السجل أمر مؤلم. نمط .env بسيط ومدعوم عالمياً — لكن لديه قواعد يسهل إغفالها.

الخطوات

  1. 1

    أضف .env إلى .gitignore فوراً

    افعل هذا قبل إنشاء الملف. بمجرد commit ورفع الملف، يبقى في سجل git حتى بعد حذفه. إذا لم يكن .env موجوداً بعد في .gitignore، أضفه الآن.

    bash
    # .gitignore
    .env
    .env.local
    .env.production
    .env.staging
    
    # لا تُدمج ملفات env الحقيقية أبداً — فقط .env.example
  2. 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. 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. 4

    استخدم dotenv مع Node 18 والإصدارات الأقدم

    إذا كنت على إصدار Node أقدم أو تحتاج مزيداً من التحكم في ترتيب التحميل، فـ dotenv هي المكتبة القياسية. استدعها في أول سطر في ملف الدخول — قبل أي imports أخرى تقرأ process.env.

    javascript
    npm install dotenv
    
    // server.js — يجب أن يكون أول شيء
    require('dotenv').config();
    
    // أو مع ES modules:
    // import 'dotenv/config';
    
    const port = process.env.PORT ?? 3000;
  5. 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. 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. 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 الوحيد الذي يُدمج، وتتحقق من المتغيرات المطلوبة عند بدء التشغيل كي يُخفق النشر غير الصحيح بصوت عالٍ وفوراً. ابنِ هذه العادات منذ بداية كل مشروع.

#Node.js #Config #Env
العودة إلى جميع الأدلة

هل تحتاج مساعدة في مشروعك؟

احجز استشارة مجانية لمدة 30 دقيقة لمناقشة تحدياتك التقنية واستكشاف الحلول معًا.