【Docker】Package.jsonとは何か?必須項目やDocker起動時に何が行われるか?

docker-prograshi(プロぐらし)-kv Docker
記事内に広告が含まれていることがあります。

Dockerを使ってNode.jsアプリを動かしている場合「package.json」というファイルを目にしているはずです。

この「package.json って結局なんなの?」そう疑問に思ったことはありませんか?

ただのファイルだと思って軽視していると、Docker環境でのデプロイや予期せぬエラーの原因を見逃してしまいます。

本記事では、Node.jsプロジェクトの「心臓部」とも言える package.json が、そもそも何のためにあり、どんな内容を記載する必要があるのかを解説しています。

さらに、Docker起動時に、このファイルが裏側でどのように機能し、あなたのアプリケーションを動かしているのかもわかりやすく解説しています。



Package.jsonとは何か?

package.jsonファイルは、Node.jsというJavaScriptの実行環境を使うプロジェクトでほぼ必ず必要となるファイルで「プロジェクトの設計書」となります。

Dockerはアプリケーションを動かすための「コンテナ」という隔離された環境を作る技術ですが、そのコンテナ内でNode.jsアプリケーションを動かす際に必要です

より具体的には、コンテナを起動するための大本となる(Docker)イメージを作成する際に使います。

MEMO

パッケージの管理ツールである、npmやyarnが依存パッケージのインストールやスクリプトの実行をする際にpackage.jsonを参照します。

このため、Node.jsを使っているツール「Vue」「React」「Angular」「Webpack」「Express」などもpackage.jsonを使っています。


Package.jsonに記述する主な内容

記述する内容

Dockerにおけるpackage.jsonには、以下の重要な情報をJSON形式で記述します。

  1. メタデータ(プロジェクトの情報)
    • プロジェクトの名前 (name)
    • バージョン (version)
    • 説明 (description)
    • 作者 (author) など。
  2. 依存関係 (Dependencies)
    • 外部からインストールする必要があるパッケージ(ライブラリ)の名前とバージョン。
    • 開発時のみ必要なパッケージ (devDependencies) と、アプリケーションの実行に必須なパッケージ (dependencies) で分けて記述。
  3. スクリプト
    • アプリケーションの実行 (start) やテスト (test) など、よく使うコマンドを短縮して実行するための定義。


package.jsonの例

例えば、Docker内にNode.js環境を構築する場合は以下のように記述します。

{
  "name": "docker-node-app",
  "version": "1.0.0",
  "description": "Sample Node.js App",
  "dependencies": {
    "express": "^4.17.1",
    "lodash": "^4.17.21"
  },
  "scripts": {
    "start": "node server.js",
  }
}


「docker-node-app」という名前で、バージョンは1.0.0です。

依存関係で「express」と「lodash」をインストールしています。

scriptsプロパティので"start": "node server.js"を指定しています。これは、Dockerfileで「start」というコマンドを実行すると、Node.jsで「node server.js」コマンドを実行するという指示です。

MEMO
  • expressとは何か?
    Webサーバーとしての基本的な機能や構造を簡単に作成するためのパッケージです。
  • lodashとは何か?
    JavaScriptでのプログラミングを効率的かつ簡単にするためのユーティリティ関数(便利機能)の集まりです。


必須の内容(Dockerの場合)

package.jsonを記述する上で絶対に必須になるのは「name」と「version」の2種類です。

ですが、これはnpmに自分が作ったコードをライブラリとして公開するために必須なもので、Dockerでのイメージ作成時には「dependency」と「script」も必須になります。

キー用途補足
nameプロジェクトの名前必須(パッケージを公開しない場合も)。
小文字、ハイフン区切り推奨。
versionプロジェクトのバージョン必須。
1.0.0 のような形式。
dependenciesアプリケーションの実行に必要なパッケージを記述例えば、Webフレームワーク (Express, Reactなど) やデータベース接続ライブラリ。
scriptsよく使うコマンドの定義
アプリの起動コマンドを指定
Dockerfileで指定したキーと実際に実行するコマンドを記載。


省略可能な項目

ライブラリとして外部に公開しないアプリケーション(Webサービスなど)をDockerで動かす場合に、省略しても問題ないことが多い項目は以下です。

キー用途補足
descriptionプロジェクトの説明Dockerで動かすためだけなら不要。
mainエントリーポイント(メインファイル)ライブラリとして使用される場合のファイル。通常のアプリならscriptsstartで指定するので不要。
author, license作者情報、ライセンスライブラリ公開時には重要。内部アプリなら省略可。
devDependencies開発テストにのみ必要なパッケージDockerの最終的な本番用イメージを作る場合、これらのパッケージは不要なため、npm install時にインストールしない設定(npm install --production)にすることが多い。
repository, keywordsリポジトリ情報、検索用キーワード公開目的でなければ不要。


Dockerで行う処理

Dockerとpackage.jsonの関係

Dockerイメージの作り方を書いたファイルである「Dockerfile」の中に以下を記述します。

Dockerfile内のpackage.jsonに関する内容
  1. package.jsonをコンテナ内にコピーする
  2. npm install(またはyarn install)を実行する
  3. 指定したコマンドを実行する

これにより、package.jsonに書かれているすべての必要なパッケージが、イメージ内に自動でインストールできます

    そして、package.jsonに書かれたコマンドを実行します


    Dockerfileの例

    例えば、DockerでNode.jsの環境のコンテナのためのイメージを作成する場合、Dockerfileに以下のように記載します。

    # 1. ベースイメージの指定
    FROM node:20-alpine
    
    # 2. 作業ディレクトリの設定
    WORKDIR /usr/src/app
    
    # 3. 依存関係ファイルのコピー
    COPY package.json ./
    
    # 4. 依存関係のインストール
    RUN npm install
    
    # 5. アプリケーションコードのコピー
    # Dockerfileと同じディレクトリにある全てのファイルを、WORKDIRにコピー
    COPY . .
    
    # 6. アプリケーションが使用するポートの公開
    EXPOSE 3000
    
    # 7. コンテナ起動時に実行するコマンド
    CMD [ "npm", "start" ]

    このうち、#3 COPY package.json ./ がルートディレクトリにあるpackage.jsonをイメージ内にコピーする記述になります。

    そして、#4でRUN npm installを実行し、pakcage.jsonで指定されたパッケージをイメージ内にインストールする記述になります。

    #7は、作成したイメージからコンテナを起動するためのコマンドの指定です。package.jsonに記述していあるscritpプロパティの中のstartプロパティの値を実行します。


    コンテナ起動コマンドをもっと詳しく|CMD [ “npm”, “start” ]

    Dockerfileの最後に、CMD [ "npm", "start" ]があります。

    これは、Dockerコンテナが起動したときにデフォルトで実行するコマンドを指定する、Dockerfileの命令です。

    コンテナが起動される(= docker runが実行される)と、CMD [ “npm”, “start” ]すなわち、npm run startを実行します。

    これにより、npmはコンテナ内のシステムファイルにあるpackage.jsonを読み込みその中の、scriptsセクションを参照し、その中のstartの値をコマンドとして実行します。

    以下のように書かれている場合、node server.jsを実行するわけです。

    {
      ・・・
      scipts": {
        "start": "node server.js",
      }
    }

    タイトルとURLをコピーしました