「Dockerfileや nginx.conf のIPアドレス・ドメインをまとめて差し替えたい。」
こういった悩みを抱えているなら、envsubst コマンドがそのまま解決策になります。
envsubst は環境変数をテンプレート文字列に埋め込むだけのシンプルなコマンドですが、
設定ファイルの動的生成・CI/CD パイプライン・Docker エントリーポイントと組み合わせると
驚くほどの作業を自動化できます。
この記事では、envsubst コマンドの基本から実務でよく使うパターンまで
RHEL 9.4 / Ubuntu 24.04 LTS の実機で確認した手順で解説します。
この記事のポイント
・envsubst はテンプレートの $VAR を環境変数で一括置換するコマンド
・置換対象変数を限定する書き方で誤置換を防げる
・nginx.conf や Docker エントリーポイントとの組み合わせが実務の定番
・変数が未定義の場合は空文字に展開される点に注意
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
envsubst とは何か・なぜ使うのか
envsubst は GNU gettext パッケージに含まれる小さなコマンドです。標準入力またはファイルを読み込み、
$変数名 や ${変数名} の形式を対応する環境変数の値に置き換えて標準出力に書き出します。
「それなら sed でもできるのでは?」と思うかもしれません。
sed でも実現できますが、変数名が増えるほど sed の -e オプションが増えてコマンドが複雑になります。
envsubst は環境変数をそのまま使うため、変数をセットするだけで自動的にテンプレートへ反映されます。
特に以下の場面で真価を発揮します。
・同じ nginx.conf をステージング環境と本番環境で使い回す
・Docker コンテナ起動時に設定ファイルを動的に生成する(エントリーポイントスクリプト)
・CI/CD パイプラインでサービスごとに異なるドメイン・ポートを埋め込む
・シェルスクリプトからメールや通知のテンプレートを生成する
インストール確認と基本構文
1. envsubst がインストール済みか確認する
RHEL / CentOS 系ではgettext パッケージに含まれています。Ubuntu / Debian 系では
gettext-base パッケージです。# インストール確認 which envsubst # 出力例 /usr/bin/envsubst # バージョン確認 envsubst --version # 出力例 envsubst (GNU gettext-runtime) 0.21 Copyright (C) 2003-2020 Free Software Foundation, Inc.
# RHEL / Rocky Linux / AlmaLinux sudo dnf install gettext -y # Ubuntu / Debian sudo apt install gettext-base -y
2. 基本的な使い方(ヒアドキュメント)
最も手軽な使い方はヒアドキュメントと組み合わせる方法です。# 環境変数をセット export SERVER_NAME=web01.example.com export LISTEN_PORT=8080 # テンプレートをヒアドキュメントで渡す envsubst << 'EOF' server { listen $LISTEN_PORT; server_name $SERVER_NAME; } EOF # 出力例 server { listen 8080; server_name web01.example.com; }
3. ファイルを入力にして別ファイルへ出力する
実務ではテンプレートファイルを事前に用意しておき、envsubst でデプロイ用の設定ファイルを生成するパターンが多いです。
# テンプレートファイルを作成 cat nginx.conf.template server { listen $LISTEN_PORT; server_name $SERVER_NAME; root /var/www/$APP_NAME; } # 環境変数をセットして展開・出力 export SERVER_NAME=prod.example.com export LISTEN_PORT=443 export APP_NAME=myapp envsubst < nginx.conf.template > /etc/nginx/conf.d/myapp.conf # 生成されたファイルを確認 cat /etc/nginx/conf.d/myapp.conf server { listen 443; server_name prod.example.com; root /var/www/myapp; }
置換する変数を限定する(誤置換防止)
1. なぜ変数の限定が必要か
nginx.conf のような設定ファイルには、シェル変数に見えるがnginx 固有の変数(例:
$uri、$host、$request_uri)が含まれることがあります。envsubst をそのまま使うと、これらも展開対象になって空文字に置き換わる危険があります。
# 危険な例($uri が空文字に展開される) cat nginx.conf.template location / { proxy_pass http://$BACKEND_HOST; return 301 https://$host$uri; # nginx 固有変数 } export BACKEND_HOST=app.internal envsubst < nginx.conf.template # 出力($uri が消える) location / { proxy_pass http://app.internal; return 301 https://; # $host も $uri も消えた }
2. 第2引数で置換対象変数を限定する
envsubst の第2引数(シングルクォートで囲んだ変数名リスト)を指定すると、そのリストに含まれる変数だけを展開し、それ以外はそのまま残します。
# BACKEND_HOST だけを展開する($host・$uri はそのまま残る) export BACKEND_HOST=app.internal envsubst '$BACKEND_HOST' < nginx.conf.template > /etc/nginx/conf.d/proxy.conf # 確認 cat /etc/nginx/conf.d/proxy.conf location / { proxy_pass http://app.internal; return 301 https://$host$uri; # nginx 固有変数は保持される }
# 複数変数を限定指定 envsubst '$SERVER_NAME $LISTEN_PORT $APP_NAME' < nginx.conf.template > /etc/nginx/conf.d/myapp.conf
実務での活用パターン
1. Docker エントリーポイントスクリプトでの設定生成
Docker コンテナを起動するとき、環境変数で挙動を変えたい場面は非常に多くあります。entrypoint.sh で envsubst を呼び出すパターンが実務の定番です。
# entrypoint.sh の例 #!/bin/bash set -e # テンプレートから実際の設定ファイルを生成 envsubst '$SERVER_NAME $LISTEN_PORT' \ < /etc/nginx/templates/default.conf.template \ > /etc/nginx/conf.d/default.conf # nginx を起動 exec nginx -g 'daemon off;'
-e SERVER_NAME=prod.example.com -e LISTEN_PORT=80 を渡すだけで設定ファイルが自動生成される仕組みです。
nginx の公式 Docker イメージはこのパターンを公式に採用しています。
2. シェルスクリプトで通知メールを動的生成する
バックアップスクリプトや監視スクリプトから送信するメールのテンプレートをenvsubst で動的に生成することも実務でよく使います。
# メールテンプレートファイル(mail.template) Subject: [$ENV] バックアップ完了通知 To: $ADMIN_EMAIL $HOSTNAME のバックアップが完了しました。 実行時刻: $TIMESTAMP バックアップ先: $BACKUP_PATH
# バックアップスクリプト内での使用例 export ENV=production export ADMIN_EMAIL=ops@example.com export HOSTNAME=$(hostname) export TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') export BACKUP_PATH=/backup/$(date '+%Y%m%d') envsubst < mail.template | sendmail -t
3. Ansible・CI/CD パイプラインとの連携
GitHub Actions や GitLab CI でも envsubst はよく使われます。リポジトリにはテンプレートだけをコミットしておき、
シークレット変数を環境変数として渡してデプロイ時に実体ファイルを生成するパターンです。
# .github/workflows/deploy.yml の抜粋例 - name: Generate config from template env: DB_HOST: ${{ secrets.DB_HOST }} DB_NAME: ${{ secrets.DB_NAME }} APP_SECRET: ${{ secrets.APP_SECRET }} run: | envsubst '$DB_HOST $DB_NAME $APP_SECRET' \ < config/app.conf.template \ > config/app.conf
セキュリティと保守性を両立できます。
トラブルシュート・よくある問題と対処
1. 変数が展開されずそのままになる
最も多いのは変数が export されていないケースです。envsubst はシェルの 環境変数(export 済み)しか参照しません。
# NG(ローカル変数のため展開されない) MY_VAR=hello echo '$MY_VAR' | envsubst # 出力: $MY_VAR(展開されない) # OK(export すれば展開される) export MY_VAR=hello echo '$MY_VAR' | envsubst # 出力: hello
2. 変数名が空文字に展開されてしまう
環境変数が未定義のまま envsubst を実行すると、$変数名 は空文字列に展開されます。誤って必要な変数を消してしまわないよう、実行前に変数が定義されているか確認しましょう。
# 実行前の変数確認スクリプト(必須チェック) required_vars=(SERVER_NAME LISTEN_PORT APP_NAME) for var in "${required_vars[@]}"; do if [ -z "${!var}" ]; then echo "Error: 環境変数 $var が未定義です" >&2 exit 1 fi done # チェック通過後に envsubst を実行 envsubst '$SERVER_NAME $LISTEN_PORT $APP_NAME' \ < nginx.conf.template > /etc/nginx/conf.d/myapp.conf
3. シングルクォートとダブルクォートの混同
第2引数(変数名リスト)は シングルクォート で囲む必要があります。ダブルクォートにするとシェルが展開してしまい、意図と異なる動作になります。
export SERVER_NAME=prod.example.com # NG(ダブルクォートはシェルが $SERVER_NAME を展開する) envsubst "$SERVER_NAME" < template.conf > output.conf # 第2引数が "prod.example.com" になるため変数名として認識されない # OK(シングルクォートで変数名をそのまま渡す) envsubst '$SERVER_NAME' < template.conf > output.conf
4. テンプレート内の $ をそのまま残したい場合
テンプレートに envsubst で展開させたくない$ 記号が含まれる場合は、第2引数で置換変数を明示的に限定するか、
$$ とエスケープします。# $$ はリテラルの $ に展開される cat template.txt 価格は $$1,000 です。サーバー: $SERVER_NAME export SERVER_NAME=web01.example.com envsubst '$SERVER_NAME' < template.txt # 出力($SERVER_NAME のみ展開、$$ はリテラル $ に変換) 価格は $1,000 です。サーバー: web01.example.com
本記事のまとめ
| やりたいこと | コマンド |
|---|---|
| ヒアドキュメントで変数展開する | envsubst << 'EOF' ... EOF |
| テンプレートファイルを展開して出力 | envsubst < template.conf > output.conf |
| 特定の変数だけ展開する(誤置換防止) | envsubst '$VAR1 $VAR2' < template.conf |
| インストール(RHEL系) | sudo dnf install gettext -y |
| インストール(Ubuntu/Debian系) | sudo apt install gettext-base -y |
| 変数が定義済みか確認してから実行 | [ -z "${VAR}" ] && exit 1 の後に envsubst |
その単純さこそが強みです。
nginx の公式 Docker イメージが採用しているように、
設定ファイルの動的生成において最もシンプルで信頼性の高い手段のひとつです。
置換対象変数を限定する第2引数をきちんと使えば、
nginx 固有変数や他のツール固有の
$変数 を誤って消してしまうリスクも排除できます。Linux ポート確認の全コマンド や
Apache タイムアウト設定の詳細 と組み合わせて、
Linuxサーバーの設定管理を自動化する一歩を踏み出してみてください。
envsubstで設定ファイルの動的生成を身につけたら、次はサーバー全体の構築スキルを体系的に固めませんか?
envsubstによるテンプレート展開はサーバー運用自動化の基礎の一つです。シェルスクリプト・ネットワーク設定・ファイアウォールと合わせて体系的に身につけることで、現場で頼られるエンジニアになれます。
ネットの切れ端の情報をコピペするだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら
- 次のページへ:jqコマンドでJSONを解析・加工する方法|フィルタ・整形・抽出の実践例も
- 前のページへ:ausearchコマンドでLinuxの監査ログを検索・分析する方法|aureportでのレポート生成と実務活用も
- この記事の属するカテゴリ:Linuxtips・シェルスクリプトへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます