Dockerの超基本をまとめてみる

プログラミング初学者 kurichiiの初投稿です。
記憶の定着を目指してアウトプットしたい！ということで、最近触り始めたDockerの超基本なことたちをまとめていきます！

# Dockerイメージとは
Dockerイメージは、コンテナの設計図のようなものです。
同じイメージからは同じコンテナを生成することができます。
Dockerイメージはレイヤー構造で、レイヤーの一つひとつがLinuxコマンドで構成され
1番下はベースレイヤーといい、LinuxOSです。
企業や個人が作成したDockerイメージがDockerhubで公開されており
ダウンロードして使用することができます。

# Dockerfileとは
Dockerfileは、Dockerイメージをファイル化したものです。
ファイルを読むと構成がすぐにわかります。


# DockerfileとDockerイメージの関係性
DockerfileとDockerイメージの関係性を簡単な図で示します。
![docker_relationship.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3841868/a4be5f30-fd9d-12b6-f29c-4aad8a1ef38a.png)


# 基本のdockerコマンド
Dockerを操作する上で必須のコマンドです。

## コンテナの起動
```
$ docker run イメージ名:タグ
```
イメージを指定して、コンテナ1つを起動するコマンドです。
ローカル上にイメージがない場合は、Dockerhubから自動で取得します。

以下のオプションがよく使われます。
| オプション |　意味 |
|:-:|:-:|
| --name  |  コンテナに任意の名前をつける |
| -d |  バックグラウンドで実行する |
| --rm |  コンテナ停止時にコンテナを削除　<br>コンテナの消し忘れ防止にもなる |
| --it  |  コンテナ内に入る<br>例）docker exec --it コンテナ名 /bin/bash |
| -p  |  ポートフォワーディング<br>ホストポート:コンテナポート |


イメージのタグを指定しない場合、デフォルトで現時点の最新バージョンがlatestタグで指定されます。
イメージとタグはセットで指定しましょう。

:::note warn
latestについて
latestは、実行する時期によってコンテナのバージョンが変わり、意図しないイメージを使用してしまうなどのトラブルに繋がる場合があります。
:::

## コンテナの一覧表示
```
$ docker ps
```
オプションを指定しない場合、稼働中のコンテナのみ表示します。
`-a`オプションで停止中のコンテナも含めて表示する。

## コンテナの起動/停止/再起動
```
$ docker start/stop/restart コンテナ名
```
１つまたは複数の実行中のコンテナを起動/停止/再起動します。

## コンテナの削除
```
$ docker rm コンテナ
```
停止中のコンテナを削除できます。
`-f`オプションで起動中のコンテナも強制削除できます。

:::note warn
コンテナを強制削除する場合
データの永続化をしていない場合は、コンテナを削除するとコンテナ内のデータも消えるため注意。
(コンテナ内で作成したファイルなど)
:::

## コンテナ内でコマンド実行
```
$ docker exec コンテナ名orID 実行したいコマンド
```
コンテナに入らずに、ホストOS上で起動中のコンテナ内でコマンドを実行できます。
`-it`オプションでコンテナ内に入ることができる。

:::note info
コンテナに入るとは？
コンテナ内のコマンドライン(bashやzsh)にアクセスすることで、
例えば、linuxコマンドなどで設定ファイルやエラーログを確認できます。
:::

## イメージの一覧表示
```
$ docker images
```
ローカルにあるイメージを全て表示します。
イメージは容量が大きいため、定期的に確認し不要なものは削除したほうがよいです。

## イメージの削除
```
$ docker rmi イメージ名orID
```
ローカルにあるイメージを削除できます。
しかし、起動中のコンテナのイメージは削除できません。
また、イメージは依存関係があるため、ベースイメージは先に削除できない。

:::note info
依存関係について
イメージのバージョンがいくつかある場合、ベースイメージとの差分だけ持っています。
:::

