DevOps बूटकैंप · पाठ

envsubst और heredoc से कॉन्फ़िगरेशन टेम्पलेट बनाना

envsubst और उद्धृत heredoc का उपयोग करके परिवेश चर से रनटाइम कॉन्फ़िगरेशन तैयार करें।

पाठ 2, कुल 4 में से13 चरण

envsubst और heredoc से कॉन्फ़िगरेशन टेम्पलेट बनाना, CoddyKit पर DevOps बूटकैंप का एक निःशुल्क पाठ है। यह 4 में से 2वाँ पाठ है। इस अध्ययन पथ के 3 तक कोई भी पाठ पूरा पढ़ना निःशुल्क है — इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ व्यावहारिक अभ्यास भी उपलब्ध कराता है। यह DevOps बूटकैंप सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। DevOps बूटकैंप पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

रनटाइम कॉन्फ़िगरेशन टेम्पलेट बनाना क्यों महत्वपूर्ण है

DevOps और कंटेनर कार्यप्रवाहों में, nginx.conf, prometheus.yml और docker-compose.yml जैसी कॉन्फ़िगरेशन फ़ाइलों को अक्सर अलग-अलग परिवेशों — स्टेजिंग, उत्पादन और DR — के बीच बदलना पड़ता है। मानों को हार्डकोड करने से असंगति और सीक्रेट उजागर होने का जोखिम पैदा होता है।

समाधान है रनटाइम कॉन्फ़िगरेशन टेम्पलेट बनाना: प्लेसहोल्डर वाला टेम्पलेट भेजें, फिर परिवेश चरों से आरंभ के समय वास्तविक मान डालें। इससे आपकी इमेज अपरिवर्तनीय और आपका कॉन्फ़िगरेशन जाँचा जा सकने योग्य रहता है।

  • इमेज में कोई सीक्रेट स्थायी रूप से शामिल नहीं
  • एक ही निर्माण-उत्पाद को विभिन्न परिवेशों में आगे बढ़ाया जा सकता है
  • प्रक्रिया शुरू होने से ठीक पहले कॉन्फ़िगरेशन तैयार किया जाता है

बैश में दो पूरक औज़ार इसे बहुत आसान बनाते हैं: envsubst और उद्धृत हेरडॉक।

envsubst: एक-पंक्ति कॉन्फ़िगरेशन निर्माता

envsubst एक छोटी GNU उपयोगिता है जो मानक इनपुट पढ़ती है, $VARIABLE और ${VARIABLE} प्लेसहोल्डर को वर्तमान परिवेश से उनके मानों से बदलती है और मानक आउटपुट में लिखती है।

यह gettext पैकेज के साथ आती है और लगभग हर लिनक्स वितरण तथा डॉकर आधार इमेज में उपलब्ध है।

  • किसी भी पाठ प्रारूप के साथ काम करती है: NGINX, YAML, TOML, JSON, INI
  • शेल सिंटैक्स का मूल्यांकन नहीं करती — केवल चर संदर्भ बदलती है
  • सुरक्षित है: टेम्पलेट के अंदर आदेश निष्पादित नहीं करेगी
#!/usr/bin/env bash
# Install check (usually already present)
which envsubst || apt-get install -y gettext-base

# Minimal demo
export APP_PORT=8080
export APP_HOST=api.example.com

echo 'server { listen ${APP_PORT}; server_name ${APP_HOST}; }' | envsubst
# Output: server { listen 8080; server_name api.example.com; }

चयनित चरों का प्रतिस्थापन

डिफ़ॉल्ट रूप से, envsubst मिलने वाले प्रत्येक $VAR को बदलती है। इससे $uri या $host जैसे NGINX चर बदल सकते हैं — वे आपके परिवेश चर नहीं, बल्कि वास्तविक NGINX निर्देश हैं।

प्रतिस्थापन को केवल उन्हीं नामों तक सीमित करने के लिए पहले तर्क के रूप में चरों की स्पष्ट सूची दें:

envsubst '$VAR1 $VAR2'

यह तर्क एकल-उद्धृत स्ट्रिंग है (इसलिए शेल इसका विस्तार नहीं करता), जिसमें बदले जाने वाले चर नाम रिक्त स्थान या नई पंक्तियों से अलग किए गए होते हैं।

#!/usr/bin/env bash
export APP_PORT=8080
export APP_HOST=api.example.com

