目次

Docker init 入門:Dockerfile と compose.yaml を自動生成する

初心者にとって Dockerfile の作成で最も難しいのは、「何から始めればよいかわからない」ことです。docker init はプロジェクトの言語を検出し、いくつか質問したあと、そのまま実行できる Docker ファイル一式を生成します。この節では、Node.js アプリケーションの Express プロジェクトで一連の手順を試し、生成された内容を一行ずつ確認します。

docker init は Docker Desktop に組み込まれたプラグインです。Docker Engine だけをインストールした Linux ホストにはこのコマンドがありませんが、生成されたファイルはどこでも使用できます。

プロジェクトを準備する

init-demo フォルダーには 3 つのファイルだけがあり、Docker 関連のファイルはまだありません。

init-demo/
├── package.json
├── package-lock.json
└── server.js

server.js はポート 3000 で待ち受ける Express プログラムで、内容はNode.js アプリケーションと同じです。

docker init を実行する

プロジェクトフォルダーで次を実行します。

$ docker init

Welcome to the Docker Init CLI!

This utility will walk you through creating the following files with sensible defaults for your project:
  - .dockerignore
  - Dockerfile
  - compose.yaml
  - README.Docker.md

Let's get started!

? What application platform does your project use?  [Use arrows to move, type to filter]
> Node - (detected) suitable for a Node server application
  Go - suitable for a Go server application
  Python - suitable for a Python server application
  Rust - suitable for a Rust server application
  ASP.NET Core - suitable for an ASP.NET Core application
  PHP with Apache - suitable for a PHP web application
  Java - suitable for a Java application that uses Maven and packages as an uber jar
  Other - general purpose starting point for containerizing your application
  Don't see something you need? Let us know!
  Quit

docker init は package.json を見つけ、Node を (detected) として自動選択します。矢印キーで選択し、Enter キーで確定します。次に、以下の質問が順に表示されます。

? What application platform does your project use? Node
? What version of Node do you want to use? 24
? Which package manager do you want to use? npm
? What command do you want to use to start the app? npm start
? What port does your server listen on? 3000

✔ Created → .dockerignore
✔ Created → Dockerfile
✔ Created → compose.yaml
✔ Created → README.Docker.md

→ Your Docker files are ready!
  Review your Docker files and tailor them to your application.
  Consult README.Docker.md for information about using the generated files.

What's next?
  Start your application by running → docker compose up --build
  Your application will be available at http://localhost:3000
質問この例の回答説明
application platformNodepackage.json が検出されるため、そのまま Enter キーを押します
version of Node24デフォルト値がないため入力が必要です。入力しないと Value is required と表示されます
package managernpmpackage-lock.json が検出され、デフォルトは npm です
command to start the appnpm startデフォルト値は package.json の scripts.start から取得されます
port3000プログラムが待ち受けるポートです。デフォルト値はありません

Node のバージョンを入力せずに Enter キーを押すと、次のように表示されます。

? What application platform does your project use? Node
X Sorry, your reply was invalid: Value is required
? What version of Node do you want to use?

プロジェクトに .nvmrc または package.json の engines.node がある場合、docker init はそれらをデフォルト値として使います。

最後に 4 つのファイルが生成されます。.dockerignore、Dockerfile、compose.yaml、README.Docker.md です。

生成された Dockerfile

説明コメントを除いた内容です(元のファイルでは各セクションに英語のコメントがあります)。

# syntax=docker/dockerfile:1

ARG NODE_VERSION=24

FROM node:${NODE_VERSION}-alpine

# Use production node environment by default.
ENV NODE_ENV production

WORKDIR /usr/src/app

RUN --mount=type=bind,source=package.json,target=package.json \
    --mount=type=bind,source=package-lock.json,target=package-lock.json \
    --mount=type=cache,target=/root/.npm \
    npm ci --omit=dev

USER node

COPY . .

EXPOSE 3000

CMD npm start
記述役割
# syntax=docker/dockerfile:1最新の Dockerfile 構文バージョンを使います(ビルド時に docker/dockerfile:1 が先にダウンロードされます)
ARG NODE_VERSION=24バージョンを変数にしておき、--build-arg NODE_VERSION=22 で変更できます
--mount=type=bind,source=package.jsonCOPY を使わず、ビルド時に package.json を直接マウントして、イメージのレイヤーを 1 つ減らします
--mount=type=cache,target=/root/.npmnpm のダウンロードキャッシュを複数回のビルドで共有しますが、イメージには含まれません
npm ci --omit=dev本番環境用のパッケージだけをインストールします
USER noderoot 以外のユーザーで実行します

