Dockerメモ

# Dockerとは

- ホストOS上に複数のコンテナ型の仮想環境を構築できるツール
- コンテナ型は軽量で高速
- 作成した環境は配布可能
- コンテナはLinux環境として動く

PC1では正常に環境構築ができたが、
PC2だとなぜか環境構築がうまくいかないといったことを回避できる。

本番環境(Linux)に近い検証環境を簡単に用意できる。

# Linux

サーバとしてLinuxが使われることが多い

Linuxをサーバとして使うメリット
- オープンソース
- 無料
- 消費リソースが抑えられるため安定している

# コンテナとは

同一マシン上で動作している処理A,Bが別のマシン上で動いているような状態にできる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604560/b11075ac-e5d7-d783-b39c-e9b12ddc3092.png)

# サーバ構築の種類

コンテナ以外でサーバ構築となると下記のやり方がある
1 物理マシンを追加で用意してLinuxをインストールする(お金かかる)
2 仮想マシンを利用する(コンテナに比べてオーバーヘッドが大きい)
3 レンタルサーバなどを利用する(お金かかる)

## コンテナだと

仮想マシンと比べて手間が少なく、複数台のサーバ構築も簡単に用意できる

# コンテナを作るには

コンテナイメージ(コンテナを作成するテンプレート)が必要
イメージ1つから複数コンテナの作成が可能

# イメージ

インターネット上にイメージが集められた場所をレジストリという
公式レジストリとしてDockerHubが提供されている

0からイメージを自作するのは難しいので、
レジストリのイメージを使うかカスタマイズして使う

レジストリからイメージを取得することをプル
レジストリに登録することをプッシュ
イメージを構築することをビルド
という

# ライフサイクル

ライフサイクルとはコンテナの下記状態を指す
- 作成(コンテナを作成した状態)
- 実行(コンテナを動作させた状態)
- 停止(コンテナを停止させた状態、再実行可能)
- 削除(コンテナを削除した状態)

コンテナは作って削除が基本
物理マシンだとインストールに手間がかかるため、
今後使うかもしれないアプリを残しておくかもしれない
コンテナだとインストールが簡単なため現時点で不要なら削除しても
あとですぐにインストールできる

# Dockerを始めるには

DockerはLinux, Windows, Macのどれでも動かせる
Windows, Macの場合はDocker Desktopというソフトをインストールする

※ここから先はWindosでセットアップ
WindowsでのDocker Desktopの使用要件

- SLAT(仮想化支援)機能を備えた64bitプロセッサ
- メモリ4GB以上
- virtualizationが有効
- WSL2が有効 or Hyper-VとContainersが有効

## virtualizationの有効化

既に有効になってたので確認していないが多分下記で有効にできる
https://jp.minitool.com/news/enable-virtualization-windows-10.html

## WSL2の有効化

1. Windowsアイコンの検索から「Windowsの機能の有効化または無効化」を検索し、起動
1. 赤枠の項目にチェックを入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604560/3f31f46d-2912-2b5d-146a-4cac4e87029f.png)
1. 再起動する
1. 下記サイトにWSL2の最新パッケージ取得リンクがあるのでクリックしてDL
https://learn.microsoft.com/ja-jp/windows/wsl/install-manual#step-4---download-the-linux-kernel-update-package
1. DLしたwsl_update_x64.msiを起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604560/d3155a9e-5c2e-aa62-10db-a83f716d1c74.png)
1. 「Next」-「Finish」ボタンを押してインストールを実行し、終了する

## Docker Desktopのインストール

1. 下記サイトにDocker DesktopのDLボタンがあるので押下
https://docs.docker.com/desktop/setup/install/windows-install/
1. DLしたDocker Desktop Installer.exeを起動
1. チェックボックスが出てるのでチェックしてOKボタンを押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604560/72d52e9a-569b-cea7-24e6-1049306357bc.png)
1. インストールが終わるとPCをサインアウトさせられるのでサインインする
1. 下記画面が勝手に表示されるのでAcceptボタンを押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604560/760496fe-aaeb-8ed8-109a-5c59fdb77bbd.png)
1. 理由がなければ上の自動設定を選択して終了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604560/7db6baab-ba76-2984-8550-465dcc4bd656.png)
1. サインイン画面が表示されたらサインイン(サインインなしでもいけるかも)
1. 下記画面が表示されるのでスキップ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604560/16c8710d-5741-e068-9206-28c87e4178cf.png)
1. 下記画面が表示されればセットアップ完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604560/5d64e560-3729-d7b8-dd49-1768b2521fb2.png)

