Docker入門 インストールからコンテナの起動まで

# この記事でやること
- GCPで作成したUbuntuVMにDockerをインストールする。
- Docker Hubよりコンテナイメージをダウンロードする。
- ダウンロードしたイメージからコンテナを作成し動かす。

# 環境
以下の内容でGCPにVMインスタンスを作成しています。

|カテゴリ|設定|
|---|---|
|リージョン|us-central 1(アイオワ)|
|ゾーン|us-central1-a|
|マシンファミリー|汎用|
|シリーズ|N1|
|マシンタイプ|n1-standard-1 (vCPU x 1、メモリ 3.75 GB)|
|OS|Ubuntu 18.04 LTS|
|ディスク|標準の永続ディスク(30GB)|

# Dockerをインストールする

作成したVMにsshでログインし、以下の手順を実行します。

## リポジトリの更新とパッケージの最新化

はじめに作成したVMに対して、リポジトリの更新とパッケージの最新化を行います。
以下のコマンドを実行します。

```terminal
$ sudo apt update
$ sudo apt upgrade
```

## インストール

[公式で紹介されている手順](https://matsuand.github.io/docs.docker.jp.onthefly/engine/install/ubuntu/)を参考にしています。以下のコマンドを実行します。

```terminal
# 1. 必要なツールをインストール
$ sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

# 2. Docker公式のGPGキーを追加
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# 3. リポジトリの設定
$ echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 4. Dockerをインストール
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin

# 5. インストールされているか確認(バージョンが表示されていれば成功です)
$ sudo docker -v
```

Dockerのコマンド(`docker ***`)はすべてルート権限が必要なので、常に`sudo`で実行するようにしてください。

# コンテナを起動して"Hello from Docker!"する

Dockerを使用する準備ができたので、実際にDockerイメージを取得してコンテナを起動させます。

## イメージとコンテナの違い

Dockerは「コンテナ」と呼ばれるホストOSとは隔離された領域で、別のOSやApacheなどのアプリケーションを動かしています。そのコンテナの元となるのが「イメージ」です。
イメージはコンテナを構築するためのライブラリなどが格納されており、これをもとにDockerはコンテナを作ります。

- イメージ: 設計図
- コンテナ: 設計図(イメージ)をもとにできた製品

と考えるとイメージしやすいと思います。

## イメージの取得

コンテナのベースとなるイメージは自分で作成するか[Docker Hub](https://hub.docker.com)から取得します。Docker Hubには公式をはじめ、たくさんのイメージが登録されています。
今回は動作確認として、[hello-worldイメージ](https://hub.docker.com/_/hello-world)を取得します。
イメージの取得は`docker pull`コマンドを使用します。書式は以下です。

```terminal
$ sudo docker pull [オプション] 名前[:タグ]
```
今回は、オプションはなしで名前は**hello-world**です。
以下のコマンドを実行してください。(タグについては後述しますが、省略してOKです)

```terminal
$ sudo docker pull hello-world
```

以下のコマンドを実行し、REPOSITORYにhello-worldが登録されていれば正しく取得できています。

```terminal
$ sudo docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
hello-world   latest    feb5d9fea6a5   11 months ago   13.3kB
```

### イメージのタグ

Dockerのイメージには**タグ**が付けられ、イメージ名の後ろに`:`で区切って指定します。
タグは主にバージョン管理のために使われ、`docker pull`コマンドでもタグを指定してイメージを取得できます。
タグは省略可能で、省略したときは`latest`を指定したのと同じことになります。

```terminal
# 以下のコマンドの実行結果は同じ
$ sudo docker pull hello-world
$ sudo docker pull hello-world:latest
```

つまり、先ほどの`docker pull hello-world`は暗黙的に最新版を指定していたわけです。

## イメージからコンテナを起動する

ダウンロードしたhello-worldイメージをベースに、コンテナを起動します。
コンテナの起動は`docker run`コマンドで行います。書式は以下です。

```terminal
$ sudo docker run [オプション] イメージ [コマンド] [引数...]
```

以下のコマンドを実行してください。
実行後に下記と同じメッセージが表示されたら、成功しています。

```terminal
$ sudo docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
```

次に、コンテナが作成されていること確認するため`docker ps`コマンドでコンテナの一覧を表示します。書式は以下です。

```terminal
$ sudo docker ps [オプション]
```

先ほど`docker run`コマンドを実行したことでコンテナが生成・起動されましたが、hello-worldコンテナはメッセージの出力が終わると稼働を停止してしまいます。そこで`-a`オプションを追加して停止しているコンテナ情報も表示させます。
以下のコマンドを実行してください。

```terminal
$ sudo docker ps -a
CONTAINER ID   IMAGE         COMMAND    CREATED         STATUS                     PORTS     NAMES
77c678506251   hello-world   "/hello"   2 minutes ago   Exited (0) 2 minutes ago             eloquent_lamarr
```

「IMAGE: hello-world」から、このコンテナが「hello-worldイメージ」をベースに作成されたことがわかります。

## コンテナおよびイメージの削除

最後に、今回使用したコンテナとイメージをDockerから削除しましょう。
まずはコンテナを削除します。コマンドと書式は以下です。

```terminal
$ sudo docker rm [オプション] コンテナID [コンテナID...]
```

削除に指定するコンテナIDは、`docker ps -a`コマンドで表示される「CONTAINER ID」を参照してください。
IDはとても長いですが、他のコンテナIDと衝突しなければ最初の3文字くらいまで省略してもOKです。
以下のコマンドを実行してください。コンテナIDは人によって異なりますので注意してください。

```terminal
$ sudo docker rm 77c
```

次にイメージの削除です。まずコマンドと書式です。

```terminal
$ sudo docker rmi [オプション] イメージID [イメージID...]
```
または
```terminal
$ sudo docker rmi [オプション] イメージ名 [イメージ名...]
```

コンテナの削除が`docker rm`でイメージの削除が`docker rmi`です。まぎらわしいので注意してください。
イメージの削除は「イメージID」かイメージ名を指定します。イメージIDを指定して削除する場合は`docker images`で該当イメージのIDを参照してください。

以下どちらかのコマンドを実行してhello-worldイメージを削除します。

イメージIDを指定して削除する場合
```terminal
$ sudo docker rmi feb
```
イメージ名を指定して削除する場合
```terminal
$ sudo docker rmi hello-world
```

# おわりに

今回はDockerのインストールからイメージの取得、コンテナの作成および起動までを行いました。
Dockerに興味はあるけれど、なかなか最初の一歩が踏み出せない方の参考になれば幸いです。