Dockerの基本動作

# はじめに

Dockerコンテナがどのように動くのか簡単にまとめたものになります。
主にこちらの書籍を参考にしています。

| [Docker/Kubernetes 実践コンテナ開発入門](http://blog.mamohacy.com/entry/2013/03/29/192149)<br><br>Docker/Kubernetesを活用したコンテナ開発スタイルを身につける! | <img src="https://images-na.ssl-images-amazon.com/images/I/51d69eJQMyL._SX396_BO1,204,203,200_.jpg" width=120>|
|:--|:-:|


# ソースコードとDockerfileの準備

以下のリポジトリに、本稿で紹介するDockerの基本動作確認用のソースとDockerfileを置いてあるので
git cloneして利用してください。

- [fumihachi94/hello_docker: docker勉強用](https://github.com/fumihachi94/hello_docker)

Go言語のコードで、以下ような挙動をするサーバアプリケーションとして作動します。

- 8080ポートにhttpリクエストを送ると"Hello Docker!!"とレスポンスする

このコードの中身は[「Docker/Kubernetes 実践コンテナ開発入門」](https://www.amazon.co.jp/Docker-Kubernetes-%E5%AE%9F%E8%B7%B5%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80-%E5%B1%B1%E7%94%B0-%E6%98%8E%E6%86%B2/dp/4297100339)の第2章で紹介されているものとほぼ同様です。
…というかまんまです（笑）

# Dockerイメージのビルド

ソースファイルとDockerfileを用意したら、`docker image build`コマンドでDockerイメージを作成していきます。
以下の例では`sample/echo`というイメージ名です。`sample`は名前空間で、コンフリクト回避のために名前空間をつけることが推奨されています。

```bash
$ docker image build -t sample/echo:latest .
```

```bash:実行結果
Sending build context to Docker daemon  56.32kB
Step 1/4 : FROM golang:1.13
1.13: Pulling from library/golang
376057ac6fa1: Pull complete 
5a63a0a859d8: Pull complete 
496548a8c952: Pull complete 
2adae3950d4d: Pull complete 
039b991354af: Pull complete 
036abadca78f: Pull complete 
0514917ef7dc: Pull complete 
Digest: sha256:c56dbb28a169f9bccdf398dc9d4bc8d41463352843dbcf03b6ef2fb3472c1794
Status: Downloaded newer image for golang:1.13
 ---> 84125009cb55
Step 2/4 : RUN mkdir /echo
 ---> Running in 2fea51c650a5
Removing intermediate container 2fea51c650a5
 ---> ec45bfb228d7
Step 3/4 : COPY main.go /echo
 ---> f1692e49f33b
Step 4/4 : CMD [ "go", "run", "/echo/main.go" ]
 ---> Running in 09eddbb7e969
Removing intermediate container 09eddbb7e969
 ---> d8956f84209a
Successfully built d8956f84209a
Successfully tagged sample/echo:latest
```

## イメージの確認

`docker image ls`コマンドで作成されたイメージを一覧表示できます。

```bash
$ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
sample/echo         latest              d8956f84209a        4 minutes ago       803MB
hello-world         latest              bf756fb1ae65        5 months ago        13.3kB <--以前作成したイメージ
```

[](###############################)

# コンテナの実行

```bash
$ docker container run sample/echo:latest 
2020/06/07 09:10:44 start server
```

Dockerコンテナ上のアプリケーションが正しく実行されていることを確認するため、
別のターミナルでhttpリクエストを送信してみましょう。
ローカルの8080ポートが公開されていないはずです。

```bash
$ curl http://localhost:8080
curl: (7) Failed to connect to localhost port 8080: 接続を拒否されました
```

コンテナの外からのリクエストをコンテナ内で実行されているアプリケーションまで到達させる必要があります。
そこで必要となるのがポートフォワーディングになります。

## ポートフォワーディング

ポートフォワーディングではホストマシンのポートをコンテナポートに紐付け、コンテナの外から来た通信をコンテナポートに転送することができます。

それでは、ポートフォワーディングを実行してみます。

- **コンテナを一度停止させる**

まず停止させたいコンテナの`CONTAINER ID`もしくは`NAMES`を`docker container ls`で確認します。

```bash
$ docker container ls
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS              PORTS               NAMES
16af6b5417d7        sample/echo:latest   "go run /echo/main.go"   About an hour ago   Up About an hour                        lucid_burnell
```

`CONTAINER ID`または`NAMES`でコンテナを停止させます。

```bash
# IDで停止させる場合
$ docker stop 16af6b5417d7

# NAMESで停止させる場合
$ docker stop lucid_burnell
```

- **ポートフォワーディング**

ホスト側の9000ポートをコンテナ側の8080ポートにポートフォワーディングします。

```bash
$ docker container run -d -p 9000:8080 sample/echo:latest
```

- **httpリクエストの送信**

9000ポートを指定してhttpリクエストを送信してみます。
今度は、`Hello Docker!!`とレスポンスが返ってくるはずです。

```bash
$ curl http://localhost:9000
Hello Docker!!
```

# コンテナの削除

```bash
$ docker rm <ID or Name>
```


# イメージの削除

練習用のイメージを作成したので、今後必要なければ削除しておいてください。
整理整頓大事！

- コンテナを持たいないイメージの削除

```bash
$ docker rmi d8956f84209a
```

- コンテナを持つイメージの削除（コンテナも削除される）

```bash
$ docker rmi -f d8956f84209a
```