🙆

Dockerfile → イメージ → コンテナ、3ステップでHello World

に公開

前回でDockerの環境構築が終わった。WSL2、Ubuntu、Docker Desktop——長い道のりだった。

ここからやっとDockerを触れる。Hello Worldを表示するWebアプリ(Node.js + Express)を作って、Dockerfile → イメージ → コンテナの流れを一通りやってみます。

イメージ作成からコンテナ実行まで

全体の流れはこう。

docker_container_creation_flow.png

ディレクトリ構成

最終的にこうなる。

~/myimage
|-- .dockerignore
|-- Dockerfile
|-- node_modules/
|-- package-lock.json
|-- package.json
`-- server.js

最新のNode.jsをインストール

バージョン管理ツール「n」を使って最新版を入れます。

パッケージの更新

sudo apt update
sudo apt upgrade

Node.js と npm のインストール

sudo apt install nodejs npm

nパッケージのインストール

sudo npm -g install n

最新のNode.jsとnpmをインストール

sudo n latest

既存のNode.jsとnpmを削除(競合防止)

sudo apt purge nodejs npm

シェルを再読み込みして反映

exec $SHELL -l

バージョン確認

node -v
# v16.4.1

npm -v
# 7.18.1

Node.jsアプリケーションを作成

作業ディレクトリを作って、プロジェクトを初期化。

mkdir ~/myimage
cd ~/myimage

package.json を作って Express をインストール。

npm init -y && npm i express

server.js にHello Worldを返すアプリを書く。

server.js
const express = require('express');

const PORT = 3000;
const HOST = '0.0.0.0';

const app = express();
app.get('/', (req, res) => {
  res.send('Hello World');
});

app.listen(PORT, HOST);

Dockerfileを作成

Dockerイメージの設計図。ベースイメージ、依存パッケージ、起動コマンドをここに書く。

docker_image_structure_diagram.png

こう書く。

Dockerfile
FROM node:16

WORKDIR /var/www

COPY package*.json ./
RUN npm install

COPY . .

EXPOSE 3000

CMD ["node", "server.js"]

各命令の解説

  • FROM node:16 — ベースイメージ。Node.js 16(npm込み)
  • WORKDIR /var/www — 作業ディレクトリ。なければ自動作成される
  • COPY package.json ./* — 依存関係の定義ファイルをコピー
  • RUN npm install — 依存パッケージをインストール
  • COPY . . — ソースコードを全部コピー
  • EXPOSE 3000 — リッスンポートの宣言(実際の公開には -p オプションが必要)
  • CMD ["node", "server.js"] — コンテナ起動時に実行されるコマンド

.dockerignoreを作成

イメージに含めたくないものは .dockerignore に書く。node_modules を除外しておかないと、ホスト側の依存がイメージに上書きされる。

.dockerignore
node_modules

Dockerイメージを構築

Dockerfileがあるディレクトリでビルド。

docker image build -t myimage .

イメージができたか確認。

docker image ls

コンテナを作成・実行

docker container run -p 8000:3000 -d --rm --name mycontainer myimage

オプションの説明

  • -p 8000:3000:ホストの8000番ポートをコンテナの3000番ポートにマッピング
  • -d:バックグラウンドで実行
  • --rm:終了時に自動削除
  • --name:コンテナ名を指定

起動してるか確認。

docker container ls

動作確認

curlで叩いてみる。

curl localhost:8000
# Hello World

返ってきた。動いてる。

図解で振り返り

  • Dockerfileを作成
  • イメージをビルド
  • コンテナを起動

docker_build_run_relationship.png

  • ポートフォワーディングにより、ホストの8000番ポートからアクセス可能に

docker_port_forwarding_diagram.png

  • curlで確認

docker_http_communication_flow.png

補足: ポートの自動割り当て

-p でホスト側のポートを省略すると、空いてるポートが自動で割り当てられる。

docker container run -p 3000 -d --rm --name mycontainer myimage

確認してみると:

docker container ls
# PORTS: 0.0.0.0:60658->3000/tcp

後片付け

使い終わったコンテナとイメージは消しておく。

docker container stop mycontainer \
  && docker image rm myimage

Dockerfile → イメージ → コンテナ。この流れさえ掴めば、あとは応用。

前回:WindowsでDockerが動くまでの6ステップ

Discussion