全体として、Node.js アプリケーションで紹介したベストプラクティスに沿っています。

docker build --check でチェックする

docker build --check は Dockerfile の書式だけをチェックし、実際のビルドは行いません。生成された Dockerfile に対して実行します。

$ docker build --check .
#0 building with "default" instance using docker driver

#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 1.20kB done
#1 DONE 0.0s

#2 resolve image config for docker-image://docker.io/docker/dockerfile:1
#2 DONE 0.2s

#3 docker-image://docker.io/docker/dockerfile:1@sha256:4edf897a3ffa55b89f906fc8cc78afdb3f1834cc9c7083565e611a8a7d5fe99e
#3 resolve docker.io/docker/dockerfile:1@sha256:4edf897a3ffa55b89f906fc8cc78afdb3f1834cc9c7083565e611a8a7d5fe99e done
#3 CACHED

#4 [internal] load metadata for docker.io/library/node:24-alpine
#4 DONE 0.2s

#5 [internal] load .dockerignore
#5 transferring context: 663B done
#5 DONE 0.0s
Check complete, 2 warnings have been found!

WARNING: LegacyKeyValueFormat - https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/
"ENV key=value" should be used instead of legacy "ENV key value" format
Dockerfile:14
--------------------
  12 |
  13 |     # Use production node environment by default.
  14 | >>> ENV NODE_ENV production
  15 |
  16 |
--------------------

WARNING: JSONArgsRecommended - https://docs.docker.com/go/dockerfile/rule/json-args-recommended/
JSON arguments recommended for CMD to prevent unintended behavior related to OS signals
Dockerfile:38
--------------------
  36 |
  37 |     # Run the application.
  38 | >>> CMD npm start
  39 |
--------------------

テンプレートには警告が 2 つあります。

  1. LegacyKeyValueFormat:ENV NODE_ENV production は古い形式です。ENV NODE_ENV=production に変更してください。
  2. JSONArgsRecommended:CMD npm start はシェル形式です。OS シグナルの伝達に影響する可能性があるため、JSON 配列形式に変更することをおすすめします。理由はDockerfile 命令の詳細を参照してください。

次の 2 行を変更します。

ENV NODE_ENV=production
CMD ["node", "server.js"]

CMD は node を直接実行する形に変更します。npm プロセスが 1 つ減るためです。実測結果はNode.js アプリケーションを参照してください。docker build --check は、ビルド前に問題のある書式を検出できるため、CI プロセスに加えるのに適しています。

生成された compose.yaml

コメントを取り除くと、数行だけになります。

services:
  server:
    build:
      context: .
    environment:
      NODE_ENV: production
    ports:
      - 3000:3000

元のファイルの後半には、コメントアウトされた PostgreSQL の例がまとまってあります。コメントを解除して使う場合は、次の 2 点に注意してください。

#   db:
#     image: postgres
#     ...
#     volumes:
#       - db-data:/var/lib/postgresql/data
#     ...
#     healthcheck:
#       test: [ "CMD", "pg_isready" ]
  • image: postgres はバージョンを指定していないため、現在は 18 版が取得されます。18 版では Volume を /var/lib/postgresql にマウントする必要があります。/var/lib/postgresql/data にマウントすると起動に失敗します。PostgreSQLを参照してください。
  • pg_isready に -h 127.0.0.1 が指定されていないため、データベースの初期化が完了する前に healthy と判定されます。

.dockerignore と README.Docker.md

生成された .dockerignore では、**/node_modules、**/.env、**/.git、**/Dockerfile*、**/compose.y*ml など、不要になりやすいファイルが除外されています。このチュートリアルで先ほど手書きしたものよりも網羅的なので、そのまま使えます。

README.Docker.md には、docker compose up --build で起動する方法と、異なる CPU アーキテクチャ向けにビルドする際の注意事項が簡潔な英語で書かれています(マルチプラットフォームイメージを参照)。

起動

表示される指示に従って docker compose up --build を実行します。ここではバックグラウンドで実行するために -d を追加し、結果を確認します。

$ docker compose up -d --build

