ইনভায়রনমেন্ট ডিটেকশন

এই চ্যাপ্টার এ আমরা ইনভায়রনমেন্ট নিয়ে বিস্তারিত আলোচনা করব।

ইনভায়রনমেন্ট সেটআপ কেন জরুরী?

বড় কোন অ্যাপ্লিকেশন এর বিভিন্ন স্টেজ থাকে । এবং প্রত্যেক স্টেজ এর জন্য সার্ভার ইন্সটলেশন অথবা ওয়েব হেড থাকে। উদাহারন হিসাবে আমরা একটা আইডিয়াল কেস চিন্তা করি।

ধরা যাক আমাদের অ্যাপ্লিকেশন এর গিট রিপো তে তিনটা ব্রাঞ্চ আছে যথাক্রমে dev, staging এবং master ( which is also maybe the main production branch) এবং তিনটা ব্রাঞ্চ এর জন্য তিনটা ওয়েব ইন্সটলেশন আছে যথাক্রমে dev.application.com staging.application.com এবং application.com এবং গিট হুক ব্যাবহার করে আমরা সহজেই অটো ডিপ্লয়মেন্ট সেট করতে পারি যেন ডেভলপাররা গিট রিপো তে নতুন কোড কমিট করার সাথে সাথেই আমারা corresponding ইন্সটলেশন এ গিয়ে ইফেক্ট দেখে চেক করতে পারি ।

ওর ম্যাবি প্রজেক্ট এর QA টিম ঐ ফিচারটা টেস্ট করা শুরু করে দিতে পারে । এখন কোন ফিচার প্রথমে dev এ যায়, সেখানে অন্য ডেভলপাররা অথবা QA টিম চেক করে গ্রিন সিগনাল দিলে, সেই ফিচার ম্যানেজার/বিজনিজ ওনার কে দেখানোর জন্য staging এ পুশ করা হয়। এবং সবাই ফাইনালি এপ্রুভ করলে production এ এন্ড ইউজার দের জন্য সেই ফিচারটা ওপেন করা হয়।

এখন আমাদের codebase তো একটা কিন্তু আমাদের তিন ধরনের কনফিগারেশন দরকার। কারণ dev, staging এবং production এর আলাদা আলাদা ডেটাবেজ থাকবে, dev এ দেখা গেল আমরা সুবিধার জন্য sqlite ব্যাবহার করলাম, বাট স্টেজিং এ মাই সিকিউএল লাগবে। প্রোড এ অন্য কোন DBMS । কিংবা ডেভ এ আমরা ফাইল বেইসড ক্যাশিং ব্যাবহার করলাম কিন্তু সার্ভার এ memcached অথবা redis লাগবে। এইসব এক্সটার্নাল সার্ভিস ব্যাবহার করার জন্য আমাদের কোন php প্যাকেজ বা লাইব্রেরী ব্যাবহার করতে হবে। বেশির ভাগ ক্ষেত্রেই এইসব প্যাকেজ এর কনফিগ ফাইল থাকে যেখানে ভিভিন্ন প্যারামিটার সেট অথবা দরকার মত বদলানো যায়।

কিংবা ধরুন আপনারা দুইজন একটা প্রোজেক্ট এ কাজ করতেসেন কিন্তু আপনাদের ডেটাবেজ এর কনফিগ ফাইল একটা। এখন কি হবে প্রত্যেক বার গিট থেকে কোড আপডেট করার পর আপনাকে ঐ ফাইল চেঞ্জ করতে হবে যেন অ্যাপ্লিকেশন আপনার লোকাল ডেটাবেজ এ কানেক্ট করতে পারে।

আরও একটা কমন কেইস হল, সেন্ডিং ইমেইল ফ্রম লোকাল মেশিন। সো আমারা চাই লোকাল ইনভায়রনমেন্ট এ মেইল ফাংশান কল করলে সেইটা শুধু লগ ফাইলে মেইল এর কন্টেন্ট লগ করবে যেহুতু লোকাল মেশিন থেকে মেইল পাঠানো সহজ না , কিন্তু সার্ভার এ যেহুতু মেইল সেন্ড করতে কোন সমস্যা নাই সেখানে যেন ঠিকমত মেইল সেন্ড হয় ।

এইরকম অবস্থায় আমাদের যা দরকার তা হল মাল্টিপল সেট অফ কনফিগ ফাইলস যা কিছু কন্ডিশন এর উপর বেইজ করে অটোম্যাটিকালি লোড হবে এবং আমারা গিট এ কোড পুশ করা মাত্রই অন্য কোন কিছু চেঞ্জ করা ছাড়াই আমাদের কমিট করা নতুন ফিচার কারেসপন্ডিং ওয়েব হেড এ কাজ করবে।

সো ইনভায়রনমেন্ ম্যানেজমেন্ট হল আমাদের অ্যাপ্লিকেশন কে কোন সময় কি করতে হবে তা ডিসাইড করতে সাহায্য করা।

লারাভেল কিভাবে ইনভায়রনমেন্ট ডিটেক্ট করে ?

প্রত্যেকটি লারাভেল অ্যাপ্লিকেশন যখন রান করে তখন বুটস্ট্র্যাপিং এর প্রথম দিকে লারাভেল ইনভায়রনমেন্ট ডিটেক্ট করে। এবং এর পর ওই রিকুয়েস্ট সাইকেল এর পরবর্তী অনেক কাজে ওই ইনভায়রনমেন্ট এর উপর নির্ভর করে বিভিন্ন ডিসিশান নেয়।

আমি এই সিরিজ এ লারাভেল এর 4.2.* ভার্শন নিয়ে কথা বলব। আমার জানি লারাভেল এর সব রিকুয়েস্ট public/index.php এর মাধ্যমে প্রসেস হয়। এই প্যাটার্ন Front Controller Pattern নামে পরিচিত। লারাভেল সহ সব MVC framework ই এই প্যাটার্ন ফলো করে। আচ্ছা আমরা লারাভেল রিকুয়েস্ট সাইকেল নিয়ে অন্য কোন পোষ্ট এ কথা বলব।

লারাভেল ডিফল্ট ইন্সটলেশন এ bootstrap/start.php ফাইল এ ইনভায়রনমেন্ট ডিটেকশন হয় যা public/index.php ফাইল এ autolaoder এর পরই লোড করা হয়। সো বলা যায় ইনভায়রনমেন্ট ডিটেকশন লারাভেল রিকুয়েস্ট লাইফ সাইকেল এর একদম প্রথম দিকেই ঘটে, কারণ ইনভায়রনমেন্ট এর উপর নির্ভর করে লারাভেল কনফিগ ফাইল লোড করে।

$env = $app->detectEnvironment(array(
'local' => array('homestead'),
));

বাই ডিফল্ট local ইনভায়রনমেন্ট এর জন্য হোস্টনেম homestead থাকে কারণ যারা homestead ব্যাবহার করে তাদের যেন কিছু পরিবর্তন করতে না হয়। এইরকম অনেক ক্ষেত্রেই লারাভেল বিভিন্ন কনভেনশন ব্যাবহার করে। এই কাজটার জন্য একটা ডেডিকেটেড টার্ম আছে Convention Over Configuration যেই কাজটা মেবি রেইলস প্রথমে শুরু করেছিল। এইটার উদ্দেশ্য হল প্রচলিত আলিখিত কিছু নিয়ম ফলো করলে কাজ অনেক সহজ হয়ে যাবে। কাইন্ড অফ দ্যা ফ্রেমওয়ার্ক উইল থিংক এহেড ফর ইয় ইন ম্যানি কেজেস টু ম্যাইক ইউর লাইফ ইজিয়ার।

লারাভেল ইনভায়রনমেন্ট ডিটেক্ট করার জন্য hostname ব্যাবহার করে। বাট লাইক ম্যানি আদার থিংস, ইউ ক্যান ইউজ ইউর ওন ওয়ে টু।

নতুন ইনভায়রনমেন্ট যোগ করা

ইনভায়রনমেন্ট যোগ করার সহজ উপায় হল hostname ব্যাবহার করা। লিনাক্স অথবা ম্যাক এ টার্মিনাল এ hostname কমান্ড ব্যাবহার করে হোস্টনেম বের করা যায়। আমরা নিচের মত করে আরও ইনভায়রনমেন্ট যোগ করতে পারি।

$env = $app->detectEnvironment(array(
'local' => array('homestead'),
'staging' => array('staging-host-name'),
'prod' => array('prod-host-name')
));

এইভাবে ইনভায়রনমেন্ট যোগ করলে লারাভেল হোস্টনেম চেক করে ঠিকমত ইনভায়রনমেন্ট ডিটেক্ট ও সেট করবে। কিন্তু আমাদের staging আর prod যদি একই সার্ভার এ থাকে তাহলে hostname ব্যাবহার করে তাদের আলাদাভাবে ডিটেক্ট করা সম্ভব না।

সো আরও সুন্দরভাবে ইনভায়রনমেন্ট যোগ করার জন্য আমরা $app->detectEnvironment() মেথড এ এরে এর পরিবর্তে পরিবর্তে closure ব্যাবহার করে আমাদের সুবিধামত ইনভায়রনমেন্ট ডিটেকশন কোড যোগ করতে পারি।

$env = $app->detectEnvironment(function(){
return getenv('LARAVEL_ENV') ?: 'local';
});

উপরের ফাংশনটি প্রথমে genenv() ফাংশান এর মাধ্যমে LARAVEL_ENV নামে কোন key ইনভায়রনমেন্ট ভ্যারিয়েবল এ আছে কিনা এবং যদি পায় তাহলে তার ভ্যালু রিটার্ন করে এবং ঐ ভ্যালূই ইনভায়রনমেন্ট হিসাবে সেট করে। আর যদি ঐ key Exist না করে তাহলে local রিটার্ন করে, অর্থাৎ ঐ key না থাকলে local ইনভায়রনমেন্ট সেট হয়।

আমারা কিভাবে ইনভায়রনমেন্ট ভ্যারিয়েবল সেট করতে পারি?

এপাচি তে ইনভায়রনমেন্ট ভ্যারিয়েবল সেট করা খুব সহজ। vhost অথবা htaccess ফাইল এ নিচের মত করে ইনভায়রনমেন্ট ভ্যারিয়েবল সেট করতে পারি।

SetEnv LARAVEL_ENV dev

অথবা আপনি যদি nginx ব্যাবহার করেন তাহলে আপনাকে php-fpm, or php-cgi এর মাধ্যমে ইনভায়রনমেন্ট ভ্যারিয়েবল সেট করতে হবে কারণ nginx, apache এর মত নিজে php প্রসেস নিজে ম্যানেজ করেনা ।

php-fpm
...
env[LARAVEL_ENV] = dev
...
php-cgi
location / {
...
fastcgi_param LARAVEL_ENV dev;
...
}

আমরা পরের পোষ্ট এ লারাভেল কিভাবে মাল্টিপল কনফিগ ফাইল ইনভায়রনমেন্ট এর উপর বেইজ করে লোড করে তা দেখব।