イメージの取得とビルド
イメージは2通りで手に入ります。1つは docker pull でレジストリ(Docker Hub など)から既成のイメージを取得する方法、もう1つは Dockerfile から docker build で自作する方法です。Dockerfile はベースイメージの指定(FROM)やファイルのコピー(COPY)、実行コマンド(RUN)などを順に書いたテキストで、各命令がレイヤとして積み重なります。-t でイメージに名前とタグを付けておくと後で扱いやすくなります。
コンテナを起動するには、もとになるイメージが要る。ではそのイメージは、どこから手に入れるのか。
方法は大きく2通りある。1つは、誰かが用意した既成のイメージをそのまま取ってくる方法。もう1つは、自分専用のイメージを自分で組み立てる方法だ。
前者は docker pull でレジストリから取得し、後者は Dockerfile を書いて docker build でビルドする。既成品で足りるならそれを使い、自分のアプリを入れた独自の環境が欲しいなら自作する。この2つを状況に応じて使い分けるのが基本になる。まずは手っ取り早い既成品の取得から見ていく。
📥 既成のイメージを取ってくる――docker pull
イメージを保管・配布している置き場をレジストリと呼び、その代表が Docker Hub だ。アプリの開発元が公式イメージを公開しており、私たちはそれを取得して使える。
取得には docker pull イメージ名 を使う。たとえば docker pull nginx で Web サーバの nginx を、docker pull alpine で数MBしかない超軽量な Linux イメージを取ってこられる。
ここで一つ注意がある。pull はあくまで「ダウンロードするだけ」で、コンテナの起動はしない(起動まで一気にやりたいなら、前に学んだ docker run がローカルに無いイメージを自動で pull してくれる)。
次に覚えておきたいのがタグだ。同じ nginx でも、いつのバージョンを取ってくるのか。それを決めるのがタグである。
イメージ名にコロンで続けて nginx:1.25 のようにバージョンを指定するもので、これをタグと呼ぶ。docker pull nginx のようにタグを省くと、自動で :latest(最新版)が補われ、docker pull nginx:latest と書いたのと同じ扱いになる。
本番運用では、いつの間にか中身が変わって挙動が変わるのを避けるため、latest 任せにせず nginx:1.25 のように版を固定するのが安全だ。取得済みのイメージは docker images で一覧でき、名前・タグ・IMAGE ID・SIZE が並ぶので、alpine がいかに小さいかといったことも一目で分かる。
🏗 自分だけのイメージを組み上げる――Dockerfile と docker build
既成イメージに自分のアプリやファイルを足した独自イメージを作るには、その設計図にあたる Dockerfile を書く。
Dockerfile は「どの土台から始めて、何をインストールして、どのファイルを入れて、起動時に何を実行するか」を、上から順に並べたただのテキストファイルだ。料理のレシピを手順どおりに書き下していくのに似ている。
よく使う命令を押さえておこう。FROM は土台にするベースイメージの指定で、必ず最初に書く。RUN はイメージを作る途中で実行するコマンド(パッケージのインストールなど)、COPY はホスト側のファイルをイメージの中へコピーする命令、WORKDIR は以降の作業ディレクトリの指定、CMD はコンテナ起動時に既定で実行するコマンドだ。
言葉だけでは像を結びにくい。Python の小さなプログラムを動かすイメージを実際に作ってみよう。作業フォルダに app.py と、次の内容の Dockerfile を置く(以下は Dockerfile の中身そのものなので、行頭にプロンプト記号は付かない)。
FROM python:3.12-slim / WORKDIR /app / COPY app.py . / EXPOSE 8080 / CMD ["python", "app.py"] という5行だ。意味は上から、「Python 3.12 の軽量版を土台にする」「作業フォルダを /app にする」「手元の app.py をそこへコピーする」「8080番ポートを使うと宣言する」「起動時に python app.py を実行する」となる。
なお EXPOSE はあくまで「このポートを使う」という宣言(ドキュメント)であって、これだけで外部からアクセスできるようになるわけではない点に注意してほしい。実際に外へ公開するには、別トピックで扱う -p オプションが必要になる。
⏺ ビルドの最後に置く、あの一文字
Dockerfile を置いたフォルダで、docker build -t myapp:1.0 . を実行するとイメージが作られる。-t は名前とタグを付けるオプションで、myapp:1.0 ならコロンの前が名前、後ろがバージョン(タグ)だ。タグを省くと :latest が自動で付く。
そして最大の注意点が、コマンド末尾の .(ドット)である。これは「今いるフォルダをビルドの材料置き場(ビルドコンテキスト)として使う」という意味で、Dockerfile や COPY 対象のファイルをここから探す。
このドットを書き忘れて docker build -t myapp:1.0 とだけ打つとエラーになる。初学者が最もよくやる失敗だ。つまずいたら、まずこれ。「最後のドットを忘れない」と覚えておこう。
⚡ ビルドが速いとき、何が再利用されているか
Dockerfile の各命令は、それぞれが1つのレイヤを生み出す。FROM の層、COPY の層、と積み上がってイメージができあがる。これが前のトピックで触れたレイヤ構造の正体だ。
ここで効いてくるのがキャッシュである。docker build をやり直したとき、上から見ていって変更のなかった命令の層は、前回の結果がそのまま再利用される。
だから、頻繁に変わるもの(自分のアプリのソースなど)を Dockerfile の後ろのほうに書き、めったに変わらないもの(依存ライブラリのインストールなど)を前に書くとよい。変更時に作り直す層が減ってビルドが速くなる。この順序の工夫は、ビルド時間を縮める実務の定番テクニックだ。
🌍 固めたイメージは、現場で何をもたらすか
ビルドが終われば、自作イメージ myapp:1.0 も既成イメージとまったく同じく docker run myapp:1.0 で起動できる。一度イメージに固めてしまえば、配布先のどのマシンでも同じ環境で動く。これが「環境ごと配る」ことの威力だ。
実務では、まず公式のベースイメージを FROM で土台にし、その上に自分のアプリと依存物を載せて独自イメージを作る、という流れが基本になる。
なお、誰でもレジストリにイメージを公開できるため、素性の怪しいイメージには注意が必要だ。FROM で土台を選ぶときは、公式(official)マークの付いたものや、信頼できる発行元のものを選ぶのが鉄則になる。作ったイメージは docker push でレジストリに登録すれば、チームや別のサーバと共有できる。