[+] Building 15.1s (13/13) FINISHED
 => [internal] load local bake definitions                                                                                                       0.0s
 => => reading from stdin 486B                                                                                                                   0.0s
 => [internal] load build definition from Dockerfile                                                                                             0.0s
 => => transferring dockerfile: 1.20kB                                                                                                           0.0s
 => resolve image config for docker-image://docker.io/docker/dockerfile:1                                                                        1.1s
 => docker-image://docker.io/docker/dockerfile:1@sha256:4edf897a3ffa55b89f906fc8cc78afdb3f1834cc9c7083565e611a8a7d5fe99e                         3.9s
 => => resolve docker.io/docker/dockerfile:1@sha256:4edf897a3ffa55b89f906fc8cc78afdb3f1834cc9c7083565e611a8a7d5fe99e                             0.0s
 => => sha256:9d2b4f57f9e20f33279375ce25c6ff14f30f64270ed5c7b613b2b30256754f62 14.28MB / 14.28MB                                                 3.5s
 => => extracting sha256:9d2b4f57f9e20f33279375ce25c6ff14f30f64270ed5c7b613b2b30256754f62                                                        0.4s
 => [internal] load metadata for docker.io/library/node:24-alpine                                                                                0.9s
 => [internal] load .dockerignore                                                                                                                0.0s
 => => transferring context: 663B                                                                                                                0.0s
 => [stage-0 1/4] FROM docker.io/library/node:24-alpine@sha256:ebfe2f90462722a7a4de65e91990e97fe0d401c70e0e762c5b53302f905ec1c1                  3.2s
 => => resolve docker.io/library/node:24-alpine@sha256:ebfe2f90462722a7a4de65e91990e97fe0d401c70e0e762c5b53302f905ec1c1                          0.0s
 => => extracting sha256:e2de96513ba9eb53b431787ec8a65cdde380ac4772a3e4c4b714dcfde2a102b5                                                        0.2s
 => => sha256:02f40d53b06f6b91fec0cd6a6719656da99270bff8ee54ed8dcdf4c157763fc1 1.26MB / 1.26MB                                                   0.8s
 => => sha256:7ce7dcbafb7f750cf0c6be3c30e34372b06dd1182fa67f6ae30782c8150c5444 444B / 444B                                                       0.2s
 => => sha256:3c504d5a797be28f9de43147d49cd8ecb2eea46dfaf7beb8715db695d5f0a7f0 56.52MB / 56.52MB                                                 1.1s
 => => extracting sha256:3c504d5a797be28f9de43147d49cd8ecb2eea46dfaf7beb8715db695d5f0a7f0                                                        1.9s
 => => extracting sha256:02f40d53b06f6b91fec0cd6a6719656da99270bff8ee54ed8dcdf4c157763fc1                                                        0.1s
 => => extracting sha256:7ce7dcbafb7f750cf0c6be3c30e34372b06dd1182fa67f6ae30782c8150c5444                                                        0.0s
 => [internal] load build context                                                                                                                0.0s
 => => transferring context: 31.23kB                                                                                                             0.0s
 => [stage-0 2/4] WORKDIR /usr/src/app                                                                                                           0.1s
 => [stage-0 3/4] RUN --mount=type=bind,source=package.json,target=package.json     --mount=type=bind,source=package-lock.json,target=package-l  2.6s
 => [stage-0 4/4] COPY . .                                                                                                                       0.0s
 => exporting to image                                                                                                                           2.7s
 => => exporting layers                                                                                                                          0.3s
 => => exporting manifest sha256:1278071dc9c5842ea834d9abc8c01262b999118ef6903ed4998b8cc8ccc5aaba                                                0.0s
 => => exporting config sha256:879a23594d9f079707b7b35c022fb427cebaaa18db9701eb78b1fbaf82efed06                                                  0.0s
 => => exporting attestation manifest sha256:012342031ad01079856bb6ebf257f096c2d8f9ff12d448ed86a58a645d64bb5d                                    0.0s
 => => exporting manifest list sha256:19aee69cf5d970c251d176f2f533bb918f9e72edf675b109b569ae2ff25cb4f3                                           0.0s
 => => naming to docker.io/library/init-demo-server:latest                                                                                       0.0s
 => => unpacking to docker.io/library/init-demo-server:latest                                                                                    2.3s
 => resolving provenance for metadata file                                                                                                       0.0s
[+] up 3/3
 ✔ Image init-demo-server       Built                                                                                                            15.2s
 ✔ Network init-demo_default    Created                                                                                                           0.0s
 ✔ Container init-demo-server-1 Started                                                                                                           0.4s

$ curl -s http://localhost:3000
{"message":"Hello from Express","node":"v24.21.0"}

