Membuat Template Konfigurasi dengan envsubst dan heredoc
Hasilkan konfigurasi saat runtime dari variabel environment menggunakan envsubst dan heredoc yang diberi tanda kutip.
Membuat Template Konfigurasi dengan envsubst dan heredoc adalah pelajaran Linux Command Line & Bash Scripting Mastery gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Linux Command Line & Bash Scripting Mastery, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Linux Command Line & Bash Scripting Mastery mencakup 4 pelajaran total.
Mengapa Pembuatan Template Konfigurasi Saat Runtime Penting
Dalam alur kerja DevOps dan container, berkas konfigurasi seperti nginx.conf, prometheus.yml, dan docker-compose.yml sering kali perlu berubah antarlingkungan — staging, produksi, DR. Menetapkan nilai secara langsung dalam kode menyebabkan perbedaan konfigurasi dan terbukanya rahasia.
Solusinya adalah pembuatan template konfigurasi saat runtime: sertakan template dengan placeholder, lalu masukkan nilai sebenarnya saat startup dari variabel lingkungan. Dengan demikian, image Anda tetap tidak berubah dan konfigurasi mudah diaudit.
- Tidak ada rahasia yang disematkan dalam image
- Artefak yang sama dapat dipromosikan ke berbagai lingkungan
- Konfigurasi dibuat sesaat sebelum proses dimulai
Dua alat yang saling melengkapi membuatnya mudah dilakukan dalam Bash: envsubst dan heredoc yang diberi tanda kutip.
envsubst: Pembuat Konfigurasi Satu Baris
envsubst adalah utilitas GNU kecil yang membaca stdin, mengganti placeholder $VARIABLE dan ${VARIABLE} dengan nilainya dari lingkungan saat ini, lalu menulis hasilnya ke stdout.
Utilitas ini disertakan dalam paket gettext dan tersedia di hampir semua distro Linux serta image basis Docker.
- Berfungsi dengan format teks apa pun: NGINX, YAML, TOML, JSON, INI
- Tidak mengevaluasi sintaks shell — hanya mengganti referensi variabel
- Aman: tidak akan menjalankan perintah di dalam template
#!/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; }Substitusi Variabel Selektif
Secara default, envsubst mengganti setiap $VAR yang ditemukannya. Hal ini dapat mengubah variabel NGINX seperti $uri atau $host — keduanya adalah direktif NGINX sebenarnya, bukan variabel lingkungan Anda.
Berikan daftar variabel eksplisit sebagai argumen pertama untuk membatasi substitusi hanya pada nama-nama tersebut:
envsubst '$VAR1 $VAR2'Argumen tersebut berupa string dengan tanda kutip tunggal (agar tidak diperluas oleh shell) yang berisi nama variabel yang ingin Anda ganti, dipisahkan oleh spasi atau baris baru.
#!/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}'
Berkas Template di Disk
Untuk konfigurasi nyata, simpan template sebagai berkas (misalnya, nginx.conf.template) bersama Dockerfile Anda. Saat container dimulai, jalankan envsubst untuk menghasilkan berkas konfigurasi akhir sebelum meluncurkan daemon.
Ini adalah pola standar yang digunakan oleh image NGINX resmi.
#!/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.confHeredoc Berpetik: Templat Sebaris Tanpa Berkas Sementara
heredoc berpetik (menggunakan << 'EOF' dengan tanda petik tunggal di sekitar pembatas) mencegah shell memperluas variabel atau menjalankan substitusi perintah di dalam blok. Konten diperlakukan sebagai teks harfiah.
Dengan demikian, heredoc menjadi cara yang sempurna untuk menulis templat sebaris dan langsung menyalurkannya ke envsubst — tanpa memerlukan berkas perantara.
<< EOF(tanpa petik) — shell segera memperluas$VAR<< 'EOF'(dengan petik) — konten bersifat harfiah; perluasan ditunda hinggaenvsubst
#!/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 shellMenggabungkan Heredoc dengan Pengalihan Keluaran
Salurkan heredoc berpetik melalui envsubst dan alihkan hasilnya ke sebuah berkas dalam satu ekspresi. Ini adalah pola penulisan paling rapi untuk membuat berkas konfigurasi dalam skrip titik masuk.
Gunakan substitusi selektif ('${VAR1} ${VAR2}') jika format tujuan (Prometheus, NGINX, dan sebagainya) memiliki sintaks $variable sendiri yang harus dilindungi.
#!/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}"Nilai Bawaan dan Validasi Sebelum Substitusi
Jangan pernah berasumsi bahwa semua variabel yang diperlukan telah ditetapkan. Gunakan perluasan parameter Bash untuk menyediakan nilai bawaan atau menghentikan eksekusi dengan pesan yang jelas:
${VAR:-default}— gunakandefaultjikaVARtidak ditetapkan atau kosong${VAR:?error message}— batalkan eksekusi dengan galat jikaVARtidak ditetapkan atau kosong
Tetapkan variabel-variabel ini sebelum memanggil envsubst agar templat selalu menerima nilai konkret atau skrip segera berhenti dengan pesan yang membantu.
#!/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}"Membuat Konfigurasi Multi-Bagian dengan Beberapa Heredoc
Untuk konfigurasi kompleks yang dibangun dari beberapa bagian logis, Anda dapat membuat setiap bagian secara terpisah lalu menggabungkannya, atau menggunakan satu heredoc yang mencakup seluruh berkas. Keduanya dapat digunakan — pilih berdasarkan keterbacaan.
Jika bagian-bagian disertakan secara kondisional (misalnya, blok TLS hanya jika jalur sertifikat telah ditetapkan), pendekatan dengan beberapa heredoc dan blok if lebih rapi.
#!/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"Pola Titik Masuk Docker
Pola titik masuk Docker yang disarankan menggunakan skrip shell (docker-entrypoint.sh) untuk membuat konfigurasi saat startup, lalu menyerahkan kendali kepada proses utama dengan exec. Penggunaan exec menggantikan proses shell dengan proses layanan, sehingga sinyal (SIGTERM, SIGINT) langsung diterima oleh proses layanan — hal yang sangat penting untuk penghentian yang baik.
Berkas templat ditambahkan ke citra saat citra dibangun; values disuntikkan saat dijalankan dari docker run -e atau Kubernetes env: / envFrom:.
#!/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}"Pola ConfigMap + envsubst Kubernetes
Di Kubernetes, variabel lingkungan disuntikkan melalui env: atau envFrom: dalam spesifikasi Pod. Titik masuk kontainer Anda memanggil envsubst untuk mewujudkan konfigurasi sebelum proses dimulai — tidak diperlukan ConfigMap untuk setiap lingkungan.
Dengan cara ini, nilai khusus lingkungan tetap berada dalam Rahasia dan ConfigMaps Kubernetes (untuk data yang tidak sensitif), sementara templat konfigurasi berada di dalam citra. Satu citra, banyak lingkungan.
- Pembangunan:
COPY nginx.conf.template /etc/nginx/templates/ - Saat dijalankan: titik masuk menjalankan
envsubst, lalu menulis/etc/nginx/nginx.conf - K8s menyuntikkan:
APP_PORT,BACKEND_HOSTdari Rahasia/ConfigMap
Men-debug envsubst: Menemukan Variabel yang Hilang atau Belum Terselesaikan
Jika konfigurasi yang dibuat berisi ${VAR} secara harfiah, bukan sebuah nilai, berarti variabel tersebut belum diekspor atau tidak disertakan dalam daftar substitusi. Gunakan teknik-teknik berikut untuk men-debug:
printenv | sort— mencantumkan semua variabel yang diekspor- Bandingkan placeholder dalam templat dengan variabel yang diekspor menggunakan
grep - Jalankan
envsubstdan gunakan grep pada keluarannya untuk mencari pola${yang masih tersisa - Gunakan
set -udalam skrip pemanggil agar referensi variabel yang belum ditetapkan dalam kode Bash segera menghentikan eksekusi
#!/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"Pemeriksaan Pengetahuan: Substitusi Selektif envsubst
Pertimbangkan templat konfigurasi NGINX yang berisi variabel aplikasi Anda, ${APP_PORT}, sekaligus variabel bawaan NGINX, $uri. Anda menjalankan perintah berikut:
envsubst < nginx.conf.template > nginx.conf
Apa hasilnya?
Ringkasan Pelajaran: Membuat Templat Konfigurasi dengan envsubst dan Heredoc
Sekarang Anda memiliki perangkat siap produksi untuk membuat konfigurasi saat runtime dalam Bash:
- envsubst mengganti placeholder
${VAR}dalam berkas teks apa pun menggunakan lingkungan saat ini — tanpa skrip dan tanpa pelolosan khusus - Substitusi selektif (
envsubst '${VAR1} ${VAR2}') melindungi variabel bawaan dalam NGINX, Prometheus, dan alat serupa agar tidak terganti secara tidak sengaja - Heredoc berpetik (
<< 'EOF') menunda perluasan shell sehingga konten templat sampai keenvsubsttanpa perubahan — tidak diperlukan berkas sementara - Validasikan sebelum melakukan substitusi: gunakan
${VAR:?message}untuk menghentikan eksekusi jika variabel wajib tidak ada dan${VAR:-default}untuk variabel opsional - Pola titik masuk Docker: buat konfigurasi saat kontainer dimulai, lalu gunakan
execuntuk proses layanan agar sinyal ditangani dengan benar - Debug placeholder yang belum terselesaikan dengan mencari pola
${yang masih tersisa dalam keluaran menggunakan grep sebelum proses dimulai
Pola-pola ini menjaga citra kontainer Anda tetap tidak berubah, menjaga rahasia agar tidak masuk ke kontrol sumber, serta memastikan konfigurasi konsisten di setiap lingkungan.
Belajar Bash dengan tutor AI — gratis
Tulis dan jalankan kode asli di browser kamu, dapatkan bantuan instan dari tutor AI 24/7, dan lanjutkan di mana kamu tinggalkan di web atau aplikasi.
- Kursus
- 22
- Pelajaran
- 88
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Membuat Template Konfigurasi dengan envsubst dan heredoc” gratis?
Ya — teks lengkap “Membuat Template Konfigurasi dengan envsubst dan heredoc” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Linux Command Line & Bash Scripting Mastery, upgrade ke CoddyKit PRO. Kursus Linux Command Line & Bash Scripting Mastery mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Membuat Template Konfigurasi dengan envsubst dan heredoc”?
Hasilkan konfigurasi saat runtime dari variabel environment menggunakan envsubst dan heredoc yang diberi tanda kutip. Kamu berlatih Linux Command Line & Bash Scripting Mastery dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Linux Command Line & Bash Scripting Mastery?
Tidak diperlukan pengalaman sebelumnya. Linux Command Line & Bash Scripting Mastery di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.
Berapa lama pelajaran “Membuat Template Konfigurasi dengan envsubst dan heredoc” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Linux Command Line & Bash Scripting Mastery ini?
Ya. Setiap pelajaran Linux Command Line & Bash Scripting Mastery menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Menulis Dockerfile dan Entrypoint Shell yang Ringkas
- Membuat Template Konfigurasi dengan envsubst dan heredoc
- Membuat Skrip Resource Cloud dengan CLI dan jq
- Probe Kesehatan, Gerbang Kesiapan, dan Loop Tunggu