「設定ファイルをコンテナ内に置くためだけに、わざわざCOPYコマンドと別ファイルを用意するのは手間が多い」
Docker BuildKit(Dockerfile 1.4以降)が導入したHEREDOC構文を使うと、この二つの課題をスッキリ解決できる。RUN命令にシェルスクリプト相当のブロックをそのまま書けるようになり、COPYを使わずファイルをインライン生成することも可能だ。
この記事では、Dockerfileのheredoc構文の有効化から、RUN <
この記事のポイント
・Dockerfile 1.4以降のBuildKitでHEREDOC構文が使える(冒頭に # syntax=docker/dockerfile:1.4 が必要)
・RUN <
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜHEREDOC構文が必要なのか
従来のDockerfileでは、複数のコマンドをワンレイヤーにまとめるために&& とバックスラッシュ継続を使う書き方が一般的だった。# 従来の書き方(バックスラッシュ継続) RUN apt-get update && \ apt-get install -y curl wget jq && \ apt-get clean && \ rm -rf /var/lib/apt/lists/*
HEREDOC構文を使うと、シェルで親しみのある
<<EOF 形式でブロックをそのまま記述できる。可読性が上がり、設定ファイルをDockerfile一本に集約できる点が現場での大きなメリットだ。HEREDOC構文を有効にする方法
1. BuildKitを有効にする
HEREDOC構文はDocker 23.0以降ではデフォルト有効のBuildKitで使える。古いバージョンではビルド前に環境変数を設定する。# BuildKitを明示的に有効化(Docker 23.0未満の場合) export DOCKER_BUILDKIT=1 # または daemon.jsonで常時有効にする # /etc/docker/daemon.json に以下を追加: # { "features": { "buildkit": true } }
2. Dockerfileの先頭に syntax ディレクティブを付ける
HEREDOC構文にはDockerfile 1.4以降のparser frontendが必要だ。Dockerfileの1行目に以下のコメント行を追加する。# syntax=docker/dockerfile:1.4 FROM ubuntu:22.04 RUN <
# syntax=docker/dockerfile:1.4 はコメントではなくparser directive(解析指示子)だ。これがないとheredoc構文がSyntax Errorになる。注意点として、この行はFROMより前の先頭1行目に書かなければならない。RUN <<EOF でマルチラインコマンドを書く実践例
1. 基本的なパッケージインストール
# syntax=docker/dockerfile:1.4 FROM ubuntu:22.04 # シェルを明示指定してHEREDOCブロックを記述 RUN <
2. 実行シェルを指定するHEREDOC
RUN <<EOF は /bin/sh を使う。/bin/bash や Python で実行したい場合はシェルを明示できる。# syntax=docker/dockerfile:1.4 FROM python:3.12-slim # bash で実行 RUN <<'EOF' bash set -euo pipefail pip install --no-cache-dir \ requests==2.32.3 \ pydantic==2.7.0 EOF # python で直接実行 RUN <<'EOF' python3 import os os.makedirs("/app/data", exist_ok=True) with open("/app/version.txt", "w") as f: f.write("1.0.0\n") EOF
'EOF')はHEREDOC内の変数展開を抑制するための構文だ。<<EOF(引用符なし)ではDockerfileレイヤービルド時に $変数 が展開されてしまう場合があるため、スクリプト本体に変数があるときは <<'EOF' を使う。COPY <
HEREDOC構文はCOPYにも使える。別ファイルを用意せずに、Dockerfile内に設定ファイルの中身を直接書ける点が運用上の注意点を減らす。
# syntax=docker/dockerfile:1.4
FROM nginx:1.26-alpine
# Nginx設定ファイルをインライン生成
COPY <
この手法により、設定ファイルとDockerfileが分離せずに管理できる。ただし、設定内容が長い場合やバイナリファイルの場合は従来のCOPYの方が適切だ。
Dockerfileの設計を含むコンテナ運用全般については、Dockerハンズオン学習コンテンツでも実践的に解説している。
ビルド結果を実測して確認する
# ビルド実行例(BuildKit有効)
$ docker build -t myapp:heredoc .
[+] Building 18.4s (6/6) FINISHED
=> [internal] load build definition from Dockerfile
=> [internal] load .dockerignore
=> [1/3] FROM docker.io/library/ubuntu:22.04
=> [2/3] RUN < [3/3] COPY < exporting to image
# コンテナ内のファイルを確認
$ docker run --rm myapp:heredoc cat /etc/myconfig.ini
[app]
debug = false
port = 8080
よくあるエラーと対処法
【エラー1】"syntax" parser directiveが効かない
# エラー例
failed to solve: failed to read dockerfile: dockerfile parse error on line 3:
unexpected keyword: <<
# 原因1: # syntax=... の行がFROMより前にない
FROM ubuntu:22.04
# syntax=docker/dockerfile:1.4 ← FROMの後ろに書いてしまっている(NG)
# 原因2: DOCKER_BUILDKIT=0 でBuildKitが無効
# 対処: export DOCKER_BUILDKIT=1 してから再ビルド
【エラー2】HEREDOC内の$変数が展開されて壊れる
# 問題: $HOMEなどのシェル変数が意図せず展開される
RUN <
【エラー3】EOFの終端マーカーに空白やタブが混入している
シェルと同様、終端の EOF は行頭から書く必要がある(インデントすると終端と認識されない)。エディタによっては自動インデントで終端行にタブが入る場合があるため注意が必要だ。
# NG: EOFの前にタブが入っている
RUN <
本記事のまとめ
DockerfileのHEREDOC構文はBuildKitと # syntax=docker/dockerfile:1.4 ディレクティブで有効になる。RUN命令のマルチライン化とCOPYのインライン化の両方に使えるため、Dockerfileの可読性と管理しやすさが向上する。
やりたいこと
構文
HEREDOC構文を有効にする
# syntax=docker/dockerfile:1.4(1行目に記述)
shでマルチラインコマンドを実行
RUN <<EOF ... EOF
bashでマルチラインコマンドを実行
RUN <<'EOF' bash ... EOF
ファイルをインラインで生成
COPY <<EOF /path/file ... EOF
変数展開を抑制して記述
RUN <<'EOF'(シングルクォートで囲む)
実運用では、短い1~2行のコマンドはバックスラッシュ継続のままで十分で、3行以上になるスクリプトや設定ファイルの埋め込みにHEREDOCが真価を発揮する。また、HEREDOC内の変数展開のコントロール(クォートあり/なし)は要注意事項として運用ルールに含めておこう。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、DockerfileやCompose設計からセキュリティ設定まで体系的に学べる「Linux Master Pro Seminar」をご覧ください。受講者3,100名以上の実績をもとに、現役サーバー管理者が現場の鉄則を直接指導します。
暗記不要・1時間後にはサーバーが動く
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 /
詳細はこちら
Linux無料マニュアル(図解60P)
名前とメールで30秒登録
- 前のページへ:DockerfileのFROM設計|debian・alpine・distrolessのベースイメージを比較して最適解を選ぶ方法
- この記事の属するカテゴリ:Dockerへ戻る
# syntax=docker/dockerfile:1.4 FROM nginx:1.26-alpine # Nginx設定ファイルをインライン生成 COPY <
Dockerfileの設計を含むコンテナ運用全般については、Dockerハンズオン学習コンテンツでも実践的に解説している。
ビルド結果を実測して確認する
# ビルド実行例(BuildKit有効) $ docker build -t myapp:heredoc . [+] Building 18.4s (6/6) FINISHED => [internal] load build definition from Dockerfile => [internal] load .dockerignore => [1/3] FROM docker.io/library/ubuntu:22.04 => [2/3] RUN <
[3/3] COPY < exporting to image # コンテナ内のファイルを確認 $ docker run --rm myapp:heredoc cat /etc/myconfig.ini [app] debug = false port = 8080
よくあるエラーと対処法
【エラー1】"syntax" parser directiveが効かない
# エラー例 failed to solve: failed to read dockerfile: dockerfile parse error on line 3: unexpected keyword: << # 原因1: # syntax=... の行がFROMより前にない FROM ubuntu:22.04 # syntax=docker/dockerfile:1.4 ← FROMの後ろに書いてしまっている(NG) # 原因2: DOCKER_BUILDKIT=0 でBuildKitが無効 # 対処: export DOCKER_BUILDKIT=1 してから再ビルド
【エラー2】HEREDOC内の$変数が展開されて壊れる
# 問題: $HOMEなどのシェル変数が意図せず展開される RUN <
【エラー3】EOFの終端マーカーに空白やタブが混入している
シェルと同様、終端のEOF は行頭から書く必要がある(インデントすると終端と認識されない)。エディタによっては自動インデントで終端行にタブが入る場合があるため注意が必要だ。# NG: EOFの前にタブが入っている RUN <
本記事のまとめ
DockerfileのHEREDOC構文はBuildKitと# syntax=docker/dockerfile:1.4 ディレクティブで有効になる。RUN命令のマルチライン化とCOPYのインライン化の両方に使えるため、Dockerfileの可読性と管理しやすさが向上する。| やりたいこと | 構文 |
|---|---|
| HEREDOC構文を有効にする | # syntax=docker/dockerfile:1.4(1行目に記述) |
| shでマルチラインコマンドを実行 | RUN <<EOF ... EOF |
| bashでマルチラインコマンドを実行 | RUN <<'EOF' bash ... EOF |
| ファイルをインラインで生成 | COPY <<EOF /path/file ... EOF |
| 変数展開を抑制して記述 | RUN <<'EOF'(シングルクォートで囲む) |
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:DockerfileのFROM設計|debian・alpine・distrolessのベースイメージを比較して最適解を選ぶ方法
- この記事の属するカテゴリ:Dockerへ戻る

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