## コンテナとホストマシン間でファイルのコピー
```
//ホストからコンテナへ
$ docker cp ホストファイルのパス コンテナ指定:コンテナファイルのパス

//コンテナからホストへ
$ docker cp コンテナ指定:コンテナファイルのパス　ホストファイルのパス
```
ログファイルや設定ファイルの取り出しや編集で使います。

## コンテナのログ出力
```
$ docker logs コンテナ
```
`-f`オプションをつけると、リアルタイムでログを表示できます。
ターミナルがリアルタイム監視状態になり、コマンドを入力できない状態になります。

## イメージのダウンロード
```
$ docker pull イメージ名:タグ　[レジストリURL]
```
プライベートレジストリを指定することでDockerhub以外からイメージをダウンロードすることができます。
本番環境などの機密情報を含むイメージをダウンロードする場合などに使われます。
Dockerhubからダウンロードする場合は、`docker run`と同じ意味です。

## コンテナをイメージ化
```
$ docker commit コンテナ名 DockerhubID/イメージ名:タグ
```
コンテナに追加操作をした後に、オリジナルイメージを保存しておきたい場合に使用します。

## Dockerhubへイメージをアップロード
```
$ docker push アカウント名/イメージ名:タグ名
```
オリジナルイメージを自分のアカウントにアップロードできます。
Dockerhubアカウントへのログインが必要です。

## イメージの履歴を確認
```
$ docker history
```
Dockerhubからイメージをダウンロードした時など、dockerfileがないときでも
イメージがどのように作られたか確認することができます。



# docker composeとは
複数のコンテナを管理することができます。
設計図となるyamlファイルをもとにアプリケーション実行に必要なコンテナをまとめて実行することができます。
linkオプションでコンテナ同士を連携させる。


# yamlファイルの中身

`varsion`:Dockerのバージョン
`services`:稼働するコンテナ。"web","db"にあたる部分は任意の名前。
`image`:DockerHubから指定
`build`:Dockerfileのパスを指定
※serviceの下に必ずbuildかimageのどちらかを書く。
　基本buildを書くが、イメージをカスタマイズする必要がない場合はimageでok
　パスは相対パス（絶対パスの場合ユーザ個別の影響を受けてしまうから）
`conteiner_name`:コンテナに任意の名前をつける
※`docker run --name`と同じ
`volume`:コンテナにホストのディレクトリを共有
`ports`:ポート解放とポートフォワーディング
※volumesとportsの子要素には- (ハイフンとスペース)必要
※`docker run -p`と同じ

```yaml
version: "3"
services:
  db: #任意のサービス名
    image: mariadb:10.4 #imageかbuild必ず含める
    container_name: "wordpress-db"
    volumes:
      - ./db-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    
  wordpress:
    image: wordpress:5
    container_name: "wordpress-wp"
    volumes:
      - ./wp-data:/var/www/html
      # バインドマウントすることでデータの永続化
      # 設定ファイルを読み込ませることもできる
    ports:
      - "8000:80" #必ず改行.外部公開ポート:コンテナ内部ポート
    environment:
      WORDPRESS_DB_HOST: db:3306#db(servise名)→内部IPに変換
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
```

# docker composeの基本コマンド
docker-compose.ymlに書いたコンテナをまとめて操作します。
カレントディレクトリのdocker-compose.yamlのみ適用し、
docker-compose.yamlが存在しない場合は、上の階層を探しにいきます。
```bash
# 起動
$ docker compose up

# 停止と削除
$ docker compose down

# 再起動
# 設定ファイルを更新した際や挙動がおかしい時に再起動する
$ docker compose restart

# コンテナ一覧の表示
# 複数プロジェクトを立ち上げている際に見やすくなる
$ docker compose ps

# サービスを一つ指定してコマンドを実行
# フレームワークのインストールなどで便利
$ docker compose run <サービス名> <コマンド>
```

# さいごに
いつもQiitaをはじめネット上の技術ブログをかなり参考にさせていただいていますが、
実際に自分で文章にしてアウトプットとなると、かなり難しいと痛感しました...!
これから色々なことをブログにしたり、記事をアップデートしていく中でうまく言語化できるように頑張ります！