# Docker Desktopの一部機能

- Containers
コンテナの管理ができる

- Images
取得済みのイメージの管理ができる

- Volumes
ボリューム(コンテナデータの保存場所)の管理ができる

# Apacheコンテナの作成

使用するイメージ
https://hub.docker.com/_/httpd

## コンテナを作成・実行

1. 下記コマンドを実行
   ```
   docker container run --name apache01 -p 8080:80 -d httpd
   ```

   コマンドについては下記に記載
   https://qiita.com/_wow_/items/6f324671377315d9a11d
   
1. 下記URLにアクセス
http://localhost:8080/

1. 下記画面が表示されるのを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604560/357d8c3c-4cc2-15eb-586d-2bbb385a5b80.png)

## コンテナの停止

1. 下記コマンドを実行
   ```
   docker container stop apache01
   ```
1. 下記URLにアクセス
http://localhost:8080/
1. サイトが表示されないのを確認

## コンテナの削除

1. 下記コマンドを実行
   ```
   docker container rm apache01
   ```
1. Docker Desktopにコンテナが表示されていないのを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604560/418939b6-cc39-081f-e3c1-d33a06b66b7c.png)

# 複数コンテナの作成

複雑なコマンドになると入力ミスが発生しがち
それを軽減してくれるのがDocker Composeというソフト

## Docker Compose

dockerコマンドの代わりにymlにやりたい事を記述できる
下記はapache01作成時のコマンドをyml化したもの
``` yml: compose.yaml
services:
  web:
    image: httpd
    container_name: apache01
    ports: 
      - "8080:80"
```
※portsは配列として扱われているためハイフンが使われている

## Docker Composeでコンテナ作成

Docker Composeではカレントフォルダがプロジェクト名になる
\apache\compose.yamlとなっていればapacheがプロジェクト名

### コンテナ作成・実行

1. apache\compose.yamlを作成
   ``` yml: compose.yaml
   services:
     web:
       image: httpd:2.4
       ports: 
         - "8080:80"
   ```
   
1. yamlファイルがある場所で下記コマンドを実行し、コンテナを実行
   ```
   docker compose up -d
   ```
    ※ 「compose up」でコンテナの作成・実行
    　 「-d」 でコンテナをバックグラウンド実行する    
   
1. 下記コマンドで実行中のコンテナを確認
   ```
   docker container ls
   ```
   ※　下記コマンドで全コンテナ表示
   ```
   docker container ls -a
   ```
   プロジェクトの表示
   ```
   docker compose ls
   ```

### コンテナ停止

1. yamlファイルがある場所で下記コマンドを実行し、実行中のコンテナを停止
   ```
   docker compose stop
   ```
1. コマンドで実行中がないことを確認

### 既存コンテナの起動

1. yamlファイルがある場所で下記コマンドを実行し、実行中のコンテナを停止
   ```
   docker compose start
   ```
1. コマンドで実行中があることを確認

### ファイルコピー

apacheコンテナからマシンへindex.htmlをコピー
apache\compose.yamlの階層で下記コマンドを実行
```
docker compose cp web:/usr/local/apache2/htdocs/index.html .
```

マシンからapacheコンテナへindex.htmlをコピー
```
docker compose cp index.html web:/usr/local/apache2/htdocs/index.html
```

### コンテナの削除

```
docker compose down
```
「docker compose rm」はコンテナの削除のみ行うが「docker compose down」は紐づくネットワークも併せてコンテナを削除する

イメージを削除
```
docker compose down --rmi all
```

イメージ確認
```
docker image ls
```

# MariaDBコンテナの作成

MariaDB
https://hub.docker.com/_/mariadb

https://hub.docker.com/_/mariadb

## yaml作成

``` yml:mariadb\compose.yaml
services:
  db:
    image: mariadb:10.7
    environment:
      MARIADB_ROOT_PASSWORD: rootpass
      MARIADB_DATABASE: testdb
      MARIADB_USER: testuser
      MARIADB_PASSWORD: testpass
    volumes:
      - db-data:/var/lib/mysql
volumes:
  db-data:
```
「volumes.db-data」はDBのデータの永続化設定

```
docker compose up -d
```

## コンテナ内でコマンド実行

MariaDBのバージョン確認
実行中のコンテナの場合
```
docker compose exec db mariadb --version
```
or
停止中のコンテナの場合
```
docker compose run db mariadb --version
```

コンテナのシェル起動
```
docker compose exec db /bin/bash
```

MariaDBログイン(コンテナのシェルで実行)
```
mariadb -u testuser -D testdb -p
```

