コンテンツにスキップ

DockerfileとDockerイメージのビルド

uml diagram

Dockerfile

Dockerfileリファレンス — Docker-docs-ja 24.0ドキュメント

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# ベースにNode.jsイメージを使用する
FROM node:20.16.0

# アプリケーションを動作させるディレクトリを指定する
WORKDIR /app

COPY package.json package-lock.json ./
RUN npm ci

# アプリケーションをコピーする
COPY . .

# 依存関係をインストールする
RUN npm i

# アプリケーションを起動するためのコマンドを記載する
CMD ["npm", "run", "start"]

イメージのビルドを高速化する

Dockerはイメージのビルドを高速化するために、COPYRUNなどの命令をレイヤーとしてキャッシュし、レイヤーが変更されたときだけ以降のレイヤーを再実行する。

このため結果が変わりにくい命令を先に実行するように記述すればイメージの作成を高速化できる。

例えばソースコードのコピー依存するパッケージをインストール依存するパッケージのインストールを先に済ませたほうが良い。

ソースコードはパッケージの依存先に比べて変わりやすいので、ソースコードのコピーを先に実行してしまうと、ソースコードを変更するたびにパッケージのインストールを再実行することになってしまう。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# ベースのイメージを指定する
FROM node:24.13.0

WORKDIR /app

# 依存関係をインストールする
COPY package.json package-lock.json ./
RUN npm ci

# ソースコードをコピーする
COPY . .

docker-compose.yml

docker-compose.yml

Dockerイメージのビルド

1
2
3
# -t: イメージ名を設定する。"名前:タグ"の形式になる。タグは省略するとlatestになるらしい。
# 末尾の".": カレントディレクトリに置かれているファイル全てを対象にDockerイメージをビルドする。
$ docker build -t $IMAGE_NAME .

トラブルシューティング

設定が反映されない、正しく動作しない

初回起動時はコンテナのビルドが必要なのでdocker-compose up --buildで起動する。(以降は--buildはいらない)

Docker Composeでサービス間で通信できない

localhostのハードコーディングを見直す

コンテナ内においてlocalhostコンテナを動作させているマシンではなくコンテナ自身を指す。

別のコンテナのURLを定義する場合は、localhostではなくdocker-compose.ymlで定義したサービス名を使用する。

ポート設定を見直す

サービス間で通信するときのポートはホストにマッピングしたポートではなくコンテナ側のポートになるので注意すること。