Docker設定ファイルの記載について #1（初心者）

今回はDockerの設定ファイルの記載に関しての説明をまとめていこうと思います。
# 1. Dockerとは？
Docker はコンテナ化技術の一つで、アプリケーションを軽量なコンテナにパッケージ化して、環境の違いに影響されず、実行できるようにします。これにより、開発・テスト・本番環境の統一が容易になり、スケーラブル*¹で保守しやすいシステムの構築が可能になります。

::: note info
**※1 スケーラブル（scalable）**
システムやアプリケーションが負荷の増加に対して適切に対応できる性質のことを指す。つまり、利用者が増えたりデータが増大したりしても、性能を維持しつつ拡張できるということ。
:::


ということらしい。

では、コンテナ化とは何なのか？

### コンテナ化
コンテナ化とは、アプリケーションやその依存関係をパッケージ化し、軽量な仮想環境で実行できるようにする技術です。これにより、異なる環境間での一貫した動作を保証し、開発・運用の効率を向上させることができます。
#### コンテナ化の主な特徴
##### 1. 軽量性
コンテナ化は仮想マシンよりもオーバーヘッド*²が少なく、迅速に起動停止できる。

::: note info
**※2 オーバヘッド**
実際の処理に直接貢献しないが、システムの動作のために必要な追加の計算やリソース消費を指す。簡単に言うと、「余分な負担」のようなもの。
:::

##### 2. ポータビリティ*³
どの環境でも同じ設定で動作するため、「開発環境では動くのに本番環境では動かない」といった問題を減らせます。

::: note info
**※3 ポータビリティ（portability）**
あるシステムやソフトウェアが異なる環境やプラットフォームでも容易に動作できる能力のこと。
:::

##### 3. スケーラビリティ
必要に応じてコンテナの数を増減でき、リーソースの最適化が可能です。
##### 4. 分離性
各コンテナは独立しているため、異なるアプリケーションを安全に運用できます。

以上のような特徴があります。

# 2. 必要なDocker関連ファイル
ここからは実例を交えて説明していきます。
現在投稿している以下の記事、#1~#3時点での記載を例にします。

https://qiita.com/syakesoba/items/73e90c14451104fb809a

### 1. Dockerfile
Dockerfileとは、環境をコンテナ化するための設定ファイルです。
今回例に挙げるシステムではバックエンド、フロントエンドのそれぞれにDockerfileを作成しています。

まずはバックエンドから見ていきましょう。
#### 1.backend
```Dockerfile:Dockerfile
FROM openjdk:21-jdk-slim
WORKDIR /app
COPY app/build/libs/*.jar app.jar
ENV SPRING_DATA_MONGODB_URI=mongodb://mongo:27017/taskDB
CMD ["java", "-jar", "app.jar"]
EXPOSE 8080
```
以上の記述を1行ずつ見ていきましょう。

**・FROM openjdk:21-jdk-slim**
これは Java 21 の JDK（開発キット）をベースイメージ*⁴として使用しています。slimバージョンを選んでいるので、不要なパッケージが省略されており、軽量なコンテナが作成されます。

::: note info
**※4 ベースイメージ**
コンテナの基盤となるOSやランタイム環境を提供するイメージのこと。
:::

**・WORKDIR/app**
このコマンドで作業ディレクトリを/appに設定します。以降の命令（ファイルコピーや実行）がこのディレクトリ内で行われるようになります。

**・COPY app/build/libs/*.jar app.jar**
app/build/libs/にある.jarファイルをコンテナ内のapp.jarという名前で/appにコピーします。
これは通常、Gradleを使ってSpring Bootアプリのビルドを行った際に.jarが生成されるパスです。

**・ENV SPRING_DATA_MONGODB_URI=mongodb://mongo:27017/taskDB**
環境変数SPRING_DATA_MONGODB_URIを設定し、Spring BootのMongoDB接続設定を行います。この場合、ホスト名mongoのコンテナにあるtaskDBデータベースへ接続するようになっています。
 mongoというホスト名は、通常Docker ComposeでMongoDBコンテナを定義する際に名前を指定することで解決されます。

 **・CMD ["java", "-jar", "app.jar"]**
コンテナ起動時に、Spring Bootアプリを実行するためのコマンドです。
java -jar app.jarを実行することで、Spring BootアプリがMongoDBと接続しつつ起動します。

**・EXPOSE 8080**
ポート8080を開放することで、コンテナの外部（ホストマシン）からSpring Bootアプリにアクセスできるようになります。
ただし、これだけではホスト側に公開されないため、Docker Composeのports設定やdocker run -pオプション を使って明示的に公開する必要があります。

次にフロントエンドを見ていきましょう。
#### 2.frontend
```Dockerfile:Dockerfile
FROM node:18-alpine
WORKDIR /usr/src/app
COPY package.json ./ package-lock.json ./
RUN npm install
COPY . .
CMD ["npm", "start"]
EXPOSE 3000
```

**・FROM node:18-alpine**
Node.js18をベースイメージ に指定しています。alpineバージョンを選ぶことで、通常のnodeイメージよりも軽量になります。

**・WORKDIR /usr/src/app**
作業ディレクトリを/usr/src/appに設定します。以降のCOPYやRUNの処理はこのディレクトリ内で行われるため、コンテナの構造が明確になります。

**・COPY package.json ./ package-lock.json ./**
package.jsonとpackage-lock.jsonをコンテナ内にコピーします。

- package.json：Node.jsの依存関係の管理を行う設定ファイル。
- package-lock.json：正確なバージョンの依存関係を保証するために重要。

このステップでは、まずpackage.jsonとpackage-lock.jsonのみをコピーすることで、npm installのキャッシュを有効に活用できます。
これにより、package.jsonに変更がない場合はnpm installのステップがキャッシュされ、ビルド時間が短縮されます。

**・RUN npm install**
npm installを実行して、必要な依存関係をインストールします。

**・COPY . .**
現在のディレクトリの すべてのファイル をコンテナ内にコピーします。
これにより、アプリケーションのコードがコンテナ内で利用可能になります。

**・CMD ["npm", "start"]**
コンテナが起動した際に、npm startを実行します。

**・EXPOSE 3000**
コンテナ内のポート3000を公開します。
しかし、これだけではホスト側と接続できないため、docker run -p 3000:3000やDocker Composeの ports設定を行う必要があります。

### 2. docker-compose.yml
docker-compose.ymlとは各環境を一括管理するための設定ファイルです。
今回のプロジェクトでは以下のように記述して。。

続きを書いていこうと思いましたが、疲れたので今回はここまで。
一気に書きすぎても頭に入らないですしね。

では、またDocker設定ファイルの記載について #2（初心者）でお会いしましょう。

https://qiita.com/syakesoba/items/85fd694b2f6136835e83