Docker 初歩の初歩

## 知っておく用語
ゲートウェイ　異なるネットワーク同士を接続する
NAT プライベートIPとグローバルIPの変換をする
ポート　通信先番号

## Dockerに関して
Dockerは今までの仮想化とは異なりOSの中核はホストOS、つまりローカルのものを使う
アプリごとにゲストOSを入れるvagrant等とは異なる、処理にかかるコストを軽減する

ただしコンテナにはまったくOSを入れないわけでは無く一部を担うソフトウェアは入れる
また、DockerはLinuxで動かします、つまりローカルの開発ではwindows上で動くLinuxが必要

コンテナは可搬性が高いので環境差異による不具合を避けれる
コンテナはイメージから作られる、一つのイメージから複数コンテナを作れる

コンテナはdocker hubから取得(pull)する方法と自身でdockerfileというテキストファイルを作成して
そこからビルド(build)をする事でイメージを構築する事も可能
ちなみに他の人に自分が作成したイメージを使って欲しい時はpushをする。

tagがバージョン名となる、Docker HubにもTagsとある。
```
docker image pull イメージ名：タグ名
```

## ライフサイクル
作成→実行→停止→削除
ここで注意点としては仮にコンテナに対して変更がある場合はコンテナに作成したコンテナに対して修正
ではなく<font color=red>削除して新たに作成するほうが手間がかからない。</font>しかしデータの保持が必要な場合は別途対策が必要(ボリュームに保存する)


下記のいずれかが必要
dockerfileはイメージを構築する際に利用
compose.yamlは


クライアントがデーモンに指示を出してdockerの処理をする
レジストリはイメージが置いてある場所、プルしたりする

docker desktopのcontainersは現在稼働しているコンテナを起動停止削除する
imagesはコンテナイメージが一覧で表示される。
vluemeはコンテナのデータの保存場所、ライフサイクル確認


## コンテナイメージの取得から起動～削除
docker hubから取得する場合は
```
dokcker image pull イメージ名：タグ名
```

```
docker 対象 操作
docker container runはイメージがローカルに無い場合一度pullしてからコンテナを作成します。
docker container run --name apache01 -p 8080:80 -d httpd
localhost:8080で表示されます。
```
コンテナの停止、削除
```
docker container stop apache01
docker container rm apache01
```

<font color=red>**上記では複数のコンテナが欲しい時毎回同じコマンドを打つ必要がある。
対策がDockerCompose、yamlファイルを参照してコンテナを立ち上げてくれる**</font>


## Docker Composeでyamlファイルからコンテナを生成
<font color=red>composeコマンドはcomposeで立ち上げたコンテナを対象とする</font>

複数のコンテナを一度に起動出来る。
yamlという拡張子のファイルに必要なコンテナ情報を記載する
yamlファイルを置くディレクトリ名がプロジェクト名となる。
- 作成したいコンテナの情報を整理する
- Docker composeファイルを作成する
- コマンドを使ってコンテナを作成・実行する

コマンドは使用するyamlファイルがある場所で実行

下記は```docker container run --name apache -p 8080:80 -d httpd```をイメージしている
<font color="red">**インデントに注意、またversion:"3"等の表記は不必要**</font>
```yaml
services:
  web: →コンテナ名
    image: httpd:2.4 →使用するimage
    ports: 
        - "8080:80" →Dockerホストとポートを紐づける
```

対象のディレクトリで下記コマンドで起動する
<font color=red>起動後コンテナが生成される</font>
```
docker compose up -d →dでデタッチモード
docker container ls →起動確認
docker container ls -a →全てのコンテナを確認
docker compose stop →コンテナを停止する
docker compose stop →起動
```

他にもyamlにはnetoworkだったりボリュームを定める事も可能

## ファイルのアップロード・ダウンロード CPコマンド
ファイルをコンテナへアップロードする

```
docker compose cp ホストのファイルパス　コンテナ名：コンテナ内ファイルパス
docker compose cp index.html web:/usr/local/apache2/htdocs/index.html
```

