<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>IaC on kenji.blog</title><link>http://kenji.blog/hi/tags/iac/</link><description>Recent content in IaC on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>hi</language><copyright>kenjinote</copyright><lastBuildDate>Sun, 13 Sep 2026 01:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/hi/tags/iac/index.xml" rel="self" type="application/rss+xml"/><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>