Dockerのおべんきょう


# Dockerとは

公式ドキュメントを日本語化したらこうなります

>Dockerは、開発者とシステム管理者 がコンテナを使用してアプリケーションを開発、展開、実行するためのプラットフォームです。Linuxコンテナを使用してアプリケーションを配備することをコンテナ化といいます。コンテナは新しいものではありませんが、アプリケーションを簡単に配備するためにコンテナを使用するのは簡単です。

イメージとコンテナ、サーバー、クライアントなどについてわかりやすくまとめてくれているのがこのサイトです。
[Dockerのすべてが5分でわかるまとめ!(コマンド一覧付き)](https://paiza.hatenablog.com/entry/docker_intro)


コンテナを定義するにはDockerfileというファイルを使用します。



# Docker Hubからイメージを持ってくる

※Docker Indexは今Docker Hubという名前になっています。

Dockerのサイトで検索してからpullしていきます。

Docker Hub 
https://hub.docker.com/

検索して、pullしたいものの名前を確認します。

これと同じことをターミナル上でもできます！

```.bash
docker search 検索したいもの
```

もしくは

```.bash
docker search 検索したいもの | more
```

個人的には下がオススメ


pullするにはこれ

```.bash
docker pull pullしたいもの
```

## imageがpullできたかどうかの確認

imageの一覧を確認してみます

```.bash
docker images
```

docker image ls　でもできます。

イメージのIDがそのイメージの実体を指すので、、ID番号が一緒の時は、実体も一緒ということです。


イメージの詳細を確認したい時は、方法は2種類あります。

1. イメージのリポジトリとタグを使用するバージョン

```
docker inspect リポジトリ名:タグ
```

2. イメージのIDを使うパターン

```
docker inspect イメージのID(最初の3~4文字くらいだけで良い)
```


## イメージを削除したい時は

これも先ほどと同様に2種類あります。

```
docker rmi リポジトリ名:タグ
```

もしくは

```
docker rmi イメージのID(最初の3~4文字くらいだけで良い)
```

このrmiは「remove image」で覚えておくと良いと思います。


# コンテナを操作する

```
docker run イメージ名 実行したいコマンド
```

バックグラウンドで実行したいなら、

```
docker run -d イメージ名　実行したいコマンド

「このイメージ名で、このコマンドを実行する」という意味になります。


実行しているコンテナを確認するには

```
docker ps
```

で、全てのコンテナを確認するには、

```
docker ps -a
```

最新の5つだけみたい！！という時はこのようにします。

```
docker ps -a -n=5
```

コンテナのログを見る場合はこうします。

```
docker logs コンテナのID
```

常にログを出しておきたい場合はこのようにします。

```
docker logs -f コンテナのID
```

実行中のコンテナを止めるには2通りあります。

```
docker stop ID番号
```

もしくは

```
docker kill ID番号
```

コンテナを実行するには

```
docker start
```

でいけます！


## コンテナからイメージを作る
コンテナからターミナルに入るにはこうします。

```
docker run -i -t イメージ名 /bin/bash
```

「インタラクティブモードで入り、ターミナルを使用する」という意味です。


ターミナルに入ったら、一旦ターミナルから抜けてください。

次は、イメージを作成します。

```
docker commit ID番号 イメージの名前
```

確認してみましょう

```
docker images
```

Docker image ls でもできる

# Dockerfileを作る

これまで、imageを作ってコンテナで編集してまたimageを作るという工程をやってきました。

それはdocker buildというコマンドでできます。


自動化するために、Dockerfileというファイルを作ります。

```dockerfile
# このイメージ名を使うよ
FROM イメージ名
# 誰がこのファイルを作成したか
MAINTAINER 名前　<メールアドレス> 

# RUNはbuildするときに実行されるもの（インストールとかできる）
RUN echo "buildなうです"

# CMDはrunするときに実行されるもの
# CMD echo "runなうです" (このように書くこともできるけど、推奨されているのは、以下の書き方)
CMD ["echo", "runなうです"]
```

このdockerfileを実行するには、

```
docker build
```
新しいイメージに名前をつけるには、こうします

```
docker build -t つけたい名前 . 
```

作ったイメージを実行させてみよう

```
docker run イメージ名
```

# もうちょっと実用的なdockerfileを作る

```dockerfile

# apache httpdをインストール
RUN yum install httpd

# /.index.htmlを/var/www/html/にコピー
ADD ./index.html /var/www/html/

# 外部に公開するポート番号を指定
EXPOSE 80

#RUNのときにサーバーを立ち上げる
CMD ["usr/sbin/httpd", "-D", "FOREGROUND"]
```

ホスト側のポートを8080、コンテナー側の80にリダイレクト
-dはバックグラウンドで動かすという意味
イメージを動かす

```.bash
docker run  -p 8080:80 -d イメージ名 
```

関係ないけど、上に出てこなかった物を紹介。
dockerファイルでワーキングディレクトリを指定したい場合はWORKDIR、パスを通したい時はENVを使います

```dockerfile

WORKDIR /app
ENV PATH $PATH:通したいパス
```

# イメージをpushする

Dockerのアカウントを持っていない人は公式サイトで登録してください

まずはDockerにログインします

```
docker login
```

イメージをpushします

```
docker push イメージ名
```

# docker-compose.yml

docker-compose.ymlファイルは、ドッカーコンテナがどのように振る舞うべきかを定義するファイルです。

## build

buildは何をするものかというと

>構築時に適用するオプションを指定します。
build で指定できるのは、構築用コンテクストのパスを含む文字列だけでなく、 context の配下にある特定の物（オブジェクト）や、 dockerfile のオプションと 引数 を指定できます。



だそうです。
一言で言えば、dockerfileからビルドするそう。

こんな感じで使うみたいです。


```.yml
build: ./dir

build:
  context: ./dir #DockerfileまでのパスやgitのリポジトリのURLとかを指定する
  dockerfile: Dockerfile-alternate # Dockerfileの代わりになるもの。構築時は別にファイルも使えますが、構築時のパスも指定する必要があります。
  args: #buildのオプション
    buildno: 1
```

### cap_add, cap_drop

> コンテナのケーパビリティ（capabilities）を追加・削除します。ケーパビリティの一覧は man 7 capabilities をご覧ください。

だそうです。

ケーパビリティってなんなんやろって調べたらこんなのが出てきました。

[明日使えない Linux の capabilities の話](http://nojima.hatenablog.com/entry/2016/12/03/000000)

[Docker のセキュリティ](http://docs.docker.jp/engine/security/security.html)


### command

>デフォルトのコマンドを上書きします。

だそうです。変更したいコマンドがあれば、上書きしましょう。

### container_name

自分でコンテナ名を指定できます。

こんな感じ

```.yml
container_name: hello
```

### depends_on

サービス間の依存関係を示します。

これは、公式ドキュメントがわかりやすい

サービス間の依存関係を指定したら、２つの効果があります。

>docker-compose up を実行したら、依存関係のある順番に従ってサービスを起動します。以下の例では、 web を開始する前に db と rails を実行します。
docker-compose up サービス（の名称） を実行したら、自動的に サービス の依存関係を処理します。以下の例では、 docker-compose up web を実行したら、 db と redis も作成・起動します。
簡単なサンプル：

```.yml
version: '2'
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres
```

### entorypoint

エントリーポイントを調べてみると、、、

>エントリポイントとは、コンピュータプログラムを構成するコードのうち、最初に実行することになっている位置のこと

だそうです、IT用語多すぎて難しい・・・

```.yml
entrypoint: /code/entrypoint.sh
```

こんな感じでしょうか

### env_file

ファイル上の定義から環境変数を追加します

>Compose ファイルを docker-compose -f ファイル名 で指定する場合は、 env_file ファイルは指定したディレクトリに対する相対パスとみなします。

なるほどなるほど


### environment
こちらも環境変数を追加します。
こっちはよく使うものだと思います。


データベースを使う時はこんな感じになります。

```.yml
environment:
      MYSQL_DATABASE: データベース名
      MYSQL_USER: ユーザー名
      MYSQL_PASSWORD: パスワード
      MYSQL_ROOT_PASSWORD: ルートのパスワード
```

パスワードが入ってなくても大丈夫なら

```.yml
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
```

とかもあります。

### expose

>ホストマシン上で公開するポートを指定せずに、コンテナの公開（露出）用のポート番号を指定します。これらはリンクされたサービス間でのみアクセス可能になります。内部で使うポートのみ指定できます。

だそうです。


### image

コンテナを起動する際に元となるイメージを指定します。

こんな感じ

```
image:hello
```


### links

コンテナを他のサービスとリンクします。

こんな感じ

```
links:
 - db
 - db:database
 - redis
```

### external

>このオプションを true に設定したら、Compose の外にネットワークを作成します（訳者注：Compose が管理していない Docker ネットワークを利用します、という意味）。 docker-compose up を実行してもネットワークを作成しません。もしネットワークが存在していなければ、エラーを返します。

だそうです。

# 新しいアプリケーションを実行する

 急にswarmという言葉が出てきたので、調べてみました。

[Docker SwarmによるDockerクラスタ環境の構築](https://knowledge.sakura.ad.jp/5197/)


まずは初期化

```
docker swarm init
```

アプリ名は自分でつけます。

```
docker stack deploy -c docker-compose.yml アプリ名
```

アプリの規模を拡大したり、縮小したりする場合は、再度実行するか、replicasの値を変更することでできます。


アプリを停止させる

```
docker stack rm アプリ名
```

swarmを停止する場合は以下のコマンドを実行します.

```
docker swarm leave --force
```