Dockerを初めてみて

###はじめに
[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしているやっきーです。

プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

#Dockerとは
DockerはOSの仮想化の一種です。Dockerはコンテナ型の仮想サービスを提供します。VM(仮想マシン)に比べると軽量で動作が速いという特徴があります。また、ホストOSに直接アクセスするためオーバーヘッドが少なく、環境の違いによる影響を受けないという利点があります。ホストOSからは1つのプロセスとして認識されます。

#Dockerのダウンロード
windowsは [こちら](https://store.docker.com/editions/community/docker-ce-desktop-windows) から、Mac OSの方は [こちら](https://store.docker.com/editions/community/docker-ce-desktop-mac) からファイルをダウンロードします。ダウンロードするためには、Docker id へのログインが必要です。

インストール完了後、

```sh
$ docker run hello-world
```
を実行すると、

```sh

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 Hubからimageをpullする
Docker Hub にあるOS、アプリケーションの入ったimageをpullします。今回は、CentOSをpullします。
コマンドに、

```sh
$ sudo docker search centos | more
```

と入力すると、初回はパスワードを求められるので、PCに設定したパスワードを入力すると、

```sh
NAME                               DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
centos                             The official build of CentOS.                   5662                [OK]                
ansible/centos7-ansible            Ansible on Centos7                              125                                     [OK]
jdeathe/centos-ssh                 OpenSSH / Supervisor / EPEL/IUS/SCL Repos - …   114                                     [OK]
consol/centos-xfce-vnc             Centos container with "headless" VNC session…   100                                     [OK]
centos/mysql-57-centos7            MySQL 5.7 SQL database server                   64                                      
imagine10255/centos6-lnmp-php56    centos6-lnmp-php56                              57                                      [OK]
tutum/centos                       Simple CentOS docker image with SSH access      44                                      
centos/postgresql-96-centos7       PostgreSQL is an advanced Object-Relational …   39                                      
kinogmt/centos-ssh                 CentOS with SSH                                 29                                      [OK]
pivotaldata/centos-gpdb-dev        CentOS image for GPDB development. Tag names…   10  
#...(以下略)
(END)
```

のように、Docker HubにあるCentOSのimageが表示されます。

次に、

```sh
$ sudo docker pull centos
```

と入力すると、実際にcentosがpullされます。

```sh
$ sudo docker images
```
で、取得したイメージの一覧を表示します。

```sh
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
debian               latest              8e9f8546050d        3 weeks ago         114MB
centos               latest              0f3e07c0138f        5 weeks ago         220MB
```

確かに、centosがpullできていることが確認できました。また、複数のimageがあるように見えても、IMAGE IDが同じであれば、実体としては同じものです。

##imageを確認する
```sh
$ sudo docker inspect centos:latest #REPOSITORY:TAG
```

もしくは、

```sh
$ sudo docker inspect 0f3e #IMAGE ID　（一意に決まれば良いので上3-4桁を指定）
```

とすると、そのimageの詳細を確認できます。

##imageを削除する
```sh
$ sudo docker rmi 0f3e #IMAGE ID
```

で指定したIMAGE IDのimageを削除できます。

##Containerの起動
hello world と表示させるには、

```sh
$ sudo docker run centos echo "hello world"
```
と入力します。このときcentosのimageから新たにcontainerを作成し、そのcontainer上で```echo "hello world"```を実行されています。
containerを確認するには、

```sh
$ sudo docker ps #実行中のcontainer一覧
```
と入力します。
しかし、今回のコマンドではechoコマンド実行→表示→終了となるため、実行済みのcontainerを表示する必要があります。

```sh
sudo docker ps -a #実行の終わったcontainer一覧
```

```-a``` を加えることで今回実行したcontainerを確認できます。

##containerを削除する

```sh
$ sudo docker rm ae77　 #CONTAINER ID （一意に決まれば良いので上3-4桁を指定）
```
を実行することで指定したcontainerを削除できます。

##containerからimage作成

```sh
$ sudo docker run -i -t centos /bin/bash
#-iはインタラクティブモード
#-tはターミナル上で実行を表す
```
こうすることで、シェルが起動し、containerの中で作業ができるようになります。
ここで、 ```# touch hello.txt```を入力し、txtファイルを作成します。その後、 ```# ls ``` と入力すると、hello.txtが作成されたことが確認できます。
シェルを終了するには ```# exit ``` と入力します。

その後、```sudo docker ps -a``` で、作成したcontainerを確認します。

```sh
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                         PORTS                  NAMES

00e69866fdf7        centos              "/bin/bash"              3 hours ago         Exited (0) 3 hours ago                                cool_payne
```
次に、containerからimageを作ります。

```sh
$ sudo docker commit 00e name/hello #CONTAINER ID とimageの名前を指定する。
#image名は<ユーザー名>/OO が慣習
```
その後、```sudo docker images``` でimageが作成されたことを確認する。

```sh
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
name/hello          latest              13958dbea44e        About a minute ago   220MB
```

最後に、name/helloというimageからcontainerを作成します。

```
$ sudo docker run -i -t name/hello /bin/bash

[root@269ac2a49246 /]# ls
bin  dev  etc  hello.txt  home	lib  lib64  lost+found	media  mnt  opt  proc  root  run  sbin	srv  sys  tmp  usr  var
```

hello.txtが存在しているため、containerからname/helloを正しく作成できていたことが確認できました。


##imageのpush
ローカルで変更したimageをDocker Hubにpushすることができます。

###Docker Hubへログイン
まず、Docker Hubへログインします。

```sh
$ sudo docker login #これを入力
Login with your Docker ID to push and pull images from Docker Hub. If you dont have a Docker ID, head over to https://hub.docker.com to create one.
Username: XXXXX  #Docker ID を入力
Password:        #パスワードを入力
Login Succeeded
```

###pushする
では、imageをpushします。

```sh
$ sudo docker push name/hello #これを入力
The push refers to repository [docker.io/name/hello]
2f9d510d118b: Preparing 
ef753f60f983: Preparing 
9e607bb861a7: Preparing 
```

いい感じに進んでいると思ったのですが、

```sh
denied: requested access to the resource is denied #アクセス拒否
```

なぜか失敗したので調べてみたら、**Docker hubのユーザー名（Docker ID）と、imageにつけたユーザー名が異なるとダメ**だそうです。
[【備忘録】docker pushしたら拒否された - Qiita](https://qiita.com/shunchandayo/items/4ae35930fe9f85f535b0)　にあるように、image名を変更してから再チャレンジすると今度は成功しました。

#最後に
まだまだDockerのことを完全には把握できておらず、分かりにくい部分が多々あったかと思います。新たにわかったことがあれば追加していこうと思います。

#参考URL
[Docker入門 #1 【Dockerとは】 - Qiita](https://qiita.com/wMETAw/items/b9bc643ded4b92bf6add)
[Docker入門 (全11回) - プログラミングならドットインストール](https://dotinstall.com/lessons/basic_docker)
[【備忘録】docker pushしたら拒否された - Qiita](https://qiita.com/shunchandayo/items/4ae35930fe9f85f535b0)
[Dockerfileとは？実際にビルドしながらイメージを作成してみよう！ | キツネの惑星](https://kitsune.blog/dockerfile-summary#Dockerfile-4)