# NGINX template contains both our vars AND nginx vars ($uri, $host)
TEMPLATE='server {
  listen ${APP_PORT};
  server_name ${APP_HOST};
  location / {
    proxy_set_header Host $host;
    proxy_pass http://backend$uri;
  }
}'

# Only substitute APP_PORT and APP_HOST — leave $host and $uri untouched
echo "$TEMPLATE" | envsubst '${APP_PORT} ${APP_HOST}'

डिस्क पर टेम्पलेट फ़ाइलें

वास्तविक कॉन्फ़िगरेशन के लिए, टेम्पलेट को अपने डॉकरफ़ाइल के साथ एक फ़ाइल के रूप में रखें (जैसे, nginx.conf.template)। कंटेनर शुरू होने पर डेमॉन लॉन्च करने से पहले अंतिम कॉन्फ़िगरेशन फ़ाइल बनाने के लिए envsubst चलाएँ।

यह आधिकारिक NGINX डॉकर इमेज में उपयोग किया जाने वाला मानक प्रतिरूप है।

#!/usr/bin/env bash
# File: nginx.conf.template
# (In practice this lives on disk; we write it here for demo purposes)
cat > /tmp/nginx.conf.template << 'TMPL'
server {
    listen ${NGINX_PORT};
    server_name ${SERVER_NAME};
    root /var/www/${APP_ENV};

    location / {
        proxy_pass http://app:${APP_PORT};
    }
}
TMPL

export NGINX_PORT=80
export SERVER_NAME=myapp.example.com
export APP_ENV=production
export APP_PORT=3000

# Generate final config
envsubst '${NGINX_PORT} ${SERVER_NAME} ${APP_ENV} ${APP_PORT}' \
  < /tmp/nginx.conf.template \
  > /tmp/nginx.conf

cat /tmp/nginx.conf

उद्धृत हेरडॉक: अस्थायी फ़ाइल के बिना इनलाइन टेम्पलेट

एक उद्धृत हेरडॉक (डिलिमिटर के चारों ओर एकल उद्धरणों के साथ << 'EOF' का उपयोग करके) शेल को ब्लॉक के भीतर वेरिएबल का विस्तार करने या कमांड प्रतिस्थापन चलाने से रोकता है। इसकी सामग्री को शाब्दिक स्ट्रिंग माना जाता है।

इससे हेरडॉक, टेम्पलेट को सीधे लिखने और उसे तुरंत envsubst में पाइप करने का सबसे अच्छा तरीका बन जाता है — किसी मध्यवर्ती फ़ाइल की आवश्यकता नहीं होती।

  • << EOF (बिना उद्धरण वाला) — शेल तुरंत $VAR का विस्तार करता है
  • << 'EOF' (उद्धरण वाला) — सामग्री शाब्दिक रहती है; विस्तार envsubst तक स्थगित रहता है
#!/usr/bin/env bash
export DB_HOST=postgres.internal
export DB_PORT=5432
export DB_NAME=myapp_prod

# Quoted heredoc: shell does NOT expand $DB_HOST etc. yet
envsubst << 'EOF'
[database]
host     = ${DB_HOST}
port     = ${DB_PORT}
dbname   = ${DB_NAME}
EOF
# Output uses actual env var values — expansion done by envsubst, not the shell

हेरडॉक को आउटपुट रीडायरेक्शन के साथ संयोजित करना

एक ही अभिव्यक्ति में उद्धृत हेरडॉक को envsubst के माध्यम से पाइप करें और परिणाम को किसी फ़ाइल में रीडायरेक्ट करें। एंट्रीपॉइंट स्क्रिप्ट में कॉन्फ़िगरेशन फ़ाइलें बनाने के लिए यह सबसे साफ़ तरीका है।

जब लक्ष्य प्रारूप (Prometheus, NGINX आदि) की अपनी $variable सिंटैक्स हो और उसे सुरक्षित रखना हो, तब चयनित प्रतिस्थापन ('${VAR1} ${VAR2}') का उपयोग करें।

#!/usr/bin/env bash
# entrypoint.sh — Docker container entrypoint
set -euo pipefail

export PROM_PORT=${PROM_PORT:-9090}
export SCRAPE_INTERVAL=${SCRAPE_INTERVAL:-15s}
export TARGET_HOST=${TARGET_HOST:-localhost:8080}

envsubst '${PROM_PORT} ${SCRAPE_INTERVAL} ${TARGET_HOST}' << 'EOF' > /etc/prometheus/prometheus.yml
global:
  scrape_interval: ${SCRAPE_INTERVAL}
  evaluation_interval: ${SCRAPE_INTERVAL}

