Dockerで学ぶコンテナ技術

# Dockerで学ぶコンテナ技術
1.Dockerって？
2.利用するメリット
3.ローカルにDockerを導入してみよう
4.最後に

## 1.Dockerって？
アプリケーションなどをひとまとめに出来る領域を作って、状態を管理してくれるオープン（公開されている）プラットフォーム（アプリケーションを動かす基盤技術）になります。
ちなみに、このDoker上で作ってくれる領域をコンテナと呼んでいて、このコンテナ上でリソースを管理してくるようになります。


[イメージ図_1]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480753/5338664d-06c0-a6e8-52e9-e9bf1c5d5f33.png)
[イメージ図_2]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480753/1b0f9b09-2177-d958-332e-7c30d3680fda.png)


## 2.利用するメリット
### １.互換性を意識して躓(つまづ)くことがなくなる
別のソフトを入れようとした際にすでに入っているソフトのバージョンの互換性が邪魔をしてうまくインストールやアップデートができない、または起動しないなんてことが実は結構あったりします。
そんな時に、コンテナの中に必要なものだけを閉じ込めておくと関係ないアプリケーションの影響を切り離すことができます。

### 2.管理が簡単になる
設定ファイルをもとに起動した際にコンテナを動かしてくれるので、同じ設定でほかのコンテナやほかの方に提供できます。
そのため、プロジェクトで開発バージョンやインストールするフレームワークなどを一つ設定ファイルにまとめて管理しておけば、開発環境や商用環境などの別環境での立ち上げが楽になります。
また、作った環境と同じ環境を他者に提供する際も、設定ファイルがあれば同じ環境を提供することができます。

### 3.開発面での理解、応用につながる
今やサーバ側技術者と言えど、インフラ技術を含めて求められることも増えてきており、インフラ技術の一端であるコンテナについても同様に様々なところで利用されております。
背景としては、クラウド技術の発達が大きいかと思いますが、サーバやコンテナ管理を含めたインフラアーキテクチャの理解ができることはエンジニアの視野を広げてくれる上に、プロジェクトに貢献できる機会も与えてくれるはずです。
例えば、障害が発生した時に、アプリ起因のものなのかインフラ起因のものなのか、インフラの場合DBが悪いのか、ロードバランサーが悪いか、コンテナが立ち上がっているのかなど切り分けをしていく必要があります。
そういった際に一つでも多くの知識を持っていると自分を助けてくれたり、技術的にチームやプロジェクトを助ける（貢献する）ことに繋がるため自身の価値を高めるうえで重要だと思います。

## 3.ローカルにDockerを導入してみよう
### 3-1.ダウンロード/インストール
https://www.docker.com/products/docker-desktop/

この画面までいけばインストール完了になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480753/95e0e76b-d7ec-2014-de90-e5351fb9fd0d.png)


起動後にこのエラー表示が出た場合は以下の手順が必要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480753/d21a89bc-f03a-d476-8d3f-a35667b13e1a.png)

[仮想化の有効化 手順]
1.power shellにて以下のコマンドを実行する。(windowsの仮想化を有効化する)
```shell:WindowsPowerShell
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
```
※hyper-vと仮想化を有効化するためにはwindowsの場合、windows proというビジネス版を購入して設定をカスタマイズできる必要があるようです。。

2.BIOSの仮想化設定を有効にする。
こちらはメーカーによって起動方法が異なる為別途確認する必要がありますが、
ウィンドウズキー+ i で設定を開き、「更新とセキュリティ」→「回復」→「PCの起動をカスタマイズする」からでも起動可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480753/939966c1-08fb-2f94-306b-f04ccb8acea7.png)


赤枠に有効と記載されていれば有効になってます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480753/6665303b-bd31-1690-b45e-473af45c5b9f.png)




### 3-2.設定
DockerのベースイメージはJava17としてます。
EXPOSEは外から受け付けるポート番号の設定で、例えば8080としておくと、ポート番号8080のリクエストが来たときに受け付けてくれるようになります。
ADDにて対象ディレクトリ配下にあるビルド資源を追加しておき、起動時にEXPOSEにて対象のjarを実行するというような設定になってます。
```Java:Dockerファイル
FROM openjdk:17-jdk-alpine

EXPOSE 8080

ADD ./build/libs/*.jar app.jar

ENTRYPOINT ["java","-jar","/app.jar"]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480753/0682fcba-ac73-1fdc-364b-d2a8885a512d.png)

### 3-3.動作確認するソースの作成/ビルド

#### 3-3-1.新規でspringスタータープロジェクトを作成する。
簡単かつメジャーなので今回はEclipceでspringを使用してgradleを使用したプロジェクトを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480753/caef9367-320a-198a-7088-44f049a686f1.png)

#### 3-3-2.sample用のコントローラーを作成する。
今回はリクエストに対して　Helloworldを返すだけのコントローラクラスを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480753/5963ca90-4bca-c9c9-e2ba-5819f0ef936b.png)

Dockerファイルを含めたファイル構成はこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480753/a747d0a5-8cb7-0a40-1f4d-d76e1039875f.png)

#### 3-3-3.gradleコマンドでビルドを実行する。
```:gradlewコマンド
./gradlew build
```

作成したプロジェクトをVsCodeで開き、ターミナルからコマンドを実行すると以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480753/bf9ae410-d0f5-ddd1-058b-3759be898f74.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480753/c5f7f438-883d-4d4c-de74-e7a4c1d12adb.png)

#### 3-3-4.Dockerのビルドを実行する。
Dockerを起動している状態で以下のコマンドを実行するとDockerファイルを読み込みビルドしてくれます。
```Java:Dockerのビルドコマンド
docker build ./ -t docker-build-java
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480753/03838bfb-c92f-6e91-8587-8dd432f21656.png)

### 3-4.動作確認
コンテナ上からサーバを立ち上げてHelloworldを表示させてみよう。

Dockerコマンドでビルドしているimageをもとにコンテナを起動する。
```Java:Dockerの実行コマンド
docker run --rm -p8080:8080 docker-build-java
```

runコマンド：dockerのコンテナ起動コマンド
--rmオプション：コンテナが停止されるとDockerがコンテナを削除してくれるオプション
-pオプション：dockerのポート番号とコンテナのポート番号をマッピングしてくれるオプション。
docker-build-java：ビルドしたDockerimageの名称

[イメージ図]
イメージ的には以下になります。仮に-pの設定を3000(-p3000:8080)にした場合は、ローカルからポート番号3000に対してリクエストを投げれば結果を返してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480753/c15c1198-80ff-05ef-7d49-31611f949bb4.png)

Springがコンテナ上から起動できるとこんな感じに表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480753/1254f1ee-40bc-0ded-acbd-dec6739136eb.png)

「localhost:8080/sample」に対してリクエストを投げると起動しているコンテナ上でリクエストを受取り
中で起動しているspringにてレスポンスのHello Worldを返却してくれる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480753/565b7930-71f2-0944-718c-a8f0101ea4ab.png)


## 4.最後に
つたない説明だったと思いますが、迷える一人でも多くの人に役に立てると嬉しいです。
閲覧いただきありがとうございました…！