Määritysten mallintaminen envsubstilla ja heredoc-rakenteilla
Luo ajonaikaiset määritykset ympäristömuuttujista envsubstilla ja lainatuilla heredoc-rakenteilla.
Määritysten mallintaminen envsubstilla ja heredoc-rakenteilla on ilmainen DevOps-bootcamp-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu DevOps-bootcamp-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. DevOps-bootcamp-kurssilla on yhteensä 4 oppituntia.
Miksi ajonaikainen asetusten mallintaminen on tärkeää
DevOps- ja konttityönkuluissa asetustiedostoja, kuten nginx.conf, prometheus.yml ja docker-compose.yml, on usein muutettava ympäristöjen välillä: staging-, tuotanto- ja DR-ympäristöissä. Arvojen kovakoodaaminen aiheuttaa ympäristöjen ajautumista erilleen ja altistaa salaisuuksien vuotamiselle.
Ratkaisu on ajonaikainen asetusten mallintaminen: toimittakaa mallipohja paikkamerkkeineen ja lisätkää todelliset arvot käynnistyksen yhteydessä ympäristömuuttujista. Näin image pysyy muuttumattomana ja asetukset ovat tarkastettavissa.
- Salaisuuksia ei upoteta imageen
- Sama artefakti voidaan viedä eri ympäristöihin
- Asetukset muodostetaan juuri ennen prosessin käynnistymistä
Kaksi toisiaan täydentävää työkalua tekee tästä helppoa Bashissa: envsubst ja lainausmerkeillä suojatut heredoc-rakenteet.
envsubst: asetusten muodostaminen yhdellä komennolla
envsubst on pieni GNU-apuohjelma, joka lukee vakiosyötettä, korvaa $VARIABLE- ja ${VARIABLE}-paikkamerkit nykyisen ympäristön arvoilla ja kirjoittaa tuloksen vakiotulosteeseen.
Se toimitetaan gettext-paketin mukana ja on saatavilla lähes kaikissa Linux-jakeluissa ja Docker-perusimageissa.
- Toimii missä tahansa tekstimuodossa: NGINX, YAML, TOML, JSON ja INI
- Ei suorita shell-syntaksia, vaan korvaa ainoastaan muuttujaviittaukset
- Turvallinen: se ei suorita mallipohjassa olevia komentoja
#!/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; }Valikoiva muuttujien korvaaminen
Oletusarvoisesti envsubst korvaa jokaisen löytämänsä $VAR-muuttujan. Tämä voi sotkea NGINX-muuttujat, kuten $uri tai $host, jotka ovat todellisia NGINX-direktiivejä eivätkä ympäristömuuttujia.
Välittäkää muuttujat eksplisiittisenä luettelona ensimmäisenä argumenttina, jotta korvaaminen rajoittuu vain kyseisiin nimiin:
envsubst '$VAR1 $VAR2'Argumentti on yksinkertaisilla lainausmerkeillä rajattu merkkijono, jolloin shell ei laajenna sitä. Merkkijono sisältää korvattavien muuttujien nimet välilyönneillä tai rivinvaihdoilla eroteltuina.
#!/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}'
Mallipohjatiedostot levyllä
Todellisia asetuksia varten tallentakaa mallipohja tiedostona (esimerkiksi nginx.conf.template) Dockerfile-tiedoston rinnalle. Suorittakaa kontin käynnistyessä envsubst, jotta lopullinen asetustiedosto muodostetaan ennen taustapalvelun käynnistämistä.
Tämä on virallisessa NGINX Docker -imagessa käytetty vakiintunut malli.
#!/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.confLainausmerkeillä rajatut heredoc-lohkot: upotetut mallipohjat ilman väliaikaistiedostoa
Lainausmerkeillä rajattu heredoc (jossa käytetään koodia << 'EOF' ja erotin on yksinkertaisissa lainausmerkeissä) estää komentotulkkia laajentamasta muuttujia tai suorittamasta komentokorvauksia lohkon sisällä. Sisältö käsitellään literaalisena merkkijonona.
Näin heredoc-lohkot ovat erinomainen tapa kirjoittaa mallipohja suoraan skriptiin ja ohjata se putkella suoraan ohjelmalle envsubst — välitiedostoa ei tarvita.
<< EOF(ilman lainausmerkkejä) — komentotulkki laajentaa$VAR-muuttujan heti<< 'EOF'(lainausmerkeillä rajattu) — sisältö on literaalista; laajennus siirtyy ohjelmalleenvsubst
#!/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 shellHeredoc-lohkojen yhdistäminen tulosteen uudelleenohjaukseen
Ohjatkaa lainausmerkeillä rajattu heredoc-lohko ohjelman envsubst läpi ja uudelleenohjatkaa tulos tiedostoon yhdellä lausekkeella. Tämä on selkein tapa luoda asetustiedostoja entrypoint-skriptissä.
Käyttäkää valikoivaa korvaamista ('${VAR1} ${VAR2}'), kun kohdemuodolla, kuten Prometheuksella tai NGINXillä, on oma suojattava $variable-syntaksinsa.
#!/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}"Oletusarvot ja tarkistus ennen korvaamista
Älkää koskaan olettako, että kaikki pakolliset muuttujat on asetettu. Käyttäkää Bashin parametrilaajennusta oletusarvojen antamiseen tai ilmoittakaa virheestä heti:
${VAR:-default}— käyttäkää arvoadefault, josVARon asettamatta tai tyhjä${VAR:?error message}— keskeyttäkää virheilmoitukseen, josVARon asettamatta tai tyhjä
Asettakaa nämä ennen ohjelman envsubst kutsumista, jotta mallipohja saa aina konkreettisen arvon tai skripti pysähtyy heti hyödyllisen viestin kanssa.
#!/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}"Moniosioisten asetustiedostojen luominen useilla heredoc-lohkoilla
Monimutkaisissa, loogisista osioista koostuvissa asetustiedostoissa voitte luoda kunkin osion erikseen ja yhdistää ne tai käyttää yhtä koko tiedoston kattavaa heredoc-lohkoa. Molemmat tavat toimivat — valitkaa luettavuuden kannalta sopivampi.
Kun osioita sisällytetään ehtojen perusteella, esimerkiksi TLS-lohko vain, jos sertifikaatin polku on asetettu, usean heredoc-lohkon käyttäminen yhdessä if-lohkojen kanssa on selkeämpää.
#!/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"Dockerin entrypoint-malli
Suositeltu Dockerin entrypoint-malli käyttää shell-skriptiä (docker-entrypoint.sh) asetustiedostojen luomiseen käynnistyksen yhteydessä ja siirtää sitten hallinnan pääprosessille komennolla exec. exec korvaa shell-prosessin daemonilla, joten signaalit (SIGTERM, SIGINT) saavuttavat daemonin suoraan — tämä on välttämätöntä hallitulle sammutukselle.
Mallipohjatiedostot lisätään levykuvaan koontivaiheessa; arvot syötetään suoritusaikana komennolla docker run -e tai Kubernetesin määrityksillä 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}"Kubernetesin ConfigMap- ja envsubst-malli
Kubernetesissa ympäristömuuttujat syötetään Pod-määrityksen kohdissa env: tai envFrom:. Säilön entrypoint kutsuu ohjelmaa envsubst asetustiedostojen muodostamiseksi ennen prosessin käynnistymistä — ympäristökohtaisia ConfigMap-resursseja ei tarvita.
Näin ympäristökohtaiset arvot säilyvät Kubernetesin Secrets- ja ConfigMaps-resursseissa (ei-arkaluonteisia tietoja varten), kun taas asetusten mallipohja sijaitsee levykuvassa. Yksi levykuva, monta ympäristöä.
- Koonti:
COPY nginx.conf.template /etc/nginx/templates/ - Suoritusaikana: entrypoint suorittaa ohjelman
envsubstja kirjoittaa tiedoston/etc/nginx/nginx.conf - K8s syöttää:
APP_PORT- jaBACKEND_HOST-arvot Secret- tai ConfigMap-resurssista
envsubst-ohjelman vianmääritys: puuttuvien tai ratkaisemattomien muuttujien etsiminen
Kun luotu asetustiedosto sisältää arvon sijaan literaalisen merkkijonon ${VAR}, muuttujaa ei ole viety ympäristöön tai sitä ei ole sisällytetty korvausluetteloon. Käyttäkää vianmääritykseen seuraavia tekniikoita:
printenv | sort— luettelee kaikki viedyt muuttujat- Verratkaa mallipohjan paikkamerkkejä vietyihin muuttujiin komennolla
grep - Suorittakaa ohjelma
envsubstja etsikää tulosteesta jäljelle jääviä${-alkuisia merkkijonoja - Käyttäkää kutsuvassa skriptissä komentoa
set -u, jotta asettamattomiin muuttujiin viittaaminen Bash-koodissa keskeyttää suorituksen heti
#!/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"Tietotesti: envsubst-ohjelman valikoiva korvaaminen
Tarkastelkaa NGINX-asetusten mallipohjaa, joka sisältää sekä sovelluksen muuttujan ${APP_PORT} että NGINXin oman muuttujan $uri. Suoritatte seuraavan komennon:
envsubst < nginx.conf.template > nginx.conf
Mikä on tulos?
Oppitunnin yhteenveto: asetusten mallintaminen envsubst-ohjelmalla ja heredoc-lohkoilla
Nyt käytössänne on tuotantokäyttöön soveltuva työkalupakki asetusten luomiseen suoritusaikana Bashissa:
- envsubst korvaa
${VAR}-paikkamerkit missä tahansa tekstitiedostossa nykyisen ympäristön avulla — ilman skriptausta tai erityistä merkkien suojausta - Valikoiva korvaaminen (
envsubst '${VAR1} ${VAR2}') suojaa NGINXin, Prometheuksen ja vastaavien työkalujen omia muuttujia tahattomalta korvaamiselta - Lainausmerkeillä rajatut heredoc-lohkot (
<< 'EOF') siirtävät shellin laajennuksen myöhemmäksi, joten mallipohjan sisältö välittyy ohjelmalleenvsubstmuuttumattomana — väliaikaistiedostoja ei tarvita - Validoikaa ennen korvaamista: käyttäkää komentoa
${VAR:?message}pakollisten muuttujien puuttuessa keskeyttämiseen ja komentoa${VAR:-default}valinnaisille muuttujille - Dockerin entrypoint-malli: luokaa asetustiedostot säilön käynnistyessä ja suorittakaa sitten daemon komennolla
exec, jotta signaalit käsitellään oikein - Selvittäkää ratkaisemattomat paikkamerkit etsimällä tulosteesta jäljelle jääviä
${-alkuisia merkkijonoja ennen prosessin käynnistymistä
Näiden mallien avulla levykuvat pysyvät muuttumattomina, salaisuudet poissa lähdekoodinhallinnasta ja asetukset yhdenmukaisina kaikissa ympäristöissä.
Opi DevOps-bootcamp tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 142
- Oppitunnit
- 568
Usein kysytyt kysymykset
Onko oppitunti ”Määritysten mallintaminen envsubstilla ja heredoc-rakenteilla” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa DevOps-bootcamp-oppimispolun 3 oppituntia, myös oppitunnin “Määritysten mallintaminen envsubstilla ja heredoc-rakenteilla”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. DevOps-bootcamp-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Määritysten mallintaminen envsubstilla ja heredoc-rakenteilla”?
Luo ajonaikaiset määritykset ympäristömuuttujista envsubstilla ja lainatuilla heredoc-rakenteilla. Harjoittelet DevOps-bootcamp-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni DevOps-bootcamp-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin DevOps-bootcamp-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.
Kuinka kauan ”Määritysten mallintaminen envsubstilla ja heredoc-rakenteilla”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä DevOps-bootcamp-oppitunnilla?
Kyllä. Jokainen DevOps-bootcamp-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Keveiden Dockerfile-tiedostojen ja shell-entripointien kirjoittaminen
- Määritysten mallintaminen envsubstilla ja heredoc-rakenteilla
- Pilviresurssien skriptaus CLI-työkaluilla ja jq:lla
- Kuntotarkistukset, valmiusportit ja odotussilmukat