scrape_configs:
  - job_name: 'app'
    static_configs:
      - targets: ['${TARGET_HOST}']

EOF

echo "[entrypoint] Prometheus config written on port ${PROM_PORT}"
exec prometheus --config.file=/etc/prometheus/prometheus.yml --web.listen-address=":${PROM_PORT}"

प्रतिस्थापन से पहले डिफ़ॉल्ट मान और सत्यापन

यह कभी न मानें कि सभी आवश्यक वेरिएबल निर्धारित हैं। डिफ़ॉल्ट मान देने या स्पष्ट त्रुटि के साथ विफल होने के लिए बैश पैरामीटर विस्तार का उपयोग करें:

  • ${VAR:-default} — यदि VAR निर्धारित नहीं है या खाली है, तो default का उपयोग करें
  • ${VAR:?error message} — यदि VAR निर्धारित नहीं है या खाली है, तो त्रुटि के साथ प्रक्रिया रोक दें

envsubst को कॉल करने से पहले इन्हें निर्धारित करें, ताकि टेम्पलेट को हमेशा कोई ठोस मान मिले या सहायक संदेश के साथ स्क्रिप्ट शुरुआत में ही रुक जाए।

#!/usr/bin/env bash
set -euo pipefail

# Required — abort if missing
: "${DATABASE_URL:?DATABASE_URL must be set}"
: "${SECRET_KEY:?SECRET_KEY must be set}"

# Optional with defaults
export APP_PORT=${APP_PORT:-8000}
export LOG_LEVEL=${LOG_LEVEL:-info}
export WORKERS=${WORKERS:-4}

envsubst '${DATABASE_URL} ${SECRET_KEY} ${APP_PORT} ${LOG_LEVEL} ${WORKERS}' \
  < /app/config/app.conf.template \
  > /app/config/app.conf

echo "[init] Config generated — port=${APP_PORT} workers=${WORKERS} log=${LOG_LEVEL}"

एकाधिक हेरडॉक से बहु-खंड कॉन्फ़िगरेशन बनाना

तार्किक खंडों से बनी जटिल कॉन्फ़िगरेशन के लिए आप प्रत्येक खंड को स्वतंत्र रूप से बना कर उन्हें जोड़ सकते हैं, या पूरी फ़ाइल को समेटने वाला एक ही हेरडॉक उपयोग कर सकते हैं। दोनों तरीके काम करते हैं — पठनीयता के आधार पर चुनाव करें।

जब खंडों को शर्त के आधार पर शामिल किया जाता है (जैसे, प्रमाणपत्र का पथ निर्धारित होने पर ही TLS ब्लॉक), तब if ब्लॉक वाला बहु-हेरडॉक तरीका अधिक साफ़ रहता है।

#!/usr/bin/env bash
set -euo pipefail

export APP_HOST=${APP_HOST:-localhost}
export APP_PORT=${APP_PORT:-8080}
export TLS_CERT=${TLS_CERT:-}
export TLS_KEY=${TLS_KEY:-}

CONFIG_FILE=/tmp/app.conf

# Base section
envsubst '${APP_HOST} ${APP_PORT}' << 'BASE' > "$CONFIG_FILE"
[server]
host = ${APP_HOST}
port = ${APP_PORT}
BASE

# Conditional TLS section — only appended when cert is provided
if [[ -n "$TLS_CERT" && -n "$TLS_KEY" ]]; then
  envsubst '${TLS_CERT} ${TLS_KEY}' << 'TLS' >> "$CONFIG_FILE"

[tls]
cert_file = ${TLS_CERT}
key_file  = ${TLS_KEY}
TLS
  echo "[init] TLS enabled"
else
  echo "[init] TLS disabled (no cert/key provided)"
fi

cat "$CONFIG_FILE"

डॉकर एंट्रीपॉइंट पैटर्न

अनुशंसित डॉकर एंट्रीपॉइंट पैटर्न में एक शेल स्क्रिप्ट (docker-entrypoint.sh) का उपयोग करके स्टार्टअप के समय कॉन्फ़िगरेशन बनाई जाती है, फिर exec के साथ मुख्य प्रक्रिया को नियंत्रण सौंप दिया जाता है। exec का उपयोग शेल प्रक्रिया को डेमन से बदल देता है, इसलिए सिग्नल (SIGTERM, SIGINT) सीधे डेमन तक पहुँचते हैं — सुचारु रूप से बंद करने के लिए यह अत्यंत महत्वपूर्ण है।

