Docker（Dockerfile、docker-compose.yml）とKubernetesの違いを簡単にまとめてみた

# はじめに
プロジェクトでよく使っているDocker。
コマンド1つで開発環境を構築できる便利ツールくらいの認識でしたが、もう少しステップアップしたいと思い、その学びの備忘を残します。

中でも本記事では、以下の内容にフォーカスして整理したいと思います。
- Docker
  - Dockerfile
  - docker-compose.yml
- Kubernetes （クーベネティス）




# 結論
DockerとKubernetesは別ツール。

Dockerはコンテナを **個別** に作って実行するソフトウェア。
Kubernetesは **複数コンテナ** をまとめて自動で管理・運用するソフトウェア。

Dockerfileとdocker-compose.ymlはどちらもDockerで使用するファイル。
Dockerfileは **1つのアプリ** を定義しているファイルで、コンテナを作る際の **設計書** になる。
docker-compose.ymlは **複数コンテナ** をまとめて操作することができる管理ファイル。

# Docker vs Kubernetes
まずは大枠として、よく混ざってしまうDockerとKubernetesの違いを簡単に見てみます。
結論にもある通り、DockerとKubernetesは別ツールです！

Dockerは **コンテナを個別に作って実行するソフトウェア** です。
Dockerfileという設計書や、公式で公開されているイメージ（[docker hub](https://hub.docker.com/search?q=&type=image&image_filter=official "docker hub")）を使ってコンテナを立ち上げることができます。

それに対してKubernetesは、 **複数コンテナをまとめて自動で管理・運用するソフトウェア** です。
コンテナをまとめて管理する仕組み（オーケストレーションって言うらしい）を実現していて、実際に使うにはKubernetesとCNI（仮想ネットワークのドライバ）をインストールする必要があるとのことです。
CNIの代表的なものはflannel,Calico,AWS VPC CNIなどがあるみたいですが、ここでは深堀りしないです。

次はDockerとKubernetesの依存関係を見ていきたいのですが、先にDockerのコンテナ操作の流れを知っておかないと厳しそうなので先に整理したいと思います。




## Dockerでコンテナを作って完全に削除するまでの流れ
### 1. Dockerfileからイメージを作る（ビルドする）
```
docker build -t myapp .

-t　：イメージに名前（タグ）を付ける
.　 ：カレントディレクトリにあるDockerfileを使う
```

### 2\. イメージからコンテナを生成・起動する
以下コマンドでは手順1で作成したイメージを用いているが、公式で公開されているイメージ（[docker hub](https://hub.docker.com/search?q=&type=image&image_filter=official "docker hub")）を使うのであれば、手順1は不要。
```
docker run -d --name mycontainer -p 3000:3000 myapp

-d：バックグラウンドで起動する。
--name mycontainer：コンテナに名前を付ける
-p：ポートを指定
myapp：使うイメージ名
```

### 3\. コンテナを停止する
```
docker stop mycontainer
```

### 4\. 停止中のコンテナを削除する
コンテナ本体を削除します。
ただ、イメージは残ります。
```
docker rm mycontainer
```

### 5\. イメージを削除する
myapp という名前のイメージを削除します。
```
docker rmi myapp
```




## DockerとKubernetesの依存関係
それでは依存関係を見ていきたいと思います。
結論としては **直接的な依存関係はなく** 、「dockerがないとkubernetesが使えない」みたいなことはないです！
ただし、実際の現場では併用することがよくあります。

Kubernetesはコンテナをまとめて管理するソフトウェアとお伝えしましたが、イメージを使ってコンテナを生成しています。
使いたいイメージがdocker hubとかで存在するならKubernetesだけでもいいのですが、実際にはそのプロジェクト独自の設定をしていたりしますよね？
そのため、DockerでDockerfileをビルドしてイメージを生成、生成したイメージを使ってKubernetesで管理していくという流れが主流みたいです。

改めて整理すると
- Dockerは「コンテナを1つずつ管理するソフトウェア。イメージを作ることもできる。」
- Kubernetesは「コンテナをまとめて管理するソフトウェア。イメージは用意しておいてね。」

という理解が一番しっくりきますね。 

また、開発時にはDocker、本番環境などはKubernetesで管理というのも一般的です。
これは、開発中は手軽に動かせるDockerで確認しつつ、運用時にはより堅牢で自動化されたKubernetesを使って、大量のコンテナを安定して動かすためです。




# Dockerfile vs docker-compose.yml
今までの説明でDockerfileがよく出てきましたが、改めて以下にまとめます。
よく一緒に使われるdocker-compose.ymlも比較することで理解を深めたいと思います。

Dockerfileは **1つのコンテナイメージを作る設計書** のこと。
docker-compose.ymlは **複数のコンテナをまとめて起動・管理** する定義ファイル

自作アプリとかで独自の名前や設定を付けたいときってありますよね。
そんな時はDockerfileに定義してビルドすることで、独自の設定を持ったイメージを生成することができます。
ここで注意したいのは、Dockerfileには原則1つのアプリの定義しか記載しないという点です。
Dockerfile内に複数アプリの情報を記載することも可能ですが、公式は推奨していないです。
その理由は、**1コンテナ1プロセス** という概念があり、それぞれのアプリを独立させることでどれか1つのコンテナが動かなくなってしまったときでも、他のコンテナに影響を与えないというメリットがあります。

そうなると、複数コンテナを立てたいときに複数回コマンドを実行することになり、ちょっとめんどくさいですよね。。。
そんな時に使うのがdocker-composeです！
これは関連するコンテナを一度にまとめて起動したり削除したりできます。

docker-composeでコンテナを立ち上げる際は、Dockerfileを指定したり、docker hubで提供されているイメージを使うことができます。
そのため、docker hubのイメージだけ使う場合は、Dockerfileを用意しなくても大丈夫です。

## Dockerfileの書き方
Dockerfileの例をNode.jsを用いて書いてみたいと思います。
必ず使うコマンドは「FROM」でそれ以外は必要なものを書いていきます。

```
# 1. ベースイメージを指定（Node.js公式）
FROM node:18

# 2. 作業ディレクトリを作成・設定
WORKDIR /app

# 3. 依存ファイル（package.jsonなど）をコピー
COPY package*.json ./

# 4. 依存パッケージをインストール
RUN npm install

# 5. アプリのソースコードをコピー
COPY . .

# 6. 必要ならビルド（例: TypeScriptやReactなど）
# RUN npm run build

# 7. 公開ポートの指定（ホストとの通信のため）
EXPOSE 3000

# 8. アプリを起動するコマンドを定義
CMD ["npm", "start"]
```




## docker-compose.ymlの書き方
上記で書いたDockerfileとdocker hubで提供されているpostgresDBのイメージを使って書きました。

```
version: "3.9"  # 推奨される最新の安定バージョン（Docker Engine 20.10以降）

services:
  app:
    build: ./app        # ./app/Dockerfile を使ってビルド
    ports:
      - "3000:3000"     # ホスト:コンテナ のポート指定
    depends_on:
      - db
    environment:
      - NODE_ENV=development

  db:
    image: postgres:15  # Docker Hubの公式PostgreSQLイメージを使用
    environment:
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=secret
      - POSTGRES_DB=mydb
    volumes:
      - db-data:/var/lib/postgresql/data
    ports:
      - "5432:5432"

volumes:
  db-data:
```




# 最後に
参考書などでは「Dockerはサーバーエンジニア等が用意するから、アプリ開発者はそこまで気にしなくていい」と書いてあることもありますが、エンジニアとしては多少なりとも気になりますよね。
本記事は初歩的な内容ではありますが、皆さんの助けになっていれば幸いです。




# おまけ
よく使うコマンドを以下にまとめます。


```
■■■■■■■■■ Docker ■■■■■■■■■

# 実行中のコンテナを一覧表示
docker ps

# 全コンテナ（停止中のコンテナも含む）を一覧表示
docker ps -a

# イメージ一覧を表示
docker images

# ボリューム一覧を表示
docker volume ls

■■■■■■■■■ docker-compose ■■■■■■■■■

# 初回起動（ビルド含む）
docker-compose up --build

# 一時停止 → 再開
docker-compose stop
docker-compose start

# コンテナ削除（ボリューム残す）
docker-compose down

# コンテナ・ボリューム完全削除（初期化）
docker-compose down -v

# サービスの中に入る
docker-compose exec app bash

# 全ログ表示
docker-compose logs

# リアルタイムログ
docker-compose logs -f

```