コンテナ内にあるファイルをローカルにコピーする
```
docker compose cp コンテナ名：コンテナ内のファイルパス　ホストのファイルパス
docker-compose cp web:/usr/local/apache2/htdocs/index.html .
```

## コンテナの削除・イメージの削除　downコマンド
rmコマンドが別途あるが紐づくネットワークの削除はしません。
ネットワークとコンテナを一度に削除するdownコマンドがあります。
```
docker compose down
```

イメージを削除する。
イメージを使用中のコンテナがある場合は削除できない
```
apache>docker compose down --rmi all
```


## composeを使ってDBの起動

```
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:
```
```
docker compose up -d
```

## コンテナに対しての操作コマンド　shellの立ち上げ
```
dokcer compose exec コンテナ名　コンテナで実行したいコマンド

dbのバージョン確認
docker compose exec db mariadb --version
```

コンテナ内でShellコマンドを入力したい場合は下記
```
docker compose exec db /bin/bash
mariadb --version
mariadb -u testuser -D testdb -p
```

## Docker ComposeでWordPressを立ち上げる
<font color=red>depends_onで作成順番がdb→wordpressとなる
理由としてはワードプレスはデータベースが無いと利用できない為</font>

```
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:
```
```
docker compose up -d
```

基本的にはひとつのコンテナに一つのサービスとする
dbとwordpressまとめる事はしない方が保守としては柔軟性がある。



## コンテナデータの永続化 ボリュームとバインド

### バインド
ファイルの変更が多い場合はバインドを利用ローカルの変更がコンテナにも反映される
<font color=red>一番下のvolumes: db-data:の後ろを削除してservices配下のvolumesにバインドを定義する</font>
```
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:
    #ローカルhtmlというフォルダが生成される。
    #コンテナ内のhtmlをバインドしている
      - ./html:/var/www/html
volumes:
  db-data:
```



## DockerFileを使ってのイメージ作成
<font color=blue>ここで確認したいのはDockerComposeはあくまでコンテナ生成の為に使用している、
Dockerfileはカスタムイメージの作成である。**カスタムイメージとはソフトウェアのインストールやファイルのコピーを実施したイメージ**</font>

<font color=red>**つまりDockerfileでイメージを作成してDockerComposeでコンテナの生成が可能**</font>

### Flaskのイメージ
flaskの<font color=green>**Dockerfile**</font>
```
# pythonをインストール
FROM python:3.10
# 作業ディレクトリを作成
WORKDIR /usr/src/app
# flaskをインストール
RUN pip install flask==2.1.0
# flaskに組み込まれているwebサーバーを起動
CMD ["flask", "run", "--host=0.0.0.0"]
```

flaskの<font color=blue>**Componentファイル**</font>

```
services:
  web:
  # 同一ディレクトリのDockerfileを元にコンテナを作成する今回はcompose.yamlと
  # 同じディレクトリな為 .と記載
    build: .
    environment:
      FLASK_ENV: development
    ports:
    # Flaskのデフォルトポート
      - "5000:5000"
    volumes:
      - ./src:/usr/src/app
```

Dockerfileからイメージのビルドを実施
```
docker compose up -d
```

## Dockerのネットワークに関して
dokcerは自動でネットワークを作成する。
bridge:コンテナ間とコンテナ外を通信する
host::Dockerホストのネットワークをそのまま使う
none:コンテナ間、コンテナ外とも通信できない。

下記ではservicesに記載されているのがコンテナ名となる
そしてwordpressコンテナではWORDPRESS_DB_HOST: dbと記載がある
つまり<font color="red">dbコンテナ名を指定する事でwordpressコンテナとdbコンテナが通信出来るようになっている</font>

```
# Docker Composeでは、
# 同じDocker Composeファイル内で定義されたサービスは、
# デフォルトで同じ内部ネットワークに属します
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
  #dbとする事でデータベースが生成されてからワードプレスのコンテナが起動する
    depends_on:
      - db
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
    ports:
      - "8080:80"
    volumes:
    #コンテナを起動するとローカルにhtmlというフォルダが生成される。
    #コンテナ内のhtmlをバインドしている
      - ./html:/var/www/html
volumes:
  db-data:
```