0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Docker Storage】バインドマウントでホストマシンのファイルを Node.js コンテナで実行する

Last updated at Posted at 2024-07-21

はじめに

この記事では、Docker のバインドマウント機能を利用して、ホストマシンのファイルを Node.js コンテナで実行する手順について記載します。

以下の記事でも Node.js / TypeScript のコンテナを作成しましたが、このケースでは、ホストマシンのファイルに変更があった場合、都度イメージをビルドする必要があります。

バインドマウントを利用して、ホストマシンのファイルをコンテナで実行できるようにすることで、都度イメージをビルドする必要がなくなります。

開発環境

開発環境は以下の通りです。

  • Windows 11
  • Docker Engine 26.1.1
  • Node.js 20.15.1
  • npm 10.8.2
  • @types/node 20.14.10
  • nodemon 3.1.4
  • ts-node 10.9.2
  • TypeScript 5.5.3

Node.js / TypeScript アプリケーションの作成

package.json を作成します。

npm init -y

TypeScript 及び以下のパッケージをインストールします。

  • ts-node : TypeScript を Node.js で直接実行できるようにする
  • @types/node : Node.js の型定義

npm install typescript ts-node @types/node nodemon --save-dev

TypeScirpt 設定ファイルを作成します。

npx tsc --init

Node.js 20 系を、ES Modules (ECMA Script Modules) で利用する設定に変更します。

tsconfig.json
{
  "compilerOptions": {
    /* Language and Environment */
    "target": "ES2022" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
    "lib": [
      "ES2023"
    ] /* Specify a set of bundled library declaration files that describe the target runtime environment. */,

    /* Modules */
    "module": "node16" /* Specify what module code is generated. */,

    /* Interop Constraints */
    "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
    "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,

    /* Type Checking */
    "strict": true /* Enable all strict type-checking options. */,

    /* Completeness */
    "skipLibCheck": true /* Skip type checking all .d.ts files. */
  }
}

src/index.ts ファイルを作成し、ログを出力するコードを実装します。

src/index.ts
import http from "http";

const HOSTNAME = "0.0.0.0";
const PORT = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader("Content-Type", "text/plain");
  res.end("Hello World");
});

server.listen(PORT, HOSTNAME, () => {
  console.log(`Server running at http://${HOSTNAME}:${PORT}`);
});

package.json でエントリーポイントの変更とアプリケーションを実行するスクリプトの追加を行います。

package.json
{
  ...
  "main": "src/index.ts",
  "scripts": {
    "start": "ts-node src/index.ts",
    ...
  ...
}

ここまでで、一度動作確認します。

npm start

実装通りログが出力されます。

image.png

Dockerfile の作成

Dockerfile を作成し、イメージをビルドします。

FROM node:20-alpine3.19
WORKDIR /app
COPY package*.json ./
RUN npm install
EXPOSE 3000
CMD ["npm", "start"]

今回ソースコードはバインドマウントしたホストマシンのファイルを利用するので、ホストマシンの全ファイルのコピー(COPY . .)は不要です。

作成した Dockerfile からイメージをビルドします。

docker image build --tag node-ts:1.0.0 .

image.png

イメージがビルドできたか確認します。

docker image ls node-ts

image.png

コンテナの起動とバインドマウント

ビルドしたイメージを使ってコンテナを起動します。また、コンテナ起動時にホストマシンのファイルをバインドマウントします。

docker container run                          `
--name node-ts                                `
--rm                                          `
--publish 3000:3000                           `
--mount type=bind,source="$(pwd)",target=/app `
node-ts:1.0.0

実装したログが出力されます。

image.png

Node.js のバージョンを出力するログを追加して再度コンテナを起動します。

src/index.ts
import http from "http";

const HOSTNAME = "0.0.0.0";
const PORT = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader("Content-Type", "text/plain");
  res.end("Hello World");
});

server.listen(PORT, HOSTNAME, () => {
  console.log(`Server running at http://${HOSTNAME}:${PORT}`);
  console.log("node version is:" + process.version); // 追加
});

イメージを再ビルドしなくても Node.js のバージョンも出力されます。

image.png

Docker Compose を利用するとイメージのビルドコマンド実行が不要になります。また、コンテナ起動時のコマンドも docker compose up --build のみで大丈夫です。

compose.yaml
services:
  app:
    ports:
      - "3000:3000"
    volumes:
      - type: bind
        source: ./
        target: /app
    build: .
docker compose up --build

image.png

参考

関連リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?