<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Infrastructure on kenji.blog</title><link>http://kenji.blog/hi/categories/infrastructure/</link><description>Recent content in Infrastructure on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>hi</language><copyright>kenjinote</copyright><lastBuildDate>Sun, 13 Sep 2026 07:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/hi/categories/infrastructure/index.xml" rel="self" type="application/rss+xml"/><item><title>Hyper-V vs WSL2: Windows पर वर्चुअलाइजेशन तकनीक की तुलना</title><link>http://kenji.blog/hi/p/hyper-v-vs-wsl2-windows-virtualization/</link><pubDate>Sun, 13 Sep 2026 07:00:00 +0900</pubDate><guid>http://kenji.blog/hi/p/hyper-v-vs-wsl2-windows-virtualization/</guid><description>&lt;img src="http://kenji.blog/p/hyper-v-vs-wsl2-windows-virtualization/img/eyecatch.jpg" alt="Featured image of post Hyper-V vs WSL2: Windows पर वर्चुअलाइजेशन तकनीक की तुलना" />&lt;h2 id="1-परचय-windows-म-वरचअलइजशन-क-वकस">1. परिचय: Windows में वर्चुअलाइजेशन का विकास
&lt;/h2>&lt;p>Windows प्लेटफॉर्म में वर्चुअलाइजेशन तकनीक ने पिछले कुछ दशकों में नाटकीय विकास देखा है। पहले, थर्ड-पार्टी टाइप 2 हाइपरवाइज़र (जैसे VMware Workstation या VirtualBox) मुख्यधारा में थे, लेकिन जब से Microsoft ने Windows Server 2008 में &amp;ldquo;Hyper-V&amp;rdquo; पेश किया है, तब से टाइप 1 हाइपरवाइज़र को डेस्कटॉप OS जैसे Windows 10/11 में भी शामिल किया जाने लगा है।&lt;/p>
&lt;p>और हाल के वर्षों में, डेवलपर्स के बीच सबसे ज्यादा ध्यान &amp;ldquo;WSL2 (Windows Subsystem for Linux 2)&amp;rdquo; पर दिया गया है। जबकि WSL1 सिस्टम कॉल ट्रांसलेशन पर निर्भर था, WSL2 ने Hyper-V की तकनीक को लागू करते हुए एक &amp;ldquo;लाइटवेट यूटिलिटी VM (Lightweight Utility VM)&amp;rdquo; अपनाया है, जिससे पूर्ण Linux संगतता और प्रदर्शन में भारी सुधार हुआ है।&lt;/p>
&lt;p>इस लेख में, हम इन दो शक्तिशाली वर्चुअलाइजेशन तकनीकों - पूर्ण विशेषताओं वाले &amp;ldquo;Hyper-V&amp;rdquo; और डेवलपर अनुभव पर केंद्रित &amp;ldquo;WSL2&amp;rdquo; - के आर्किटेक्चर, प्रदर्शन (CPU, मेमोरी, डिस्क I/O), नेटवर्क कॉन्फ़िगरेशन और सर्वोत्तम उपयोग के मामलों (यूज़ केस) की गहराई से तकनीकी जानकारी के साथ पूरी तरह से तुलना और व्याख्या करेंगे।&lt;/p>
&lt;hr>
&lt;h2 id="2-हइपरवइजर-क-बनयद-सदधत-और-आरकटकचर-क-तलन">2. हाइपरवाइज़र का बुनियादी सिद्धांत और आर्किटेक्चर की तुलना
&lt;/h2>&lt;p>वर्चुअलाइजेशन तकनीक को समझने के लिए हाइपरवाइज़र (वर्चुअल मशीन मॉनिटर: VMM) के प्रकार का वर्गीकरण बहुत आवश्यक है।&lt;/p>
&lt;h3 id="21-type-1-और-type-2-हइपरवइजर-क-बच-अतर">2.1. Type 1 और Type 2 हाइपरवाइज़र के बीच अंतर
&lt;/h3>&lt;p>हाइपरवाइज़र एक सॉफ़्टवेयर लेयर है जो हार्डवेयर एक्सेस को एब्स्ट्रेक्ट करती है और कई OS (गेस्ट OS) को एक साथ एक ही भौतिक मशीन पर चलाने की अनुमति देती है।&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Type 1 (बेयर-मेटल प्रकार)&lt;/strong>: सीधे हार्डवेयर पर चलता है। इसमें होस्ट OS की कोई अवधारणा नहीं होती (हालांकि कभी-कभी विशेषाधिकार प्राप्त एक मैनेजमेंट OS हो सकता है), इसका ओवरहेड बहुत कम होता है, और यह उच्च प्रदर्शन और सुरक्षा प्रदान करता है। उदाहरण: Hyper-V, VMware ESXi, Xen।&lt;/li>
&lt;li>&lt;strong>Type 2 (होस्ट प्रकार)&lt;/strong>: होस्ट OS (जैसे Windows या macOS) के ऊपर एक एप्लिकेशन के रूप में चलता है। सभी हार्डवेयर एक्सेस होस्ट OS के माध्यम से होते हैं, जिससे ओवरहेड बढ़ जाता है। उदाहरण: VMware Workstation, Oracle VirtualBox।&lt;/li>
&lt;/ul>
&lt;p>Windows का Hyper-V एक पूर्ण &lt;strong>Type 1 हाइपरवाइज़र&lt;/strong> है। जब आप Hyper-V को सक्षम करते हैं, तो वास्तव में जो Windows OS आप उपयोग कर रहे हैं वह भी &amp;ldquo;रूट पार्टीशन (Root Partition)&amp;rdquo; नामक एक विशेष वर्चुअल मशीन के अंदर चलने लगता है।&lt;/p>
&lt;h3 id="22-hyper-v-क-आरकटकचर-ववरण">2.2. Hyper-V का आर्किटेक्चर विवरण
&lt;/h3>&lt;p>Hyper-V का आर्किटेक्चर एक माइक्रो-कर्नेल डिज़ाइन को अपनाता है और पार्टीशन (Partition) नामक लॉजिकल अलगाव इकाइयों पर आधारित होता है।&lt;/p>
&lt;pre class="mermaid">
graph TD
A[&amp;#34;हार्डवेयर (CPU, RAM, Disk, NIC)&amp;#34;] --&amp;gt; B[&amp;#34;Windows हाइपरवाइज़र (Ring -1)&amp;#34;]
B --&amp;gt; C[&amp;#34;रूट पार्टीशन (Windows OS)&amp;#34;]
B --&amp;gt; D[&amp;#34;चाइल्ड पार्टीशन 1 (Windows VM)&amp;#34;]
B --&amp;gt; E[&amp;#34;चाइल्ड पार्टीशन 2 (Linux VM)&amp;#34;]
C --&amp;gt; F[&amp;#34;VMBus (वर्चुअल मशीन बस)&amp;#34;]
D --&amp;gt; F
E --&amp;gt; F
C --&amp;gt; G[&amp;#34;VID (वर्चुअलाइजेशन इंफ्रास्ट्रक्चर ड्राइवर)&amp;#34;]
C --&amp;gt; H[&amp;#34;VMWP.exe (वर्कर प्रोसेस)&amp;#34;]
&lt;/pre>
&lt;ul>
&lt;li>&lt;strong>Windows Hypervisor&lt;/strong>: CPU के सबसे उच्च विशेषाधिकार प्राप्त स्तर (Ring -1 या VMX Root Mode) में चलता है, और केवल मेमोरी आवंटन और CPU शेड्यूलिंग को संभालता है। इसमें डिवाइस ड्राइवर शामिल नहीं होते हैं।&lt;/li>
&lt;li>&lt;strong>Root Partition&lt;/strong>: वह पार्टीशन जिसमें होस्ट Windows OS चलता है। इसमें सभी डिवाइस ड्राइवर होते हैं और यह सीधे हार्डवेयर को नियंत्रित करता है। यह चाइल्ड पार्टीशन के प्रबंधन के लिए कार्य (जैसे WMI प्रोवाइडर और VMWP.exe) भी प्रदान करता है।&lt;/li>
&lt;li>&lt;strong>Child Partition&lt;/strong>: वह पार्टीशन जिसमें गेस्ट OS चलता है। इसे सीधे हार्डवेयर तक पहुंचने की अनुमति नहीं है, और यह I/O रिक्वेस्ट (सिंथेटिक I/O) को रूट पार्टीशन में &amp;ldquo;VMBus&amp;rdquo; नामक लॉजिकल मेमोरी-शेयर्ड बस के माध्यम से भेजता है।&lt;/li>
&lt;/ul>
&lt;h3 id="23-wsl2-और-lightweight-utility-vm-क-कम-करन-क-तरक">2.3. WSL2 और Lightweight Utility VM का काम करने का तरीका
&lt;/h3>&lt;p>WSL2 उसी Type 1 हाइपरवाइज़र बेस तकनीक का उपयोग करता है जिसका Hyper-V करता है, लेकिन यह पूर्ण-सुविधा वाले Hyper-V वर्चुअल मशीन के बजाय &amp;ldquo;वर्चुअल मशीन प्लेटफ़ॉर्म (Virtual Machine Platform: VMP)&amp;rdquo; नामक एक सबसेट सुविधा का उपयोग करता है।&lt;/p>
&lt;p>WSL2 में उपयोग किए जाने वाले &amp;ldquo;लाइटवेट यूटिलिटी VM (Lightweight Utility VM)&amp;rdquo; में पारंपरिक VM के लेगेसी हार्डवेयर एमुलेशन (जैसे वर्चुअल BIOS और वर्चुअल मदरबोर्ड) को पूरी तरह से हटा दिया गया है।&lt;/p>
&lt;pre class="mermaid">
graph TD
A[&amp;#34;Windows होस्ट OS (यूज़र स्पेस)&amp;#34;]
B[&amp;#34;NTFS फाइल सिस्टम&amp;#34;]
C[&amp;#34;9P प्रोटोकॉल सर्वर (Plan 9)&amp;#34;]
D[&amp;#34;लाइटवेट यूटिलिटी VM (Linux कर्नेल)&amp;#34;]
E[&amp;#34;ext4.vhdx (वर्चुअल डिस्क)&amp;#34;]
F[&amp;#34;Linux यूज़र स्पेस (WSL2 डिस्ट्रिब्यूशन)&amp;#34;]
A --&amp;gt; C
C --&amp;gt;| क्रॉस-OS फाइल शेयरिंग | D
D --&amp;gt; E
D --&amp;gt; F
&lt;/pre>
&lt;p>WSL2 की सबसे बड़ी विशेषता इसकी &lt;strong>स्टार्टअप गति&lt;/strong> और &lt;strong>होस्ट OS के साथ निर्बाध एकीकरण&lt;/strong> है। Linux कर्नेल कुछ सेकंड से भी कम समय में बूट हो जाता है और Plan 9 के &lt;code>9P&lt;/code> नेटवर्क फाइल सिस्टम प्रोटोकॉल के माध्यम से Windows फ़ाइल सिस्टम (NTFS) तक पहुंचता है।&lt;/p>
&lt;hr>
&lt;h2 id="3-परदरशन-क-सपरण-वशलषण-गणन-ससधन-और-io">3. प्रदर्शन का संपूर्ण विश्लेषण: गणना संसाधन और I/O
&lt;/h2>&lt;p>वर्चुअल मशीन के प्रदर्शन को CPU, मेमोरी और डिस्क I/O घटकों में ओवरहेड के योग के रूप में दर्शाया जाता है।&lt;/p>
&lt;h3 id="31-cpu-और-कनटकसट-सवच-ओवरहड">3.1. CPU और कॉन्टेक्स्ट स्विच ओवरहेड
&lt;/h3>&lt;p>Hyper-V और WSL2 दोनों हार्डवेयर-असिस्टेड वर्चुअलाइजेशन (Intel VT-x / AMD-V) का उपयोग करते हैं। CPU निर्देश मूल रूप से नेटिव गति से निष्पादित होते हैं, लेकिन जब विशेषाधिकार प्राप्त निर्देश या I/O ऑपरेशन निष्पादित होते हैं, तो &amp;ldquo;VM Exit&amp;rdquo; नामक एक इंटरप्ट उत्पन्न होता है, जो हाइपरवाइज़र पर कॉन्टेक्स्ट स्विच करता है।&lt;/p>
&lt;p>इस समय CPU ओवरहेड $T_{overhead}$ को निम्नलिखित गणितीय मॉडल द्वारा दर्शाया जा सकता है:&lt;/p>
$$ T_{overhead} = \sum_{i=1}^{N} (t_{vm\_exit} + t_{hypercall\_process} + t_{vm\_entry}) $$&lt;p>जहाँ:&lt;/p>
&lt;ul>
&lt;li>$N$: प्रति यूनिट समय में VM Exit होने की संख्या&lt;/li>
&lt;li>$t_{vm\_exit}$: गेस्ट से हाइपरवाइज़र तक का ट्रांज़िशन समय&lt;/li>
&lt;li>$t_{hypercall\_process}$: VMBus के माध्यम से I/O प्रोसेसिंग या इंटरप्ट का प्रोसेसिंग समय&lt;/li>
&lt;li>$t_{vm\_entry}$: हाइपरवाइज़र से गेस्ट तक वापसी का समय&lt;/li>
&lt;/ul>
&lt;p>चूँकि WSL2 में लेगेसी एमुलेशन नहीं है, इसलिए $t_{hypercall\_process}$ अत्यधिक अनुकूलित और बहुत छोटा है। इसलिए, शुद्ध CPU गणनाओं (जैसे कर्नेल को संकलित करना या मशीन लर्निंग मॉडल इनफेरेंस) में, बेयर-मेटल वातावरण की तुलना में प्रदर्शन में गिरावट कुछ प्रतिशत के भीतर ही रहती है।&lt;/p>
&lt;h3 id="32-ममर-आवटन-क-ततर">3.2. मेमोरी आवंटन का तंत्र
&lt;/h3>&lt;p>जब मेमोरी प्रबंधन के तरीकों की बात आती है, तो दोनों के बीच स्पष्ट रूप से अलग-अलग डिज़ाइन दर्शन होते हैं।&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Hyper-V (Dynamic Memory)&lt;/strong>: गेस्ट VM की मेमोरी मांग के अनुसार, रूट पार्टीशन गतिशील रूप से मेमोरी आवंटित और पुनर्प्राप्त (रीक्लेम) करता है। हालाँकि, जब तक सिस्टम में मेमोरी की कमी नধি न हो, गेस्ट OS के भीतर पेज कैशे के रूप में सुरक्षित मेमोरी आसानी से रिलीज़ नहीं होती है।&lt;/li>
&lt;li>&lt;strong>WSL2 (डायनेमिक मेमोरी रिक्लेम)&lt;/strong>: WSL2 का अपना अनूठा तंत्र है, जो नियमित रूप से अनावश्यक मेमोरी (कैशे सहित) को Linux VM के भीतर से Windows होस्ट को वापस (Reclaim) कर देता है। शुरुआती WSL2 में एक समस्या थी जहाँ Linux पेज कैशे Windows मेमोरी की खपत कर लेता था (Vmmem प्रक्रिया का फूलना), लेकिन इसे अब कर्नेल पैच के माध्यम से सुधार दिया गया है।&lt;/li>
&lt;/ul>
&lt;h3 id="33-डसक-io-क-वशषतए-vhdx-vs-ext4vhdx">3.3. डिस्क I/O की विशेषताएं (VHDX vs ext4.vhdx)
&lt;/h3>&lt;p>वर्चुअल मशीन के प्रदर्शन में डिस्क I/O सबसे आसानी से बॉटलनेक (अड़चन) बन सकता है।&lt;/p>
&lt;p>I/O लेटेंसी $L_{total}$ की गणना इस प्रकार की जाती है:&lt;/p>
$$ L_{total} = L_{guest\_fs} + L_{vmbus} + L_{host\_fs} + L_{physical\_disk} $$&lt;p>&lt;strong>Hyper-V के मामले में&lt;/strong>:
सामान्य Hyper-V गेस्ट &lt;code>VHDX&lt;/code> फॉर्मेट वर्चुअल डिस्क का उपयोग करते हैं। गेस्ट OS (ext4 या NTFS) के अंदर फाइल सिस्टम से जारी I/O रिक्वेस्ट VMBus के ब्लॉक डिवाइस स्टोरेज ड्राइवर (storvsc) से होकर गुजरती है और Windows पर NTFS पर VHDX फाइल तक एक्सेस के रूप में प्रोसेस होती है।&lt;/p>
&lt;p>&lt;strong>WSL2 के मामले में&lt;/strong>:
WSL2 के Linux डिस्ट्रिब्यूशन एक समर्पित &lt;code>ext4.vhdx&lt;/code> फाइल के भीतर निर्मित नेटिव ext4 फाइल सिस्टम पर चलते हैं। Linux के भीतर फाइल संचालन (जैसे &lt;code>~&lt;/code> डायरेक्टरी में) उपरोक्त Hyper-V के समान नेटिव प्रदर्शन प्रदान करते हैं।
हालाँकि, &lt;strong>जब WSL2 Linux से Windows साइड फाइलों (जैसे &lt;code>/mnt/c/&lt;/code>) तक पहुँचते हैं&lt;/strong>, या इसके विपरीत, तो प्रक्रिया काफी अलग होती है। इस क्रॉस-OS एक्सेस के लिए &lt;code>9P (Plan 9 File System Protocol)&lt;/code> का उपयोग किया जाता है।&lt;/p>
$$ L_{cross\_os} = L_{9p\_client} + L_{socket\_transfer} + L_{9p\_server} + L_{ntfs} $$&lt;p>इस 9P प्रोटोकॉल के माध्यम से एक्सेस करने पर सीरियलाइज़ेशन का बड़ा ओवरहेड होता है, और ऐसे उपयोगों के लिए जहाँ बड़ी संख्या में छोटी फ़ाइलों को पढ़ा और लिखा जाता है (उदाहरण के लिए: Windows-साइड डायरेक्टरी में स्थित Node.js प्रोजेक्ट पर &lt;code>npm install&lt;/code> या Git संचालन), प्रदर्शन में काफी गिरावट आती है (कभी-कभी 10 गुना से अधिक देरी)।
इसलिए, &lt;strong>WSL2 का उपयोग करते समय, यह सुनिश्चित करना एक मूल नियम है कि प्रोजेक्ट फाइलें Linux के नेटिव फाइल सिस्टम (जैसे &lt;code>~/&lt;/code> के तहत) में रखी जाएँ&lt;/strong>।&lt;/p>
&lt;hr>
&lt;h2 id="4-नटवरक-सरचन-nat-default-switch-bridged">4. नेटवर्क संरचना: NAT, Default Switch, Bridged
&lt;/h2>&lt;p>नेटवर्क क्षमताओं का लचीलापन Hyper-V और WSL2 के बीच सबसे बड़े अंतरों में से एक है।&lt;/p>
&lt;h3 id="41-wsl2-क-नटवरक-nat-आधरत">4.1. WSL2 का नेटवर्क (NAT-आधारित)
&lt;/h3>&lt;p>WSL2 का नेटवर्क डिफ़ॉल्ट रूप से Hyper-V की वर्चुअल स्विच तकनीक का उपयोग करके &amp;ldquo;NAT (Network Address Translation)&amp;rdquo; कॉन्फ़िगरेशन में सेट होता है।
Linux VM को स्वचालित रूप से एक निजी IP एड्रेस (जैसे: &lt;code>172.20.x.x&lt;/code>) सौंपा जाता है जो Windows होस्ट से अलग होता है। एक बिल्ट-इन तंत्र है जो Windows होस्ट से &lt;code>localhost&lt;/code> को WSL2 के भीतर शुरू की गई सेवाओं (पोर्ट्स) पर फॉरवर्ड करता है, जिससे डेवलपर्स नेटवर्क के बारे में चिंता किए बिना वेब सर्वर आदि का परीक्षण कर सकते हैं।&lt;/p>
&lt;p>हाल के वर्षों में, WSL2 के प्रीव्यू वर्जन में &amp;ldquo;Mirrored मोड&amp;rdquo; नामक एक नया नेटवर्क मोड पेश किया गया है। इससे IPv6 के लिए सपोर्ट और VPN कनेक्शन के साथ अनुकूलता में सुधार होता है (इसे &lt;code>.wslconfig&lt;/code> में सेट किया जा सकता है)।&lt;/p>
&lt;h3 id="42-hyper-v-क-वरचअल-सवच-virtual-switch">4.2. Hyper-V का वर्चुअल स्विच (Virtual Switch)
&lt;/h3>&lt;p>Hyper-V उन्नत एंटरप्राइज़-स्तरीय नेटवर्क बनाने में सक्षम है। यह &amp;ldquo;वर्चुअल स्विच मैनेजर&amp;rdquo; के माध्यम से मुख्य रूप से तीन मोड प्रदान करता है:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>बाहरी (External)&lt;/strong>: होस्ट मशीन के फिजिकल NIC को वर्चुअल स्विच से बांधता है, जिससे गेस्ट VM सीधे फिजिकल नेटवर्क से जुड़ सकता है (ब्रिज कनेक्शन)। VM को DHCP सर्वर से उसी सबनेट का IP मिलता है जो फिजिकल नेटवर्क का है।&lt;/li>
&lt;li>&lt;strong>आंतरिक (Internal)&lt;/strong>: केवल होस्ट OS और VM के बीच, और VMs के बीच संचार की अनुमति देता है। यह सीधे बाहरी नेटवर्क तक नहीं पहुंच सकता।&lt;/li>
&lt;li>&lt;strong>निजी (Private)&lt;/strong>: केवल VMs के बीच संचार की अनुमति देता है, और होस्ट OS के साथ संचार को अवरुद्ध करता है। इसका उपयोग आइसोलेटेड (अलग-थलग) परीक्षण वातावरण बनाने के लिए किया जाता है।&lt;/li>
&lt;/ol>
&lt;h3 id="43-powershell-क-सथ-उननत-hyper-v-नटवरक-क-नरमण">4.3. PowerShell के साथ उन्नत Hyper-V नेटवर्क का निर्माण
&lt;/h3>&lt;p>डेवलपमेंट या टेस्टिंग वातावरण में, यदि आप VM के लिए एक कस्टमाइज़्ड NAT नेटवर्क बनाना चाहते हैं, तो आप PowerShell का उपयोग करके विस्तृत नियंत्रण प्राप्त कर सकते हैं। यहाँ एक स्क्रिप्ट का उदाहरण दिया गया है जो एक इंटरनल वर्चुअल स्विच बनाता है, उस पर NAT कॉन्फ़िगर करता है, और VM को इंटरनेट एक्सेस प्रदान करता है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 1. इंटरनल वर्चुअल स्विच बनाना&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$SwitchName&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;HyperV-NatSwitch&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">New-VMSwitch&lt;/span> &lt;span class="n">-SwitchName&lt;/span> &lt;span class="nv">$SwitchName&lt;/span> &lt;span class="n">-SwitchType&lt;/span> &lt;span class="n">Internal&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 2. होस्ट-साइड वर्चुअल NIC पर IP एड्रेस सेट करना (IP जो गेटवे के रूप में काम करेगा)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$GatewayIP&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;192.168.100.1&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$NetPrefix&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="mf">24&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$InterfaceAlias&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;vEthernet (&lt;/span>&lt;span class="nv">$SwitchName&lt;/span>&lt;span class="s2">)&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">New-NetIPAddress&lt;/span> &lt;span class="n">-IPAddress&lt;/span> &lt;span class="nv">$GatewayIP&lt;/span> &lt;span class="n">-PrefixLength&lt;/span> &lt;span class="nv">$NetPrefix&lt;/span> &lt;span class="n">-InterfaceAlias&lt;/span> &lt;span class="nv">$InterfaceAlias&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 3. NAT नेटवर्क को कॉन्फ़िगर करना&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$NatName&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;HyperV-NatNetwork&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$NatSubnet&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;192.168.100.0/24&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">New-NetNat&lt;/span> &lt;span class="n">-Name&lt;/span> &lt;span class="nv">$NatName&lt;/span> &lt;span class="n">-InternalIPInterfaceAddressPrefix&lt;/span> &lt;span class="nv">$NatSubnet&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># वेरिफिकेशन कमांड&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">Get-NetNat&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इस कॉन्फ़िगरेशन के साथ, आप निर्दिष्ट Hyper-V गेस्ट पर मैन्युअल रूप से IP &lt;code>192.168.100.x&lt;/code> और गेटवे &lt;code>192.168.100.1&lt;/code> सेट करके एक कस्टम NAT सेगमेंट बना सकते हैं, जो होस्ट के माध्यम से बाहरी दुनिया के साथ संवाद कर सकता है।&lt;/p>
&lt;hr>
&lt;h2 id="5-उपयग-क-ममल-यज-कस-और-वयवहरक-चयन-मरगदरशक">5. उपयोग के मामले (यूज़ केस) और व्यावहारिक चयन मार्गदर्शिका
&lt;/h2>&lt;p>अब तक आर्किटेक्चर और प्रदर्शन में अंतर को देखते हुए, हम परिभाषित करेंगे कि किस स्थिति में कौन सी तकनीक अपनाई जानी चाहिए।&lt;/p>
&lt;h3 id="51-परदशय-सनरय-जह-wsl2-चन-जन-चहए">5.1. परिदृश्य (सिनेरियो) जहाँ WSL2 चुना जाना चाहिए
&lt;/h3>&lt;p>WSL2 विशेष रूप से &amp;ldquo;डेवलपर्स की उत्पादकता में सुधार&amp;rdquo; के लिए डिज़ाइन किया गया है। यह निम्नलिखित उपयोगों के लिए आदर्श है:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>वेब डेवलपमेंट और क्लाउड-नेटिव डेवलपमेंट&lt;/strong>: Docker Desktop (WSL2 बैकएंड) या Podman का उपयोग करके कंटेनर डेवलपमेंट।&lt;/li>
&lt;li>&lt;strong>Linux-विशिष्ट टूल का उपयोग&lt;/strong>: अगर आप रोज़ाना bash, grep, awk, sed, या Linux के लिए GCC और Clang कंपाइलर का उपयोग करते हैं।&lt;/li>
&lt;li>&lt;strong>GUI एप्लिकेशन (WSLg)&lt;/strong>: यदि आप Windows डेस्कटॉप पर Linux X11/Wayland एप्लिकेशन को निर्बाध (सीमलेस) रूप से चलाना चाहते हैं।&lt;/li>
&lt;li>&lt;strong>मशीन लर्निंग और AI डेवलपमेंट&lt;/strong>: GPU पास-थ्रू फीचर (NVIDIA CUDA on WSL) का उपयोग करके TensorFlow या PyTorch में तेज़ ट्रेनिंग।&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>ध्यान दें&lt;/strong>: यदि आप कर्नेल को बारीक रूप से कस्टमाइज़ करना चाहते हैं या ऐसी जटिल सेवाएँ बनाना चाहते हैं जो systemd पर बहुत अधिक निर्भर करती हैं (हालांकि systemd अब समर्थित है, डिफ़ॉल्ट रूप से यह अक्षम या सीमित हो सकता है), तो आपको प्रतिबंधों का सामना करना पड़ सकता है।&lt;/p>
&lt;h3 id="52-परदशय-सनरय-जह-hyper-v-चन-जन-चहए">5.2. परिदृश्य (सिनेरियो) जहाँ Hyper-V चुना जाना चाहिए
&lt;/h3>&lt;p>Hyper-V का उद्देश्य &amp;ldquo;इंफ्रास्ट्रक्चर वर्चुअलाइजेशन और पूर्ण अलगाव (आइसोलेशन)&amp;rdquo; है। यह निम्नलिखित उपयोगों के लिए आवश्यक है:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Windows VM चलाना&lt;/strong>: यदि आप परीक्षण वातावरण के रूप में Windows के विभिन्न संस्करणों (जैसे Windows Server या पुराने Windows 10) को चलाना चाहते हैं।&lt;/li>
&lt;li>&lt;strong>नेस्टेड वर्चुअलाइजेशन&lt;/strong>: यदि आप वर्चुअल मशीन के अंदर एक और वर्चुअल मशीन (Hyper-V या KVM) चलाना चाहते हैं। यह इंफ्रास्ट्रक्चर इंजीनियरों के परीक्षण वातावरण के लिए अनिवार्य है।&lt;/li>
&lt;li>&lt;strong>उन्नत नेटवर्क आवश्यकताएँ&lt;/strong>: यदि नेटवर्क कॉन्फ़िगरेशन को सख्ती से नियंत्रित करना आवश्यक है, जैसे कि एक्सटर्नल ब्रिजिंग (एक ही LAN से जुड़ना), VLAN टैगिंग, या कई NIC असाइन करना।&lt;/li>
&lt;li>&lt;strong>स्नैपशॉट (चेकपॉइंट्स)&lt;/strong>: VM को किसी विशिष्ट समय की स्थिति में सहेजने और उसे तुरंत रोलबैक (वापस पलटने) की क्षमता। यह सॉफ़्टवेयर के विनाशकारी परीक्षण या मैलवेयर विश्लेषण के लिए बेहद उपयोगी है।&lt;/li>
&lt;li>&lt;strong>निश्चित संसाधन आवंटन&lt;/strong>: यदि आप CPU कोर की संख्या और मेमोरी की मात्रा को सख्ती से फिक्स करना चाहते हैं ताकि होस्ट OS पर प्रभाव कम से कम हो।&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="6-गणतय-मडल-क-मधयम-स-io-थरपट-क-अधययन-परशषट">6. गणितीय मॉडल के माध्यम से I/O थ्रूपुट का अध्ययन (परिशिष्ट)
&lt;/h2>&lt;p>एक सिस्टम इंजीनियर के रूप में, दोनों की I/O प्रदर्शन सीमाओं का आकलन करते समय थ्रूपुट $S$ और ब्लॉक साइज़ $B$ के बीच के संबंध को सैद्धांतिक रूप से समझना महत्वपूर्ण है।&lt;/p>
&lt;p>डेटा ट्रांसफर थ्रूपुट $S$, प्रति यूनिट समय में ट्रांसफर किए गए डेटा की मात्रा है, और इसे इस प्रकार मॉडल किया जा सकता है:&lt;/p>
$$ S(B) = \frac{B}{L_{setup} + \frac{B}{R_{max}}} $$&lt;ul>
&lt;li>$B$: ब्लॉक साइज़ (Bytes)&lt;/li>
&lt;li>$L_{setup}$: I/O अनुरोध को सेट अप करने और कॉन्टेक्स्ट स्विच से जुड़ी निश्चित लेटेंसी&lt;/li>
&lt;li>$R_{max}$: कॉपी या डिवाइस ट्रांसफर में हार्डवेयर की अधिकतम बैंडविड्थ&lt;/li>
&lt;/ul>
&lt;p>WSL2 में 9P प्रोटोकॉल के माध्यम से फाइल एक्सेस करते समय, यह $L_{setup}$ बहुत बड़ा होता है (सॉकेट संचार और प्रोटोकॉल के सीरियलाइज़ेशन/डी-सीरियलाइज़ेशन के कारण)। इसलिए, जब ब्लॉक साइज़ $B$ छोटा होता है (जैसे कुछ KB की छोटी फाइलों का बड़े पैमाने पर पढ़ना/लिखना), तो डिनॉमिनेटर (हर) में $L_{setup}$ का प्रभाव हावी हो जाता है, और थ्रूपुट $S$ में भारी गिरावट आती है।
इसके विपरीत, Hyper-V के VMBus के माध्यम से VHDX एक्सेस में, $L_{setup}$ को हार्डवेयर इंटरप्ट के स्तर के करीब अनुकूलित किया जाता है, जिससे यह छोटे ब्लॉकों के साथ भी उच्च IOPS बनाए रख सकता है।&lt;/p>
&lt;p>यही गणितीय वास्तविकता उस सर्वोत्तम अभ्यास (बेस्ट प्रैक्टिस) का तार्किक आधार है कि &amp;ldquo;WSL2 में प्रोजेक्ट फाइलों को Windows साइड पर नहीं रखा जाना चाहिए&amp;rdquo;।&lt;/p>
&lt;hr>
&lt;h2 id="7-नषकरष-द-सह-असततव-वल-वरचअलइजशन-तकनक">7. निष्कर्ष: दो सह-अस्तित्व वाली वर्चुअलाइजेशन तकनीकें
&lt;/h2>&lt;p>यह कहना सही नहीं होगा कि Hyper-V या WSL2 में से कोई एक दूसरे से बेहतर है; बल्कि ये &lt;strong>&amp;ldquo;अलग-अलग उद्देश्यों वाले दो समाधान&amp;rdquo;&lt;/strong> हैं।&lt;/p>
&lt;ul>
&lt;li>&lt;strong>WSL2&lt;/strong> Windows OS की सीमाओं को तोड़ता है और Linux इकोसिस्टम को Windows उपयोगकर्ताओं तक निर्बाध और तेज़ी से पहुँचाने के लिए &amp;ldquo;सर्वोत्तम एकीकरण उपकरण (इंटीग्रेशन टूल)&amp;rdquo; है। इसे डेवलपर्स के लिए अंतिम CLI वातावरण कहना कोई अतिशयोक्ति नहीं होगी।&lt;/li>
&lt;li>&lt;strong>Hyper-V&lt;/strong> एक &amp;ldquo;पूर्ण-विकसित हाइपरवाइज़र&amp;rdquo; है जो एंटरप्राइज़ डेटा सेंटरों में विकसित मजबूत अलगाव (आइसोलेशन) और प्रबंधन क्षमताओं को डेस्कटॉप पर लाता है। नेटवर्क निर्माण, Windows OS परीक्षण, और इंफ्रास्ट्रक्चर वातावरण सिमुलेशन के मामले में यह बेजोड़ है।&lt;/li>
&lt;/ul>
&lt;p>आधुनिक Windows वातावरण में, ये दोनों तकनीकें आपस में प्रतिस्पर्धा करने के बजाय एक ही VM प्लेटफॉर्म पर खूबसूरती से सह-अस्तित्व में हैं। अपने उपयोग के आधार पर सही जगह पर सही तकनीक का उपयोग करके, Windows दुनिया में सबसे शक्तिशाली और लचीला इंजीनियरिंग वर्कस्टेशन बन जाएगा।&lt;/p></description></item><item><title>Docker का उपयोग करके पुनरुत्पादित (Reproducible) स्थानीय विकास वातावरण स्थापित करने की मार्गदर्शिका</title><link>http://kenji.blog/hi/p/docker-reproducible-local-dev-environment/</link><pubDate>Sun, 13 Sep 2026 01:00:00 +0900</pubDate><guid>http://kenji.blog/hi/p/docker-reproducible-local-dev-environment/</guid><description>&lt;img src="http://kenji.blog/p/docker-reproducible-local-dev-environment/img/eyecatch.jpg" alt="Featured image of post Docker का उपयोग करके पुनरुत्पादित (Reproducible) स्थानीय विकास वातावरण स्थापित करने की मार्गदर्शिका" />&lt;h2 id="1-परसतवन-यह-मर-ससटम-पर-कम-करत-ह-स-छटकर-पन">1. प्रस्तावना: &amp;ldquo;यह मेरे सिस्टम पर काम करता है&amp;rdquo; से छुटकारा पाना
&lt;/h2>&lt;p>सॉफ्टवेयर विकास में, डेवलपर्स के बीच वातावरण भिन्न होने के कारण उत्पन्न होने वाली &amp;ldquo;यह मेरे सिस्टम पर काम करता है (It works on my machine)&amp;rdquo; जैसी समस्या, लंबे समय से कई परियोजनाओं में समय बर्बाद करने वाला एक प्रमुख कारक रही है। ऑपरेटिंग सिस्टम में अंतर, इंस्टॉल किए गए प्रोग्रामिंग भाषाओं के संस्करण, लाइब्रेरी की निर्भरताएं, और विश्व स्तर पर (globally) इंस्टॉल किए गए उपकरणों के बीच टकराव आदि के कारण, स्थानीय वातावरण हमेशा &amp;ldquo;स्थिति की अनिश्चितता&amp;rdquo; के संपर्क में रहता है।&lt;/p>
&lt;p>इन चुनौतियों को जड़ से हल करने का काम &lt;strong>Docker&lt;/strong> जैसी कंटेनर तकनीकें और &lt;strong>Infrastructure as Code (IaC)&lt;/strong> प्रतिमान (paradigm) करते हैं। स्थानीय विकास वातावरण को कंटेनरीकृत करके, OS स्तर पर अलगाव (isolation) प्राप्त किया जा सकता है और कोडबेस के साथ-साथ वातावरण को भी संस्करण-नियंत्रित (version-controlled) किया जा सकता है।&lt;/p>
&lt;p>इस लेख में, हम Docker, Docker Compose, और VSCode DevContainers का उपयोग करके एक &lt;strong>&amp;ldquo;पुनरुत्पादित (reproducible) स्थानीय विकास वातावरण, जो हमेशा एक समान स्थिति में शुरू होता है, चाहे कोई भी, कभी भी, किसी भी मशीन पर इसे शुरू करे&amp;rdquo;&lt;/strong> बनाने की प्रक्रिया और इसके पीछे के गहरे तकनीकी तंत्र (mechanism) के बारे में, गणितीय दृष्टिकोण के साथ, विस्तार से बताएंगे।&lt;/p>
&lt;hr>
&lt;h2 id="2-infrastructure-as-code-iac-और-कटनर-तकनक-क-अनकलत">2. Infrastructure as Code (IaC) और कंटेनर तकनीक की अनुकूलता
&lt;/h2>&lt;h3 id="iac-क-सदधत-और-सथनय-वतवरण-म-उनक-अनपरयग">IaC के सिद्धांत और स्थानीय वातावरण में उनका अनुप्रयोग
&lt;/h3>&lt;p>Infrastructure as Code (IaC) बुनियादी ढांचे (infrastructure) के कॉन्फ़िगरेशन और प्रावधान (provisioning) को मैन्युअल प्रक्रियाओं के बजाय मशीन-पठनीय (machine-readable) परिभाषा फ़ाइलों के माध्यम से प्रबंधित करने का एक दृष्टिकोण है। IaC के मुख्य सिद्धांतों में निम्नलिखित तत्व शामिल हैं:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>घोषणात्मक दृष्टिकोण (Declarative Approach)&lt;/strong>: &amp;ldquo;स्थिति को कैसे बदलें&amp;rdquo; के बजाय &amp;ldquo;अंतिम स्थिति कैसी होनी चाहिए&amp;rdquo;, इसे परिभाषित करता है।&lt;/li>
&lt;li>&lt;strong>समरूपता (Idempotency)&lt;/strong>: स्क्रिप्ट को कितनी बार भी निष्पादित किया जाए, हमेशा एक ही परिणाम (स्थिति) की गारंटी होती है।&lt;/li>
&lt;li>&lt;strong>संस्करण नियंत्रण (Version Control)&lt;/strong>: बुनियादी ढांचे की स्थिति को कोड के रूप में Git जैसे VCS में सहेजा जाता है, जिससे परिवर्तन इतिहास को ट्रैक करना और पीयर रिव्यू संभव हो पाता है।&lt;/li>
&lt;/ol>
&lt;p>स्थानीय विकास वातावरण में IaC को लागू करने का अर्थ है &lt;code>Dockerfile&lt;/code>, &lt;code>docker-compose.yml&lt;/code>, और &lt;code>devcontainer.json&lt;/code> का उपयोग करके विकास वातावरण की &amp;ldquo;आदर्श स्थिति&amp;rdquo; को कोड के रूप में परिभाषित करना। इससे टीम में शामिल होने वाले नए सदस्य भी केवल रिपॉजिटरी को क्लोन करके और एक कमांड चलाकर तुरंत अपना काम शुरू कर सकते हैं, जिससे ऑनबोर्डिंग अनुभव (onboarding experience) बहुत सहज हो जाता है।&lt;/p>
&lt;h3 id="कटनर-तकनक-क-समरथन-दन-वल-करनल-फकशस">कंटेनर तकनीक को समर्थन देने वाले कर्नेल फ़ंक्शंस
&lt;/h3>&lt;p>कंटेनर तकनीक वर्चुअल मशीन (VM) जैसे हाइपरवाइज़र-आधारित वर्चुअलाइजेशन से अलग है। यह एक हल्की (lightweight) वर्चुअलाइजेशन तकनीक है जो होस्ट OS के कर्नेल को साझा करते हुए प्रक्रियाओं (processes) को अलग (isolate) करती है। इसे प्राप्त करने के लिए, मुख्य रूप से Linux कर्नेल के निम्नलिखित फ़ंक्शंस का उपयोग किया जाता है:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Namespaces (नेमस्पेस)&lt;/strong>: प्रत्येक प्रक्रिया के लिए सिस्टम संसाधनों (PID, नेटवर्क, माउंट पॉइंट, उपयोगकर्ता आदि) का एक स्वतंत्र दृश्य (view) प्रदान करता है।&lt;/li>
&lt;li>&lt;strong>Cgroups (Control Groups)&lt;/strong>: एक प्रक्रिया द्वारा उपयोग किए जा सकने वाले भौतिक संसाधनों (CPU, मेमोरी, डिस्क I/O आदि) को सीमित और आवंटित (allocate) करता है।&lt;/li>
&lt;li>&lt;strong>UnionFS (Union File System)&lt;/strong>: यह एक ऐसी तकनीक है जो कई डायरेक्टरी ट्री (लेयर) को पारदर्शी रूप से ओवरले करती है और उन्हें एक एकल फ़ाइल सिस्टम के रूप में प्रस्तुत करती है। Docker की इमेज लेयर्स इसी तकनीक पर निर्भर करती हैं।&lt;/li>
&lt;/ul>
&lt;p>आइए संसाधन सीमा के गणितीय मॉडल पर विचार करें। मान लीजिए कि होस्ट मशीन की कुल मेमोरी क्षमता $M_{\text{total}}$ है, और होस्ट पर चलने वाले $n$ कंटेनरों की मेमोरी सीमा $m_i$ है। होस्ट OS और अन्य प्रक्रियाओं द्वारा खपत की जाने वाली बेस मेमोरी $M_{\text{os}}$ को ध्यान में रखते हुए, सिस्टम के स्थिर रूप से चलने की आवश्यक शर्त को निम्नलिखित असमानता (inequality) के रूप में व्यक्त किया जा सकता है:&lt;/p>
$$ \sum_{i=1}^{n} m_i \le M_{\text{total}} - M_{\text{os}} $$&lt;p>Cgroups का उपयोग करके प्रत्येक कंटेनर के लिए $m_i$ को कड़ाई से परिभाषित करने से, किसी विशिष्ट कंटेनर में मेमोरी लीक होने पर भी, OOM (Out Of Memory) Killer को अन्य कंटेनरों या पूरे होस्ट सिस्टम को क्रैश करने से रोका जा सकता है।&lt;/p>
&lt;hr>
&lt;h2 id="3-कशल-dockerfile-डजइन-मलट-सटज-बलड-multi-stage-build-म-महरत-हसल-करन">3. कुशल Dockerfile डिज़ाइन: मल्टी-स्टेज बिल्ड (Multi-stage Build) में महारत हासिल करना
&lt;/h2>&lt;p>पुनरुत्पादित वातावरण की दिशा में पहला कदम एप्लिकेशन के निष्पादन वातावरण (execution environment) को परिभाषित करने वाले &lt;code>Dockerfile&lt;/code> को डिज़ाइन करना है। यहाँ, हम Python (FastAPI) को एक उदाहरण के रूप में उपयोग करके, &lt;strong>मल्टी-स्टेज बिल्ड&lt;/strong> का लाभ उठाने वाले एक सुरक्षित और हल्के Dockerfile के सर्वोत्तम अभ्यासों (best practices) की व्याख्या करेंगे।&lt;/p>
&lt;p>मल्टी-स्टेज बिल्ड एक ऐसी तकनीक है जो एक ही &lt;code>Dockerfile&lt;/code> में कई &lt;code>FROM&lt;/code> निर्देशों (instructions) का उपयोग करती है। यह बिल्ड वातावरण (एक भारी वातावरण जिसमें कंपाइलर और विकास उपकरण शामिल होते हैं) और निष्पादन वातावरण (एक हल्का वातावरण जिसमें केवल आवश्यक परिणामी फ़ाइलें होती हैं) को अलग करती है।&lt;/p>
&lt;h3 id="वयवहरक-python-fastapi-dockerfile">व्यावहारिक Python FastAPI Dockerfile
&lt;/h3>&lt;p>निम्नलिखित कोड Poetry का उपयोग करके निर्भरता प्रबंधन (dependency management) और मल्टी-स्टेज बिल्ड को संयोजित करने वाले एक उन्नत &lt;code>Dockerfile&lt;/code> का उदाहरण है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-dockerfile" data-lang="dockerfile">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># ---------------------------------------------------------&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># Stage 1: Builder (बिल्ड वातावरण)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># ---------------------------------------------------------&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="s"> python:3.11-slim AS builder&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># आवश्यक पर्यावरण चर (environment variables) सेट करना&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">ENV&lt;/span> &lt;span class="nv">PYTHONUNBUFFERED&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> &lt;span class="nv">PYTHONDONTWRITEBYTECODE&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> &lt;span class="nv">POETRY_VERSION&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span>.6.1 &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> &lt;span class="nv">POETRY_HOME&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;/opt/poetry&amp;#34;&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> &lt;span class="nv">POETRY_VIRTUALENVS_IN_PROJECT&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="nb">true&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> &lt;span class="nv">POETRY_NO_INTERACTION&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># निर्भरता पैकेज इंस्टॉल करना&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">RUN&lt;/span> apt-get update &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> apt-get install -y --no-install-recommends &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> curl build-essential &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> curl -sSL https://install.python-poetry.org &lt;span class="p">|&lt;/span> python3 - &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> apt-get clean &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> rm -rf /var/lib/apt/lists/*&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">ENV&lt;/span> &lt;span class="nv">PATH&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$POETRY_HOME&lt;/span>&lt;span class="s2">/bin:&lt;/span>&lt;span class="nv">$PATH&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">WORKDIR&lt;/span>&lt;span class="s"> /app&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># निर्भरता फ़ाइलों को कॉपी और इंस्टॉल करना&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">COPY&lt;/span> pyproject.toml poetry.lock ./&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">RUN&lt;/span> poetry install --no-root --only main&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># ---------------------------------------------------------&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># Stage 2: Runtime (निष्पादन वातावरण)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># ---------------------------------------------------------&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="s"> python:3.11-slim AS runtime&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">ENV&lt;/span> &lt;span class="nv">PYTHONUNBUFFERED&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> &lt;span class="nv">PYTHONDONTWRITEBYTECODE&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> &lt;span class="nv">PATH&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;/app/.venv/bin:&lt;/span>&lt;span class="nv">$PATH&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># एक न्यूनतम गैर-विशेषाधिकार प्राप्त (non-privileged) उपयोगकर्ता बनाना&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">RUN&lt;/span> groupadd -r appuser &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> useradd -r -g appuser appuser&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">WORKDIR&lt;/span>&lt;span class="s"> /app&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># बिल्डर से केवल वर्चुअल वातावरण (निर्भरताएँ) कॉपी करना&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">COPY&lt;/span> --from&lt;span class="o">=&lt;/span>builder --chown&lt;span class="o">=&lt;/span>appuser:appuser /app/.venv /app/.venv&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># एप्लिकेशन कोड कॉपी करना&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">COPY&lt;/span> --chown&lt;span class="o">=&lt;/span>appuser:appuser ./src /app/src&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># गैर-विशेषाधिकार प्राप्त उपयोगकर्ता पर स्विच करना&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">USER&lt;/span>&lt;span class="s"> appuser&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># कंटेनर के शुरू होने पर डिफ़ॉल्ट कमांड&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">ENTRYPOINT&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;uvicorn&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;src.main:app&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;--host&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;0.0.0.0&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;--port&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;8000&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="मलट-सटज-बलड-क-मधयम-स-इमज-क-आकर-क-गणतय-मलयकन">मल्टी-स्टेज बिल्ड के माध्यम से इमेज के आकार का गणितीय मूल्यांकन
&lt;/h3>&lt;p>मान लीजिए कि सिंगल-स्टेज बिल्ड का उपयोग करने पर इमेज का आकार $S_{\text{single}}$ है, और मल्टी-स्टेज बिल्ड लागू करने पर इमेज का आकार $S_{\text{multi}}$ है। आकार में कमी की दर $R$ की गणना इस प्रकार की जा सकती है:&lt;/p>
$$ R = \left( 1 - \frac{S_{\text{multi}}}{S_{\text{single}}} \right) \times 100 \ (\%) $$&lt;p>उदाहरण के लिए, मान लें कि $S_{\text{single}}$ में OS की बेस इमेज (लगभग 110MB), विकास पैकेज (gcc आदि लगभग 150MB), Poetry (लगभग 40MB), प्रोजेक्ट की निर्भरता लाइब्रेरी (लगभग 80MB), और सोर्स कोड (लगभग 5MB) शामिल हैं, जो कुल 385MB हो जाता है।
दूसरी ओर, $S_{\text{multi}}$ में, बेस इमेज (110MB) में केवल निर्भरता लाइब्रेरी (80MB) और सोर्स कोड (5MB) कॉपी किए जाते हैं, जिससे कुल आकार 195MB हो जाता है।&lt;/p>
$$ R = \left( 1 - \frac{195}{385} \right) \times 100 \approx 49.35\% $$&lt;p>इस प्रकार, मल्टी-स्टेज बिल्ड लागू करके, इमेज के आकार को लगभग आधा किया जा सकता है। इमेज के आकार को कम करने का सीधा परिणाम रजिस्ट्री से पुल (Pull) करने के समय में कमी, डिस्क स्थान की बचत और हमले के सतह क्षेत्र (Attack Surface) को कम करके सुरक्षा में सुधार के रूप में मिलता है।&lt;/p>
&lt;hr>
&lt;h2 id="4-docker-compose-क-मधयम-स-कई-कटनर-क-ऑरकसटरशन">4. Docker Compose के माध्यम से कई कंटेनरों का ऑर्केस्ट्रेशन
&lt;/h2>&lt;p>आधुनिक वेब एप्लिकेशन विकास में, एक माइक्रोसर्विस आर्किटेक्चर आम है जहां कई घटक (components) जैसे वेब सर्वर, डेटाबेस, और कैश सर्वर एक साथ काम करते हैं। स्थानीय वातावरण में इन सभी को एक ही स्थान से प्रबंधित करने के लिए &lt;code>docker-compose.yml&lt;/code> का उपयोग किया जाता है।&lt;/p>
&lt;p>इस बार, हम स्थानीय स्तर पर एक 3-स्तरीय सिस्टम बनाएंगे: &amp;ldquo;Web (FastAPI)&amp;rdquo;, &amp;ldquo;Database (PostgreSQL)&amp;rdquo;, और &amp;ldquo;Cache (Redis)&amp;quot;।&lt;/p>
&lt;h3 id="आरकटकचर-आरख-mermaid">आर्किटेक्चर आरेख (Mermaid)
&lt;/h3>&lt;p>नीचे दिया गया आरेख स्थानीय मशीन पर प्रत्येक कंटेनर, नेटवर्क और वॉल्यूम के बीच के संबंध को दर्शाता है।&lt;/p>
&lt;pre class="mermaid">
graph TD
User[&amp;#34;होस्ट मशीन (ब्राउज़र/curl)&amp;#34;] --&amp;gt;|लोकलहोस्ट:8000| Web[&amp;#34;FastAPI वेब कंटेनर&amp;#34;]
subgraph &amp;#34;डॉकर ब्रिज नेटवर्क (app-network)&amp;#34;
Web --&amp;gt;|पोर्ट 5432| DB[&amp;#34;PostgreSQL कंटेनर&amp;#34;]
Web --&amp;gt;|पोर्ट 6379| Redis[&amp;#34;Redis कंटेनर&amp;#34;]
end
DB --&amp;gt; Volume1[&amp;#34;नेम्ड वॉल्यूम (postgres_data)&amp;#34;]
Redis --&amp;gt; Volume2[&amp;#34;नेम्ड वॉल्यूम (redis_data)&amp;#34;]
HostDir[&amp;#34;होस्ट सोर्स कोड (./src)&amp;#34;] -.-&amp;gt;|बाइंड माउंट| Web
&lt;/pre>
&lt;h3 id="docker-composeyml-क-करयनवयन-और-वसतत-ववरण">docker-compose.yml का कार्यान्वयन और विस्तृत विवरण
&lt;/h3>&lt;p>नीचे एक मजबूत &lt;code>docker-compose.yml&lt;/code> का उदाहरण दिया गया है जो एक व्यावहारिक वातावरण के निर्माण को सहन कर सकता है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;span class="lnt">60
&lt;/span>&lt;span class="lnt">61
&lt;/span>&lt;span class="lnt">62
&lt;/span>&lt;span class="lnt">63
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">version&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;3.8&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">services&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">web&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">build&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">context&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">target&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">runtime&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">container_name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">dev_web&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">ports&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;8000:8000&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">volumes&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">./src:/app/src:ro &lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># होस्ट कोड को रीड-ओनली रूप में माउंट करें (हॉट रिलोड के लिए)&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">environment&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">REDIS_URL=redis://redis:6379/0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">env_file&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">.env&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">depends_on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">db&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">condition&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">service_healthy&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">redis&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">condition&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">service_started&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">networks&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">app-network&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">command&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;uvicorn&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;src.main:app&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;--host&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;0.0.0.0&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;--port&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;8000&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;--reload&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">db&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">image&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">postgres:15-alpine&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">container_name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">dev_db&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">ports&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;5432:5432&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">environment&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">POSTGRES_USER&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">postgres&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">POSTGRES_PASSWORD&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">${POSTGRES_PASSWORD}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">POSTGRES_DB&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">${POSTGRES_DB}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">volumes&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">postgres_data:/var/lib/postgresql/data&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">networks&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">app-network&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">healthcheck&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">test&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;CMD-SHELL&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;pg_isready -U postgres -d ${POSTGRES_DB}&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">interval&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">5s&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">timeout&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">5s&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">retries&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">5&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">redis&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">image&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">redis:7-alpine&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">container_name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">dev_redis&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">ports&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;6379:6379&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">volumes&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">redis_data:/data&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">networks&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">app-network&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">command&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;redis-server&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;--appendonly&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;yes&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">volumes&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">postgres_data&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">redis_data&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">networks&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">app-network&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">driver&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">bridge&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="वलयम-volumes-और-डट-क-सरकषत-रखन-persistence">वॉल्यूम (Volumes) और डेटा को सुरक्षित रखना (Persistence)
&lt;/h3>&lt;p>कंटेनर सिद्धांत रूप में &amp;ldquo;स्टेटलेस (stateless)&amp;rdquo; और &amp;ldquo;एफेमेरल (ephemeral - अल्पकालिक)&amp;rdquo; होते हैं। जब एक कंटेनर नष्ट हो जाता है, तो उसके अंदर का डेटा भी खो जाता है। डेटाबेस डेटा और कैश को बनाए रखने के लिए, आपको होस्ट मशीन के फाइल सिस्टम स्पेस को कंटेनर में माउंट करना होगा।&lt;/p>
&lt;ul>
&lt;li>&lt;strong>बाइंड माउंट (Bind Mount)&lt;/strong>: यह उपर्युक्त &lt;code>web&lt;/code> सेवा में &lt;code>./src:/app/src:ro&lt;/code> से मेल खाता है। यह होस्ट पर एक विशिष्ट डायरेक्टरी को सीधे कंटेनर में मैप करता है। इसका उपयोग स्थानीय रूप से किए गए कोड संपादन (हॉट रिलोड) को तुरंत कंटेनर में प्रतिबिंबित करने के लिए किया जाता है। सुरक्षा के दृष्टिकोण से, सर्वोत्तम अभ्यास &lt;code>:ro&lt;/code> (रीड-ओनली) विकल्प को लागू करना है ताकि कंटेनर होस्ट के सोर्स कोड को संशोधित न कर सके।&lt;/li>
&lt;li>&lt;strong>नेम्ड वॉल्यूम (Named Volume)&lt;/strong>: यह &lt;code>postgres_data&lt;/code> और &lt;code>redis_data&lt;/code> से मेल खाता है। यह Docker द्वारा आंतरिक रूप से प्रबंधित एक क्षेत्र है (जैसे &lt;code>/var/lib/docker/volumes/&lt;/code>)। यह बाइंड माउंट की तुलना में बेहतर I/O प्रदर्शन प्रदान करता है और OS के बीच फ़ाइल सिस्टम के अंतर को छुपाता है। डेटाबेस को सुरक्षित रखने (persistence) के लिए हमेशा इसका उपयोग करें।&lt;/li>
&lt;/ul>
&lt;h3 id="नटवरकग-networking-और-सरवस-डसकवर">नेटवर्किंग (Networking) और सर्विस डिस्कवरी
&lt;/h3>&lt;p>Docker Compose डिफ़ॉल्ट रूप से प्रत्येक प्रोजेक्ट के लिए एक अलग ब्रिज नेटवर्क बनाता है। उपर्युक्त &lt;code>app-network&lt;/code> इसका एक उदाहरण है।
एक ही नेटवर्क से संबंधित कंटेनर एक दूसरे को IP पते के बजाय उनके &amp;ldquo;सेवा नाम (उदा. &lt;code>db&lt;/code>, &lt;code>redis&lt;/code>)&amp;rdquo; का उपयोग करके होस्टनाम के रूप में हल कर सकते हैं (DNS रिज़ॉल्यूशन)।
उदाहरण के लिए, वेब कंटेनर से, आप &lt;code>postgresql://postgres:password@db:5432/mydb&lt;/code> URL का उपयोग करके डेटाबेस तक पहुंच सकते हैं। यह आपको इन्फ्रास्ट्रक्चर कोड को बदले बिना पर्यावरण चर (environment variables) के माध्यम से स्थानीय और उत्पादन वातावरण (production environment) के बीच कनेक्शन गंतव्य को पारदर्शी रूप से बदलने की अनुमति देता है।&lt;/p>
&lt;h3 id="हलथचक-healthcheck-और-सटरटअप-अनकरम-क-नयतरत-करन">हेल्थचेक (Healthcheck) और स्टार्टअप अनुक्रम को नियंत्रित करना
&lt;/h3>&lt;p>&lt;code>depends_on&lt;/code> निर्देश कंटेनरों के स्टार्टअप अनुक्रम को नियंत्रित करता है, लेकिन केवल &lt;code>depends_on&lt;/code> निर्दिष्ट करने से वेब कंटेनर तब शुरू हो जाएगा जब &amp;ldquo;DB कंटेनर शुरू हो गया है&amp;rdquo;। वास्तव में, DB आरंभीकरण प्रक्रिया (PostgreSQL प्रक्रिया शुरू होना और तालिकाओं की तैयारी) को पूरा होने में कुछ सेकंड लगते हैं, इसलिए वेब कंटेनर से DB कनेक्शन में त्रुटि हो सकती है।
इसे रोकने के लिए, &lt;code>healthcheck&lt;/code> को परिभाषित करके और &lt;code>condition: service_healthy&lt;/code> निर्दिष्ट करके, आप वेब कंटेनर को तभी शुरू कर सकते हैं जब यह पुष्टि हो जाए कि &amp;ldquo;DB कनेक्शन अनुरोध स्वीकार करने के लिए तैयार है&amp;rdquo;।&lt;/p>
&lt;hr>
&lt;h2 id="5-परयवरण-चर-परबधन-और-सरकष-env">5. पर्यावरण चर प्रबंधन और सुरक्षा (.env)
&lt;/h2>&lt;p>डेटाबेस पासवर्ड और API कुंजियों जैसी संवेदनशील जानकारी को &lt;code>docker-compose.yml&lt;/code> में हार्ड-कोड करना एक एंटी-पैटर्न है जिससे सख्ती से बचा जाना चाहिए। इसके बजाय, इन मानों को इंजेक्ट करने के लिए पर्यावरण चर (environment variable) फ़ाइल &lt;code>.env&lt;/code> का उपयोग करें।&lt;/p>
&lt;p>प्रोजेक्ट के रूट में एक &lt;code>.env&lt;/code> फ़ाइल बनाएँ।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-ini" data-lang="ini">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># .env फ़ाइल (Git द्वारा प्रबंधित होने से बचने के लिए इसे .gitignore में जोड़ें)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">POSTGRES_PASSWORD&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">supersecretpassword&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">POSTGRES_DB&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">devdb&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">API_SECRET_KEY&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">dev_secret_key_12345&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Docker Compose डिफ़ॉल्ट रूप से निष्पादन डायरेक्टरी में &lt;code>.env&lt;/code> फ़ाइल को पढ़ता है और YAML फ़ाइल में &lt;code>${VAR_NAME}&lt;/code> प्लेसहोल्डर का विस्तार करता है। यह दृष्टिकोण आपको इन्फ्रास्ट्रक्चर कोड को बदले बिना स्थानीय, स्टेजिंग और उत्पादन (production) जैसे विभिन्न वातावरणों के लिए कॉन्फ़िगरेशन मानों को सुरक्षित रूप से प्रबंधित करने की अनुमति देता है।&lt;/p>
&lt;hr>
&lt;h2 id="6-vscode-devcontainers-क-सथ-बहतरन-वकस-अनभव">6. VSCode DevContainers के साथ बेहतरीन विकास अनुभव
&lt;/h2>&lt;p>अब तक, हमने Docker का उपयोग करके एक मजबूत बैकएंड वातावरण स्थापित कर लिया है। हालाँकि, हम एक कदम और आगे जा सकते हैं। &lt;strong>VSCode DevContainers (Remote - Containers)&lt;/strong> सुविधा का उपयोग करके, आप कंटेनर के अंदर एडिटर (VSCode) के बैकएंड को चला सकते हैं।&lt;/p>
&lt;p>यह आपकी स्थानीय मशीन पर Python या Node.js इंस्टॉल करने की आवश्यकता को पूरी तरह से समाप्त कर देता है। लिनटर्स (flake8/eslint) और फॉर्मेटर्स (black/prettier) से लेकर IDE एक्सटेंशन तक सब कुछ कोडबेस के भीतर परिभाषित किया जा सकता है और पूरी टीम द्वारा साझा किया जा सकता है।&lt;/p>
&lt;h3 id="devcontainerjson-कनफगरशन">devcontainer.json कॉन्फ़िगरेशन
&lt;/h3>&lt;p>प्रोजेक्ट के रूट में एक &lt;code>.devcontainer&lt;/code> डायरेक्टरी बनाएँ और कॉन्फ़िगरेशन फ़ाइल को उसके अंदर रखें।&lt;/p>
&lt;p>&lt;code>.devcontainer/devcontainer.json&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;name&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Python FastAPI Dev Environment&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;dockerComposeFile&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;../docker-compose.yml&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;service&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;web&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;workspaceFolder&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;/app&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;customizations&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;vscode&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;settings&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;python.defaultInterpreterPath&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;/app/.venv/bin/python&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;python.formatting.provider&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;black&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;editor.formatOnSave&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;extensions&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;ms-python.python&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;ms-python.vscode-pylance&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;ms-python.black-formatter&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;tamasfe.even-better-toml&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;forwardPorts&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">8000&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">5432&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">6379&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;remoteUser&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;appuser&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;postCreateCommand&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;poetry install&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इस फ़ाइल को रिपॉजिटरी में शामिल करके, जैसे ही आप VSCode में प्रोजेक्ट खोलते हैं, &amp;ldquo;कंटेनर में फिर से खोलें (Reopen in Container)&amp;rdquo; का एक प्रॉम्प्ट दिखाई देगा। बस उस पर क्लिक करने से सभी आवश्यक कंटेनर शुरू हो जाएंगे, एक्सटेंशन इंस्टॉल हो जाएंगे, और आप तुरंत कोडिंग शुरू करने के लिए तैयार होंगे। यह सचमुच एक जादुई अनुभव है।&lt;/p>
&lt;hr>
&lt;h2 id="7-अनरध-परससकरण-request-processing-अनकरम-और-परदरशन-मडलग">7. अनुरोध प्रसंस्करण (Request Processing) अनुक्रम और प्रदर्शन मॉडलिंग
&lt;/h2>&lt;p>हम बनाए गए स्थानीय विकास वातावरण में वेब एप्लिकेशन के अनुरोध प्रसंस्करण के जीवनचक्र की पुष्टि करने के लिए एक अनुक्रम आरेख (sequence diagram) का उपयोग करेंगे, और इसके प्रदर्शन के गणितीय मॉडल पर विचार करेंगे।&lt;/p>
&lt;h3 id="अनकरम-आरख-sequence-diagram---request-flow">अनुक्रम आरेख (Sequence Diagram - Request Flow)
&lt;/h3>&lt;pre class="mermaid">
sequenceDiagram
participant Client as &amp;#34;ब्राउज़र / VSCode&amp;#34;
participant Web as &amp;#34;FastAPI (वेब)&amp;#34;
participant Redis as &amp;#34;Redis कैश&amp;#34;
participant DB as &amp;#34;PostgreSQL&amp;#34;
Client-&amp;gt;&amp;gt;Web: &amp;#34;GET /api/users/123&amp;#34;
activate Web
Web-&amp;gt;&amp;gt;Redis: &amp;#34;user:123 के लिए कैश की जाँच करें&amp;#34;
activate Redis
alt &amp;#34;कैश हिट (डेटा मौजूद है)&amp;#34;
Redis--&amp;gt;&amp;gt;Web: &amp;#34;कैश किया गया उपयोगकर्ता डेटा लौटाएं&amp;#34;
Web--&amp;gt;&amp;gt;Client: &amp;#34;200 OK (तीव्र प्रतिक्रिया)&amp;#34;
else &amp;#34;कैश मिस (डेटा नहीं है)&amp;#34;
Redis--&amp;gt;&amp;gt;Web: &amp;#34;Null (नहीं मिला)&amp;#34;
deactivate Redis
Web-&amp;gt;&amp;gt;DB: &amp;#34;SELECT * FROM users WHERE id = 123&amp;#34;
activate DB
DB--&amp;gt;&amp;gt;Web: &amp;#34;डेटाबेस पंक्ति लौटाएं&amp;#34;
deactivate DB
Web-&amp;gt;&amp;gt;Redis: &amp;#34;user:123 डेटा सेट करें (TTL: 60s)&amp;#34;
activate Redis
Redis--&amp;gt;&amp;gt;Web: &amp;#34;OK&amp;#34;
deactivate Redis
Web--&amp;gt;&amp;gt;Client: &amp;#34;200 OK (मानक प्रतिक्रिया)&amp;#34;
end
deactivate Web
&lt;/pre>
&lt;h3 id="परससग-दर-latency-क-गणतय-मडल">प्रोसेसिंग देरी (Latency) का गणितीय मॉडल
&lt;/h3>&lt;p>उपरोक्त सिस्टम में औसत अनुरोध प्रसंस्करण समय $T_{\text{total}}$ को गणितीय रूप से मॉडल करें।
प्रत्येक प्रक्रिया की विलंबता (latency) को निम्नानुसार परिभाषित किया गया है:&lt;/p>
&lt;ul>
&lt;li>$T_{\text{net}}$: क्लाइंट और वेब कंटेनर के बीच नेटवर्क विलंबता&lt;/li>
&lt;li>$T_{\text{app}}$: एप्लिकेशन-पक्ष पर शुद्ध प्रसंस्करण समय (क्रमबद्धता आदि)&lt;/li>
&lt;li>$T_{\text{cache}}$: Redis से पढ़ने/लिखने में लगने वाला समय&lt;/li>
&lt;li>$T_{\text{db}}$: PostgreSQL पर क्वेरी निष्पादित करने में लगने वाला समय&lt;/li>
&lt;li>$p_{\text{miss}}$: कैश मिस रेट ($0 \le p_{\text{miss}} \le 1$)&lt;/li>
&lt;/ul>
&lt;p>इस समय, औसत प्रतिक्रिया समय निम्नलिखित अपेक्षित मूल्य गणना सूत्र द्वारा व्यक्त किया गया है:&lt;/p>
$$ T_{\text{total}} = T_{\text{net}} + T_{\text{app}} + T_{\text{cache}} + p_{\text{miss}} \times (T_{\text{db}} + T_{\text{cache\_write}}) $$&lt;p>स्थानीय विकास वातावरण (Docker के अंदर) में, $T_{\text{net}}$ लगभग 0 के करीब होगा, लेकिन ध्यान देने योग्य बात &lt;strong>बाइंड माउंट करते समय I/O प्रदर्शन&lt;/strong> है। खासकर जब Windows/macOS पर Docker Desktop का उपयोग किया जाता है, तो होस्ट OS और VM (कंटेनर) के बीच फ़ाइल साझाकरण ओवरहेड के कारण $T_{\text{app}}$ (कोड लोड करने का समय आदि) बढ़ने की प्रवृत्ति होती है। इस अड़चन (bottleneck) को हल करने के लिए, उपर्युक्त DevContainers का उपयोग करके पूरे सोर्स कोड को नेम्ड वॉल्यूम में रखने या WSL2 (Windows Subsystem for Linux 2) वातावरण में मूल रूप से Docker इंजन को चलाने वाले आर्किटेक्चर की दृढ़ता से अनुशंसा की जाती है।&lt;/p>
&lt;hr>
&lt;h2 id="8-docker-बलड-परदरशन-अनकलन-optimization-लयर-कश-रणनत">8. Docker बिल्ड प्रदर्शन अनुकूलन (Optimization): लेयर कैश रणनीति
&lt;/h2>&lt;p>Dockerfile लिखते समय, यह समझना कि &amp;ldquo;लेयर कैश&amp;rdquo; कैसे काम करता है, बिल्ड समय को काफी हद तक बदल सकता है।
Docker Dockerfile में प्रत्येक निर्देश (&lt;code>FROM&lt;/code>, &lt;code>RUN&lt;/code>, &lt;code>COPY&lt;/code>, आदि) के लिए फ़ाइल सिस्टम अंतर (लेयर्स) बनाता है और उन्हें कैश के रूप में रखता है। पुनर्निर्माण के दौरान, जिन लेयर्स में कोई बदलाव नहीं हुआ है, उनके कैश का पुनः उपयोग किया जाता है।&lt;/p>
&lt;p>महत्वपूर्ण सिद्धांत यह है कि &lt;strong>&amp;ldquo;उन चीज़ों को पहले लिखें जो कम बदलती हैं&amp;rdquo;&lt;/strong>।&lt;/p>
&lt;p>आइए उस प्रभाव का मॉडल तैयार करें जो सोर्स कोड में परिवर्तन बिल्ड समय पर डालता है। मान लीजिए कि कुल बिल्ड समय $T_{\text{build}}$ है, प्रत्येक चरण का निष्पादन समय $T_{\text{layer}_i}$ है, और क्या कैश हिट हुआ है या नहीं, यह एक बूलियन मान $c_i \in \{0, 1\}$ (कैश हिट होने पर 1) है।&lt;/p>
$$ T_{\text{build}} = T_{\text{init}} + \sum_{i=1}^{n} (1 - c_i) \times T_{\text{layer}_i} $$&lt;p>एक बार लेयर $k$ ($c_k = 0$) में कैश मिस होने पर, बाद की सभी लेयर्स $j > k$ ($c_j = 0$) के लिए कैश अमान्य (invalidated) हो जाता है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-dockerfile" data-lang="dockerfile">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># खराब उदाहरण (सोर्स कोड पहले कॉपी किया गया है)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">COPY&lt;/span> ./src /app/src&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">COPY&lt;/span> pyproject.toml poetry.lock ./&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">RUN&lt;/span> poetry install&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>उपरोक्त मामले में, कोड की एक पंक्ति को संशोधित करने से पहला &lt;code>COPY&lt;/code> एक कैश मिस बन जाएगा, और समय लेने वाला &lt;code>RUN poetry install&lt;/code> हर बार निष्पादित किया जाएगा।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-dockerfile" data-lang="dockerfile">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># अच्छा उदाहरण (पहले निर्भरताओं को हल करें)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">COPY&lt;/span> pyproject.toml poetry.lock ./&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">RUN&lt;/span> poetry install&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="k">COPY&lt;/span> ./src /app/src&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इस तरह से लिखने से, भले ही आप सोर्स कोड बदल दें, &lt;code>poetry install&lt;/code> का लेयर कैश ($c_i = 1$) काम करेगा, इसलिए बिल्ड समय मिनटों से घटकर सेकंडों में आ जाएगा।&lt;/p>
&lt;hr>
&lt;h2 id="9-समसय-नवरण-troubleshooting-और-टपस">9. समस्या निवारण (Troubleshooting) और टिप्स
&lt;/h2>&lt;p>स्थानीय वातावरण को चलाते समय अक्सर आने वाली समस्याएँ और उनके समाधान यहाँ दिए गए हैं:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>पोर्ट टकराव त्रुटि (Port Conflict Error)&lt;/strong>
यदि आपको &lt;code>Bind for 0.0.0.0:8000 failed: port is already allocated&lt;/code> जैसी त्रुटि मिलती है, तो आपकी स्थानीय मशीन पर कोई अन्य प्रक्रिया उस पोर्ट का उपयोग कर रही है। आप होस्ट-साइड पोर्ट नंबर को &lt;code>ports: - &amp;quot;8080:8000&amp;quot;&lt;/code> की तरह बदलकर इससे बच सकते हैं।&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>डिस्क स्पेस का खत्म होना&lt;/strong>
यदि आप लंबे समय तक Docker का उपयोग करते हैं, तो अप्रयुक्त इमेज और वॉल्यूम (Dangling Images / Volumes) जमा हो सकते हैं, जिससे दसियों GB डिस्क स्थान भर सकता है। सिस्टम को नियमित रूप से साफ़ करने के लिए निम्न कमांड की अनुशंसा की जाती है:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">docker system prune -a --volumes
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;/li>
&lt;li>
&lt;p>&lt;strong>फ़ाइल अनुमति (Permissions) की समस्या&lt;/strong>
लिनक्स वातावरण में बाइंड माउंट का उपयोग करते समय, कंटेनर के अंदर बनाई गई फ़ाइलों का स्वामी (owner) &lt;code>root&lt;/code> बन सकता है, जिससे आप उन्हें होस्ट साइड पर संपादित नहीं कर पाते। आप Dockerfile के भीतर एक गैर-विशेषाधिकार प्राप्त उपयोगकर्ता बनाकर और उसे होस्ट OS (उदा. 1000:1000) पर अपने स्वयं के UID/GID से मिलाकर इस समस्या को हल कर सकते हैं।&lt;/p>
&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="10-नषकरष-पनरतपदत-वतवरण-reproducibility-स-वकस-गत-म-सधर">10. निष्कर्ष: पुनरुत्पादित वातावरण (Reproducibility) से विकास गति में सुधार
&lt;/h2>&lt;p>Docker, Docker Compose, और VSCode DevContainers को मिलाकर, एक मजबूत स्थानीय विकास वातावरण प्राप्त किया जाता है जहाँ &amp;ldquo;चाहे कोई भी वातावरण स्थापित करे, यह पूरी तरह से समान होगा।&amp;rdquo;&lt;/p>
&lt;p>स्थानीय वातावरण में IaC प्रतिमान लाने से न केवल प्रारंभिक सेटअप समय कम होता है। यह इन्फ्रास्ट्रक्चर कॉन्फ़िगरेशन में बदलाव की चिंता को दूर करता है, नए प्रौद्योगिकी स्टैक (technology stacks) के प्रयोग को आसान बनाता है, CI/CD पाइपलाइनों में सुचारू संक्रमण (transition) को सक्षम बनाता है, और संपूर्ण विकास चक्र की गति और गुणवत्ता में नाटकीय रूप से सुधार करता है।&lt;/p>
&lt;p>कृपया इस लेख में चर्चा की गई सर्वोत्तम प्रथाओं, जैसे मल्टी-स्टेज बिल्ड के माध्यम से इमेज आकार का अनुकूलन, हेल्थचेक का उपयोग करके निर्भरता नियंत्रण, और लेयर कैश के बारे में जागरूक Dockerfile लेखन का उपयोग करें, और अपनी परियोजनाओं में सर्वोत्तम विकास अनुभव (DX: Developer Experience) लाएँ।&lt;/p></description></item></channel></rss>