# WordPress + MariaDBコンテナの構築

WordPress
https://hub.docker.com/_/wordpress


## yaml作成

``` yaml:wordpress/compose.yaml
services:
  db:
    image: mariadb:10.7
    environment:
      MARIADB_ROOT_PASSWORD: rootpass
      MARIADB_DATABASE: wordpress
      MARIADB_USER: wordpress
      MARIADB_PASSWORD: wordpress
    volumes:
      - db-data:/var/lib/mysql
  wordpress:
    image: wordpress:6.0
    depends_on:
      - db
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
    ports:
      - "8080:80"
    volumes:
      - wordpress-data:/var/www/html
volumes:
  db-data:
  wordpress-data:
```

「depends_on」はコンテナの作成順
「db」と記載しているのでコンテナ作成を実行すると
　MariaDB、Wordpressの順にコンテナが作成される
```
docker compose up -d
```

1コンテナに様々な機能を持たせることは再利用性が低いため推奨されていない
今回の場合だと1コンテナに1機能となっている

# コンテナのデータの保存

コンテナは削除するとコンテナ内のデータは消える
なのでDBに登録したデータなども消える

## ボリューム

公式推奨
Dockerが管理する記憶領域にデータを永続化する仕組み
データの移行やバックアップが容易
Dockerが管理する記憶領域に保存され、データ更新にはコンテナが必要になるので
DBのデータなど直接変更することがないデータ向き

「docker compose down」はデフォルトだとボリュームは消えないので
コンテナを削除しても再度コンテナを作成し、マウントすればデータを再利用できる

## バインドマウント

ホストOSのフォルダやファイルをマウントする仕組み
ホストOSのファイルを変更することでコンテナにも自動反映されるので
変更頻度が高いデータ向け

## yaml作成

``` yaml:wordpress02/compose.yaml
services:
  db:
    image: mariadb:10.7
    environment:
      MARIADB_ROOT_PASSWORD: rootpass
      MARIADB_DATABASE: wordpress
      MARIADB_USER: wordpress
      MARIADB_PASSWORD: wordpress
    volumes:
      - db-data:/var/lib/mysql
  wordpress:
    image: wordpress:6.0
    depends_on:
      - db
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
    ports:
      - "8080:80"
    volumes:
      # - wordpress-data:/var/www/html
      - ./html:/var/www/html
volumes:
  db-data:
  # wordpress-data:
```

```
docker compose up -d
```

実行するとローカルにhtmlフォルダーができる

## ポート

yamlにでてくる「ports」の「8080:80」はホストのポート8080と
コンテナのポート80を紐づけている(ポートフォワーディング)

WordPressは公開ポートが80に指定されている。
使用するイメージの公開ポートはDockerHubに記載されている

# Flaskコンテナ作成

Dockerファイルを作成することでイメージをカスタムできる
これにより下記が可能
1. Pythonをインストール
1. 「pip install flask」実行
1. app.pyをコンテナにコピー
1. 「flask run --host=0.0.0.0」コマンドを実行

python
https://hub.docker.com/_/python

## app.py作成

``` python:flask\app.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_flask():
  return 'Hello Flask'
```

## Dockerfile作成

``` flask\Dockerfile
FROM python:3.10
WORKDIR /usr/src/app
RUN pip install flask==2.3.3
CMD ["flask", "run", "--host=0.0.0.0"]
```

「CMD」はコンテナ起動時のコマンドを記載する
「flask run --host=0.0.0.0」という記載もできるがカンマ区切りが推奨されている

## compose.yaml

``` yaml:compose.yaml
services:
  web:
    build: .
    environment:
      FLASK_RUN_RELOAD: 1
    ports:
      - "5000:5000"
    volumes:
      - ./src:/usr/src/app
```

「FLASK_RUN_RELOAD: 1」にするとマシン上で更新したファイルが
コンテナ側に即時反映される

log確認
```
docker compose logs web
```

イメージのビルド
```
docker compose build
```

更新が反映されない場合
```
docker compose build -no-cache
```

ビルド後コンテナ起動
```
docker compose up -d --build
```

# コンテナのネットワーク

Dockerで作成されたネットワークの確認
```
docker network ls
```

表示されたNAME欄の項目で下記の項目はDockerが自動で作成したデフォルトネットワーク
- bridge
コンテナ間、コンテナ外と通信
- host
Dockerホストのネットワークを使用
- none
通信不可

# 参考

- Docker&仮想サーバー完全入門
Webクリエイター＆エンジニアの作業がはかどる開発環境構築ガイド