$ docker compose exec server ps
PID   USER     TIME  COMMAND
    1 node      0:00 npm start
   18 node      0:00 {MainThread} node server.js
   25 node      0:00 ps

$ time docker compose stop
 Container init-demo-server-1 Stopping
 Container init-demo-server-1 Stopped
real	0m 0.21s
user	0m 0.04s
sys	0m 0.02s

$ docker compose logs server
server-1  |
server-1  | > express-app@1.0.0 start
server-1  | > node server.js
server-1  |
server-1  | Listening on port 3000
server-1  | SIGTERM received, closing server
server-1  | npm notice
server-1  | npm notice New major version of npm available! 11.19.0 -> 12.2.0
server-1  | npm notice Changelog: https://github.com/npm/cli/releases/tag/v12.2.0
server-1  | npm notice To update run: npm install -g npm@12.2.0
server-1  | npm notice
  • ビルドの最初の手順では docker/dockerfile:1 をダウンロードします。これは # syntax= の行の効果です。
  • サービス名は server で、Webサイトは正常に応答しています。
  • ps の表示では、PID 1 は npm start で、node はその子プロセスです。docker compose stop は 0.21 秒で完了しており、npm は停止シグナルを node に転送しています。

docker init を使うタイミング

  • 新しいプロジェクトで、Dockerfile に慣れていない場合:これを使って出発点を作成し、このチュートリアルを見ながら一行ずつ理解して修正します。
  • すでに Dockerfile があるプロジェクトの場合:別のフォルダーで生成し、その書き方(キャッシュマウントなど)を参考にできます。
  • できないこと:データベースのマイグレーション、環境変数、HTTPS、マルチステージビルドの詳細には対応しません。生成されるファイルはあくまで出発点です。

まとめ

  • docker init はプロジェクトの言語を検出し、いくつか質問した後、Dockerfile、compose.yaml、.dockerignore、README.Docker.md を生成します。
  • Node のバージョンとポートにはデフォルト値がないため、入力が必要です。
  • 生成される Dockerfile は BuildKit の bind マウントと cache マウントを使っています。よい書き方ですが、古い構文に関する警告は残ります。
  • docker build --check を使って、任意の Dockerfile をチェックできます。
  • テンプレート内でコメントアウトされている PostgreSQL の例は、postgres:18 で使うには修正が必要です。

練習問題

練習 1:自分で書いた Dockerfile(例:Dockerfile 入門 のサンプル)に対して docker build --check . を実行し、警告があるか確認します。

ヒント

問題がなければ Check complete, no warnings found. と表示されます。最もよくある警告は JSONArgsRecommended(CMD、ENTRYPOINT にシェル形式を使っている)と LegacyKeyValueFormat(ENV で = を使っていない)です。

練習 2:生成された Dockerfile を変更せずに、Node のバージョンを 22 に変更します。

解答

NODE_VERSION は ARG なので、ビルド時に渡します。

docker build --build-arg NODE_VERSION=22 -t init-demo:node22 .

Compose では build.args に記述します。

services:
  server:
    build:
      context: .
      args:
        NODE_VERSION: "22"

練習 3:この章の説明に従って ENV と CMD の2行を修正し、もう一度 docker build --check . を実行して、警告が消えたことを確認します。

よくある質問

Linux の Docker Engine で docker init を使えますか?

docker init は Docker Desktop に組み込まれた CLI プラグインです(Windows、macOS、Linux 版の Docker Desktop に含まれます)。Docker Engine だけをインストールした Linux ホストには通常このコマンドがなく、実行すると docker: unknown command: docker init と表示されます。

Dockerfile がすでにあるプロジェクトで docker init を実行できますか?

できますが、既存ファイルを上書きするか確認されます。先に Git にコミットするか、別のフォルダーで試し、生成された内容を比較してから採用するか決めることをおすすめします。

docker init はどの言語に対応していますか?

v1.4.0 のメニューには、Node、Go、Python、Rust、ASP.NET Core、PHP with Apache、Java、および汎用の Other があります。package.json などのプロジェクト内のファイルを検出し、デフォルト値を自動選択します。

生成されたファイルをそのまま本番環境で使えますか?

出発点として使えますが、自分で確認する必要があります。たとえば、この章で確認したテンプレートでは古い ENV key value 形式と shell 形式の CMD が使われており、docker build --check で警告が出ます。また、テンプレート内でコメントアウトされている PostgreSQL の例は postgres:18 には適用できません。

更新日 2026年10月13日