DockerfileのHEREDOC構文でRUN命令をすっきり書く方法|マルチラインとCOPYを使わないファイル生成の実践設計

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOME > Linux技術 リナックスマスター.JP(Linuxマスター.JP) > Docker > DockerfileのHEREDOC構文でRUN命令をすっきり書く方法|マルチラインとCOPYを使わないファイル生成の実践設計
「Dockerfileに複数のaptインストールを書くたびに、バックスラッシュ(\)で行を繋ぐのが面倒だ」
「設定ファイルをコンテナ内に置くためだけに、わざわざCOPYコマンドと別ファイルを用意するのは手間が多い」

Docker BuildKit(Dockerfile 1.4以降)が導入したHEREDOC構文を使うと、この二つの課題をスッキリ解決できる。RUN命令にシェルスクリプト相当のブロックをそのまま書けるようになり、COPYを使わずファイルをインライン生成することも可能だ。

この記事では、Dockerfileのheredoc構文の有効化から、RUN <

この記事のポイント

・Dockerfile 1.4以降のBuildKitでHEREDOC構文が使える(冒頭に # syntax=docker/dockerfile:1.4 が必要)
・RUN < ・COPY < ・バックスラッシュ継続(RUN cmd1 && cmd2)との使い分けは可読性と複雑さで判断する


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

なぜHEREDOC構文が必要なのか

従来のDockerfileでは、複数のコマンドをワンレイヤーにまとめるために && とバックスラッシュ継続を使う書き方が一般的だった。

# 従来の書き方(バックスラッシュ継続) RUN apt-get update && \ apt-get install -y curl wget jq && \ apt-get clean && \ rm -rf /var/lib/apt/lists/*

この書き方は機能するが、長くなると見通しが悪くなる。また、設定ファイルを埋め込む際には別ファイルを作ってCOPYする必要があり、Dockerfileと設定ファイルが散在する問題があった。

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名以上の実績をもとに、現役サーバー管理者が現場の鉄則を直接指導します。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。