टेम्पलेट फ़ाइलें इमेज निर्माण के समय इमेज में जोड़ी जाती हैं; रनटाइम पर docker run -e या कुबेरनेटिस के env: / envFrom: से values डाले जाते हैं।

#!/usr/bin/env bash
# docker-entrypoint.sh
set -euo pipefail

# Validate required env vars
for var in DATABASE_URL REDIS_URL SECRET_KEY; do
  : "${!var:?$var is required}"
done

export APP_PORT=${APP_PORT:-8000}
export WORKERS=${WORKERS:-$(nproc)}

echo "[entrypoint] Generating configuration..."
envsubst '${DATABASE_URL} ${REDIS_URL} ${SECRET_KEY} ${APP_PORT} ${WORKERS}' \
  < /app/config/settings.toml.template \
  > /app/config/settings.toml

echo "[entrypoint] Starting server on port ${APP_PORT} with ${WORKERS} workers"
exec gunicorn app:application \
  --bind "0.0.0.0:${APP_PORT}" \
  --workers "${WORKERS}"

कुबेरनेटिस ConfigMap + एन्वसब्स्ट पैटर्न

कुबेरनेटिस में पर्यावरण वेरिएबल, पॉड विनिर्देशन में env: या envFrom: के माध्यम से डाले जाते हैं। प्रक्रिया शुरू होने से पहले आपका कंटेनर एंट्रीपॉइंट envsubst चलाकर कॉन्फ़िगरेशन को तैयार करता है — हर पर्यावरण के लिए अलग ConfigMap की आवश्यकता नहीं होती।

इससे पर्यावरण-विशिष्ट मान कुबेरनेटिस के सीक्रेट्स और ConfigMaps (गैर-संवेदनशील डेटा के लिए) में रहते हैं, जबकि कॉन्फ़िगरेशन टेम्पलेट इमेज में रहता है। एक इमेज, अनेक पर्यावरण।

  • निर्माण: COPY nginx.conf.template /etc/nginx/templates/
  • रनटाइम: एंट्रीपॉइंट envsubst चलाता है और /etc/nginx/nginx.conf लिखता है
  • कुबेरनेटिस द्वारा डाले गए मान: APP_PORT, BACKEND_HOST, किसी सीक्रेट/ConfigMap से

एन्वसब्स्ट की डीबगिंग: अनुपलब्ध या अनसुलझे वेरिएबल ढूँढना

जब बनाई गई कॉन्फ़िगरेशन में किसी मान के बजाय शाब्दिक ${VAR} दिखाई दे, तो वेरिएबल या तो निर्यात नहीं किया गया है या प्रतिस्थापन सूची में शामिल नहीं है। डीबग करने के लिए ये तरीके अपनाएँ:

  • printenv | sort — सभी निर्यात किए गए वेरिएबल की सूची बनाएँ
  • grep की सहायता से टेम्पलेट के स्थानधारकों की तुलना निर्यात किए गए वेरिएबल से करें
  • envsubst चलाएँ और आउटपुट में बचे हुए ${ पैटर्न को ग्रेप करके ढूँढें
  • कॉल करने वाली स्क्रिप्ट में set -u का उपयोग करें, ताकि बैश कोड में निर्धारित न किए गए वेरिएबल के संदर्भ तुरंत प्रक्रिया रोक दें
#!/usr/bin/env bash
set -euo pipefail

TEMPLATE=/tmp/app.conf.template
OUTPUT=/tmp/app.conf

# Write a demo template
cat > "$TEMPLATE" << 'EOF'
host=${DB_HOST}
port=${DB_PORT}
name=${DB_NAME}
EOF

export DB_HOST=db.internal
export DB_PORT=5432
# DB_NAME intentionally left unset

envsubst < "$TEMPLATE" > "$OUTPUT"

# Detect unresolved placeholders
if grep -qE '\$\{[A-Z_]+\}' "$OUTPUT"; then
  echo "ERROR: unresolved placeholders found:"
  grep -oE '\$\{[A-Z_]+\}' "$OUTPUT" | sort -u
  exit 1
fi

echo "Config OK:"
cat "$OUTPUT"

ज्ञान जाँच: एन्वसब्स्ट का चयनित प्रतिस्थापन

ऐसे NGINX कॉन्फ़िगरेशन टेम्पलेट पर विचार करें जिसमें आपका एप्लिकेशन वेरिएबल ${APP_PORT} और मूल NGINX वेरिएबल $uri दोनों मौजूद हैं। आप यह कमांड चलाते हैं:

envsubst < nginx.conf.template > nginx.conf

परिणाम क्या होगा?

पाठ का पुनरावलोकन: एन्वसब्स्ट और हेरडॉक से कॉन्फ़िगरेशन टेम्पलेट बनाना

अब आपके पास बैश में रनटाइम कॉन्फ़िगरेशन बनाने के लिए उत्पादन-स्तर के उपकरण हैं:

  • एन्वसब्स्ट वर्तमान पर्यावरण का उपयोग करके किसी भी टेक्स्ट फ़ाइल में मौजूद ${VAR} स्थानधारकों को बदलता है — न स्क्रिप्ट लिखने की आवश्यकता, न विशेष एस्केपिंग
  • चयनित प्रतिस्थापन (envsubst '${VAR1} ${VAR2}') NGINX, Prometheus और इसी तरह के उपकरणों में मौजूद मूल वेरिएबल को गलती से बदले जाने से सुरक्षित रखता है
  • उद्धृत हेरडॉक (<< 'EOF') शेल विस्तार को स्थगित रखते हैं, इसलिए टेम्पलेट की सामग्री बिना बदलाव के envsubst तक पहुँचती है — अस्थायी फ़ाइलों की आवश्यकता नहीं होती
  • प्रतिस्थापन से पहले सत्यापन करें: आवश्यक वेरिएबल न मिलने पर प्रक्रिया रोकने के लिए ${VAR:?message} और वैकल्पिक वेरिएबल के लिए ${VAR:-default} का उपयोग करें
  • डॉकर एंट्रीपॉइंट पैटर्न: कंटेनर स्टार्टअप पर कॉन्फ़िगरेशन बनाएँ, फिर डेमन के लिए exec चलाएँ, ताकि सिग्नल सही ढंग से संभाले जाएँ
  • अनसुलझे स्थानधारकों को डीबग करें: प्रक्रिया शुरू होने से पहले आउटपुट में बचे हुए ${ पैटर्न को ग्रेप करके ढूँढें

ये पैटर्न आपकी कंटेनर इमेज को अपरिवर्तनीय, आपके सीक्रेट्स को स्रोत नियंत्रण से बाहर और आपकी कॉन्फ़िगरेशन को हर पर्यावरण में सुसंगत बनाए रखते हैं।

शुरुआत निःशुल्क

एआई शिक्षक के साथ DevOps बूटकैंप सीखें — निःशुल्क

अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।

पाठ्यक्रम
142
पाठ
568

अक्सर पूछे जाने वाले प्रश्न

क्या “envsubst और heredoc से कॉन्फ़िगरेशन टेम्पलेट बनाना” पाठ निःशुल्क है?

हाँ — DevOps बूटकैंप अध्ययन पथ के 3 तक कोई भी पाठ, जिसमें “envsubst और heredoc से कॉन्फ़िगरेशन टेम्पलेट बनाना” भी शामिल है, यहाँ वेब पर पूरा पढ़ना निःशुल्क है। इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ इंटरैक्टिव अभ्यास भी उपलब्ध कराता है। DevOps बूटकैंप पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

“envsubst और heredoc से कॉन्फ़िगरेशन टेम्पलेट बनाना” में मैं क्या सीखूँगा?

envsubst और उद्धृत heredoc का उपयोग करके परिवेश चर से रनटाइम कॉन्फ़िगरेशन तैयार करें। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ DevOps बूटकैंप का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।

क्या DevOps बूटकैंप शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?

पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर DevOps बूटकैंप शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 2वाँ पाठ है।

“envsubst और heredoc से कॉन्फ़िगरेशन टेम्पलेट बनाना” पाठ पूरा करने में कितना समय लगता है?

CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।

क्या मैं इस DevOps बूटकैंप पाठ में कोड लिख और चला सकता हूँ?

हाँ। हर DevOps बूटकैंप पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।

इस पाठ्यक्रम के सभी पाठ

  1. हल्की Dockerfile और Shell एंट्रीपॉइंट लिखना
  2. envsubst और heredoc से कॉन्फ़िगरेशन टेम्पलेट बनाना
  3. CLI और jq से क्लाउड संसाधनों की स्क्रिप्टिंग
  4. स्वास्थ्य जाँच, तत्परता द्वार और प्रतीक्षा लूप
← DevOps बूटकैंप पर वापस जाएँ